diff options
Diffstat (limited to 'MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.c')
| -rw-r--r-- | MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.c | 1476 |
1 files changed, 738 insertions, 738 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; + } +} |
