--- /dev/null
+/** @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