]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterGraphics.c
apply for doxgen format.
[mirror_edk2.git] / MdeModulePkg / Universal / Console / ConSplitterDxe / ConSplitterGraphics.c
index f70b0765ea8c1f17a9f0822a2810d25151b81b38..28de49c773b1633d511412c85de85dfa2494f182 100644 (file)
@@ -1,6 +1,10 @@
-/*++\r
+/** @file\r
+  Support for ConsoleControl protocol. Support for Graphics output spliter.\r
+  Support for DevNull Console Out. This console uses memory buffers\r
+  to represnt the console. It allows a console to start very early and\r
+  when a new console is added it is synced up with the current console.\r
 \r
-Copyright (c) 2006 - 2007, Intel Corporation\r
+Copyright (c) 2006 - 2008, Intel Corporation. <BR>\r
 All rights reserved. This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -9,18 +13,8 @@ http://opensource.org/licenses/bsd-license.php
 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
-Module Name:\r
-\r
-  ConSplitterGraphics.c\r
-\r
-Abstract:\r
-\r
-  Support for ConsoleControl protocol. Support for UGA Draw spliter.\r
-  Support for DevNull Console Out. This console uses memory buffers\r
-  to represnt the console. It allows a console to start very early and\r
-  when a new console is added it is synced up with the current console\r
+**/\r
 \r
---*/\r
 \r
 #include "ConSplitter.h"\r
 \r
