summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Library/FrameBufferBltLib
diff options
context:
space:
mode:
Diffstat (limited to 'MdeModulePkg/Library/FrameBufferBltLib')
-rw-r--r--MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.c1476
-rw-r--r--MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf56
2 files changed, 766 insertions, 766 deletions
diff --git a/MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.c b/MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.c
index 432577bcfd..8893a1c1a5 100644
--- a/MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.c
+++ b/MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.c
@@ -1,738 +1,738 @@
-/** @file
- FrameBufferBltLib - Library to perform blt operations on a frame buffer.
-
- Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <Uefi/UefiBaseType.h>
-#include <Protocol/GraphicsOutput.h>
-
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/FrameBufferBltLib.h>
-
-struct FRAME_BUFFER_CONFIGURE {
- UINT32 PixelsPerScanLine;
- UINT32 BytesPerPixel;
- UINT32 Width;
- UINT32 Height;
- UINT8 *FrameBuffer;
- EFI_GRAPHICS_PIXEL_FORMAT PixelFormat;
- EFI_PIXEL_BITMASK PixelMasks;
- INT8 PixelShl[4]; // R-G-B-Rsvd
- INT8 PixelShr[4]; // R-G-B-Rsvd
- UINT8 LineBuffer[0];
-};
-
-CONST EFI_PIXEL_BITMASK mRgbPixelMasks = {
- 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000
-};
-
-CONST EFI_PIXEL_BITMASK mBgrPixelMasks = {
- 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000
-};
-
-/**
- Initialize the bit mask in frame buffer configure.
-
- @param BitMask The bit mask of pixel.
- @param BytesPerPixel Size in bytes of pixel.
- @param PixelShl Left shift array.
- @param PixelShr Right shift array.
-**/
-VOID
-FrameBufferBltLibConfigurePixelFormat (
- IN CONST EFI_PIXEL_BITMASK *BitMask,
- OUT UINT32 *BytesPerPixel,
- OUT INT8 *PixelShl,
- OUT INT8 *PixelShr
- )
-{
- UINT8 Index;
- UINT32 *Masks;
- UINT32 MergedMasks;
-
- ASSERT (BytesPerPixel != NULL);
-
- MergedMasks = 0;
- Masks = (UINT32 *)BitMask;
- for (Index = 0; Index < 3; Index++) {
- ASSERT ((MergedMasks & Masks[Index]) == 0);
-
- PixelShl[Index] = (INT8)HighBitSet32 (Masks[Index]) - 23 + (Index * 8);
- if (PixelShl[Index] < 0) {
- PixelShr[Index] = -PixelShl[Index];
- PixelShl[Index] = 0;
- } else {
- PixelShr[Index] = 0;
- }
-
- DEBUG ((
- DEBUG_INFO,
- "%d: shl:%d shr:%d mask:%x\n",
- Index,
- PixelShl[Index],
- PixelShr[Index],
- Masks[Index]
- ));
-
- MergedMasks = (UINT32)(MergedMasks | Masks[Index]);
- }
-
- MergedMasks = (UINT32)(MergedMasks | Masks[3]);
-
- ASSERT (MergedMasks != 0);
- *BytesPerPixel = (UINT32)((HighBitSet32 (MergedMasks) + 7) / 8);
- DEBUG ((DEBUG_INFO, "Bytes per pixel: %d\n", *BytesPerPixel));
-}
-
-/**
- Create the configuration for a video frame buffer.
-
- The configuration is returned in the caller provided buffer.
-
- @param[in] FrameBuffer Pointer to the start of the frame buffer.
- @param[in] FrameBufferInfo Describes the frame buffer characteristics.
- @param[in,out] Configure The created configuration information.
- @param[in,out] ConfigureSize Size of the configuration information.
-
- @retval RETURN_SUCCESS The configuration was successful created.
- @retval RETURN_BUFFER_TOO_SMALL The Configure is to too small. The required
- size is returned in ConfigureSize.
- @retval RETURN_UNSUPPORTED The requested mode is not supported by
- this implementaion.
-
-**/
-RETURN_STATUS
-EFIAPI
-FrameBufferBltConfigure (
- IN VOID *FrameBuffer,
- IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo,
- IN OUT FRAME_BUFFER_CONFIGURE *Configure,
- IN OUT UINTN *ConfigureSize
- )
-{
- CONST EFI_PIXEL_BITMASK *BitMask;
- UINT32 BytesPerPixel;
- INT8 PixelShl[4];
- INT8 PixelShr[4];
-
- if (ConfigureSize == NULL) {
- return RETURN_INVALID_PARAMETER;
- }
-
- switch (FrameBufferInfo->PixelFormat) {
- case PixelRedGreenBlueReserved8BitPerColor:
- BitMask = &mRgbPixelMasks;
- break;
-
- case PixelBlueGreenRedReserved8BitPerColor:
- BitMask = &mBgrPixelMasks;
- break;
-
- case PixelBitMask:
- BitMask = &FrameBufferInfo->PixelInformation;
- break;
-
- case PixelBltOnly:
- ASSERT (FrameBufferInfo->PixelFormat != PixelBltOnly);
- return RETURN_UNSUPPORTED;
-
- default:
- ASSERT (FALSE);
- return RETURN_INVALID_PARAMETER;
- }
-
- if (FrameBufferInfo->PixelsPerScanLine < FrameBufferInfo->HorizontalResolution) {
- return RETURN_UNSUPPORTED;
- }
-
- FrameBufferBltLibConfigurePixelFormat (BitMask, &BytesPerPixel, PixelShl, PixelShr);
-
- if (*ConfigureSize < sizeof (FRAME_BUFFER_CONFIGURE)
- + FrameBufferInfo->HorizontalResolution * BytesPerPixel)
- {
- *ConfigureSize = sizeof (FRAME_BUFFER_CONFIGURE)
- + FrameBufferInfo->HorizontalResolution * BytesPerPixel;
- return RETURN_BUFFER_TOO_SMALL;
- }
-
- if (Configure == NULL) {
- return RETURN_INVALID_PARAMETER;
- }
-
- CopyMem (&Configure->PixelMasks, BitMask, sizeof (*BitMask));
- CopyMem (Configure->PixelShl, PixelShl, sizeof (PixelShl));
- CopyMem (Configure->PixelShr, PixelShr, sizeof (PixelShr));
- Configure->BytesPerPixel = BytesPerPixel;
- Configure->PixelFormat = FrameBufferInfo->PixelFormat;
- Configure->FrameBuffer = (UINT8 *)FrameBuffer;
- Configure->Width = FrameBufferInfo->HorizontalResolution;
- Configure->Height = FrameBufferInfo->VerticalResolution;
- Configure->PixelsPerScanLine = FrameBufferInfo->PixelsPerScanLine;
-
- return RETURN_SUCCESS;
-}
-
-/**
- Performs a UEFI Graphics Output Protocol Blt Video Fill.
-
- @param[in] Configure Pointer to a configuration which was successfully
- created by FrameBufferBltConfigure ().
- @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 RETURN_INVALID_PARAMETER Invalid parameter was passed in.
- @retval RETURN_SUCCESS The video was filled successfully.
-
-**/
-EFI_STATUS
-FrameBufferBltLibVideoFill (
- IN FRAME_BUFFER_CONFIGURE *Configure,
- IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Color,
- IN UINTN DestinationX,
- IN UINTN DestinationY,
- IN UINTN Width,
- IN UINTN Height
- )
-{
- UINTN IndexX;
- UINTN IndexY;
- UINT8 *Destination;
- UINT8 Uint8;
- UINT32 Uint32;
- UINT64 WideFill;
- BOOLEAN UseWideFill;
- BOOLEAN LineBufferReady;
- UINTN Offset;
- UINTN WidthInBytes;
- UINTN SizeInBytes;
-
- //
- // BltBuffer to Video: Source is BltBuffer, destination is Video
- //
- if (DestinationY + Height > Configure->Height) {
- DEBUG ((DEBUG_VERBOSE, "VideoFill: Past screen (Y)\n"));
- return RETURN_INVALID_PARAMETER;
- }
-
- if (DestinationX + Width > Configure->Width) {
- DEBUG ((DEBUG_VERBOSE, "VideoFill: Past screen (X)\n"));
- return RETURN_INVALID_PARAMETER;
- }
-
- if ((Width == 0) || (Height == 0)) {
- DEBUG ((DEBUG_VERBOSE, "VideoFill: Width or Height is 0\n"));
- return RETURN_INVALID_PARAMETER;
- }
-
- WidthInBytes = Width * Configure->BytesPerPixel;
-
- Uint32 = *(UINT32 *)Color;
- WideFill =
- (UINT32)(
- (((Uint32 << Configure->PixelShl[0]) >> Configure->PixelShr[0]) &
- Configure->PixelMasks.RedMask) |
- (((Uint32 << Configure->PixelShl[1]) >> Configure->PixelShr[1]) &
- Configure->PixelMasks.GreenMask) |
- (((Uint32 << Configure->PixelShl[2]) >> Configure->PixelShr[2]) &
- Configure->PixelMasks.BlueMask)
- );
- DEBUG ((
- DEBUG_VERBOSE,
- "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) % Configure->BytesPerPixel) == 0) {
- for (IndexX = Configure->BytesPerPixel; IndexX < sizeof (WideFill); IndexX++) {
- ((UINT8 *)&WideFill)[IndexX] = ((UINT8 *)&WideFill)[IndexX % Configure->BytesPerPixel];
- }
- } else {
- //
- // If all the bytes in the pixel are the same value, then use
- // a wide fill operation.
- //
- for (
- IndexX = 1, Uint8 = ((UINT8 *)&WideFill)[0];
- IndexX < Configure->BytesPerPixel;
- IndexX++)
- {
- if (Uint8 != ((UINT8 *)&WideFill)[IndexX]) {
- UseWideFill = FALSE;
- break;
- }
- }
-
- if (UseWideFill) {
- SetMem (&WideFill, sizeof (WideFill), Uint8);
- }
- }
-
- if (UseWideFill && (DestinationX == 0) && (Width == Configure->PixelsPerScanLine)) {
- DEBUG ((DEBUG_VERBOSE, "VideoFill (wide, one-shot)\n"));
- Offset = DestinationY * Configure->PixelsPerScanLine;
- Offset = Configure->BytesPerPixel * Offset;
- Destination = Configure->FrameBuffer + Offset;
- SizeInBytes = WidthInBytes * Height;
- if (SizeInBytes >= 8) {
- SetMem32 (Destination, SizeInBytes & ~3, (UINT32)WideFill);
- Destination += SizeInBytes & ~3;
- SizeInBytes &= 3;
- }
-
- if (SizeInBytes > 0) {
- SetMem (Destination, SizeInBytes, (UINT8)(UINTN)WideFill);
- }
- } else {
- LineBufferReady = FALSE;
- for (IndexY = DestinationY; IndexY < (Height + DestinationY); IndexY++) {
- Offset = (IndexY * Configure->PixelsPerScanLine) + DestinationX;
- Offset = Configure->BytesPerPixel * Offset;
- Destination = Configure->FrameBuffer + Offset;
-
- if (UseWideFill && (((UINTN)Destination & 7) == 0)) {
- DEBUG ((DEBUG_VERBOSE, "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 {
- DEBUG ((DEBUG_VERBOSE, "VideoFill (not wide)\n"));
- if (!LineBufferReady) {
- CopyMem (Configure->LineBuffer, &WideFill, Configure->BytesPerPixel);
- for (IndexX = 1; IndexX < Width; ) {
- CopyMem (
- (Configure->LineBuffer + (IndexX * Configure->BytesPerPixel)),
- Configure->LineBuffer,
- MIN (IndexX, Width - IndexX) * Configure->BytesPerPixel
- );
- IndexX += MIN (IndexX, Width - IndexX);
- }
-
- LineBufferReady = TRUE;
- }
-
- CopyMem (Destination, Configure->LineBuffer, WidthInBytes);
- }
- }
- }
-
- return RETURN_SUCCESS;
-}
-
-/**
- Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation
- with extended parameters.
-
- @param[in] Configure Pointer to a configuration which was successfully
- created by FrameBufferBltConfigure ().
- @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 RETURN_INVALID_PARAMETER Invalid parameter were passed in.
- @retval RETURN_SUCCESS The Blt operation was performed successfully.
-**/
-RETURN_STATUS
-FrameBufferBltLibVideoToBltBuffer (
- IN FRAME_BUFFER_CONFIGURE *Configure,
- 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
- )
-{
- UINTN DstY;
- UINTN SrcY;
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
- UINT8 *Source;
- UINT8 *Destination;
- UINTN IndexX;
- UINT32 Uint32;
- UINTN Offset;
- UINTN WidthInBytes;
-
- //
- // Video to BltBuffer: Source is Video, destination is BltBuffer
- //
- if (SourceY + Height > Configure->Height) {
- return RETURN_INVALID_PARAMETER;
- }
-
- if (SourceX + Width > Configure->Width) {
- return RETURN_INVALID_PARAMETER;
- }
-
- if ((Width == 0) || (Height == 0)) {
- return RETURN_INVALID_PARAMETER;
- }
-
- //
- // 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 * Configure->BytesPerPixel;
-
- //
- // Video to BltBuffer: Source is Video, destination is BltBuffer
- //
- for (SrcY = SourceY, DstY = DestinationY;
- DstY < (Height + DestinationY);
- SrcY++, DstY++)
- {
- Offset = (SrcY * Configure->PixelsPerScanLine) + SourceX;
- Offset = Configure->BytesPerPixel * Offset;
- Source = Configure->FrameBuffer + Offset;
-
- if (Configure->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
- Destination = (UINT8 *)BltBuffer + (DstY * Delta) + (DestinationX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
- } else {
- Destination = Configure->LineBuffer;
- }
-
- CopyMem (Destination, Source, WidthInBytes);
-
- if (Configure->PixelFormat != PixelBlueGreenRedReserved8BitPerColor) {
- for (IndexX = 0; IndexX < Width; IndexX++) {
- Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)
- ((UINT8 *)BltBuffer + (DstY * Delta) +
- (DestinationX + IndexX) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
- Uint32 = *(UINT32 *)(Configure->LineBuffer + (IndexX * Configure->BytesPerPixel));
- *(UINT32 *)Blt =
- (UINT32)(
- (((Uint32 & Configure->PixelMasks.RedMask) >>
- Configure->PixelShl[0]) << Configure->PixelShr[0]) |
- (((Uint32 & Configure->PixelMasks.GreenMask) >>
- Configure->PixelShl[1]) << Configure->PixelShr[1]) |
- (((Uint32 & Configure->PixelMasks.BlueMask) >>
- Configure->PixelShl[2]) << Configure->PixelShr[2])
- );
- }
- }
- }
-
- return RETURN_SUCCESS;
-}
-
-/**
- Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation
- with extended parameters.
-
- @param[in] Configure Pointer to a configuration which was successfully
- created by FrameBufferBltConfigure ().
- @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 RETURN_INVALID_PARAMETER Invalid parameter were passed in.
- @retval RETURN_SUCCESS The Blt operation was performed successfully.
-**/
-RETURN_STATUS
-FrameBufferBltLibBufferToVideo (
- IN FRAME_BUFFER_CONFIGURE *Configure,
- 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
- )
-{
- UINTN DstY;
- UINTN SrcY;
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
- UINT8 *Source;
- UINT8 *Destination;
- UINTN IndexX;
- UINT32 Uint32;
- UINTN Offset;
- UINTN WidthInBytes;
-
- //
- // BltBuffer to Video: Source is BltBuffer, destination is Video
- //
- if (DestinationY + Height > Configure->Height) {
- return RETURN_INVALID_PARAMETER;
- }
-
- if (DestinationX + Width > Configure->Width) {
- return RETURN_INVALID_PARAMETER;
- }
-
- if ((Width == 0) || (Height == 0)) {
- return RETURN_INVALID_PARAMETER;
- }
-
- //
- // 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 * Configure->BytesPerPixel;
-
- for (SrcY = SourceY, DstY = DestinationY;
- SrcY < (Height + SourceY);
- SrcY++, DstY++)
- {
- Offset = (DstY * Configure->PixelsPerScanLine) + DestinationX;
- Offset = Configure->BytesPerPixel * Offset;
- Destination = Configure->FrameBuffer + Offset;
-
- if (Configure->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
- Source = (UINT8 *)BltBuffer + (SrcY * Delta) + SourceX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
- } else {
- for (IndexX = 0; IndexX < Width; IndexX++) {
- Blt =
- (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)(
- (UINT8 *)BltBuffer +
- (SrcY * Delta) +
- ((SourceX + IndexX) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))
- );
- Uint32 = *(UINT32 *)Blt;
- *(UINT32 *)(Configure->LineBuffer + (IndexX * Configure->BytesPerPixel)) =
- (UINT32)(
- (((Uint32 << Configure->PixelShl[0]) >> Configure->PixelShr[0]) &
- Configure->PixelMasks.RedMask) |
- (((Uint32 << Configure->PixelShl[1]) >> Configure->PixelShr[1]) &
- Configure->PixelMasks.GreenMask) |
- (((Uint32 << Configure->PixelShl[2]) >> Configure->PixelShr[2]) &
- Configure->PixelMasks.BlueMask)
- );
- }
-
- Source = Configure->LineBuffer;
- }
-
- CopyMem (Destination, Source, WidthInBytes);
- }
-
- return RETURN_SUCCESS;
-}
-
-/**
- Performs a UEFI Graphics Output Protocol Blt Video to Video operation
-
- @param[in] Configure Pointer to a configuration which was successfully
- created by FrameBufferBltConfigure ().
- @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 RETURN_INVALID_PARAMETER Invalid parameter were passed in.
- @retval RETURN_SUCCESS The Blt operation was performed successfully.
-**/
-RETURN_STATUS
-FrameBufferBltLibVideoToVideo (
- IN FRAME_BUFFER_CONFIGURE *Configure,
- IN UINTN SourceX,
- IN UINTN SourceY,
- IN UINTN DestinationX,
- IN UINTN DestinationY,
- IN UINTN Width,
- IN UINTN Height
- )
-{
- UINT8 *Source;
- UINT8 *Destination;
- UINTN Offset;
- UINTN WidthInBytes;
- INTN LineStride;
-
- //
- // Video to Video: Source is Video, destination is Video
- //
- if (SourceY + Height > Configure->Height) {
- return RETURN_INVALID_PARAMETER;
- }
-
- if (SourceX + Width > Configure->Width) {
- return RETURN_INVALID_PARAMETER;
- }
-
- if (DestinationY + Height > Configure->Height) {
- return RETURN_INVALID_PARAMETER;
- }
-
- if (DestinationX + Width > Configure->Width) {
- return RETURN_INVALID_PARAMETER;
- }
-
- if ((Width == 0) || (Height == 0)) {
- return RETURN_INVALID_PARAMETER;
- }
-
- WidthInBytes = Width * Configure->BytesPerPixel;
-
- Offset = (SourceY * Configure->PixelsPerScanLine) + SourceX;
- Offset = Configure->BytesPerPixel * Offset;
- Source = Configure->FrameBuffer + Offset;
-
- Offset = (DestinationY * Configure->PixelsPerScanLine) + DestinationX;
- Offset = Configure->BytesPerPixel * Offset;
- Destination = Configure->FrameBuffer + Offset;
-
- LineStride = Configure->BytesPerPixel * Configure->PixelsPerScanLine;
- 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 RETURN_SUCCESS;
-}
-
-/**
- Performs a UEFI Graphics Output Protocol Blt operation.
-
- @param[in] Configure Pointer to a configuration which was successfully
- created by FrameBufferBltConfigure ().
- @param[in,out] BltBuffer The data to transfer to screen.
- @param[in] BltOperation The operation to perform.
- @param[in] SourceX The X coordinate of the source for BltOperation.
- @param[in] SourceY The Y coordinate of the source for BltOperation.
- @param[in] DestinationX The X coordinate of the destination for
- BltOperation.
- @param[in] DestinationY The Y coordinate of the destination for
- BltOperation.
- @param[in] Width The width of a rectangle in the blt rectangle
- in pixels.
- @param[in] Height The height of a rectangle in the blt rectangle
- in pixels.
- @param[in] Delta Not used for EfiBltVideoFill and
- EfiBltVideoToVideo operation. If a Delta of 0
- is used, the entire BltBuffer will be operated
- on. If a subrectangle of the BltBuffer is
- used, then Delta represents the number of
- bytes in a row of the BltBuffer.
-
- @retval RETURN_INVALID_PARAMETER Invalid parameter were passed in.
- @retval RETURN_SUCCESS The Blt operation was performed successfully.
-**/
-RETURN_STATUS
-EFIAPI
-FrameBufferBlt (
- IN FRAME_BUFFER_CONFIGURE *Configure,
- IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL,
- IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
- IN UINTN SourceX,
- IN UINTN SourceY,
- IN UINTN DestinationX,
- IN UINTN DestinationY,
- IN UINTN Width,
- IN UINTN Height,
- IN UINTN Delta
- )
-{
- if (Configure == NULL) {
- return RETURN_INVALID_PARAMETER;
- }
-
- switch (BltOperation) {
- case EfiBltVideoToBltBuffer:
- return FrameBufferBltLibVideoToBltBuffer (
- Configure,
- BltBuffer,
- SourceX,
- SourceY,
- DestinationX,
- DestinationY,
- Width,
- Height,
- Delta
- );
-
- case EfiBltVideoToVideo:
- return FrameBufferBltLibVideoToVideo (
- Configure,
- SourceX,
- SourceY,
- DestinationX,
- DestinationY,
- Width,
- Height
- );
-
- case EfiBltVideoFill:
- return FrameBufferBltLibVideoFill (
- Configure,
- BltBuffer,
- DestinationX,
- DestinationY,
- Width,
- Height
- );
-
- case EfiBltBufferToVideo:
- return FrameBufferBltLibBufferToVideo (
- Configure,
- BltBuffer,
- SourceX,
- SourceY,
- DestinationX,
- DestinationY,
- Width,
- Height,
- Delta
- );
-
- default:
- return RETURN_INVALID_PARAMETER;
- }
-}
+/** @file
+ FrameBufferBltLib - Library to perform blt operations on a frame buffer.
+
+ Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi/UefiBaseType.h>
+#include <Protocol/GraphicsOutput.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/FrameBufferBltLib.h>
+
+struct FRAME_BUFFER_CONFIGURE {
+ UINT32 PixelsPerScanLine;
+ UINT32 BytesPerPixel;
+ UINT32 Width;
+ UINT32 Height;
+ UINT8 *FrameBuffer;
+ EFI_GRAPHICS_PIXEL_FORMAT PixelFormat;
+ EFI_PIXEL_BITMASK PixelMasks;
+ INT8 PixelShl[4]; // R-G-B-Rsvd
+ INT8 PixelShr[4]; // R-G-B-Rsvd
+ UINT8 LineBuffer[0];
+};
+
+CONST EFI_PIXEL_BITMASK mRgbPixelMasks = {
+ 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000
+};
+
+CONST EFI_PIXEL_BITMASK mBgrPixelMasks = {
+ 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000
+};
+
+/**
+ Initialize the bit mask in frame buffer configure.
+
+ @param BitMask The bit mask of pixel.
+ @param BytesPerPixel Size in bytes of pixel.
+ @param PixelShl Left shift array.
+ @param PixelShr Right shift array.
+**/
+VOID
+FrameBufferBltLibConfigurePixelFormat (
+ IN CONST EFI_PIXEL_BITMASK *BitMask,
+ OUT UINT32 *BytesPerPixel,
+ OUT INT8 *PixelShl,
+ OUT INT8 *PixelShr
+ )
+{
+ UINT8 Index;
+ UINT32 *Masks;
+ UINT32 MergedMasks;
+
+ ASSERT (BytesPerPixel != NULL);
+
+ MergedMasks = 0;
+ Masks = (UINT32 *)BitMask;
+ for (Index = 0; Index < 3; Index++) {
+ ASSERT ((MergedMasks & Masks[Index]) == 0);
+
+ PixelShl[Index] = (INT8)HighBitSet32 (Masks[Index]) - 23 + (Index * 8);
+ if (PixelShl[Index] < 0) {
+ PixelShr[Index] = -PixelShl[Index];
+ PixelShl[Index] = 0;
+ } else {
+ PixelShr[Index] = 0;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "%d: shl:%d shr:%d mask:%x\n",
+ Index,
+ PixelShl[Index],
+ PixelShr[Index],
+ Masks[Index]
+ ));
+
+ MergedMasks = (UINT32)(MergedMasks | Masks[Index]);
+ }
+
+ MergedMasks = (UINT32)(MergedMasks | Masks[3]);
+
+ ASSERT (MergedMasks != 0);
+ *BytesPerPixel = (UINT32)((HighBitSet32 (MergedMasks) + 7) / 8);
+ DEBUG ((DEBUG_INFO, "Bytes per pixel: %d\n", *BytesPerPixel));
+}
+
+/**
+ Create the configuration for a video frame buffer.
+
+ The configuration is returned in the caller provided buffer.
+
+ @param[in] FrameBuffer Pointer to the start of the frame buffer.
+ @param[in] FrameBufferInfo Describes the frame buffer characteristics.
+ @param[in,out] Configure The created configuration information.
+ @param[in,out] ConfigureSize Size of the configuration information.
+
+ @retval RETURN_SUCCESS The configuration was successful created.
+ @retval RETURN_BUFFER_TOO_SMALL The Configure is to too small. The required
+ size is returned in ConfigureSize.
+ @retval RETURN_UNSUPPORTED The requested mode is not supported by
+ this implementaion.
+
+**/
+RETURN_STATUS
+EFIAPI
+FrameBufferBltConfigure (
+ IN VOID *FrameBuffer,
+ IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo,
+ IN OUT FRAME_BUFFER_CONFIGURE *Configure,
+ IN OUT UINTN *ConfigureSize
+ )
+{
+ CONST EFI_PIXEL_BITMASK *BitMask;
+ UINT32 BytesPerPixel;
+ INT8 PixelShl[4];
+ INT8 PixelShr[4];
+
+ if (ConfigureSize == NULL) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ switch (FrameBufferInfo->PixelFormat) {
+ case PixelRedGreenBlueReserved8BitPerColor:
+ BitMask = &mRgbPixelMasks;
+ break;
+
+ case PixelBlueGreenRedReserved8BitPerColor:
+ BitMask = &mBgrPixelMasks;
+ break;
+
+ case PixelBitMask:
+ BitMask = &FrameBufferInfo->PixelInformation;
+ break;
+
+ case PixelBltOnly:
+ ASSERT (FrameBufferInfo->PixelFormat != PixelBltOnly);
+ return RETURN_UNSUPPORTED;
+
+ default:
+ ASSERT (FALSE);
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ if (FrameBufferInfo->PixelsPerScanLine < FrameBufferInfo->HorizontalResolution) {
+ return RETURN_UNSUPPORTED;
+ }
+
+ FrameBufferBltLibConfigurePixelFormat (BitMask, &BytesPerPixel, PixelShl, PixelShr);
+
+ if (*ConfigureSize < sizeof (FRAME_BUFFER_CONFIGURE)
+ + FrameBufferInfo->HorizontalResolution * BytesPerPixel)
+ {
+ *ConfigureSize = sizeof (FRAME_BUFFER_CONFIGURE)
+ + FrameBufferInfo->HorizontalResolution * BytesPerPixel;
+ return RETURN_BUFFER_TOO_SMALL;
+ }
+
+ if (Configure == NULL) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ CopyMem (&Configure->PixelMasks, BitMask, sizeof (*BitMask));
+ CopyMem (Configure->PixelShl, PixelShl, sizeof (PixelShl));
+ CopyMem (Configure->PixelShr, PixelShr, sizeof (PixelShr));
+ Configure->BytesPerPixel = BytesPerPixel;
+ Configure->PixelFormat = FrameBufferInfo->PixelFormat;
+ Configure->FrameBuffer = (UINT8 *)FrameBuffer;
+ Configure->Width = FrameBufferInfo->HorizontalResolution;
+ Configure->Height = FrameBufferInfo->VerticalResolution;
+ Configure->PixelsPerScanLine = FrameBufferInfo->PixelsPerScanLine;
+
+ return RETURN_SUCCESS;
+}
+
+/**
+ Performs a UEFI Graphics Output Protocol Blt Video Fill.
+
+ @param[in] Configure Pointer to a configuration which was successfully
+ created by FrameBufferBltConfigure ().
+ @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 RETURN_INVALID_PARAMETER Invalid parameter was passed in.
+ @retval RETURN_SUCCESS The video was filled successfully.
+
+**/
+EFI_STATUS
+FrameBufferBltLibVideoFill (
+ IN FRAME_BUFFER_CONFIGURE *Configure,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Color,
+ IN UINTN DestinationX,
+ IN UINTN DestinationY,
+ IN UINTN Width,
+ IN UINTN Height
+ )
+{
+ UINTN IndexX;
+ UINTN IndexY;
+ UINT8 *Destination;
+ UINT8 Uint8;
+ UINT32 Uint32;
+ UINT64 WideFill;
+ BOOLEAN UseWideFill;
+ BOOLEAN LineBufferReady;
+ UINTN Offset;
+ UINTN WidthInBytes;
+ UINTN SizeInBytes;
+
+ //
+ // BltBuffer to Video: Source is BltBuffer, destination is Video
+ //
+ if (DestinationY + Height > Configure->Height) {
+ DEBUG ((DEBUG_VERBOSE, "VideoFill: Past screen (Y)\n"));
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ if (DestinationX + Width > Configure->Width) {
+ DEBUG ((DEBUG_VERBOSE, "VideoFill: Past screen (X)\n"));
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ if ((Width == 0) || (Height == 0)) {
+ DEBUG ((DEBUG_VERBOSE, "VideoFill: Width or Height is 0\n"));
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ WidthInBytes = Width * Configure->BytesPerPixel;
+
+ Uint32 = *(UINT32 *)Color;
+ WideFill =
+ (UINT32)(
+ (((Uint32 << Configure->PixelShl[0]) >> Configure->PixelShr[0]) &
+ Configure->PixelMasks.RedMask) |
+ (((Uint32 << Configure->PixelShl[1]) >> Configure->PixelShr[1]) &
+ Configure->PixelMasks.GreenMask) |
+ (((Uint32 << Configure->PixelShl[2]) >> Configure->PixelShr[2]) &
+ Configure->PixelMasks.BlueMask)
+ );
+ DEBUG ((
+ DEBUG_VERBOSE,
+ "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) % Configure->BytesPerPixel) == 0) {
+ for (IndexX = Configure->BytesPerPixel; IndexX < sizeof (WideFill); IndexX++) {
+ ((UINT8 *)&WideFill)[IndexX] = ((UINT8 *)&WideFill)[IndexX % Configure->BytesPerPixel];
+ }
+ } else {
+ //
+ // If all the bytes in the pixel are the same value, then use
+ // a wide fill operation.
+ //
+ for (
+ IndexX = 1, Uint8 = ((UINT8 *)&WideFill)[0];
+ IndexX < Configure->BytesPerPixel;
+ IndexX++)
+ {
+ if (Uint8 != ((UINT8 *)&WideFill)[IndexX]) {
+ UseWideFill = FALSE;
+ break;
+ }
+ }
+
+ if (UseWideFill) {
+ SetMem (&WideFill, sizeof (WideFill), Uint8);
+ }
+ }
+
+ if (UseWideFill && (DestinationX == 0) && (Width == Configure->PixelsPerScanLine)) {
+ DEBUG ((DEBUG_VERBOSE, "VideoFill (wide, one-shot)\n"));
+ Offset = DestinationY * Configure->PixelsPerScanLine;
+ Offset = Configure->BytesPerPixel * Offset;
+ Destination = Configure->FrameBuffer + Offset;
+ SizeInBytes = WidthInBytes * Height;
+ if (SizeInBytes >= 8) {
+ SetMem32 (Destination, SizeInBytes & ~3, (UINT32)WideFill);
+ Destination += SizeInBytes & ~3;
+ SizeInBytes &= 3;
+ }
+
+ if (SizeInBytes > 0) {
+ SetMem (Destination, SizeInBytes, (UINT8)(UINTN)WideFill);
+ }
+ } else {
+ LineBufferReady = FALSE;
+ for (IndexY = DestinationY; IndexY < (Height + DestinationY); IndexY++) {
+ Offset = (IndexY * Configure->PixelsPerScanLine) + DestinationX;
+ Offset = Configure->BytesPerPixel * Offset;
+ Destination = Configure->FrameBuffer + Offset;
+
+ if (UseWideFill && (((UINTN)Destination & 7) == 0)) {
+ DEBUG ((DEBUG_VERBOSE, "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 {
+ DEBUG ((DEBUG_VERBOSE, "VideoFill (not wide)\n"));
+ if (!LineBufferReady) {
+ CopyMem (Configure->LineBuffer, &WideFill, Configure->BytesPerPixel);
+ for (IndexX = 1; IndexX < Width; ) {
+ CopyMem (
+ (Configure->LineBuffer + (IndexX * Configure->BytesPerPixel)),
+ Configure->LineBuffer,
+ MIN (IndexX, Width - IndexX) * Configure->BytesPerPixel
+ );
+ IndexX += MIN (IndexX, Width - IndexX);
+ }
+
+ LineBufferReady = TRUE;
+ }
+
+ CopyMem (Destination, Configure->LineBuffer, WidthInBytes);
+ }
+ }
+ }
+
+ return RETURN_SUCCESS;
+}
+
+/**
+ Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation
+ with extended parameters.
+
+ @param[in] Configure Pointer to a configuration which was successfully
+ created by FrameBufferBltConfigure ().
+ @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 RETURN_INVALID_PARAMETER Invalid parameter were passed in.
+ @retval RETURN_SUCCESS The Blt operation was performed successfully.
+**/
+RETURN_STATUS
+FrameBufferBltLibVideoToBltBuffer (
+ IN FRAME_BUFFER_CONFIGURE *Configure,
+ 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
+ )
+{
+ UINTN DstY;
+ UINTN SrcY;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
+ UINT8 *Source;
+ UINT8 *Destination;
+ UINTN IndexX;
+ UINT32 Uint32;
+ UINTN Offset;
+ UINTN WidthInBytes;
+
+ //
+ // Video to BltBuffer: Source is Video, destination is BltBuffer
+ //
+ if (SourceY + Height > Configure->Height) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ if (SourceX + Width > Configure->Width) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ if ((Width == 0) || (Height == 0)) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ //
+ // 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 * Configure->BytesPerPixel;
+
+ //
+ // Video to BltBuffer: Source is Video, destination is BltBuffer
+ //
+ for (SrcY = SourceY, DstY = DestinationY;
+ DstY < (Height + DestinationY);
+ SrcY++, DstY++)
+ {
+ Offset = (SrcY * Configure->PixelsPerScanLine) + SourceX;
+ Offset = Configure->BytesPerPixel * Offset;
+ Source = Configure->FrameBuffer + Offset;
+
+ if (Configure->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
+ Destination = (UINT8 *)BltBuffer + (DstY * Delta) + (DestinationX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+ } else {
+ Destination = Configure->LineBuffer;
+ }
+
+ CopyMem (Destination, Source, WidthInBytes);
+
+ if (Configure->PixelFormat != PixelBlueGreenRedReserved8BitPerColor) {
+ for (IndexX = 0; IndexX < Width; IndexX++) {
+ Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)
+ ((UINT8 *)BltBuffer + (DstY * Delta) +
+ (DestinationX + IndexX) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+ Uint32 = *(UINT32 *)(Configure->LineBuffer + (IndexX * Configure->BytesPerPixel));
+ *(UINT32 *)Blt =
+ (UINT32)(
+ (((Uint32 & Configure->PixelMasks.RedMask) >>
+ Configure->PixelShl[0]) << Configure->PixelShr[0]) |
+ (((Uint32 & Configure->PixelMasks.GreenMask) >>
+ Configure->PixelShl[1]) << Configure->PixelShr[1]) |
+ (((Uint32 & Configure->PixelMasks.BlueMask) >>
+ Configure->PixelShl[2]) << Configure->PixelShr[2])
+ );
+ }
+ }
+ }
+
+ return RETURN_SUCCESS;
+}
+
+/**
+ Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation
+ with extended parameters.
+
+ @param[in] Configure Pointer to a configuration which was successfully
+ created by FrameBufferBltConfigure ().
+ @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 RETURN_INVALID_PARAMETER Invalid parameter were passed in.
+ @retval RETURN_SUCCESS The Blt operation was performed successfully.
+**/
+RETURN_STATUS
+FrameBufferBltLibBufferToVideo (
+ IN FRAME_BUFFER_CONFIGURE *Configure,
+ 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
+ )
+{
+ UINTN DstY;
+ UINTN SrcY;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
+ UINT8 *Source;
+ UINT8 *Destination;
+ UINTN IndexX;
+ UINT32 Uint32;
+ UINTN Offset;
+ UINTN WidthInBytes;
+
+ //
+ // BltBuffer to Video: Source is BltBuffer, destination is Video
+ //
+ if (DestinationY + Height > Configure->Height) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ if (DestinationX + Width > Configure->Width) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ if ((Width == 0) || (Height == 0)) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ //
+ // 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 * Configure->BytesPerPixel;
+
+ for (SrcY = SourceY, DstY = DestinationY;
+ SrcY < (Height + SourceY);
+ SrcY++, DstY++)
+ {
+ Offset = (DstY * Configure->PixelsPerScanLine) + DestinationX;
+ Offset = Configure->BytesPerPixel * Offset;
+ Destination = Configure->FrameBuffer + Offset;
+
+ if (Configure->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
+ Source = (UINT8 *)BltBuffer + (SrcY * Delta) + SourceX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
+ } else {
+ for (IndexX = 0; IndexX < Width; IndexX++) {
+ Blt =
+ (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)(
+ (UINT8 *)BltBuffer +
+ (SrcY * Delta) +
+ ((SourceX + IndexX) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))
+ );
+ Uint32 = *(UINT32 *)Blt;
+ *(UINT32 *)(Configure->LineBuffer + (IndexX * Configure->BytesPerPixel)) =
+ (UINT32)(
+ (((Uint32 << Configure->PixelShl[0]) >> Configure->PixelShr[0]) &
+ Configure->PixelMasks.RedMask) |
+ (((Uint32 << Configure->PixelShl[1]) >> Configure->PixelShr[1]) &
+ Configure->PixelMasks.GreenMask) |
+ (((Uint32 << Configure->PixelShl[2]) >> Configure->PixelShr[2]) &
+ Configure->PixelMasks.BlueMask)
+ );
+ }
+
+ Source = Configure->LineBuffer;
+ }
+
+ CopyMem (Destination, Source, WidthInBytes);
+ }
+
+ return RETURN_SUCCESS;
+}
+
+/**
+ Performs a UEFI Graphics Output Protocol Blt Video to Video operation
+
+ @param[in] Configure Pointer to a configuration which was successfully
+ created by FrameBufferBltConfigure ().
+ @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 RETURN_INVALID_PARAMETER Invalid parameter were passed in.
+ @retval RETURN_SUCCESS The Blt operation was performed successfully.
+**/
+RETURN_STATUS
+FrameBufferBltLibVideoToVideo (
+ IN FRAME_BUFFER_CONFIGURE *Configure,
+ IN UINTN SourceX,
+ IN UINTN SourceY,
+ IN UINTN DestinationX,
+ IN UINTN DestinationY,
+ IN UINTN Width,
+ IN UINTN Height
+ )
+{
+ UINT8 *Source;
+ UINT8 *Destination;
+ UINTN Offset;
+ UINTN WidthInBytes;
+ INTN LineStride;
+
+ //
+ // Video to Video: Source is Video, destination is Video
+ //
+ if (SourceY + Height > Configure->Height) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ if (SourceX + Width > Configure->Width) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ if (DestinationY + Height > Configure->Height) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ if (DestinationX + Width > Configure->Width) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ if ((Width == 0) || (Height == 0)) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ WidthInBytes = Width * Configure->BytesPerPixel;
+
+ Offset = (SourceY * Configure->PixelsPerScanLine) + SourceX;
+ Offset = Configure->BytesPerPixel * Offset;
+ Source = Configure->FrameBuffer + Offset;
+
+ Offset = (DestinationY * Configure->PixelsPerScanLine) + DestinationX;
+ Offset = Configure->BytesPerPixel * Offset;
+ Destination = Configure->FrameBuffer + Offset;
+
+ LineStride = Configure->BytesPerPixel * Configure->PixelsPerScanLine;
+ 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 RETURN_SUCCESS;
+}
+
+/**
+ Performs a UEFI Graphics Output Protocol Blt operation.
+
+ @param[in] Configure Pointer to a configuration which was successfully
+ created by FrameBufferBltConfigure ().
+ @param[in,out] BltBuffer The data to transfer to screen.
+ @param[in] BltOperation The operation to perform.
+ @param[in] SourceX The X coordinate of the source for BltOperation.
+ @param[in] SourceY The Y coordinate of the source for BltOperation.
+ @param[in] DestinationX The X coordinate of the destination for
+ BltOperation.
+ @param[in] DestinationY The Y coordinate of the destination for
+ BltOperation.
+ @param[in] Width The width of a rectangle in the blt rectangle
+ in pixels.
+ @param[in] Height The height of a rectangle in the blt rectangle
+ in pixels.
+ @param[in] Delta Not used for EfiBltVideoFill and
+ EfiBltVideoToVideo operation. If a Delta of 0
+ is used, the entire BltBuffer will be operated
+ on. If a subrectangle of the BltBuffer is
+ used, then Delta represents the number of
+ bytes in a row of the BltBuffer.
+
+ @retval RETURN_INVALID_PARAMETER Invalid parameter were passed in.
+ @retval RETURN_SUCCESS The Blt operation was performed successfully.
+**/
+RETURN_STATUS
+EFIAPI
+FrameBufferBlt (
+ IN FRAME_BUFFER_CONFIGURE *Configure,
+ IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL,
+ IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
+ IN UINTN SourceX,
+ IN UINTN SourceY,
+ IN UINTN DestinationX,
+ IN UINTN DestinationY,
+ IN UINTN Width,
+ IN UINTN Height,
+ IN UINTN Delta
+ )
+{
+ if (Configure == NULL) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ switch (BltOperation) {
+ case EfiBltVideoToBltBuffer:
+ return FrameBufferBltLibVideoToBltBuffer (
+ Configure,
+ BltBuffer,
+ SourceX,
+ SourceY,
+ DestinationX,
+ DestinationY,
+ Width,
+ Height,
+ Delta
+ );
+
+ case EfiBltVideoToVideo:
+ return FrameBufferBltLibVideoToVideo (
+ Configure,
+ SourceX,
+ SourceY,
+ DestinationX,
+ DestinationY,
+ Width,
+ Height
+ );
+
+ case EfiBltVideoFill:
+ return FrameBufferBltLibVideoFill (
+ Configure,
+ BltBuffer,
+ DestinationX,
+ DestinationY,
+ Width,
+ Height
+ );
+
+ case EfiBltBufferToVideo:
+ return FrameBufferBltLibBufferToVideo (
+ Configure,
+ BltBuffer,
+ SourceX,
+ SourceY,
+ DestinationX,
+ DestinationY,
+ Width,
+ Height,
+ Delta
+ );
+
+ default:
+ return RETURN_INVALID_PARAMETER;
+ }
+}
diff --git a/MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf b/MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
index d186ca163a..d033cff035 100644
--- a/MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
+++ b/MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
@@ -1,28 +1,28 @@
-## @file
-# FrameBufferBltLib - Library to perform blt operations on a frame buffer.
-#
-# Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = FrameBufferBltLib
- FILE_GUID = 243D3E8C-2780-4A25-9693-A410475BFCEC
- MODULE_TYPE = UEFI_DRIVER
- VERSION_STRING = 1.0
- LIBRARY_CLASS = FrameBufferBltLib
-
-[Sources.common]
- FrameBufferBltLib.c
-
-[LibraryClasses]
- BaseLib
- BaseMemoryLib
- DebugLib
-
-[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
+## @file
+# FrameBufferBltLib - Library to perform blt operations on a frame buffer.
+#
+# Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FrameBufferBltLib
+ FILE_GUID = 243D3E8C-2780-4A25-9693-A410475BFCEC
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = FrameBufferBltLib
+
+[Sources.common]
+ FrameBufferBltLib.c
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec