summaryrefslogtreecommitdiff
path: root/Platform/BroxtonPlatformPkg/Common/Library/FrameBufferBltLib
diff options
context:
space:
mode:
authorGuo Mang <mang.guo@intel.com>2016-12-23 13:33:16 +0800
committerGuo Mang <mang.guo@intel.com>2017-05-09 13:02:58 +0800
commite7b8e072fd6da92d7820b0a18c30bd3eea6ffc44 (patch)
tree99cae09b138c37a958c7e4e80e318ad20dab553f /Platform/BroxtonPlatformPkg/Common/Library/FrameBufferBltLib
parent54901c47dd992753dfce0a234c8cd53492e70d1a (diff)
downloadedk2-platforms-e7b8e072fd6da92d7820b0a18c30bd3eea6ffc44.tar.xz
BroxtonPlatformPkg: Add package Include and Library
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang <mang.guo@intel.com>
Diffstat (limited to 'Platform/BroxtonPlatformPkg/Common/Library/FrameBufferBltLib')
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/FrameBufferBltLib/FrameBufferBltLib.c578
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/FrameBufferBltLib/FrameBufferBltLib.inf34
2 files changed, 612 insertions, 0 deletions
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/FrameBufferBltLib/FrameBufferBltLib.c b/Platform/BroxtonPlatformPkg/Common/Library/FrameBufferBltLib/FrameBufferBltLib.c
new file mode 100644
index 0000000000..2a558566e5
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/FrameBufferBltLib/FrameBufferBltLib.c
@@ -0,0 +1,578 @@
+/** @file
+ FrameBufferBltLib - Library to perform blt operations on a frame buffer.
+
+ Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/GraphicsOutput.h>
+
+#if 0
+#define VDEBUG DEBUG
+#else
+#define VDEBUG(x)
+#endif
+
+#define MAX_LINE_BUFFER_SIZE (SIZE_4KB * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))
+
+UINT8 mBltLibLineBuffer[MAX_LINE_BUFFER_SIZE];
+EFI_PIXEL_BITMASK mBltLibRgbPixelMasks = {0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000};
+EFI_PIXEL_BITMASK mBltLibBgrPixelMasks = {0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000};
+
+EFI_STATUS
+BltLibParsePixelFormat (
+ IN EFI_GRAPHICS_PIXEL_FORMAT PixelFormat,
+ IN EFI_PIXEL_BITMASK *PixelInformation,
+ OUT UINT8 *PixelShl,
+ OUT UINT8 *PixelShr,
+ OUT UINT32 *PixelMask,
+ OUT UINT8 *BytesPerPixel
+ )
+{
+ UINTN Index;
+ UINT32 MergedMasks;
+ UINT32 *Mask;
+
+ switch (PixelFormat) {
+ case PixelRedGreenBlueReserved8BitPerColor:
+ return BltLibParsePixelFormat (PixelBitMask, &mBltLibRgbPixelMasks, PixelShl, PixelShr, PixelMask, BytesPerPixel);
+
+ case PixelBlueGreenRedReserved8BitPerColor:
+ return BltLibParsePixelFormat (PixelBitMask, &mBltLibBgrPixelMasks, PixelShl, PixelShr, PixelMask, BytesPerPixel);
+
+ case PixelBitMask:
+ break;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ MergedMasks = 0;
+ Mask = (UINT32 *) PixelInformation;
+ for (Index = 0; Index < 4; Index++) {
+ //
+ // Only ReservedMask can be 0
+ //
+ if (Index != 3 && Mask[Index] == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // The Mask of each color shouldn't overlap
+ //
+ if ((MergedMasks & Mask[Index]) != 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ MergedMasks |= Mask[Index];
+
+ if (PixelShl != NULL && PixelShr != NULL) {
+ PixelShl[Index] = (UINT8) (HighBitSet32 (Mask[Index]) - 23 + (Index * 8));
+ PixelShl[Index] %= 32;
+ if ((INT8) PixelShl[Index] < 0) {
+ PixelShr[Index] = -PixelShl[Index];
+ PixelShl[Index] = 0;
+ } else {
+ PixelShr[Index] = 0;
+ }
+ VDEBUG ((EFI_D_INFO, "%d: shl:%d shr:%d mask:%x\n", Index, PixelShl[Index], PixelShr[Index], Mask[Index]));
+ }
+ }
+ if (PixelMask != NULL) {
+ CopyMem (PixelMask, PixelInformation, sizeof (EFI_PIXEL_BITMASK));
+ }
+
+ if (BytesPerPixel != NULL) {
+ *BytesPerPixel = (UINT8) ((HighBitSet32 (MergedMasks) + 7) / 8);
+ VDEBUG ((EFI_D_INFO, "Bytes per pixel: %d\n", *BytesPerPixel));
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+BltLibVerifyLocation (
+ IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo,
+ IN UINTN X,
+ IN UINTN Y,
+ IN UINTN Width,
+ IN UINTN Height
+ )
+{
+ if ((X >= FrameBufferInfo->HorizontalResolution) ||
+ (Width > FrameBufferInfo->HorizontalResolution - X)) {
+ VDEBUG ((EFI_D_INFO, "VideoFill: Past screen (X)\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((Y >= FrameBufferInfo->VerticalResolution) ||
+ (Height > FrameBufferInfo->VerticalResolution - Y)) {
+ VDEBUG ((EFI_D_INFO, "VideoFill: Past screen (Y)\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Performs a UEFI Graphics Output Protocol Blt Video Fill.
+
+ @param[in] FrameBuffer Pointer to the start of the frame buffer
+ @param[in] FrameBufferInfo Describes the frame buffer characteristics
+ @param[in] Color Color to fill the region with
+ @param[in] DestinationX X location to start fill operation
+ @param[in] DestinationY Y location to start fill operation
+ @param[in] Width Width (in pixels) to fill
+ @param[in] Height Height to fill
+
+ @retval EFI_DEVICE_ERROR A hardware error occured
+ @retval EFI_INVALID_PARAMETER Invalid parameter passed in
+ @retval EFI_SUCCESS Blt operation success
+
+**/
+EFI_STATUS
+EFIAPI
+BltVideoFill (
+ IN VOID *FrameBuffer,
+ IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Color,
+ IN UINTN DestinationX,
+ IN UINTN DestinationY,
+ IN UINTN Width,
+ IN UINTN Height
+ )
+{
+ EFI_STATUS Status;
+ UINTN Y;
+ UINT8 *Destination;
+ UINTN X;
+ UINT8 Uint8;
+ UINT32 Uint32;
+ UINT64 WideFill;
+ BOOLEAN UseWideFill;
+ BOOLEAN LineBufferReady;
+ UINTN Offset;
+ UINTN WidthInBytes;
+ UINTN SizeInBytes;
+ UINT8 PixelShr[4];
+ UINT8 PixelShl[4];
+ UINT32 PixelMask[4];
+ UINT8 BytesPerPixel;
+
+ Status = BltLibVerifyLocation (FrameBufferInfo, DestinationX, DestinationY, Width, Height);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = BltLibParsePixelFormat (
+ FrameBufferInfo->PixelFormat,
+ &FrameBufferInfo->PixelInformation,
+ PixelShr, PixelShl, PixelMask, &BytesPerPixel
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ WidthInBytes = Width * BytesPerPixel;
+
+ Uint32 = *(UINT32 *) Color;
+ WideFill = (((Uint32 << PixelShl[0]) >> PixelShr[0]) & PixelMask[0]) |
+ (((Uint32 << PixelShl[1]) >> PixelShr[1]) & PixelMask[1]) |
+ (((Uint32 << PixelShl[2]) >> PixelShr[2]) & PixelMask[2]) |
+ (((Uint32 << PixelShl[3]) >> PixelShr[3]) & PixelMask[3]);
+ VDEBUG ((EFI_D_INFO, "VideoFill: color=0x%x, wide-fill=0x%x\n", Uint32, WideFill));
+
+ //
+ // If the size of the pixel data evenly divides the sizeof
+ // WideFill, then a wide fill operation can be used
+ //
+ UseWideFill = TRUE;
+ if (sizeof (WideFill) % BytesPerPixel == 0) {
+ for (X = BytesPerPixel; X < sizeof (WideFill); X++) {
+ ((UINT8 *) &WideFill)[X] = ((UINT8 *) &WideFill)[X % BytesPerPixel];
+ }
+ } else {
+ //
+ // If all the bytes in the pixel are the same value, then use
+ // a wide fill operation.
+ //
+ for (X = 1, Uint8 = ((UINT8 *) &WideFill)[0]; X < BytesPerPixel; X++) {
+ if (Uint8 != ((UINT8 *) &WideFill)[X]) {
+ UseWideFill = FALSE;
+ break;
+ }
+ }
+ if (UseWideFill) {
+ SetMem (&WideFill, sizeof (WideFill), Uint8);
+ }
+ }
+
+ if (UseWideFill && (DestinationX == 0) && (Width == FrameBufferInfo->HorizontalResolution)) {
+ VDEBUG ((EFI_D_INFO, "VideoFill (wide, one-shot)\n"));
+ Offset = DestinationY * FrameBufferInfo->PixelsPerScanLine * BytesPerPixel;
+ Destination = (UINT8 *) FrameBuffer + Offset;
+ SizeInBytes = WidthInBytes * Height;
+ if (SizeInBytes >= 8) {
+ SetMem64 (Destination, SizeInBytes & ~7, WideFill);
+ Destination += (SizeInBytes & ~7);
+ SizeInBytes &= 7;
+ }
+ if (SizeInBytes > 0) {
+ CopyMem (Destination, &WideFill, SizeInBytes);
+ }
+ } else {
+ LineBufferReady = FALSE;
+ for (Y = DestinationY; Y < (Height + DestinationY); Y++) {
+ Offset = ((Y * FrameBufferInfo->PixelsPerScanLine) + DestinationX) * BytesPerPixel;
+ Destination = (UINT8 *) FrameBuffer + Offset;
+
+ if (UseWideFill && (((UINTN) Destination & 7) == 0)) {
+ VDEBUG ((EFI_D_INFO, "VideoFill (wide)\n"));
+ SizeInBytes = WidthInBytes;
+ if (SizeInBytes >= 8) {
+ SetMem64 (Destination, SizeInBytes & ~7, WideFill);
+ Destination += (SizeInBytes & ~7);
+ SizeInBytes &= 7;
+ }
+ if (SizeInBytes > 0) {
+ CopyMem (Destination, &WideFill, SizeInBytes);
+ }
+ } else {
+ VDEBUG ((EFI_D_INFO, "VideoFill (not wide)\n"));
+ if (!LineBufferReady) {
+ CopyMem (mBltLibLineBuffer, &WideFill, BytesPerPixel);
+ for (X = 1; X < Width; ) {
+ CopyMem (
+ (mBltLibLineBuffer + (X * BytesPerPixel)),
+ mBltLibLineBuffer,
+ MIN (X, Width - X) * BytesPerPixel
+ );
+ X += MIN (X, Width - X);
+ }
+ LineBufferReady = TRUE;
+ }
+ CopyMem (Destination, mBltLibLineBuffer, WidthInBytes);
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation.
+
+ @param[in] FrameBuffer Pointer to the start of the frame buffer
+ @param[in] FrameBufferInfo Describes the frame buffer characteristics
+ @param[out] BltBuffer Output buffer for pixel color data
+ @param[in] SourceX X location within video
+ @param[in] SourceY Y location within video
+ @param[in] DestinationX X location within BltBuffer
+ @param[in] DestinationY Y location within BltBuffer
+ @param[in] Width Width (in pixels)
+ @param[in] Height Height
+ @param[in] Delta Number of bytes in a row of BltBuffer
+
+ @retval EFI_DEVICE_ERROR A hardware error occured
+ @retval EFI_INVALID_PARAMETER Invalid parameter passed in
+ @retval EFI_SUCCESS Blt operation success
+
+**/
+EFI_STATUS
+EFIAPI
+BltVideoToBuffer (
+ IN VOID *FrameBuffer,
+ IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo,
+ OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer,
+ IN UINTN SourceX,
+ IN UINTN SourceY,
+ IN UINTN DestinationX,
+ IN UINTN DestinationY,
+ IN UINTN Width,
+ IN UINTN Height,
+ IN UINTN Delta
+ )
+{
+ EFI_STATUS Status;
+ UINTN DstY;
+ UINTN SrcY;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
+ UINT8 *Source;
+ UINT8 *Destination;
+ UINTN X;
+ UINT32 Uint32;
+ UINTN Offset;
+ UINTN WidthInBytes;
+ UINT8 PixelShr[4];
+ UINT8 PixelShl[4];
+ UINT32 PixelMask[4];
+ UINT8 BytesPerPixel;
+
+ //
+ // Video to BltBuffer: Source is Video, destination is BltBuffer
+ //
+ Status = BltLibVerifyLocation (FrameBufferInfo, SourceX, SourceY, Width, Height);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = BltLibParsePixelFormat (
+ FrameBufferInfo->PixelFormat,
+ &FrameBufferInfo->PixelInformation,
+ PixelShl, PixelShr, PixelMask, &BytesPerPixel
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // If Delta is zero, then the entire BltBuffer is being used, so Delta
+ // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,
+ // the number of bytes in each row can be computed.
+ //
+ if (Delta == 0) {
+ Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
+ }
+
+ WidthInBytes = Width * BytesPerPixel;
+
+ //
+ // Video to BltBuffer: Source is Video, destination is BltBuffer
+ //
+ for (SrcY = SourceY, DstY = DestinationY; DstY < (DestinationY + Height); SrcY++, DstY++) {
+
+ Offset = ((SrcY * FrameBufferInfo->PixelsPerScanLine) + SourceX) * BytesPerPixel;
+ Source = (UINT8 *) FrameBuffer + Offset;
+
+ if (FrameBufferInfo->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
+ Destination = (UINT8 *) BltBuffer + (DstY * Delta) + (DestinationX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+ } else {
+ Destination = mBltLibLineBuffer;
+ }
+
+ CopyMem (Destination, Source, WidthInBytes);
+
+ if (FrameBufferInfo->PixelFormat != PixelBlueGreenRedReserved8BitPerColor) {
+ for (X = 0; X < Width; X++) {
+ Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer + (DstY * Delta) + (DestinationX + X) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+ Uint32 = *(UINT32 *) (mBltLibLineBuffer + (X * BytesPerPixel));
+ *(UINT32 *) Blt = (((Uint32 & PixelMask[0]) >> PixelShl[0]) << PixelShr[0]) |
+ (((Uint32 & PixelMask[1]) >> PixelShl[1]) << PixelShr[1]) |
+ (((Uint32 & PixelMask[2]) >> PixelShl[2]) << PixelShr[2]) |
+ (((Uint32 & PixelMask[3]) >> PixelShl[3]) << PixelShr[3]);
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation.
+
+ @param[in] FrameBuffer Pointer to the start of the frame buffer
+ @param[in] FrameBufferInfo Describes the frame buffer characteristics
+ @param[in] BltBuffer Output buffer for pixel color data
+ @param[in] SourceX X location within BltBuffer
+ @param[in] SourceY Y location within BltBuffer
+ @param[in] DestinationX X location within video
+ @param[in] DestinationY Y location within video
+ @param[in] Width Width (in pixels)
+ @param[in] Height Height
+ @param[in] Delta Number of bytes in a row of BltBuffer
+
+ @retval EFI_DEVICE_ERROR A hardware error occured
+ @retval EFI_INVALID_PARAMETER Invalid parameter passed in
+ @retval EFI_SUCCESS Blt operation success
+
+**/
+EFI_STATUS
+EFIAPI
+BltBufferToVideo (
+ IN VOID *FrameBuffer,
+ IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer,
+ IN UINTN SourceX,
+ IN UINTN SourceY,
+ IN UINTN DestinationX,
+ IN UINTN DestinationY,
+ IN UINTN Width,
+ IN UINTN Height,
+ IN UINTN Delta
+ )
+{
+ EFI_STATUS Status;
+ UINTN DstY;
+ UINTN SrcY;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
+ UINT8 *Source;
+ UINT8 *Destination;
+ UINTN X;
+ UINT32 Uint32;
+ UINTN Offset;
+ UINTN WidthInBytes;
+ UINT8 PixelShr[4];
+ UINT8 PixelShl[4];
+ UINT32 PixelMask[4];
+ UINT8 BytesPerPixel;
+
+ //
+ // BltBuffer to Video: Source is BltBuffer, destination is Video
+ //
+ Status = BltLibVerifyLocation (FrameBufferInfo, DestinationX, DestinationY, Width, Height);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = BltLibParsePixelFormat (
+ FrameBufferInfo->PixelFormat,
+ &FrameBufferInfo->PixelInformation,
+ PixelShl, PixelShr, PixelMask, &BytesPerPixel
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // If Delta is zero, then the entire BltBuffer is being used, so Delta
+ // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,
+ // the number of bytes in each row can be computed.
+ //
+ if (Delta == 0) {
+ Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
+ }
+
+ WidthInBytes = Width * BytesPerPixel;
+
+ for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {
+
+ Offset = ((DstY * FrameBufferInfo->PixelsPerScanLine) + DestinationX) * BytesPerPixel;
+ Destination = (UINT8 *) FrameBuffer + Offset;
+
+ if (FrameBufferInfo->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
+ Source = (UINT8 *) BltBuffer + (SrcY * Delta);
+ } else {
+ for (X = 0; X < Width; X++) {
+ Blt =
+ (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) (
+ (UINT8 *) BltBuffer +
+ (SrcY * Delta) +
+ ((SourceX + X) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))
+ );
+ Uint32 = *(UINT32 *) Blt;
+ *(UINT32 *) (mBltLibLineBuffer + (X * BytesPerPixel)) =
+ (((Uint32 << PixelShl[0]) >> PixelShr[0]) & PixelMask[0]) |
+ (((Uint32 << PixelShl[1]) >> PixelShr[1]) & PixelMask[1]) |
+ (((Uint32 << PixelShl[2]) >> PixelShr[2]) & PixelMask[2]) |
+ (((Uint32 << PixelShl[3]) >> PixelShr[3]) & PixelMask[3]);
+ }
+ Source = mBltLibLineBuffer;
+ }
+
+ CopyMem (Destination, Source, WidthInBytes);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Performs a UEFI Graphics Output Protocol Blt Video to Video operation.
+
+ @param[in] FrameBuffer Pointer to the start of the frame buffer
+ @param[in] FrameBufferInfo Describes the frame buffer characteristics
+ @param[in] SourceX X location within video
+ @param[in] SourceY Y location within video
+ @param[in] DestinationX X location within video
+ @param[in] DestinationY Y location within video
+ @param[in] Width Width (in pixels)
+ @param[in] Height Height
+
+ @retval EFI_DEVICE_ERROR A hardware error occured
+ @retval EFI_INVALID_PARAMETER Invalid parameter passed in
+ @retval EFI_SUCCESS Blt operation success
+
+**/
+EFI_STATUS
+EFIAPI
+BltVideoToVideo (
+ IN VOID *FrameBuffer,
+ IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo,
+ IN UINTN SourceX,
+ IN UINTN SourceY,
+ IN UINTN DestinationX,
+ IN UINTN DestinationY,
+ IN UINTN Width,
+ IN UINTN Height
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *Source;
+ UINT8 *Destination;
+ UINTN Offset;
+ UINTN WidthInBytes;
+ INTN LineStride;
+ UINT8 BytesPerPixel;
+
+ //
+ // Video to Video: Source is Video, destination is Video
+ //
+ Status = BltLibVerifyLocation (FrameBufferInfo, SourceX, SourceY, Width, Height);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = BltLibVerifyLocation (FrameBufferInfo, DestinationX, DestinationY, Width, Height);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = BltLibParsePixelFormat (
+ FrameBufferInfo->PixelFormat,
+ &FrameBufferInfo->PixelInformation,
+ NULL, NULL, NULL, &BytesPerPixel
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ WidthInBytes = Width * BytesPerPixel;
+
+ Offset = ((SourceY * FrameBufferInfo->PixelsPerScanLine) + SourceX) * BytesPerPixel;
+ Source = (UINT8 *) FrameBuffer + Offset;
+
+ Offset = ((DestinationY * FrameBufferInfo->PixelsPerScanLine) + DestinationX) * BytesPerPixel;
+ Destination = (UINT8 *) FrameBuffer + Offset;
+
+ LineStride = FrameBufferInfo->PixelsPerScanLine * BytesPerPixel;
+ if (Destination > Source) {
+ //
+ // Copy from last line to avoid source is corrupted by copying
+ //
+ Source += Height * LineStride;
+ Destination += Height * LineStride;
+ LineStride = -LineStride;
+ }
+
+ while (Height-- > 0) {
+ CopyMem (Destination, Source, WidthInBytes);
+
+ Source += LineStride;
+ Destination += LineStride;
+ }
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/FrameBufferBltLib/FrameBufferBltLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/FrameBufferBltLib/FrameBufferBltLib.inf
new file mode 100644
index 0000000000..850551d2ea
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/FrameBufferBltLib/FrameBufferBltLib.inf
@@ -0,0 +1,34 @@
+## @file
+# FrameBufferBltLib - Library to perform blt operations on a frame buffer.
+#
+# Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FrameBufferBltLib
+ FILE_GUID = 2a40f516-c852-4baa-b7a8-0e9ea090d659
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = BltLib
+
+[Sources.common]
+ FrameBufferBltLib.c
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+