]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg: Add FrameBufferBltLib library instance
authorRuiyu Ni <ruiyu.ni@intel.com>
Thu, 7 Jul 2016 05:31:27 +0000 (13:31 +0800)
committerRuiyu Ni <ruiyu.ni@intel.com>
Wed, 12 Oct 2016 02:42:16 +0000 (10:42 +0800)
This library provides interfaces to perform UEFI Graphics
Output Protocol Video BLT operations.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Feng Tian <feng.tian@intel.com>
Cc: Justen Jordan <jordan.l.justen@intel.com>
Tested-by: Laszlo Ersek <lersek at redhat.com>
MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.c [new file with mode: 0644]
MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf [new file with mode: 0644]
MdeModulePkg/MdeModulePkg.dsc

diff --git a/MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.c b/MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.c
new file mode 100644 (file)
index 0000000..c9bb206
--- /dev/null
@@ -0,0 +1,704 @@
+/** @file\r
+  FrameBufferBltLib - Library to perform blt operations on a frame buffer.\r
+\r
+  Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>\r
+  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 <Uefi/UefiBaseType.h>\r
+#include <Protocol/GraphicsOutput.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/FrameBufferBltLib.h>\r
+\r
+struct FRAME_BUFFER_CONFIGURE {\r
+  UINTN                           ColorDepth;\r
+  UINTN                           WidthInBytes;\r
+  UINTN                           BytesPerPixel;\r
+  UINTN                           WidthInPixels;\r
+  UINTN                           Height;\r
+  UINT8                           LineBuffer[SIZE_4KB * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)];\r
+  UINT8                           *FrameBuffer;\r
+  EFI_GRAPHICS_PIXEL_FORMAT       PixelFormat;\r
+  EFI_PIXEL_BITMASK               PixelMasks;\r
+  INTN                            PixelShl[4]; // R-G-B-Rsvd\r
+  INTN                            PixelShr[4]; // R-G-B-Rsvd\r
+};\r
+\r
+CONST EFI_PIXEL_BITMASK mRgbPixelMasks = {\r
+  0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000\r
+};\r
+\r
+CONST EFI_PIXEL_BITMASK mBgrPixelMasks = {\r
+  0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000\r
+};\r
+\r
+/**\r
+  Initialize the bit mask in frame buffer configure.\r
+\r
+  @param Configure  The frame buffer configure.\r
+  @param BitMask    The bit mask of pixel.\r
+**/\r
+VOID\r
+ConfigurePixelBitMaskFormat (\r
+  IN FRAME_BUFFER_CONFIGURE     *Configure,\r
+  IN CONST 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
+    Configure->PixelShl[Loop] = HighBitSet32 (Masks[Loop]) - 23 + (Loop * 8);\r
+    if (Configure->PixelShl[Loop] < 0) {\r
+      Configure->PixelShr[Loop] = -Configure->PixelShl[Loop];\r
+      Configure->PixelShl[Loop] = 0;\r
+    } else {\r
+      Configure->PixelShr[Loop] = 0;\r
+    }\r
+    MergedMasks = (UINT32) (MergedMasks | Masks[Loop]);\r
+    DEBUG ((EFI_D_VERBOSE, "%d: shl:%d shr:%d mask:%x\n", Loop,\r
+            Configure->PixelShl[Loop], Configure->PixelShr[Loop], Masks[Loop]));\r
+  }\r
+  MergedMasks = (UINT32) (MergedMasks | Masks[3]);\r
+\r
+  ASSERT (MergedMasks != 0);\r
+  Configure->BytesPerPixel = (UINTN) ((HighBitSet32 (MergedMasks) + 7) / 8);\r
+\r
+  DEBUG ((EFI_D_VERBOSE, "Bytes per pixel: %d\n", Configure->BytesPerPixel));\r
+\r
+  CopyMem (&Configure->PixelMasks, BitMask, sizeof (*BitMask));\r
+}\r
+\r
+/**\r
+  Create the configuration for a video frame buffer.\r
+\r
+  The configuration is returned in the caller provided buffer.\r
+\r
+  @param[in] FrameBuffer       Pointer to the start of the frame buffer.\r
+  @param[in] FrameBufferInfo   Describes the frame buffer characteristics.\r
+  @param[in,out] Configure     The created configuration information.\r
+  @param[in,out] ConfigureSize Size of the configuration information.\r
+\r
+  @retval RETURN_SUCCESS            The configuration was successful created.\r
+  @retval RETURN_BUFFER_TOO_SMALL   The Configure is to too small. The required\r
+                                    size is returned in ConfigureSize.\r
+  @retval RETURN_UNSUPPORTED        The requested mode is not supported by\r
+                                    this implementaion.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+FrameBufferBltConfigure (\r
+  IN     VOID                                  *FrameBuffer,\r
+  IN     EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *FrameBufferInfo,\r
+  IN OUT FRAME_BUFFER_CONFIGURE                *Configure,\r
+  IN OUT UINTN                                 *ConfigureSize\r
+  )\r
+{\r
+  if (ConfigureSize == NULL) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (*ConfigureSize < sizeof (FRAME_BUFFER_CONFIGURE)) {\r
+    *ConfigureSize = sizeof (FRAME_BUFFER_CONFIGURE);\r
+    return RETURN_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  if (Configure == NULL) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  switch (FrameBufferInfo->PixelFormat) {\r
+  case PixelRedGreenBlueReserved8BitPerColor:\r
+    ConfigurePixelBitMaskFormat (Configure, &mRgbPixelMasks);\r
+    break;\r
+\r
+  case PixelBlueGreenRedReserved8BitPerColor:\r
+    ConfigurePixelBitMaskFormat (Configure, &mBgrPixelMasks);\r
+    break;\r
+\r
+  case PixelBitMask:\r
+    ConfigurePixelBitMaskFormat (Configure, &(FrameBufferInfo->PixelInformation));\r
+    break;\r
+\r
+  case PixelBltOnly:\r
+    ASSERT (FrameBufferInfo->PixelFormat != PixelBltOnly);\r
+    return RETURN_UNSUPPORTED;\r
+\r
+  default:\r
+    ASSERT (FALSE);\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  Configure->PixelFormat   = FrameBufferInfo->PixelFormat;\r
+  Configure->FrameBuffer   = (UINT8*) FrameBuffer;\r
+  Configure->WidthInPixels = (UINTN) FrameBufferInfo->HorizontalResolution;\r
+  Configure->Height        = (UINTN) FrameBufferInfo->VerticalResolution;\r
+  Configure->WidthInBytes  = Configure->WidthInPixels * Configure->BytesPerPixel;\r
+\r
+  ASSERT (Configure->WidthInBytes < sizeof (Configure->LineBuffer));\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Performs a UEFI Graphics Output Protocol Blt Video Fill.\r
+\r
+  @param[in]  Configure     Pointer to a configuration which was successfully\r
+                            created by FrameBufferBltConfigure ().\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  RETURN_INVALID_PARAMETER Invalid parameter was passed in.\r
+  @retval  RETURN_SUCCESS           The video was filled successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+FrameBufferBltLibVideoFill (\r
+  IN  FRAME_BUFFER_CONFIGURE        *Configure,\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                             IndexX;\r
+  UINTN                             IndexY;\r
+  UINT8                             *Destination;\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 > Configure->Height) {\r
+    DEBUG ((EFI_D_VERBOSE, "VideoFill: Past screen (Y)\n"));\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (DestinationX + Width > Configure->WidthInPixels) {\r
+    DEBUG ((EFI_D_VERBOSE, "VideoFill: Past screen (X)\n"));\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Width == 0 || Height == 0) {\r
+    DEBUG ((EFI_D_VERBOSE, "VideoFill: Width or Height is 0\n"));\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  WidthInBytes = Width * Configure->BytesPerPixel;\r
+\r
+  Uint32 = *(UINT32*) Color;\r
+  WideFill =\r
+    (UINT32) (\r
+    (((Uint32 << Configure->PixelShl[0]) >> Configure->PixelShr[0]) &\r
+     Configure->PixelMasks.RedMask) |\r
+     (((Uint32 << Configure->PixelShl[1]) >> Configure->PixelShr[1]) &\r
+      Configure->PixelMasks.GreenMask) |\r
+      (((Uint32 << Configure->PixelShl[2]) >> Configure->PixelShr[2]) &\r
+       Configure->PixelMasks.BlueMask)\r
+      );\r
+  DEBUG ((EFI_D_VERBOSE, "VideoFill: color=0x%x, wide-fill=0x%x\n",\r
+          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) % Configure->BytesPerPixel) == 0) {\r
+    for (IndexX = Configure->BytesPerPixel; IndexX < sizeof (WideFill); IndexX++) {\r
+      ((UINT8*) &WideFill)[IndexX] = ((UINT8*) &WideFill)[IndexX % Configure->BytesPerPixel];\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
+      IndexX = 1, Uint8 = ((UINT8*) &WideFill)[0];\r
+      IndexX < Configure->BytesPerPixel;\r
+      IndexX++) {\r
+      if (Uint8 != ((UINT8*) &WideFill)[IndexX]) {\r
+        UseWideFill = FALSE;\r
+        break;\r
+      }\r
+    }\r
+    if (UseWideFill) {\r
+      SetMem (&WideFill, sizeof (WideFill), Uint8);\r
+    }\r
+  }\r
+\r
+  if (UseWideFill && (DestinationX == 0) && (Width == Configure->WidthInPixels)) {\r
+    DEBUG ((EFI_D_VERBOSE, "VideoFill (wide, one-shot)\n"));\r
+    Offset = DestinationY * Configure->WidthInPixels;\r
+    Offset = Configure->BytesPerPixel * Offset;\r
+    Destination = Configure->FrameBuffer + Offset;\r
+    SizeInBytes = WidthInBytes * Height;\r
+    if (SizeInBytes >= 8) {\r
+      SetMem32 (Destination, SizeInBytes & ~3, (UINT32) WideFill);\r
+      SizeInBytes &= 3;\r
+    }\r
+    if (SizeInBytes > 0) {\r
+      SetMem (Destination, SizeInBytes, (UINT8) (UINTN) WideFill);\r
+    }\r
+  } else {\r
+    LineBufferReady = FALSE;\r
+    for (IndexY = DestinationY; IndexY < (Height + DestinationY); IndexY++) {\r
+      Offset = (IndexY * Configure->WidthInPixels) + DestinationX;\r
+      Offset = Configure->BytesPerPixel * Offset;\r
+      Destination = Configure->FrameBuffer + Offset;\r
+\r
+      if (UseWideFill && (((UINTN) Destination & 7) == 0)) {\r
+        DEBUG ((EFI_D_VERBOSE, "VideoFill (wide)\n"));\r
+        SizeInBytes = WidthInBytes;\r
+        if (SizeInBytes >= 8) {\r
+          SetMem64 (Destination, SizeInBytes & ~7, WideFill);\r
+          SizeInBytes &= 7;\r
+        }\r
+        if (SizeInBytes > 0) {\r
+          CopyMem (Destination, &WideFill, SizeInBytes);\r
+        }\r
+      } else {\r
+        DEBUG ((EFI_D_VERBOSE, "VideoFill (not wide)\n"));\r
+        if (!LineBufferReady) {\r
+          CopyMem (Configure->LineBuffer, &WideFill, Configure->BytesPerPixel);\r
+          for (IndexX = 1; IndexX < Width; ) {\r
+            CopyMem (\r
+              (Configure->LineBuffer + (IndexX * Configure->BytesPerPixel)),\r
+              Configure->LineBuffer,\r
+              MIN (IndexX, Width - IndexX) * Configure->BytesPerPixel\r
+            );\r
+            IndexX += MIN (IndexX, Width - IndexX);\r
+          }\r
+          LineBufferReady = TRUE;\r
+        }\r
+        CopyMem (Destination, Configure->LineBuffer, WidthInBytes);\r
+      }\r
+    }\r
+  }\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation\r
+  with extended parameters.\r
+\r
+  @param[in]  Configure     Pointer to a configuration which was successfully\r
+                            created by FrameBufferBltConfigure ().\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 RETURN_INVALID_PARAMETER Invalid parameter were passed in.\r
+  @retval RETURN_SUCCESS           The Blt operation was performed successfully.\r
+**/\r
+RETURN_STATUS\r
+FrameBufferBltLibVideoToBltBuffer (\r
+  IN     FRAME_BUFFER_CONFIGURE          *Configure,\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
+  UINT8                                  *Source;\r
+  UINT8                                  *Destination;\r
+  UINTN                                  IndexX;\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 > Configure->Height) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (SourceX + Width > Configure->WidthInPixels) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Width == 0 || Height == 0) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // If Delta is zero, then the entire BltBuffer is being used, so Delta is\r
+  // the number of bytes in each row of BltBuffer. Since BltBuffer is Width\r
+  // pixels size, 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 * Configure->BytesPerPixel;\r
+\r
+  //\r
+  // Video to BltBuffer: Source is Video, destination is BltBuffer\r
+  //\r
+  for (SrcY = SourceY, DstY = DestinationY;\r
+       DstY < (Height + DestinationY);\r
+       SrcY++, DstY++) {\r
+\r
+    Offset = (SrcY * Configure->WidthInPixels) + SourceX;\r
+    Offset = Configure->BytesPerPixel * Offset;\r
+    Source = Configure->FrameBuffer + Offset;\r
+\r
+    if (Configure->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) {\r
+      Destination = (UINT8 *) BltBuffer + (DstY * Delta) + (DestinationX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+    } else {\r
+      Destination = Configure->LineBuffer;\r
+    }\r
+\r
+    CopyMem (Destination, Source, WidthInBytes);\r
+\r
+    if (Configure->PixelFormat != PixelBlueGreenRedReserved8BitPerColor) {\r
+      for (IndexX = 0; IndexX < Width; IndexX++) {\r
+        Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)\r
+          ((UINT8 *) BltBuffer + (DstY * Delta) +\r
+          (DestinationX + IndexX) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+        Uint32 = *(UINT32*) (Configure->LineBuffer + (IndexX * Configure->BytesPerPixel));\r
+        *(UINT32*) Blt =\r
+          (UINT32) (\r
+          (((Uint32 & Configure->PixelMasks.RedMask) >>\r
+            Configure->PixelShl[0]) << Configure->PixelShr[0]) |\r
+            (((Uint32 & Configure->PixelMasks.GreenMask) >>\r
+              Configure->PixelShl[1]) << Configure->PixelShr[1]) |\r
+              (((Uint32 & Configure->PixelMasks.BlueMask) >>\r
+                Configure->PixelShl[2]) << Configure->PixelShr[2])\r
+            );\r
+      }\r
+    }\r
+  }\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation\r
+  with extended parameters.\r
+\r
+  @param[in]  Configure     Pointer to a configuration which was successfully\r
+                            created by FrameBufferBltConfigure ().\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 RETURN_INVALID_PARAMETER Invalid parameter were passed in.\r
+  @retval RETURN_SUCCESS           The Blt operation was performed successfully.\r
+**/\r
+RETURN_STATUS\r
+FrameBufferBltLibBufferToVideo (\r
+  IN  FRAME_BUFFER_CONFIGURE                *Configure,\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
+  UINT8                                    *Source;\r
+  UINT8                                    *Destination;\r
+  UINTN                                    IndexX;\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 > Configure->Height) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (DestinationX + Width > Configure->WidthInPixels) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Width == 0 || Height == 0) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // If Delta is zero, then the entire BltBuffer is being used, so Delta is\r
+  // the number of bytes in each row of BltBuffer. Since BltBuffer is Width\r
+  // pixels size, 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 * Configure->BytesPerPixel;\r
+\r
+  for (SrcY = SourceY, DstY = DestinationY;\r
+       SrcY < (Height + SourceY);\r
+       SrcY++, DstY++) {\r
+\r
+    Offset = (DstY * Configure->WidthInPixels) + DestinationX;\r
+    Offset = Configure->BytesPerPixel * Offset;\r
+    Destination = Configure->FrameBuffer + Offset;\r
+\r
+    if (Configure->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) {\r
+      Source = (UINT8 *) BltBuffer + (SrcY * Delta);\r
+    } else {\r
+      for (IndexX = 0; IndexX < Width; IndexX++) {\r
+        Blt =\r
+          (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) (\r
+              (UINT8 *) BltBuffer +\r
+              (SrcY * Delta) +\r
+              ((SourceX + IndexX) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))\r
+            );\r
+        Uint32 = *(UINT32*) Blt;\r
+        *(UINT32*) (Configure->LineBuffer + (IndexX * Configure->BytesPerPixel)) =\r
+          (UINT32) (\r
+              (((Uint32 << Configure->PixelShl[0]) >> Configure->PixelShr[0]) &\r
+               Configure->PixelMasks.RedMask) |\r
+              (((Uint32 << Configure->PixelShl[1]) >> Configure->PixelShr[1]) &\r
+               Configure->PixelMasks.GreenMask) |\r
+              (((Uint32 << Configure->PixelShl[2]) >> Configure->PixelShr[2]) &\r
+               Configure->PixelMasks.BlueMask)\r
+            );\r
+      }\r
+      Source = Configure->LineBuffer;\r
+    }\r
+\r
+    CopyMem (Destination, Source, WidthInBytes);\r
+  }\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Performs a UEFI Graphics Output Protocol Blt Video to Video operation\r
+\r
+  @param[in]  Configure     Pointer to a configuration which was successfully\r
+                            created by FrameBufferBltConfigure ().\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 RETURN_INVALID_PARAMETER Invalid parameter were passed in.\r
+  @retval RETURN_SUCCESS           The Blt operation was performed successfully.\r
+**/\r
+RETURN_STATUS\r
+FrameBufferBltLibVideoToVideo (\r
+  IN  FRAME_BUFFER_CONFIGURE                *Configure,\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
+  UINT8                                     *Source;\r
+  UINT8                                     *Destination;\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 > Configure->Height) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (SourceX + Width > Configure->WidthInPixels) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (DestinationY + Height > Configure->Height) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (DestinationX + Width > Configure->WidthInPixels) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Width == 0 || Height == 0) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  WidthInBytes = Width * Configure->BytesPerPixel;\r
+\r
+  Offset = (SourceY * Configure->WidthInPixels) + SourceX;\r
+  Offset = Configure->BytesPerPixel * Offset;\r
+  Source = Configure->FrameBuffer + Offset;\r
+\r
+  Offset = (DestinationY * Configure->WidthInPixels) + DestinationX;\r
+  Offset = Configure->BytesPerPixel * Offset;\r
+  Destination = Configure->FrameBuffer + Offset;\r
+\r
+  LineStride = Configure->WidthInBytes;\r
+  if (Destination > Source) {\r
+    //\r
+    // Copy from last line to avoid source is corrupted by copying\r
+    //\r
+    Source += Height * LineStride;\r
+    Destination += Height * LineStride;\r
+    LineStride = -LineStride;\r
+  }\r
+\r
+  while (Height-- > 0) {\r
+    CopyMem (Destination, Source, WidthInBytes);\r
+\r
+    Source += LineStride;\r
+    Destination += LineStride;\r
+  }\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Performs a UEFI Graphics Output Protocol Blt operation.\r
+\r
+  @param[in]     Configure    Pointer to a configuration which was successfully\r
+                              created by FrameBufferBltConfigure ().\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\r
+                              BltOperation.\r
+  @param[in]     DestinationY The Y coordinate of the destination for\r
+                              BltOperation.\r
+  @param[in]     Width        The width of a rectangle in the blt rectangle\r
+                              in pixels.\r
+  @param[in]     Height       The height of a rectangle in the blt rectangle\r
+                              in pixels.\r
+  @param[in]     Delta        Not used for EfiBltVideoFill and\r
+                              EfiBltVideoToVideo operation. If a Delta of 0\r
+                              is used, the entire BltBuffer will be operated\r
+                              on. If a subrectangle of the BltBuffer is\r
+                              used, then Delta represents the number of\r
+                              bytes in a row of the BltBuffer.\r
+\r
+  @retval RETURN_INVALID_PARAMETER Invalid parameter were passed in.\r
+  @retval RETURN_SUCCESS           The Blt operation was performed successfully.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+FrameBufferBlt (\r
+  IN     FRAME_BUFFER_CONFIGURE                *Configure,\r
+  IN OUT 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
+  if (Configure == NULL) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  switch (BltOperation) {\r
+  case EfiBltVideoToBltBuffer:\r
+    return FrameBufferBltLibVideoToBltBuffer (\r
+             Configure,\r
+             BltBuffer,\r
+             SourceX,\r
+             SourceY,\r
+             DestinationX,\r
+             DestinationY,\r
+             Width,\r
+             Height,\r
+             Delta\r
+             );\r
+\r
+  case EfiBltVideoToVideo:\r
+    return FrameBufferBltLibVideoToVideo (\r
+             Configure,\r
+             SourceX,\r
+             SourceY,\r
+             DestinationX,\r
+             DestinationY,\r
+             Width,\r
+             Height\r
+             );\r
+\r
+  case EfiBltVideoFill:\r
+    return FrameBufferBltLibVideoFill (\r
+             Configure,\r
+             BltBuffer,\r
+             DestinationX,\r
+             DestinationY,\r
+             Width,\r
+             Height\r
+             );\r
+\r
+  case EfiBltBufferToVideo:\r
+    return FrameBufferBltLibBufferToVideo (\r
+             Configure,\r
+             BltBuffer,\r
+             SourceX,\r
+             SourceY,\r
+             DestinationX,\r
+             DestinationY,\r
+             Width,\r
+             Height,\r
+             Delta\r
+             );\r
+\r
+  default:\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+}\r
diff --git a/MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf b/MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
new file mode 100644 (file)
index 0000000..57e4adb
--- /dev/null
@@ -0,0 +1,34 @@
+## @file\r
+#  FrameBufferBltLib - Library to perform blt operations on a frame buffer.\r
+#\r
+#  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  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
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = FrameBufferBltLib\r
+  FILE_GUID                      = 243D3E8C-2780-4A25-9693-A410475BFCEC\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = FrameBufferBltLib\r
+\r
+[Sources.common]\r
+  FrameBufferBltLib.c\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
index 214cb6ceeef0461542d7bf886bc256d5963d14cf..6efd2c2f3719617fe65c02e41646bb35e54a50be 100644 (file)
   MdeModulePkg/Library/DxeIpmiLibIpmiProtocol/DxeIpmiLibIpmiProtocol.inf\r
   MdeModulePkg/Library/PeiIpmiLibIpmiPpi/PeiIpmiLibIpmiPpi.inf\r
   MdeModulePkg/Library/SmmIpmiLibSmmIpmiProtocol/SmmIpmiLibSmmIpmiProtocol.inf\r
+  MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf\r
 \r
   MdeModulePkg/Universal/BdsDxe/BdsDxe.inf\r
   MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf\r