]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.c
OptionRomPkg: Add FrameBufferBltLib implementation of BltLib
[mirror_edk2.git] / OptionRomPkg / Library / FrameBufferBltLib / FrameBufferBltLib.c
diff --git a/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.c b/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.c
new file mode 100644 (file)
index 0000000..dd54b07
--- /dev/null
@@ -0,0 +1,753 @@
+/** @file\r
+  FrameBufferBltLib - Library to perform blt operations on a frame buffer.\r
+\r
+  Copyright (c) 2007 - 2011, Intel Corporation\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
+  http://opensource.org/licenses/bsd-license.php\r
+  \r
+  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
+**/\r
+\r
+#include "PiDxe.h"\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/BltLib.h>\r
+#include <Library/DebugLib.h>\r
+\r
+#if 0\r
+#define VDEBUG DEBUG\r
+#else\r
+#define VDEBUG(x)\r
+#endif\r
+\r
+#define MAX_LINE_BUFFER_SIZE (SIZE_4KB * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))\r
+\r
+UINTN                           mBltLibColorDepth;\r
+UINTN                           mBltLibWidthInBytes;\r
+UINTN                           mBltLibBytesPerPixel;\r
+UINTN                           mBltLibWidthInPixels;\r
+UINTN                           mBltLibHeight;\r
+UINT8                           mBltLibLineBuffer[MAX_LINE_BUFFER_SIZE];\r
+UINT8                           *mBltLibFrameBuffer;\r
+EFI_GRAPHICS_PIXEL_FORMAT       mPixelFormat;\r
+EFI_PIXEL_BITMASK               mPixelBitMasks;\r
+INTN                            mPixelShl[4]; // R-G-B-Rsvd\r
+INTN                            mPixelShr[4]; // R-G-B-Rsvd\r
+\r
+\r
+VOID\r
+ConfigurePixelBitMaskFormat (\r
+  IN EFI_PIXEL_BITMASK          *BitMask\r
+  )\r
+{\r
+  UINTN   Loop;\r
+  UINT32  *Masks;\r
+  UINT32  MergedMasks;\r
+\r
+  MergedMasks = 0;\r
+  Masks = (UINT32*) BitMask;\r
+  for (Loop = 0; Loop < 3; Loop++) {\r
+    ASSERT ((Loop == 3) || (Masks[Loop] != 0));\r
+    ASSERT ((MergedMasks & Masks[Loop]) == 0);\r
+    mPixelShl[Loop] = HighBitSet32 (Masks[Loop]) - 23 + (Loop * 8);\r
+    if (mPixelShl[Loop] < 0) {\r
+      mPixelShr[Loop] = -mPixelShl[Loop];\r
+      mPixelShl[Loop] = 0;\r
+    } else {\r
+      mPixelShr[Loop] = 0;\r
+    }\r
+    MergedMasks = (UINT32) (MergedMasks | Masks[Loop]);\r
+    DEBUG ((EFI_D_INFO, "%d: shl:%d shr:%d mask:%x\n", Loop, mPixelShl[Loop], mPixelShr[Loop], Masks[Loop]));\r
+  }\r
+  MergedMasks = (UINT32) (MergedMasks | Masks[3]);\r
+\r
+  mBltLibBytesPerPixel = HighBitSet32 (MergedMasks);\r
+  ASSERT (mBltLibBytesPerPixel >= 0);\r
+  mBltLibBytesPerPixel = (mBltLibBytesPerPixel + 7) / 8;\r
+\r
+  DEBUG ((EFI_D_INFO, "Bytes per pixel: %d\n", mBltLibBytesPerPixel));\r
+\r
+  CopyMem (&mPixelBitMasks, BitMask, sizeof (*BitMask));\r
+}\r
+\r
+\r
+/**\r
+  Configure the FrameBufferLib instance\r
+\r
+  @param[in] FrameBuffer      Pointer to the start of the frame buffer\r
+  @param[in] FrameBufferInfo  Describes the frame buffer characteristics\r
+\r
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter\r
+  @retval  EFI_UNSUPPORTED - The BltLib does not support this configuration\r
+  @retval  EFI_SUCCESS - Blt operation success\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BltLibConfigure (\r
+  IN  VOID                                 *FrameBuffer,\r
+  IN  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo\r
+  )\r
+{\r
+  STATIC EFI_PIXEL_BITMASK  RgbPixelMasks =\r
+    { 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 };\r
+  STATIC EFI_PIXEL_BITMASK  BgrPixelMasks =\r
+    { 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 };\r
+\r
+  switch (FrameBufferInfo->PixelFormat) {\r
+  case PixelRedGreenBlueReserved8BitPerColor:\r
+    ConfigurePixelBitMaskFormat (&RgbPixelMasks);\r
+    break;\r
+  case PixelBlueGreenRedReserved8BitPerColor:\r
+    ConfigurePixelBitMaskFormat (&BgrPixelMasks);\r
+    break;\r
+  case PixelBitMask:\r
+    ConfigurePixelBitMaskFormat (&(FrameBufferInfo->PixelInformation));\r
+    break;\r
+  case PixelBltOnly:\r
+    ASSERT (FrameBufferInfo->PixelFormat != PixelBltOnly);\r
+    return EFI_UNSUPPORTED;\r
+  default:\r
+    ASSERT (FALSE);\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  mPixelFormat = FrameBufferInfo->PixelFormat;\r
+\r
+  mBltLibFrameBuffer = (UINT8*) FrameBuffer;\r
+  mBltLibWidthInPixels = (UINTN) FrameBufferInfo->HorizontalResolution;\r
+  mBltLibHeight = (UINTN) FrameBufferInfo->VerticalResolution;\r
+  mBltLibWidthInBytes = mBltLibWidthInPixels * mBltLibBytesPerPixel;\r
+\r
+  ASSERT (mBltLibWidthInBytes < sizeof (mBltLibLineBuffer));\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Performs a UEFI Graphics Output Protocol Blt operation.\r
+\r
+  @param[in,out] BltBuffer     - The data to transfer to screen\r
+  @param[in]     BltOperation  - The operation to perform\r
+  @param[in]     SourceX       - The X coordinate of the source for BltOperation\r
+  @param[in]     SourceY       - The Y coordinate of the source for BltOperation\r
+  @param[in]     DestinationX  - The X coordinate of the destination for BltOperation\r
+  @param[in]     DestinationY  - The Y coordinate of the destination for BltOperation\r
+  @param[in]     Width         - The width of a rectangle in the blt rectangle in pixels\r
+  @param[in]     Height        - The height of a rectangle in the blt rectangle in pixels\r
+  @param[in]     Delta         - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.\r
+                                 If a Delta of 0 is used, the entire BltBuffer will be operated on.\r
+                                 If a subrectangle of the BltBuffer is used, then Delta represents\r
+                                 the number of bytes in a row of the BltBuffer.\r
+\r
+  @retval  EFI_DEVICE_ERROR - A hardware error occured\r
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in\r
+  @retval  EFI_SUCCESS - Blt operation success\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BltLibGopBlt (\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\r
+  )\r
+{\r
+  switch (BltOperation) {\r
+  case EfiBltVideoToBltBuffer:\r
+    return BltLibVideoToBltBufferEx (\r
+             BltBuffer,\r
+             SourceX,\r
+             SourceY,\r
+             DestinationX,\r
+             DestinationY,\r
+             Width,\r
+             Height,\r
+             Delta\r
+             );\r
+\r
+  case EfiBltVideoToVideo:\r
+    return BltLibVideoToVideo (\r
+             SourceX,\r
+             SourceY,\r
+             DestinationX,\r
+             DestinationY,\r
+             Width,\r
+             Height\r
+             );\r
+\r
+  case EfiBltVideoFill:\r
+    return BltLibVideoFill (\r
+             BltBuffer,\r
+             DestinationX,\r
+             DestinationY,\r
+             Width,\r
+             Height\r
+             );\r
+\r
+  case EfiBltBufferToVideo:\r
+    return BltLibBufferToVideoEx (\r
+             BltBuffer,\r
+             SourceX,\r
+             SourceY,\r
+             DestinationX,\r
+             DestinationY,\r
+             Width,\r
+             Height,\r
+             Delta\r
+             );\r
+  default:\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+}\r
+\r
+\r
+/**\r
+  Performs a UEFI Graphics Output Protocol Blt Video Fill.\r
+\r
+  @param[in]  Color         Color to fill the region with\r
+  @param[in]  DestinationX  X location to start fill operation\r
+  @param[in]  DestinationY  Y location to start fill operation\r
+  @param[in]  Width         Width (in pixels) to fill\r
+  @param[in]  Height        Height to fill\r
+\r
+  @retval  EFI_DEVICE_ERROR - A hardware error occured\r
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in\r
+  @retval  EFI_SUCCESS - The sizes were returned\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BltLibVideoFill (\r
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *Color,\r
+  IN  UINTN                                 DestinationX,\r
+  IN  UINTN                                 DestinationY,\r
+  IN  UINTN                                 Width,\r
+  IN  UINTN                                 Height\r
+  )\r
+{\r
+  UINTN                           DstY;\r
+  VOID                            *BltMemSrc;\r
+  VOID                            *BltMemDst;\r
+  UINTN                           X;\r
+  UINT8                           Uint8;\r
+  UINT32                          Uint32;\r
+  UINT64                          WideFill;\r
+  BOOLEAN                         UseWideFill;\r
+  BOOLEAN                         LineBufferReady;\r
+  UINTN                           Offset;\r
+  UINTN                           WidthInBytes;\r
+  UINTN                           SizeInBytes;\r
+\r
+  //\r
+  // BltBuffer to Video: Source is BltBuffer, destination is Video\r
+  //\r
+  if (DestinationY + Height > mBltLibHeight) {\r
+    DEBUG ((EFI_D_INFO, "VideoFill: Past screen (Y)\n"));\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (DestinationX + Width > mBltLibWidthInPixels) {\r
+    DEBUG ((EFI_D_INFO, "VideoFill: Past screen (X)\n"));\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Width == 0 || Height == 0) {\r
+    DEBUG ((EFI_D_INFO, "VideoFill: Width or Height is 0\n"));\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  WidthInBytes = Width * mBltLibBytesPerPixel;\r
+\r
+  Uint32 = *(UINT32*) Color;\r
+  WideFill =\r
+    (UINT32) (\r
+        (((Uint32 << mPixelShl[0]) >> mPixelShr[0]) & mPixelBitMasks.RedMask) |\r
+        (((Uint32 << mPixelShl[1]) >> mPixelShr[1]) & mPixelBitMasks.GreenMask) |\r
+        (((Uint32 << mPixelShl[2]) >> mPixelShr[2]) & mPixelBitMasks.BlueMask)\r
+      );\r
+  VDEBUG ((EFI_D_INFO, "VideoFill: color=0x%x, wide-fill=0x%x\n", Uint32, WideFill));\r
+\r
+  //\r
+  // If the size of the pixel data evenly divides the sizeof\r
+  // WideFill, then a wide fill operation can be used\r
+  //\r
+  UseWideFill = TRUE;\r
+  if ((sizeof (WideFill) % mBltLibBytesPerPixel) == 0) {\r
+    for (X = mBltLibBytesPerPixel; X < sizeof (WideFill); X++) {\r
+      ((UINT8*)&WideFill)[X] = ((UINT8*)&WideFill)[X % mBltLibBytesPerPixel];\r
+    }\r
+  } else {\r
+    //\r
+    // If all the bytes in the pixel are the same value, then use\r
+    // a wide fill operation.\r
+    //\r
+    for (\r
+      X = 1, Uint8 = ((UINT8*)&WideFill)[0];\r
+      X < mBltLibBytesPerPixel;\r
+      X++) {\r
+      if (Uint8 != ((UINT8*)&WideFill)[X]) {\r
+        UseWideFill = FALSE;\r
+        break;\r
+      }\r
+    }\r
+    if (UseWideFill) {\r
+      SetMem ((VOID*) &WideFill, sizeof (WideFill), Uint8);\r
+    }\r
+  }\r
+\r
+  if (UseWideFill && (DestinationX == 0) && (Width == mBltLibWidthInPixels)) {\r
+    VDEBUG ((EFI_D_INFO, "VideoFill (wide, one-shot)\n"));\r
+    Offset = DestinationY * mBltLibWidthInPixels;\r
+    Offset = mBltLibBytesPerPixel * Offset;\r
+    BltMemDst = (VOID*) (mBltLibFrameBuffer + Offset);\r
+    SizeInBytes = WidthInBytes * Height;\r
+    if (SizeInBytes >= 8) {\r
+      SetMem32 (BltMemDst, SizeInBytes & ~3, (UINT32) WideFill);\r
+      SizeInBytes = SizeInBytes & 3;\r
+    }\r
+    if (SizeInBytes > 0) {\r
+      SetMem (BltMemDst, SizeInBytes, (UINT8)(UINTN) WideFill);\r
+    }\r
+  } else {\r
+    LineBufferReady = FALSE;\r
+    for (DstY = DestinationY; DstY < (Height + DestinationY); DstY++) {\r
+      Offset = (DstY * mBltLibWidthInPixels) + DestinationX;\r
+      Offset = mBltLibBytesPerPixel * Offset;\r
+      BltMemDst = (VOID*) (mBltLibFrameBuffer + Offset);\r
+\r
+      if (UseWideFill && (((UINTN) BltMemDst & 7) == 0)) {\r
+        VDEBUG ((EFI_D_INFO, "VideoFill (wide)\n"));\r
+        SizeInBytes = WidthInBytes;\r
+        if (SizeInBytes >= 8) {\r
+          SetMem64 (BltMemDst, SizeInBytes & ~7, WideFill);\r
+          SizeInBytes = SizeInBytes & 7;\r
+        }\r
+        if (SizeInBytes > 0) {\r
+          CopyMem (BltMemDst, (VOID*) &WideFill, SizeInBytes);\r
+        }\r
+      } else {\r
+        VDEBUG ((EFI_D_INFO, "VideoFill (not wide)\n"));\r
+        if (!LineBufferReady) {\r
+          CopyMem (mBltLibLineBuffer, &WideFill, mBltLibBytesPerPixel);\r
+          for (X = 1; X < Width; ) {\r
+            CopyMem(\r
+              (mBltLibLineBuffer + (X * mBltLibBytesPerPixel)),\r
+              mBltLibLineBuffer,\r
+              MIN (X, Width - X) * mBltLibBytesPerPixel\r
+              );\r
+            X = X + MIN (X, Width - X);\r
+          }\r
+          BltMemSrc = (VOID *) mBltLibLineBuffer;\r
+          LineBufferReady = TRUE;\r
+        }\r
+        CopyMem (BltMemDst, mBltLibLineBuffer, WidthInBytes);\r
+      }\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation.\r
+\r
+  @param[out] BltBuffer     Output buffer for pixel color data\r
+  @param[in]  SourceX       X location within video\r
+  @param[in]  SourceY       Y location within video\r
+  @param[in]  Width         Width (in pixels)\r
+  @param[in]  Height        Height\r
+\r
+  @retval  EFI_DEVICE_ERROR - A hardware error occured\r
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in\r
+  @retval  EFI_SUCCESS - The sizes were returned\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BltLibVideoToBltBuffer (\r
+  OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,\r
+  IN  UINTN                                 SourceX,\r
+  IN  UINTN                                 SourceY,\r
+  IN  UINTN                                 Width,\r
+  IN  UINTN                                 Height\r
+  )\r
+{\r
+  return BltLibVideoToBltBufferEx (\r
+           BltBuffer,\r
+           SourceX,\r
+           SourceY,\r
+           0,\r
+           0,\r
+           Width,\r
+           Height,\r
+           0\r
+           );\r
+}\r
+\r
+\r
+/**\r
+  Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation\r
+  with extended parameters.\r
+\r
+  @param[out] BltBuffer     Output buffer for pixel color data\r
+  @param[in]  SourceX       X location within video\r
+  @param[in]  SourceY       Y location within video\r
+  @param[in]  DestinationX  X location within BltBuffer\r
+  @param[in]  DestinationY  Y location within BltBuffer\r
+  @param[in]  Width         Width (in pixels)\r
+  @param[in]  Height        Height\r
+  @param[in]  Delta         Number of bytes in a row of BltBuffer\r
+\r
+  @retval  EFI_DEVICE_ERROR - A hardware error occured\r
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in\r
+  @retval  EFI_SUCCESS - The sizes were returned\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BltLibVideoToBltBufferEx (\r
+  OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,\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\r
+  )\r
+{\r
+  UINTN                           DstY;\r
+  UINTN                           SrcY;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *Blt;\r
+  VOID                            *BltMemSrc;\r
+  VOID                            *BltMemDst;\r
+  UINTN                           X;\r
+  UINT32                          Uint32;\r
+  UINTN                           Offset;\r
+  UINTN                           WidthInBytes;\r
+\r
+  //\r
+  // Video to BltBuffer: Source is Video, destination is BltBuffer\r
+  //\r
+  if (SourceY + Height > mBltLibHeight) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (SourceX + Width > mBltLibWidthInPixels) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Width == 0 || Height == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // If Delta is zero, then the entire BltBuffer is being used, so Delta\r
+  // is the number of bytes in each row of BltBuffer.  Since BltBuffer is Width pixels size,\r
+  // the number of bytes in each row can be computed.\r
+  //\r
+  if (Delta == 0) {\r
+    Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
+  }\r
+\r
+  WidthInBytes = Width * mBltLibBytesPerPixel;\r
+\r
+  //\r
+  // Video to BltBuffer: Source is Video, destination is BltBuffer\r
+  //\r
+  for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY); SrcY++, DstY++) {\r
+\r
+    Offset = (SrcY * mBltLibWidthInPixels) + SourceX;\r
+    Offset = mBltLibBytesPerPixel * Offset;\r
+    BltMemSrc = (VOID *) (mBltLibFrameBuffer + Offset);\r
+\r
+    if (mPixelFormat == PixelBlueGreenRedReserved8BitPerColor) {\r
+      BltMemDst =\r
+        (VOID *) (\r
+            (UINT8 *) BltBuffer +\r
+            (DstY * Delta) +\r
+            (DestinationX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))\r
+          );\r
+    } else {\r
+      BltMemDst = (VOID *) mBltLibLineBuffer;\r
+    }\r
+\r
+    CopyMem (BltMemDst, BltMemSrc, WidthInBytes);\r
+\r
+    if (mPixelFormat != PixelBlueGreenRedReserved8BitPerColor) {\r
+      for (X = 0; X < Width; X++) {\r
+        Blt         = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer + (DstY * Delta) + (DestinationX + X) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+        Uint32 = *(UINT32*) (mBltLibLineBuffer + (X * mBltLibBytesPerPixel));\r
+        *(UINT32*) Blt =\r
+          (UINT32) (\r
+              (((Uint32 & mPixelBitMasks.RedMask)   >> mPixelShl[0]) << mPixelShr[0]) |\r
+              (((Uint32 & mPixelBitMasks.GreenMask) >> mPixelShl[1]) << mPixelShr[1]) |\r
+              (((Uint32 & mPixelBitMasks.BlueMask)  >> mPixelShl[2]) << mPixelShr[2])\r
+            );\r
+      }\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation.\r
+\r
+  @param[in]  BltBuffer     Output buffer for pixel color data\r
+  @param[in]  DestinationX  X location within video\r
+  @param[in]  DestinationY  Y location within video\r
+  @param[in]  Width         Width (in pixels)\r
+  @param[in]  Height        Height\r
+\r
+  @retval  EFI_DEVICE_ERROR - A hardware error occured\r
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in\r
+  @retval  EFI_SUCCESS - The sizes were returned\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BltLibBufferToVideo (\r
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,\r
+  IN  UINTN                                 DestinationX,\r
+  IN  UINTN                                 DestinationY,\r
+  IN  UINTN                                 Width,\r
+  IN  UINTN                                 Height\r
+  )\r
+{\r
+  return BltLibBufferToVideoEx (\r
+           BltBuffer,\r
+           0,\r
+           0,\r
+           DestinationX,\r
+           DestinationY,\r
+           Width,\r
+           Height,\r
+           0\r
+           );\r
+}\r
+\r
+\r
+/**\r
+  Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation\r
+  with extended parameters.\r
+\r
+  @param[in]  BltBuffer     Output buffer for pixel color data\r
+  @param[in]  SourceX       X location within BltBuffer\r
+  @param[in]  SourceY       Y location within BltBuffer\r
+  @param[in]  DestinationX  X location within video\r
+  @param[in]  DestinationY  Y location within video\r
+  @param[in]  Width         Width (in pixels)\r
+  @param[in]  Height        Height\r
+  @param[in]  Delta         Number of bytes in a row of BltBuffer\r
+\r
+  @retval  EFI_DEVICE_ERROR - A hardware error occured\r
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in\r
+  @retval  EFI_SUCCESS - The sizes were returned\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BltLibBufferToVideoEx (\r
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,\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\r
+  )\r
+{\r
+  UINTN                           DstY;\r
+  UINTN                           SrcY;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *Blt;\r
+  VOID                            *BltMemSrc;\r
+  VOID                            *BltMemDst;\r
+  UINTN                           X;\r
+  UINT32                          Uint32;\r
+  UINTN                           Offset;\r
+  UINTN                           WidthInBytes;\r
+\r
+  //\r
+  // BltBuffer to Video: Source is BltBuffer, destination is Video\r
+  //\r
+  if (DestinationY + Height > mBltLibHeight) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (DestinationX + Width > mBltLibWidthInPixels) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Width == 0 || Height == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // If Delta is zero, then the entire BltBuffer is being used, so Delta\r
+  // is the number of bytes in each row of BltBuffer.  Since BltBuffer is Width pixels size,\r
+  // the number of bytes in each row can be computed.\r
+  //\r
+  if (Delta == 0) {\r
+    Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
+  }\r
+\r
+  WidthInBytes = Width * mBltLibBytesPerPixel;\r
+\r
+  for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {\r
+\r
+    Offset = (DstY * mBltLibWidthInPixels) + DestinationX;\r
+    Offset = mBltLibBytesPerPixel * Offset;\r
+    BltMemDst = (VOID*) (mBltLibFrameBuffer + Offset);\r
+\r
+    if (mPixelFormat == PixelBlueGreenRedReserved8BitPerColor) {\r
+      BltMemSrc = (VOID *) (UINT8 *) BltBuffer + (SrcY * Delta);\r
+    } else {\r
+      for (X = 0; X < Width; X++) {\r
+        Blt =\r
+          (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) (\r
+              (UINT8 *) BltBuffer +\r
+              (SrcY * Delta) +\r
+              ((SourceX + X) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))\r
+            );\r
+        Uint32 = *(UINT32*) Blt;\r
+        *(UINT32*) (mBltLibLineBuffer + (X * mBltLibBytesPerPixel)) =\r
+          (UINT32) (\r
+              (((Uint32 << mPixelShl[0]) >> mPixelShr[0]) & mPixelBitMasks.RedMask) |\r
+              (((Uint32 << mPixelShl[1]) >> mPixelShr[1]) & mPixelBitMasks.GreenMask) |\r
+              (((Uint32 << mPixelShl[2]) >> mPixelShr[2]) & mPixelBitMasks.BlueMask)\r
+            );\r
+      }\r
+      BltMemSrc = (VOID *) mBltLibLineBuffer;\r
+    }\r
+\r
+    CopyMem (BltMemDst, BltMemSrc, WidthInBytes);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Performs a UEFI Graphics Output Protocol Blt Video to Video operation\r
+\r
+  @param[in]  SourceX       X location within video\r
+  @param[in]  SourceY       Y location within video\r
+  @param[in]  DestinationX  X location within video\r
+  @param[in]  DestinationY  Y location within video\r
+  @param[in]  Width         Width (in pixels)\r
+  @param[in]  Height        Height\r
+\r
+  @retval  EFI_DEVICE_ERROR - A hardware error occured\r
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in\r
+  @retval  EFI_SUCCESS - The sizes were returned\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BltLibVideoToVideo (\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
+  )\r
+{\r
+  VOID                            *BltMemSrc;\r
+  VOID                            *BltMemDst;\r
+  UINTN                           Offset;\r
+  UINTN                           WidthInBytes;\r
+  INTN                            LineStride;\r
+\r
+  //\r
+  // Video to Video: Source is Video, destination is Video\r
+  //\r
+  if (SourceY + Height > mBltLibHeight) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (SourceX + Width > mBltLibWidthInPixels) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (DestinationY + Height > mBltLibHeight) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (DestinationX + Width > mBltLibWidthInPixels) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Width == 0 || Height == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  WidthInBytes = Width * mBltLibBytesPerPixel;\r
+\r
+  Offset = (SourceY * mBltLibWidthInPixels) + SourceX;\r
+  Offset = mBltLibBytesPerPixel * Offset;\r
+  BltMemSrc = (VOID *) (mBltLibFrameBuffer + Offset);\r
+\r
+  Offset = (DestinationY * mBltLibWidthInPixels) + DestinationX;\r
+  Offset = mBltLibBytesPerPixel * Offset;\r
+  BltMemDst = (VOID *) (mBltLibFrameBuffer + Offset);\r
+\r
+  LineStride = mBltLibWidthInBytes;\r
+  if ((UINTN) BltMemDst > (UINTN) BltMemSrc) {\r
+    LineStride = -LineStride;\r
+  }\r
+\r
+  while (Height > 0) {\r
+    CopyMem (BltMemDst, BltMemSrc, WidthInBytes);\r
+\r
+    BltMemSrc = (VOID*) ((UINT8*) BltMemSrc + LineStride);\r
+    BltMemDst = (VOID*) ((UINT8*) BltMemDst + LineStride);\r
+    Height--;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Returns the sizes related to the video device\r
+\r
+  @param[out]  Width   Width (in pixels)\r
+  @param[out]  Height  Height (in pixels)\r
+\r
+  @retval  EFI_INVALID_PARAMETER - Invalid parameter passed in\r
+  @retval  EFI_SUCCESS - The sizes were returned\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BltLibGetSizes (\r
+  OUT UINTN                                 *Width,  OPTIONAL\r
+  OUT UINTN                                 *Height  OPTIONAL\r
+  )\r
+{\r
+  if (Width != NULL) {\r
+    *Width = mBltLibWidthInPixels;\r
+  }\r
+  if (Height != NULL) {\r
+    *Height = mBltLibHeight;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r