]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.c
sync tracker to remove duplicate display mode in ConOut virtual handle GOP instance.
[mirror_edk2.git] / MdeModulePkg / Universal / Console / ConSplitterDxe / ConSplitter.c
index babf3c6cd147948347015006ebd1a7f8e037f3c5..8e49c480972686426c5fd3ea1e4f7a729d48056d 100644 (file)
@@ -170,7 +170,8 @@ STATIC TEXT_OUT_SPLITTER_PRIVATE_DATA mConOut = {
     NULL\r
   },\r
   (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) NULL,\r
-  (TEXT_OUT_GOP_MODE *) NULL,\r
+  (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *) NULL,\r
+  0,\r
   0,\r
   TRUE,\r
   {\r
@@ -233,7 +234,8 @@ STATIC TEXT_OUT_SPLITTER_PRIVATE_DATA mStdErr = {
     NULL\r
   },\r
   (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) NULL,\r
-  (TEXT_OUT_GOP_MODE *) NULL,\r
+  (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *) NULL,\r
+  0,\r
   0,\r
   TRUE,\r
   {\r
@@ -663,6 +665,7 @@ ConSplitterTextOutConstructor (
   )\r
 {\r
   EFI_STATUS  Status;\r
+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info;\r
 \r
   //\r
   // Copy protocols template\r
@@ -722,21 +725,24 @@ ConSplitterTextOutConstructor (
     }\r
     //\r
     // Setup the DevNullGraphicsOutput to 800 x 600 x 32 bits per pixel\r
+    // DevNull will be updated to user-defined mode after driver has started.\r
     //\r
-    if ((ConOutPrivate->GraphicsOutputModeBuffer = AllocateZeroPool (sizeof (TEXT_OUT_GOP_MODE))) == NULL) {\r
+    if ((ConOutPrivate->GraphicsOutputModeBuffer = AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION))) == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
-    ConOutPrivate->GraphicsOutputModeBuffer[0].HorizontalResolution = 800;\r
-    ConOutPrivate->GraphicsOutputModeBuffer[0].VerticalResolution = 600;\r
+    Info = &ConOutPrivate->GraphicsOutputModeBuffer[0];\r
+    Info->Version = 0;\r
+    Info->HorizontalResolution = 800;\r
+    Info->VerticalResolution = 600;\r
+    Info->PixelFormat = PixelBltOnly;\r
+    Info->PixelsPerScanLine = 800;\r
+    CopyMem (ConOutPrivate->GraphicsOutput.Mode->Info, Info, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
+    ConOutPrivate->GraphicsOutput.Mode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
 \r
     //\r
     // Initialize the following items, theset items remain unchanged in GraphicsOutput->SetMode()\r
-    //  GraphicsOutputMode->Info->Version, GraphicsOutputMode->Info->PixelFormat\r
-    //  GraphicsOutputMode->SizeOfInfo, GraphicsOutputMode->FrameBufferBase, GraphicsOutputMode->FrameBufferSize\r
+    // GraphicsOutputMode->FrameBufferBase, GraphicsOutputMode->FrameBufferSize\r
     //\r
-    ConOutPrivate->GraphicsOutput.Mode->Info->Version = 0;\r
-    ConOutPrivate->GraphicsOutput.Mode->Info->PixelFormat = PixelBltOnly;\r
-    ConOutPrivate->GraphicsOutput.Mode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
     ConOutPrivate->GraphicsOutput.Mode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) NULL;\r
     ConOutPrivate->GraphicsOutput.Mode->FrameBufferSize = 0;\r
 \r
@@ -2464,14 +2470,15 @@ Returns:
 {\r
   EFI_STATUS                           Status;\r
   UINTN                                Index;\r
-  TEXT_OUT_GOP_MODE                    *Mode;\r
+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Mode;\r
   UINTN                                SizeOfInfo;\r
   EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;\r
   EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE    *CurrentGraphicsOutputMode;\r
-  TEXT_OUT_GOP_MODE                    *ModeBuffer;\r
-  TEXT_OUT_GOP_MODE                    *MatchedMode;\r
+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *ModeBuffer;\r
+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *MatchedMode;\r
   UINTN                                NumberIndex;\r
   BOOLEAN                              Match;\r
+  BOOLEAN                              AlreadyExist;\r
 \r
   if ((GraphicsOutput == NULL) && (UgaDraw == NULL)) {\r
     return EFI_UNSUPPORTED;\r
@@ -2479,6 +2486,17 @@ Returns:
 \r
   CurrentGraphicsOutputMode = Private->GraphicsOutput.Mode;\r
 \r
+  Index        = 0;\r
+\r
+  if (Private->CurrentNumberOfUgaDraw != 0) {\r
+    //\r
+    // If any UGA device has already been added, then there is no need to\r
+    // calculate intersection of display mode of different GOP/UGA device,\r
+    // since only one display mode will be exported (i.e. user-defined mode)\r
+    //\r
+    goto Done;\r
+  }\r
+\r
   if (GraphicsOutput != NULL) {\r
     if (Private->CurrentNumberOfGraphicsOutput == 0) {\r
         //\r
@@ -2494,7 +2512,7 @@ Returns:
         //\r
         // Allocate resource for the private mode buffer\r
         //\r
-        ModeBuffer = AllocatePool (sizeof (TEXT_OUT_GOP_MODE) * GraphicsOutput->Mode->MaxMode);\r
+        ModeBuffer = AllocatePool (GraphicsOutput->Mode->SizeOfInfo * GraphicsOutput->Mode->MaxMode);\r
         if (ModeBuffer == NULL) {\r
           return EFI_OUT_OF_RESOURCES;\r
         }\r
@@ -2510,8 +2528,7 @@ Returns:
           if (EFI_ERROR (Status)) {\r
             return Status;\r
           }\r
-          Mode->HorizontalResolution = Info->HorizontalResolution;\r
-          Mode->VerticalResolution = Info->VerticalResolution;\r
+          CopyMem (Mode, Info, SizeOfInfo);\r
           Mode++;\r
           FreePool (Info);\r
         }\r
@@ -2519,7 +2536,7 @@ Returns:
       //\r
       // Check intersection of display mode\r
       //\r
-      ModeBuffer = AllocatePool (sizeof (TEXT_OUT_GOP_MODE) * CurrentGraphicsOutputMode->MaxMode);\r
+      ModeBuffer = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION) * CurrentGraphicsOutputMode->MaxMode);\r
       if (ModeBuffer == NULL) {\r
         return EFI_OUT_OF_RESOURCES;\r
       }\r
@@ -2535,7 +2552,7 @@ Returns:
             return Status;\r
           }\r
           if ((Info->HorizontalResolution == Mode->HorizontalResolution) &&\r
-              (Info->VerticalResolution == Mode->VerticalResolution)){\r
+              (Info->VerticalResolution == Mode->VerticalResolution)) {\r
             Match = TRUE;\r
             FreePool (Info);\r
             break;\r
@@ -2544,8 +2561,28 @@ Returns:
         }\r
 \r
         if (Match) {\r
-          CopyMem (MatchedMode, Mode, sizeof (TEXT_OUT_GOP_MODE));\r
-          MatchedMode++;\r
+          AlreadyExist = FALSE;\r
+\r
+          for (Info = ModeBuffer; Info < MatchedMode; Info++) {\r
+            if ((Info->HorizontalResolution == Mode->HorizontalResolution) &&\r
+                (Info->VerticalResolution == Mode->VerticalResolution)) {\r
+              AlreadyExist = TRUE;\r
+              break;\r
+            }\r
+          }\r
+\r
+          if (!AlreadyExist) {\r
+            CopyMem (MatchedMode, Mode, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
+\r
+            //\r
+            // Physical frame buffer is no longer available, change PixelFormat to PixelBltOnly\r
+            //\r
+            MatchedMode->Version = 0;\r
+            MatchedMode->PixelFormat = PixelBltOnly;\r
+            ZeroMem (&MatchedMode->PixelInformation, sizeof (EFI_PIXEL_BITMASK));\r
+\r
+            MatchedMode++;\r
+          }\r
         }\r
 \r
         Mode++;\r
@@ -2560,7 +2597,7 @@ Returns:
       //\r
       // Physical frame buffer is no longer available when there are more than one physical GOP devices\r
       //\r
-      CurrentGraphicsOutputMode->MaxMode = (UINT32) (((UINTN) MatchedMode - (UINTN) ModeBuffer) / sizeof (TEXT_OUT_GOP_MODE));\r
+      CurrentGraphicsOutputMode->MaxMode = (UINT32) (((UINTN) MatchedMode - (UINTN) ModeBuffer) / sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
       CurrentGraphicsOutputMode->Info->PixelFormat = PixelBltOnly;\r
       ZeroMem (&CurrentGraphicsOutputMode->Info->PixelInformation, sizeof (EFI_PIXEL_BITMASK));\r
       CurrentGraphicsOutputMode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
@@ -2584,21 +2621,19 @@ Returns:
       Index = 0;\r
     }\r
 \r
-    //\r
-    // Current mode number may need update now, so set it to an invalide mode number\r
-    //\r
-    CurrentGraphicsOutputMode->Mode = 0xffff;\r
-  } else {\r
+  }\r
+  if (UgaDraw != NULL) {\r
     //\r
     // For UGA device, it's inconvenient to retrieve all the supported display modes.\r
     // To simplify the implementation, only add one resolution(800x600, 32bit color depth) as defined in UEFI spec\r
     //\r
     CurrentGraphicsOutputMode->MaxMode = 1;\r
-    CurrentGraphicsOutputMode->Info->Version = 0;\r
-    CurrentGraphicsOutputMode->Info->HorizontalResolution = 800;\r
-    CurrentGraphicsOutputMode->Info->VerticalResolution = 600;\r
-    CurrentGraphicsOutputMode->Info->PixelFormat = PixelBltOnly;\r
-    CurrentGraphicsOutputMode->Info->PixelsPerScanLine = 800;\r
+    Info = CurrentGraphicsOutputMode->Info;\r
+    Info->Version = 0;\r
+    Info->HorizontalResolution = 800;\r
+    Info->VerticalResolution = 600;\r
+    Info->PixelFormat = PixelBltOnly;\r
+    Info->PixelsPerScanLine = 800;\r
     CurrentGraphicsOutputMode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
     CurrentGraphicsOutputMode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) NULL;\r
     CurrentGraphicsOutputMode->FrameBufferSize = 0;\r
@@ -2606,26 +2641,33 @@ Returns:
     //\r
     // Update the private mode buffer\r
     //\r
-    ModeBuffer = &Private->GraphicsOutputModeBuffer[0];\r
-    ModeBuffer->HorizontalResolution = 800;\r
-    ModeBuffer->VerticalResolution   = 600;\r
+    CopyMem (&Private->GraphicsOutputModeBuffer[0], Info, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
 \r
     //\r
-    // Current mode is unknow now, set it to an invalid mode number 0xffff\r
+    // Only mode 0 is available to be set\r
     //\r
-    CurrentGraphicsOutputMode->Mode = 0xffff;\r
     Index = 0;\r
   }\r
 \r
+Done:\r
+\r
+  if (GraphicsOutput != NULL) {\r
+    Private->CurrentNumberOfGraphicsOutput++;\r
+  }\r
+  if (UgaDraw != NULL) {\r
+    Private->CurrentNumberOfUgaDraw++;\r
+  }\r
+\r
   //\r
   // Force GraphicsOutput mode to be set,\r
   // regardless whether the console is in EfiConsoleControlScreenGraphics or EfiConsoleControlScreenText mode\r
   //\r
   Private->HardwareNeedsStarting = TRUE;\r
+  //\r
+  // Current mode number may need update now, so set it to an invalid mode number\r
+  //\r
   Status = Private->GraphicsOutput.SetMode (&Private->GraphicsOutput, (UINT32) Index);\r
 \r
-  Private->CurrentNumberOfGraphicsOutput++;\r
-\r
   return Status;\r
 }\r
 \r
@@ -2737,7 +2779,7 @@ Returns:
     //\r
     // The new console supports the same mode of the current console so sync up\r
     //\r
-    DevNullSyncGopStdOut (Private);\r
+    DevNullSyncStdOut (Private);\r
   } else {\r
     //\r
     // If ConOut, then set the mode to Mode #0 which us 80 x 25\r
@@ -2781,6 +2823,14 @@ Returns:
     if (TextOutList->TextOut == TextOut) {\r
       CopyMem (TextOutList, TextOutList + 1, sizeof (TEXT_OUT_AND_GOP_DATA) * Index);\r
       CurrentNumOfConsoles--;\r
+    if (FeaturePcdGet (PcdConOutGopSupport)) {\r
+      if (TextOutList->UgaDraw != NULL) {\r
+        Private->CurrentNumberOfUgaDraw--;\r
+      }\r
+      if (TextOutList->GraphicsOutput != NULL) {\r
+        Private->CurrentNumberOfGraphicsOutput--;\r
+      }\r
+    }\r
       break;\r
     }\r
 \r