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