]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkModulePkg/Universal/Console/ConSplitter/Dxe/ConSplitterGraphics.c
Merge GOP related code from r8->r9.
[mirror_edk2.git] / EdkModulePkg / Universal / Console / ConSplitter / Dxe / ConSplitterGraphics.c
index 412d695d77e21c975cf9c9697daaa7560bb4578b..5aa2bae2f05f73505240c74764b2ece3f156a38d 100644 (file)
@@ -32,7 +32,7 @@ EFIAPI
 ConSpliterConsoleControlGetMode (\r
   IN  EFI_CONSOLE_CONTROL_PROTOCOL    *This,\r
   OUT EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode,\r
-  OUT BOOLEAN                         *UgaExists,\r
+  OUT BOOLEAN                         *GopExists,\r
   OUT BOOLEAN                         *StdInLocked\r
   )\r
 /*++\r
@@ -63,13 +63,13 @@ ConSpliterConsoleControlGetMode (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  *Mode = Private->UgaMode;\r
+  *Mode = Private->ConsoleOutputMode;\r
 \r
-  if (UgaExists != NULL) {\r
-    *UgaExists = FALSE;\r
+  if (GopExists != NULL) {\r
+    *GopExists = FALSE;\r
     for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {\r
-      if (Private->TextOutList[Index].UgaDraw != NULL) {\r
-        *UgaExists = TRUE;\r
+      if ((Private->TextOutList[Index].GraphicsOutput != NULL) || (Private->TextOutList[Index].UgaDraw != NULL)) {\r
+        *GopExists = TRUE;\r
         break;\r
       }\r
     }\r
@@ -107,7 +107,7 @@ ConSpliterConsoleControlSetMode (
 {\r
   TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;\r
   UINTN                           Index;\r
-  TEXT_OUT_AND_UGA_DATA           *TextAndUga;\r
+  TEXT_OUT_AND_GOP_DATA           *TextAndGop;\r
   BOOLEAN                         Supported;\r
 \r
   Private = CONSOLE_CONTROL_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
@@ -117,9 +117,9 @@ ConSpliterConsoleControlSetMode (
   }\r
 \r
   Supported   = FALSE;\r
-  TextAndUga  = &Private->TextOutList[0];\r
-  for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++, TextAndUga++) {\r
-    if (TextAndUga->UgaDraw != NULL) {\r
+  TextAndGop  = &Private->TextOutList[0];\r
+  for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++, TextAndGop++) {\r
+    if ((TextAndGop->GraphicsOutput != NULL) || (TextAndGop->UgaDraw != NULL)) {\r
       Supported = TRUE;\r
       break;\r
     }\r
@@ -129,28 +129,513 @@ ConSpliterConsoleControlSetMode (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
-  Private->UgaMode  = Mode;\r
+  Private->ConsoleOutputMode  = Mode;\r
 \r
-  TextAndUga        = &Private->TextOutList[0];\r
-  for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++, TextAndUga++) {\r
+  TextAndGop = &Private->TextOutList[0];\r
+  for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++, TextAndGop++) {\r
 \r
-    TextAndUga->TextOutEnabled = TRUE;\r
+    TextAndGop->TextOutEnabled = TRUE;\r
     //\r
     // If we are going into Graphics mode disable ConOut to any UGA device\r
     //\r
-    if ((Mode == EfiConsoleControlScreenGraphics) && (TextAndUga->UgaDraw != NULL)) {\r
-      TextAndUga->TextOutEnabled = FALSE;\r
-      DevNullUgaSync (Private, TextAndUga->UgaDraw);\r
+    if ((Mode == EfiConsoleControlScreenGraphics) &&((TextAndGop->GraphicsOutput != NULL) || (TextAndGop->UgaDraw != NULL))) {\r
+      TextAndGop->TextOutEnabled = FALSE;\r
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)\r
+      DevNullGopSync (Private, TextAndGop->GraphicsOutput, TextAndGop->UgaDraw);\r
+#else\r
+      DevNullUgaSync (Private, TextAndGop->UgaDraw);\r
+#endif\r
     }\r
   }\r
 \r
   if (Mode == EfiConsoleControlScreenText) {\r
-    DevNullSyncUgaStdOut (Private);\r
+    DevNullSyncGopStdOut (Private);\r
   }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)\r
+EFI_STATUS\r
+EFIAPI\r
+ConSpliterGraphicsOutputQueryMode (\r
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,\r
+  IN  UINT32                                ModeNumber,\r
+  OUT UINTN                                 *SizeOfInfo,\r
+  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  **Info\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Return the current video mode information.\r
+\r
+  Arguments:\r
+    This                  - Protocol instance pointer.\r
+    ModeNumber            - The mode number to return information on.\r
+    Info                  - Caller allocated buffer that returns information about ModeNumber.\r
+    SizeOfInfo            - A pointer to the size, in bytes, of the Info buffer.\r
+\r
+  Returns:\r
+    EFI_SUCCESS           - Mode information returned.\r
+    EFI_BUFFER_TOO_SMALL  - The Info buffer was too small.\r
+    EFI_DEVICE_ERROR      - A hardware error occurred trying to retrieve the video mode.\r
+    EFI_NOT_STARTED       - Video display is not initialized. Call SetMode ()\r
+    EFI_INVALID_PARAMETER - One of the input args was NULL.\r
+\r
+--*/\r
+{\r
+  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;\r
+  EFI_STATUS                      Status;\r
+  TEXT_OUT_GOP_MODE               *Mode;\r
+\r
+  if (This == NULL || Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode->MaxMode) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // retrieve private data\r
+  //\r
+  Private = GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  if (Private->HardwareNeedsStarting) {\r
+    return EFI_NOT_STARTED;\r
+  }\r
+\r
+  Status = gBS->AllocatePool (\r
+                  EfiBootServicesData,\r
+                  sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),\r
+                  Info\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
+\r
+  CopyMem (*Info, Private->GraphicsOutput.Mode->Info, *SizeOfInfo);\r
+  Mode = &Private->GraphicsOutputModeBuffer[ModeNumber];\r
+  (*Info)->HorizontalResolution = Mode->HorizontalResolution;\r
+  (*Info)->VerticalResolution = Mode->VerticalResolution;\r
+  (*Info)->PixelsPerScanLine = Mode->HorizontalResolution;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+ConSpliterGraphicsOutputSetMode (\r
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL * This,\r
+  IN  UINT32                       ModeNumber\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Graphics output protocol interface to set video mode\r
+\r
+  Arguments:\r
+    This             - Protocol instance pointer.\r
+    ModeNumber       - The mode number to be set.\r
+\r
+  Returns:\r
+    EFI_SUCCESS      - Graphics mode was changed.\r
+    EFI_DEVICE_ERROR - The device had an error and could not complete the request.\r
+    EFI_UNSUPPORTED  - ModeNumber is not supported by this device.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                             Status;\r
+  TEXT_OUT_SPLITTER_PRIVATE_DATA         *Private;\r
+  UINTN                                  Index;\r
+  EFI_STATUS                             ReturnStatus;\r
+  TEXT_OUT_GOP_MODE                      *Mode;\r
+  UINTN                                  Size;\r
+  EFI_GRAPHICS_OUTPUT_PROTOCOL           *GraphicsOutput;\r
+  UINTN                                  NumberIndex;\r
+  UINTN                                  SizeOfInfo;\r
+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION   *Info;\r
+  EFI_UGA_DRAW_PROTOCOL                  *UgaDraw;\r
+\r
+  if (ModeNumber >= This->Mode->MaxMode) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  if (ModeNumber == This->Mode->Mode) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  Private = GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  //\r
+  // GopDevNullSetMode ()\r
+  //\r
+  ReturnStatus = EFI_SUCCESS;\r
+\r
+  //\r
+  // Free the old version\r
+  //\r
+  if (Private->GraphicsOutputBlt != NULL) {\r
+    gBS->FreePool (Private->GraphicsOutputBlt);\r
+  }\r
+\r
+  //\r
+  // Allocate the virtual Blt buffer\r
+  //\r
+  Mode = &Private->GraphicsOutputModeBuffer[ModeNumber];\r
+  Size = Mode->HorizontalResolution * Mode->VerticalResolution * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
+  Private->GraphicsOutputBlt = AllocateZeroPool (Size);\r
+\r
+  if (Private->GraphicsOutputBlt == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  if (!Private->HardwareNeedsStarting) {\r
+    if (Private->ConsoleOutputMode != EfiConsoleControlScreenGraphics) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+  }\r
+  //\r
+  // return the worst status met\r
+  //\r
+  for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {\r
+    GraphicsOutput = Private->TextOutList[Index].GraphicsOutput;\r
+    if (GraphicsOutput != NULL) {\r
+      //\r
+      // Find corresponding ModeNumber of this GraphicsOutput instance\r
+      //\r
+      for (NumberIndex = 0; NumberIndex < GraphicsOutput->Mode->MaxMode; NumberIndex ++) {\r
+        Status = GraphicsOutput->QueryMode (GraphicsOutput, (UINT32) NumberIndex, &SizeOfInfo, &Info);\r
+        if (EFI_ERROR (Status)) {\r
+          return Status;\r
+        }\r
+        if ((Info->HorizontalResolution == Mode->HorizontalResolution) && (Info->VerticalResolution == Mode->VerticalResolution)) {\r
+          gBS->FreePool (Info);\r
+          break;\r
+        }\r
+        gBS->FreePool (Info);\r
+      }\r
+\r
+      Status = GraphicsOutput->SetMode (GraphicsOutput, (UINT32) NumberIndex);\r
+      if (EFI_ERROR (Status)) {\r
+        ReturnStatus = Status;\r
+      }\r
+    }\r
+\r
+    UgaDraw = Private->TextOutList[Index].UgaDraw;\r
+    if (UgaDraw != NULL) {\r
+      Status = UgaDraw->SetMode (\r
+                          UgaDraw,\r
+                          Mode->HorizontalResolution,\r
+                          Mode->VerticalResolution,\r
+                          32,\r
+                          60\r
+                          );\r
+      if (EFI_ERROR (Status)) {\r
+        ReturnStatus = Status;\r
+      }\r
+    }\r
+  }\r
+\r
+  This->Mode->Mode = ModeNumber;\r
+\r
+  Info = This->Mode->Info;\r
+  Info->HorizontalResolution = Mode->HorizontalResolution;\r
+  Info->VerticalResolution   = Mode->VerticalResolution;\r
+  Info->PixelsPerScanLine    = Mode->HorizontalResolution;\r
+\r
+  //\r
+  // Information is not enough here, so the following items remain unchanged:\r
+  //  GraphicsOutputMode->Info->Version, GraphicsOutputMode->Info->PixelFormat\r
+  //  GraphicsOutputMode->SizeOfInfo, GraphicsOutputMode->FrameBufferBase, GraphicsOutputMode->FrameBufferSize\r
+  // These items will be initialized/updated when a new GOP device is added into ConsoleSplitter.\r
+  //\r
+\r
+  Private->HardwareNeedsStarting = FALSE;\r
+\r
+  return ReturnStatus;\r
+}\r
+\r
+EFI_STATUS\r
+DevNullGraphicsOutputBlt (\r
+  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA                *Private,\r
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL                 *BltBuffer, OPTIONAL\r
+  IN  EFI_GRAPHICS_OUTPUT_BLT_OPERATION             BltOperation,\r
+  IN  UINTN                                         SourceX,\r
+  IN  UINTN                                         SourceY,\r
+  IN  UINTN                                         DestinationX,\r
+  IN  UINTN                                         DestinationY,\r
+  IN  UINTN                                         Width,\r
+  IN  UINTN                                         Height,\r
+  IN  UINTN                                         Delta         OPTIONAL\r
+  )\r
+{\r
+  UINTN                         SrcY;\r
+  UINTN                         Index;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltPtr;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *ScreenPtr;\r
+  UINTN                         HorizontalResolution;\r
+  UINTN                         VerticalResolution;\r
+\r
+  if ((BltOperation < EfiBltVideoFill) || (BltOperation >= EfiGraphicsOutputBltOperationMax)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Width == 0 || Height == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Delta == 0) {\r
+    Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
+  }\r
+\r
+  HorizontalResolution  = Private->GraphicsOutput.Mode->Info->HorizontalResolution;\r
+  VerticalResolution    = Private->GraphicsOutput.Mode->Info->VerticalResolution;\r
+\r
+  //\r
+  // We need to fill the Virtual Screen buffer with the blt data.\r
+  //\r
+  if (BltOperation == EfiBltVideoToBltBuffer) {\r
+    //\r
+    // Video to BltBuffer: Source is Video, destination is BltBuffer\r
+    //\r
+    if ((SourceY + Height) > VerticalResolution) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    if ((SourceX + Width) > HorizontalResolution) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    BltPtr    = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer + DestinationY * Delta + DestinationX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+    ScreenPtr = &Private->GraphicsOutputBlt[SourceY * HorizontalResolution + SourceX];\r
+    while (Height) {\r
+      CopyMem (BltPtr, ScreenPtr, Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+      BltPtr = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltPtr + Delta);\r
+      ScreenPtr += HorizontalResolution;\r
+      Height--;\r
+    }\r
+  } else {\r
+    //\r
+    // BltBuffer to Video: Source is BltBuffer, destination is Video\r
+    //\r
+    if (DestinationY + Height > VerticalResolution) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    if (DestinationX + Width > HorizontalResolution) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    ScreenPtr = &Private->GraphicsOutputBlt[DestinationY * HorizontalResolution + DestinationX];\r
+    SrcY      = SourceY;\r
+    while (Height) {\r
+      if (BltOperation == EfiBltVideoFill) {\r
+        for (Index = 0; Index < Width; Index++) {\r
+          ScreenPtr[Index] = *BltBuffer;\r
+        }\r
+      } else {\r
+        if (BltOperation == EfiBltBufferToVideo) {\r
+          BltPtr = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer + SrcY * Delta + SourceX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+        } else {\r
+          BltPtr = &Private->GraphicsOutputBlt[SrcY * HorizontalResolution + SourceX];\r
+        }\r
+\r
+        CopyMem (ScreenPtr, BltPtr, Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+      }\r
+\r
+      ScreenPtr += HorizontalResolution;\r
+      SrcY++;\r
+      Height--;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+ConSpliterGraphicsOutputBlt (\r
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL                  *This,\r
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL                 *BltBuffer, OPTIONAL\r
+  IN  EFI_GRAPHICS_OUTPUT_BLT_OPERATION             BltOperation,\r
+  IN  UINTN                                         SourceX,\r
+  IN  UINTN                                         SourceY,\r
+  IN  UINTN                                         DestinationX,\r
+  IN  UINTN                                         DestinationY,\r
+  IN  UINTN                                         Width,\r
+  IN  UINTN                                         Height,\r
+  IN  UINTN                                         Delta         OPTIONAL\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    The following table defines actions for BltOperations:\r
+    EfiBltVideoFill - Write data from the  BltBuffer pixel (SourceX, SourceY)\r
+      directly to every pixel of the video display rectangle\r
+      (DestinationX, DestinationY)\r
+      (DestinationX + Width, DestinationY + Height).\r
+      Only one pixel will be used from the BltBuffer. Delta is NOT used.\r
+    EfiBltVideoToBltBuffer - Read data from the video display rectangle\r
+      (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in\r
+      the BltBuffer rectangle (DestinationX, DestinationY )\r
+      (DestinationX + Width, DestinationY + Height). If DestinationX or\r
+      DestinationY is not zero then Delta must be set to the length in bytes\r
+      of a row in the BltBuffer.\r
+    EfiBltBufferToVideo - Write data from the  BltBuffer rectangle\r
+      (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the\r
+      video display rectangle (DestinationX, DestinationY)\r
+      (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is\r
+      not zero then Delta must be set to the length in bytes of a row in the\r
+      BltBuffer.\r
+    EfiBltVideoToVideo - Copy from the video display rectangle\r
+      (SourceX, SourceY) (SourceX + Width, SourceY + Height) .\r
+      to the video display rectangle (DestinationX, DestinationY)\r
+      (DestinationX + Width, DestinationY + Height).\r
+     The BltBuffer and Delta  are not used in this mode.\r
+\r
+  Arguments:\r
+    This          - Protocol instance pointer.\r
+    BltBuffer     - Buffer containing data to blit into video buffer. This\r
+                    buffer has a size of Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
+    BltOperation  - Operation to perform on BlitBuffer and video memory\r
+    SourceX       - X coordinate of source for the BltBuffer.\r
+    SourceY       - Y coordinate of source for the BltBuffer.\r
+    DestinationX  - X coordinate of destination for the BltBuffer.\r
+    DestinationY  - Y coordinate of destination for the BltBuffer.\r
+    Width         - Width of rectangle in BltBuffer in pixels.\r
+    Height        - Hight of rectangle in BltBuffer in pixels.\r
+    Delta         -\r
+\r
+  Returns:\r
+    EFI_SUCCESS           - The Blt operation completed.\r
+    EFI_INVALID_PARAMETER - BltOperation is not valid.\r
+    EFI_DEVICE_ERROR      - A hardware error occured writting to the video\r
+                             buffer.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                      Status;\r
+  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;\r
+  UINTN                           Index;\r
+  EFI_STATUS                      ReturnStatus;\r
+  EFI_GRAPHICS_OUTPUT_PROTOCOL    *GraphicsOutput;\r
+  EFI_UGA_DRAW_PROTOCOL           *UgaDraw;\r
+\r
+  Private = GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  //\r
+  // Sync up DevNull GOP device\r
+  //\r
+  ReturnStatus = DevNullGraphicsOutputBlt (\r
+                  Private,\r
+                  BltBuffer,\r
+                  BltOperation,\r
+                  SourceX,\r
+                  SourceY,\r
+                  DestinationX,\r
+                  DestinationY,\r
+                  Width,\r
+                  Height,\r
+                  Delta\r
+                  );\r
+\r
+  if (Private->ConsoleOutputMode != EfiConsoleControlScreenGraphics) {\r
+    return ReturnStatus;\r
+  }\r
+  //\r
+  // return the worst status met\r
+  //\r
+  for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {\r
+    GraphicsOutput = Private->TextOutList[Index].GraphicsOutput;\r
+    if (GraphicsOutput != NULL) {\r
+      Status = GraphicsOutput->Blt (\r
+                              GraphicsOutput,\r
+                              BltBuffer,\r
+                              BltOperation,\r
+                              SourceX,\r
+                              SourceY,\r
+                              DestinationX,\r
+                              DestinationY,\r
+                              Width,\r
+                              Height,\r
+                              Delta\r
+                              );\r
+      if (EFI_ERROR (Status)) {\r
+        ReturnStatus = Status;\r
+      } else if (BltOperation == EfiBltVideoToBltBuffer) {\r
+        //\r
+        // Only need to read the data into buffer one time\r
+        //\r
+        return EFI_SUCCESS;\r
+      }\r
+    }\r
+\r
+    UgaDraw = Private->TextOutList[Index].UgaDraw;\r
+    if (UgaDraw != NULL) {\r
+      Status = UgaDraw->Blt (\r
+                              UgaDraw,\r
+                              (EFI_UGA_PIXEL *) BltBuffer,\r
+                              BltOperation,\r
+                              SourceX,\r
+                              SourceY,\r
+                              DestinationX,\r
+                              DestinationY,\r
+                              Width,\r
+                              Height,\r
+                              Delta\r
+                              );\r
+      if (EFI_ERROR (Status)) {\r
+        ReturnStatus = Status;\r
+      } else if (BltOperation == EfiBltVideoToBltBuffer) {\r
+        //\r
+        // Only need to read the data into buffer one time\r
+        //\r
+        return EFI_SUCCESS;\r
+      }\r
+    }\r
+  }\r
+\r
+  return ReturnStatus;\r
+}\r
+\r
+EFI_STATUS\r
+DevNullGopSync (\r
+  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private,\r
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL    *GraphicsOutput,\r
+  IN  EFI_UGA_DRAW_PROTOCOL           *UgaDraw\r
+  )\r
+{\r
+  if (GraphicsOutput != NULL) {\r
+    return GraphicsOutput->Blt (\r
+                      GraphicsOutput,\r
+                      Private->GraphicsOutputBlt,\r
+                      EfiBltBufferToVideo,\r
+                      0,\r
+                      0,\r
+                      0,\r
+                      0,\r
+                      Private->GraphicsOutput.Mode->Info->HorizontalResolution,\r
+                      Private->GraphicsOutput.Mode->Info->VerticalResolution,\r
+                      0\r
+                      );\r
+  } else {\r
+    return UgaDraw->Blt (\r
+                      UgaDraw,\r
+                      (EFI_UGA_PIXEL *) Private->GraphicsOutputBlt,\r
+                      EfiUgaBltBufferToVideo,\r
+                      0,\r
+                      0,\r
+                      0,\r
+                      0,\r
+                      Private->GraphicsOutput.Mode->Info->HorizontalResolution,\r
+                      Private->GraphicsOutput.Mode->Info->VerticalResolution,\r
+                      0\r
+                      );\r
+  }\r
+}\r
+\r
+#else\r
+\r
 EFI_STATUS\r
 EFIAPI\r
 ConSpliterUgaDrawGetMode (\r
@@ -260,7 +745,7 @@ ConSpliterUgaDrawSetMode (
   Private->UgaColorDepth            = ColorDepth;\r
   Private->UgaRefreshRate           = RefreshRate;\r
 \r
-  if (Private->UgaMode != EfiConsoleControlScreenGraphics) {\r
+  if (Private->ConsoleOutputMode != EfiConsoleControlScreenGraphics) {\r
     return ReturnStatus;\r
   }\r
   //\r
@@ -465,7 +950,7 @@ ConSpliterUgaDrawBlt (
                   Height,\r
                   Delta\r
                   );\r
-  if (Private->UgaMode != EfiConsoleControlScreenGraphics) {\r
+  if (Private->ConsoleOutputMode != EfiConsoleControlScreenGraphics) {\r
     return ReturnStatus;\r
   }\r
   //\r
@@ -518,6 +1003,7 @@ DevNullUgaSync (
                     Private->UgaHorizontalResolution * sizeof (EFI_UGA_PIXEL)\r
                     );\r
 }\r
+#endif\r
 \r
 EFI_STATUS\r
 DevNullTextOutOutputString (\r
@@ -927,7 +1413,7 @@ DevNullTextOutEnableCursor (
 }\r
 \r
 EFI_STATUS\r
-DevNullSyncUgaStdOut (\r
+DevNullSyncGopStdOut (\r
   IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private\r
   )\r
 /*++\r
@@ -977,9 +1463,9 @@ DevNullSyncUgaStdOut (
     Sto = Private->TextOutList[List].TextOut;\r
 \r
     //\r
-    // Skip non UGA devices\r
+    // Skip non GOP/UGA devices\r
     //\r
-    if (Private->TextOutList[List].UgaDraw != NULL) {\r
+    if ((Private->TextOutList[List].GraphicsOutput != NULL) || (Private->TextOutList[List].UgaDraw != NULL)) {\r
       Sto->EnableCursor (Sto, FALSE);\r
       Sto->ClearScreen (Sto);\r
     }\r
@@ -1034,9 +1520,9 @@ DevNullSyncUgaStdOut (
           Sto = Private->TextOutList[List].TextOut;\r
 \r
           //\r
-          // Skip non UGA devices\r
+          // Skip non GOP/UGA devices\r
           //\r
-          if (Private->TextOutList[List].UgaDraw != NULL) {\r
+          if ((Private->TextOutList[List].GraphicsOutput != NULL) || (Private->TextOutList[List].UgaDraw != NULL)) {\r
             Sto->SetAttribute (Sto, CurrentAttribute);\r
             Sto->SetCursorPosition (Sto, CurrentColumn, Row);\r
             Status = Sto->OutputString (Sto, Buffer);\r
@@ -1058,9 +1544,9 @@ DevNullSyncUgaStdOut (
     Sto = Private->TextOutList[List].TextOut;\r
 \r
     //\r
-    // Skip non UGA devices\r
+    // Skip non GOP/UGA devices\r
     //\r
-    if (Private->TextOutList[List].UgaDraw != NULL) {\r
+    if ((Private->TextOutList[List].GraphicsOutput != NULL) || (Private->TextOutList[List].UgaDraw != NULL)) {\r
       Sto->SetAttribute (Sto, StartAttribute);\r
       Sto->SetCursorPosition (Sto, StartColumn, StartRow);\r
       Status = Sto->EnableCursor (Sto, StartCursorState);\r