@@ -39,13 +33,13 @@ ConSpliterConsoleControlGetMode (
 \r
   Routine Description:\r
     Return the current video mode information. Also returns info about existence\r
-    of UGA Draw devices in system, and if the Std In device is locked. All the\r
+    of Graphics Output devices or UGA Draw devices in system, and if the Std In device is locked. All the\r
     arguments are optional and only returned if a non NULL pointer is passed in.\r
 \r
   Arguments:\r
     This - Protocol instance pointer.\r
     Mode        - Are we in text of grahics mode.\r
-    UgaExists   - TRUE if UGA Spliter has found a UGA device\r
+    GopExists   - TRUE if GOP Spliter has found a GOP/UGA device\r
     StdInLocked - TRUE if StdIn device is keyboard locked\r
 \r
   Returns:\r
@@ -147,14 +141,16 @@ ConSpliterConsoleControlSetMode (
     //\r
     if ((Mode == EfiConsoleControlScreenGraphics) &&((TextAndGop->GraphicsOutput != NULL) || (TextAndGop->UgaDraw != NULL))) {\r
       TextAndGop->TextOutEnabled = FALSE;\r
-      DevNullGopSync (Private, TextAndGop->GraphicsOutput, TextAndGop->UgaDraw);\r
+      if (FeaturePcdGet (PcdConOutGopSupport)) {\r
+        DevNullGopSync (Private, TextAndGop->GraphicsOutput, TextAndGop->UgaDraw);\r
+      } else if (FeaturePcdGet (PcdConOutUgaSupport)) {\r
+        DevNullUgaSync (Private, TextAndGop->GraphicsOutput, TextAndGop->UgaDraw);\r
+      }\r
     }\r
   }\r
-\r
   if (Mode == EfiConsoleControlScreenText) {\r
-    DevNullSyncGopStdOut (Private);\r
+    DevNullSyncStdOut (Private);\r
   }\r
-\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -187,7 +183,6 @@ ConSpliterGraphicsOutputQueryMode (
 --*/\r
 {\r
   TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;\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
@@ -210,11 +205,7 @@ ConSpliterGraphicsOutputQueryMode (
 \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
+  CopyMem (*Info, &Private->GraphicsOutputModeBuffer[ModeNumber], *SizeOfInfo);\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -246,7 +237,7 @@ Routine Description:
   TEXT_OUT_SPLITTER_PRIVATE_DATA         *Private;\r
   UINTN                                  Index;\r
   EFI_STATUS                             ReturnStatus;\r
-  TEXT_OUT_GOP_MODE                      *Mode;\r
+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION   *Mode;\r
   UINTN                                  Size;\r
   EFI_GRAPHICS_OUTPUT_PROTOCOL           *GraphicsOutput;\r
   UINTN                                  NumberIndex;\r
@@ -287,11 +278,6 @@ Routine Description:
     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
@@ -319,27 +305,26 @@ Routine Description:
       }\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
+    if (EFI_ERROR (ReturnStatus) && FeaturePcdGet (PcdUgaConsumeSupport)) {\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
 \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
+  CopyMem (This->Mode->Info, &Private->GraphicsOutputModeBuffer[ModeNumber], This->Mode->SizeOfInfo);\r
 \r
   //\r
   // Information is not enough here, so the following items remain unchanged:\r
@@ -590,7 +575,7 @@ ConSpliterGraphicsOutputBlt (
     }\r
 \r
     UgaDraw = Private->TextOutList[Index].UgaDraw;\r
-    if (UgaDraw != NULL) {\r
+    if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
       Status = UgaDraw->Blt (\r
                               UgaDraw,\r
                               (EFI_UGA_PIXEL *) BltBuffer,\r
@@ -637,7 +622,7 @@ DevNullGopSync (
                       Private->GraphicsOutput.Mode->Info->VerticalResolution,\r
                       0\r
                       );\r
-  } else {\r
+  } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
     return UgaDraw->Blt (\r
                       UgaDraw,\r
                       (EFI_UGA_PIXEL *) Private->GraphicsOutputBlt,\r
@@ -650,9 +635,479 @@ DevNullGopSync (
                       Private->GraphicsOutput.Mode->Info->VerticalResolution,\r
                       0\r
                       );\r
+  } else {\r
+    return EFI_UNSUPPORTED;\r
   }\r
 }\r
 \r
+EFI_STATUS\r
+EFIAPI\r
+ConSpliterUgaDrawGetMode (\r
+  IN  EFI_UGA_DRAW_PROTOCOL           *This,\r
+  OUT UINT32                          *HorizontalResolution,\r
+  OUT UINT32                          *VerticalResolution,\r
+  OUT UINT32                          *ColorDepth,\r
+  OUT UINT32                          *RefreshRate\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Return the current video mode information.\r
+\r
+  Arguments:\r
+    This                  - Protocol instance pointer.\r
+    HorizontalResolution  - Current video horizontal resolution in pixels\r
+    VerticalResolution    - Current video vertical resolution in pixels\r
+    ColorDepth            - Current video color depth in bits per pixel\r
+    RefreshRate           - Current video refresh rate in Hz.\r
+\r
+  Returns:\r
+    EFI_SUCCESS           - Mode information returned.\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
+\r
+  if (!(HorizontalResolution && VerticalResolution && RefreshRate && ColorDepth)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // retrieve private data\r
+  //\r
+  Private               = UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  *HorizontalResolution = Private->UgaHorizontalResolution;\r
+  *VerticalResolution   = Private->UgaVerticalResolution;\r
+  *ColorDepth           = Private->UgaColorDepth;\r
+  *RefreshRate          = Private->UgaRefreshRate;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+ConSpliterUgaDrawSetMode (\r
+  IN  EFI_UGA_DRAW_PROTOCOL           *This,\r
+  IN UINT32                           HorizontalResolution,\r
+  IN UINT32                           VerticalResolution,\r
+  IN UINT32                           ColorDepth,\r
+  IN UINT32                           RefreshRate\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Return the current video mode information.\r
+\r
+  Arguments:\r
+    This                  - Protocol instance pointer.\r
+    HorizontalResolution  - Current video horizontal resolution in pixels\r
+    VerticalResolution    - Current video vertical resolution in pixels\r
+    ColorDepth            - Current video color depth in bits per pixel\r
+    RefreshRate           - Current video refresh rate in Hz.\r
+\r
+  Returns:\r
+    EFI_SUCCESS     - Mode information returned.\r
+    EFI_NOT_STARTED - Video display is not initialized. Call SetMode ()\r
+    EFI_OUT_OF_RESOURCES - Out of resources.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                             Status;\r
+  TEXT_OUT_SPLITTER_PRIVATE_DATA         *Private;\r
+  UINTN                                  Index;\r
+  EFI_STATUS                             ReturnStatus;\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
+  Private = UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  //\r
+  // UgaDevNullSetMode ()\r
+  //\r
+  ReturnStatus = EFI_SUCCESS;\r
+\r
+  //\r
+  // Free the old version\r
+  //\r
+  if (Private->UgaBlt != NULL) {\r
+    FreePool (Private->UgaBlt);\r
+  }\r
+\r
+  //\r
+  // Allocate the virtual Blt buffer\r
+  //\r
+  Size            = HorizontalResolution * VerticalResolution * sizeof (EFI_UGA_PIXEL);\r
+  Private->UgaBlt = AllocateZeroPool (Size);\r
+  if (Private->UgaBlt == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  //\r
+  // Update the Mode data\r
+  //\r
+  Private->UgaHorizontalResolution  = HorizontalResolution;\r
+  Private->UgaVerticalResolution    = VerticalResolution;\r
+  Private->UgaColorDepth            = ColorDepth;\r
+  Private->UgaRefreshRate           = RefreshRate;\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
+\r
+    ReturnStatus = EFI_UNSUPPORTED;\r
+\r
+    if (FeaturePcdGet (PcdUgaConsumeSupport)) {\r
+      UgaDraw = Private->TextOutList[Index].UgaDraw;\r
+      if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
+        Status = UgaDraw->SetMode (\r
+                            UgaDraw,\r
+                            HorizontalResolution,\r
+                            VerticalResolution,\r
+                            ColorDepth,\r
+                            RefreshRate\r
+                            );\r
+        if (EFI_ERROR (Status)) {\r
+          ReturnStatus = Status;\r
+        }\r
+      }\r
+    }\r
+\r
+    if (EFI_ERROR (ReturnStatus)) {\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 == HorizontalResolution) && (Info->VerticalResolution == VerticalResolution)) {\r
+            FreePool (Info);\r
+            break;\r
+          }\r
+          FreePool (Info);\r
+        }\r
+\r
+        Status = GraphicsOutput->SetMode (GraphicsOutput, (UINT32) NumberIndex);\r
+        if (EFI_ERROR (Status)) {\r
+          ReturnStatus = Status;\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  return ReturnStatus;\r
+}\r
+\r
+EFI_STATUS\r
+DevNullUgaBlt (\r
+  IN  TEXT_OUT_SPLITTER_PRIVATE_DATA                *Private,\r
+  IN  EFI_UGA_PIXEL                                 *BltBuffer, OPTIONAL\r
+  IN  EFI_UGA_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
+  BOOLEAN       Forward;\r
+  UINTN         Index;\r
+  EFI_UGA_PIXEL *BltPtr;\r
+  EFI_UGA_PIXEL *ScreenPtr;\r
+  UINT32        HorizontalResolution;\r
+  UINT32        VerticalResolution;\r
+\r
+  if ((BltOperation < 0) || (BltOperation >= EfiUgaBltMax)) {\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_UGA_PIXEL);\r
+  }\r
+\r
+  HorizontalResolution  = Private->UgaHorizontalResolution;\r
+  VerticalResolution    = Private->UgaVerticalResolution;\r
+\r
+  //\r
+  // We need to fill the Virtual Screen buffer with the blt data.\r
+  //\r
+  if (BltOperation == EfiUgaVideoToBltBuffer) {\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_UGA_PIXEL *) ((UINT8 *) BltBuffer + DestinationY * Delta + DestinationX * sizeof (EFI_UGA_PIXEL));\r
+    ScreenPtr = &Private->UgaBlt[SourceY * HorizontalResolution + SourceX];\r
+    while (Height) {\r
+      CopyMem (BltPtr, ScreenPtr, Width * sizeof (EFI_UGA_PIXEL));\r
+      BltPtr = (EFI_UGA_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
+    if ((BltOperation == EfiUgaVideoToVideo) && (DestinationY > SourceY)) {\r
+      //\r
+      // Copy backwards, only care the Video to Video Blt\r
+      //\r
+      ScreenPtr = &Private->UgaBlt[(DestinationY + Height - 1) * HorizontalResolution + DestinationX];\r
+      SrcY      = SourceY + Height - 1;\r
+      Forward   = FALSE;\r
+    } else {\r
+      //\r
+      // Copy forwards, for other cases\r
+      //\r
+      ScreenPtr = &Private->UgaBlt[DestinationY * HorizontalResolution + DestinationX];\r
+      SrcY      = SourceY;\r
+      Forward   = TRUE;\r
+    }\r
+\r
+    while (Height != 0) {\r
+      if (BltOperation == EfiUgaVideoFill) {\r
+        for (Index = 0; Index < Width; Index++) {\r
+          ScreenPtr[Index] = *BltBuffer;\r
+        }\r
+      } else {\r
+        if (BltOperation == EfiUgaBltBufferToVideo) {\r
+          BltPtr = (EFI_UGA_PIXEL *) ((UINT8 *) BltBuffer + SrcY * Delta + SourceX * sizeof (EFI_UGA_PIXEL));\r
+        } else {\r
+          BltPtr = &Private->UgaBlt[SrcY * HorizontalResolution + SourceX];\r
+        }\r
+\r
+        CopyMem (ScreenPtr, BltPtr, Width * sizeof (EFI_UGA_PIXEL));\r
+      }\r
+\r
+      if (Forward) {\r
+        ScreenPtr += HorizontalResolution;\r
+        SrcY ++;\r
+      } else {\r
+        ScreenPtr -= HorizontalResolution;\r
+        SrcY --;\r
+      }\r
+      Height--;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+ConSpliterUgaDrawBlt (\r
+  IN  EFI_UGA_DRAW_PROTOCOL                         *This,\r
+  IN  EFI_UGA_PIXEL                                 *BltBuffer, OPTIONAL\r
+  IN  EFI_UGA_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
+    EfiUgaVideoFill - 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
+    EfiUgaVideoToBltBuffer - 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
+    EfiUgaBltBufferToVideo - 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
+    EfiUgaVideoToVideo - 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_UGA_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
+\r
+  Private = UGA_DRAW_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  //\r
+  // Sync up DevNull UGA device\r
+  //\r
+  ReturnStatus = DevNullUgaBlt (\r
+                  Private,\r
+                  BltBuffer,\r
+                  BltOperation,\r
+                  SourceX,\r
+                  SourceY,\r
+                  DestinationX,\r
+                  DestinationY,\r
+                  Width,\r
+                  Height,\r
+                  Delta\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
+                              (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltBuffer,\r
+                              (EFI_GRAPHICS_OUTPUT_BLT_OPERATION) 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
+    if (Private->TextOutList[Index].UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
+      Status = Private->TextOutList[Index].UgaDraw->Blt (\r
+                                                      Private->TextOutList[Index].UgaDraw,\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 == EfiUgaVideoToBltBuffer) {\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
+DevNullUgaSync (\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 (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
+    return UgaDraw->Blt (\r
+                      UgaDraw,\r
+                      Private->UgaBlt,\r
+                      EfiUgaBltBufferToVideo,\r
+                      0,\r
+                      0,\r
+                      0,\r
+                      0,\r
+                      Private->UgaHorizontalResolution,\r
+                      Private->UgaVerticalResolution,\r
+                      Private->UgaHorizontalResolution * sizeof (EFI_UGA_PIXEL)\r
+                      );\r
+  } else if (GraphicsOutput != NULL) {\r
+    return GraphicsOutput->Blt (\r
+                      GraphicsOutput,\r
+                      (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) Private->UgaBlt,\r
+                      EfiBltBufferToVideo,\r
+                      0,\r
+                      0,\r
+                      0,\r
+                      0,\r
+                      Private->UgaHorizontalResolution,\r
+                      Private->UgaVerticalResolution,\r
+                      0\r
+                      );\r
+  } else {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+}\r
 \r
 EFI_STATUS\r
 DevNullTextOutOutputString (\r
@@ -898,6 +1353,7 @@ DevNullTextOutSetMode (
 --*/\r
 {\r
   UINTN                         Size;\r
+  INT32                         CurrentMode;\r
   UINTN                         Row;\r
   UINTN                         Column;\r
   TEXT_OUT_SPLITTER_QUERY_DATA  *Mode;\r
@@ -905,8 +1361,14 @@ DevNullTextOutSetMode (
   //\r
   // No extra check for ModeNumber here, as it has been checked in\r
   // ConSplitterTextOutSetMode. And mode 0 should always be supported.\r
+  // Row and Column should be fetched from intersection map.\r
   //\r
-  Mode    = &(Private->TextOutQueryData[ModeNumber]);\r
+  if (Private->TextOutModeMap != NULL) {\r
+    CurrentMode = *(Private->TextOutModeMap + Private->TextOutListCount * ModeNumber);\r
+  } else {\r
+    CurrentMode = (INT32)(ModeNumber);\r
+  }\r
+  Mode    = &(Private->TextOutQueryData[CurrentMode]);\r
   Row     = Mode->Rows;\r
   Column  = Mode->Columns;\r
 \r
@@ -914,7 +1376,7 @@ DevNullTextOutSetMode (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
-  if (Private->DevNullColumns != Column || Private->DevNullRows != Row) {\r
+  if (Private->TextOutMode.Mode != (INT32) ModeNumber) {\r
 \r
     Private->TextOutMode.Mode = (INT32) ModeNumber;\r
     Private->DevNullColumns   = Column;\r
@@ -1066,7 +1528,7 @@ DevNullTextOutEnableCursor (
 }\r
 \r
 EFI_STATUS\r
-DevNullSyncGopStdOut (\r
+DevNullSyncStdOut (\r
   IN  TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private\r
   )\r
 /*++\r