mirror of https://github.com/acidanthera/audk.git
751 lines
24 KiB
C
751 lines
24 KiB
C
/** @file
|
|
FrameBufferBltLib - Library to perform blt operations on a frame buffer.
|
|
|
|
Copyright (c) 2007 - 2011, 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 "PiDxe.h"
|
|
#include <Library/BaseLib.h>
|
|
#include <Library/BaseMemoryLib.h>
|
|
#include <Library/BltLib.h>
|
|
#include <Library/DebugLib.h>
|
|
|
|
#if 0
|
|
#define VDEBUG DEBUG
|
|
#else
|
|
#define VDEBUG(x)
|
|
#endif
|
|
|
|
#define MAX_LINE_BUFFER_SIZE (SIZE_4KB * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))
|
|
|
|
UINTN mBltLibColorDepth;
|
|
UINTN mBltLibWidthInBytes;
|
|
UINTN mBltLibBytesPerPixel;
|
|
UINTN mBltLibWidthInPixels;
|
|
UINTN mBltLibHeight;
|
|
UINT8 mBltLibLineBuffer[MAX_LINE_BUFFER_SIZE];
|
|
UINT8 *mBltLibFrameBuffer;
|
|
EFI_GRAPHICS_PIXEL_FORMAT mPixelFormat;
|
|
EFI_PIXEL_BITMASK mPixelBitMasks;
|
|
INTN mPixelShl[4]; // R-G-B-Rsvd
|
|
INTN mPixelShr[4]; // R-G-B-Rsvd
|
|
|
|
|
|
VOID
|
|
ConfigurePixelBitMaskFormat (
|
|
IN EFI_PIXEL_BITMASK *BitMask
|
|
)
|
|
{
|
|
UINTN Loop;
|
|
UINT32 *Masks;
|
|
UINT32 MergedMasks;
|
|
|
|
MergedMasks = 0;
|
|
Masks = (UINT32*) BitMask;
|
|
for (Loop = 0; Loop < 3; Loop++) {
|
|
ASSERT ((Loop == 3) || (Masks[Loop] != 0));
|
|
ASSERT ((MergedMasks & Masks[Loop]) == 0);
|
|
mPixelShl[Loop] = HighBitSet32 (Masks[Loop]) - 23 + (Loop * 8);
|
|
if (mPixelShl[Loop] < 0) {
|
|
mPixelShr[Loop] = -mPixelShl[Loop];
|
|
mPixelShl[Loop] = 0;
|
|
} else {
|
|
mPixelShr[Loop] = 0;
|
|
}
|
|
MergedMasks = (UINT32) (MergedMasks | Masks[Loop]);
|
|
DEBUG ((EFI_D_INFO, "%d: shl:%d shr:%d mask:%x\n", Loop, mPixelShl[Loop], mPixelShr[Loop], Masks[Loop]));
|
|
}
|
|
MergedMasks = (UINT32) (MergedMasks | Masks[3]);
|
|
|
|
ASSERT (MergedMasks != 0);
|
|
mBltLibBytesPerPixel = (UINTN) ((HighBitSet32 (MergedMasks) + 7) / 8);
|
|
|
|
DEBUG ((EFI_D_INFO, "Bytes per pixel: %d\n", mBltLibBytesPerPixel));
|
|
|
|
CopyMem (&mPixelBitMasks, BitMask, sizeof (*BitMask));
|
|
}
|
|
|
|
|
|
/**
|
|
Configure the FrameBufferLib instance
|
|
|
|
@param[in] FrameBuffer Pointer to the start of the frame buffer
|
|
@param[in] FrameBufferInfo Describes the frame buffer characteristics
|
|
|
|
@retval EFI_INVALID_PARAMETER - Invalid parameter
|
|
@retval EFI_UNSUPPORTED - The BltLib does not support this configuration
|
|
@retval EFI_SUCCESS - Blt operation success
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
BltLibConfigure (
|
|
IN VOID *FrameBuffer,
|
|
IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo
|
|
)
|
|
{
|
|
STATIC EFI_PIXEL_BITMASK RgbPixelMasks =
|
|
{ 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 };
|
|
STATIC EFI_PIXEL_BITMASK BgrPixelMasks =
|
|
{ 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 };
|
|
|
|
switch (FrameBufferInfo->PixelFormat) {
|
|
case PixelRedGreenBlueReserved8BitPerColor:
|
|
ConfigurePixelBitMaskFormat (&RgbPixelMasks);
|
|
break;
|
|
case PixelBlueGreenRedReserved8BitPerColor:
|
|
ConfigurePixelBitMaskFormat (&BgrPixelMasks);
|
|
break;
|
|
case PixelBitMask:
|
|
ConfigurePixelBitMaskFormat (&(FrameBufferInfo->PixelInformation));
|
|
break;
|
|
case PixelBltOnly:
|
|
ASSERT (FrameBufferInfo->PixelFormat != PixelBltOnly);
|
|
return EFI_UNSUPPORTED;
|
|
default:
|
|
ASSERT (FALSE);
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
mPixelFormat = FrameBufferInfo->PixelFormat;
|
|
|
|
mBltLibFrameBuffer = (UINT8*) FrameBuffer;
|
|
mBltLibWidthInPixels = (UINTN) FrameBufferInfo->HorizontalResolution;
|
|
mBltLibHeight = (UINTN) FrameBufferInfo->VerticalResolution;
|
|
mBltLibWidthInBytes = mBltLibWidthInPixels * mBltLibBytesPerPixel;
|
|
|
|
ASSERT (mBltLibWidthInBytes < sizeof (mBltLibLineBuffer));
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
Performs a UEFI Graphics Output Protocol Blt operation.
|
|
|
|
@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 EFI_DEVICE_ERROR - A hardware error occured
|
|
@retval EFI_INVALID_PARAMETER - Invalid parameter passed in
|
|
@retval EFI_SUCCESS - Blt operation success
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
BltLibGopBlt (
|
|
IN 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
|
|
)
|
|
{
|
|
switch (BltOperation) {
|
|
case EfiBltVideoToBltBuffer:
|
|
return BltLibVideoToBltBufferEx (
|
|
BltBuffer,
|
|
SourceX,
|
|
SourceY,
|
|
DestinationX,
|
|
DestinationY,
|
|
Width,
|
|
Height,
|
|
Delta
|
|
);
|
|
|
|
case EfiBltVideoToVideo:
|
|
return BltLibVideoToVideo (
|
|
SourceX,
|
|
SourceY,
|
|
DestinationX,
|
|
DestinationY,
|
|
Width,
|
|
Height
|
|
);
|
|
|
|
case EfiBltVideoFill:
|
|
return BltLibVideoFill (
|
|
BltBuffer,
|
|
DestinationX,
|
|
DestinationY,
|
|
Width,
|
|
Height
|
|
);
|
|
|
|
case EfiBltBufferToVideo:
|
|
return BltLibBufferToVideoEx (
|
|
BltBuffer,
|
|
SourceX,
|
|
SourceY,
|
|
DestinationX,
|
|
DestinationY,
|
|
Width,
|
|
Height,
|
|
Delta
|
|
);
|
|
default:
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
Performs a UEFI Graphics Output Protocol Blt Video Fill.
|
|
|
|
@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 - The sizes were returned
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
BltLibVideoFill (
|
|
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Color,
|
|
IN UINTN DestinationX,
|
|
IN UINTN DestinationY,
|
|
IN UINTN Width,
|
|
IN UINTN Height
|
|
)
|
|
{
|
|
UINTN DstY;
|
|
VOID *BltMemDst;
|
|
UINTN X;
|
|
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 > mBltLibHeight) {
|
|
DEBUG ((EFI_D_INFO, "VideoFill: Past screen (Y)\n"));
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (DestinationX + Width > mBltLibWidthInPixels) {
|
|
DEBUG ((EFI_D_INFO, "VideoFill: Past screen (X)\n"));
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (Width == 0 || Height == 0) {
|
|
DEBUG ((EFI_D_INFO, "VideoFill: Width or Height is 0\n"));
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
WidthInBytes = Width * mBltLibBytesPerPixel;
|
|
|
|
Uint32 = *(UINT32*) Color;
|
|
WideFill =
|
|
(UINT32) (
|
|
(((Uint32 << mPixelShl[0]) >> mPixelShr[0]) & mPixelBitMasks.RedMask) |
|
|
(((Uint32 << mPixelShl[1]) >> mPixelShr[1]) & mPixelBitMasks.GreenMask) |
|
|
(((Uint32 << mPixelShl[2]) >> mPixelShr[2]) & mPixelBitMasks.BlueMask)
|
|
);
|
|
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) % mBltLibBytesPerPixel) == 0) {
|
|
for (X = mBltLibBytesPerPixel; X < sizeof (WideFill); X++) {
|
|
((UINT8*)&WideFill)[X] = ((UINT8*)&WideFill)[X % mBltLibBytesPerPixel];
|
|
}
|
|
} 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 < mBltLibBytesPerPixel;
|
|
X++) {
|
|
if (Uint8 != ((UINT8*)&WideFill)[X]) {
|
|
UseWideFill = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
if (UseWideFill) {
|
|
SetMem ((VOID*) &WideFill, sizeof (WideFill), Uint8);
|
|
}
|
|
}
|
|
|
|
if (UseWideFill && (DestinationX == 0) && (Width == mBltLibWidthInPixels)) {
|
|
VDEBUG ((EFI_D_INFO, "VideoFill (wide, one-shot)\n"));
|
|
Offset = DestinationY * mBltLibWidthInPixels;
|
|
Offset = mBltLibBytesPerPixel * Offset;
|
|
BltMemDst = (VOID*) (mBltLibFrameBuffer + Offset);
|
|
SizeInBytes = WidthInBytes * Height;
|
|
if (SizeInBytes >= 8) {
|
|
SetMem32 (BltMemDst, SizeInBytes & ~3, (UINT32) WideFill);
|
|
SizeInBytes = SizeInBytes & 3;
|
|
}
|
|
if (SizeInBytes > 0) {
|
|
SetMem (BltMemDst, SizeInBytes, (UINT8)(UINTN) WideFill);
|
|
}
|
|
} else {
|
|
LineBufferReady = FALSE;
|
|
for (DstY = DestinationY; DstY < (Height + DestinationY); DstY++) {
|
|
Offset = (DstY * mBltLibWidthInPixels) + DestinationX;
|
|
Offset = mBltLibBytesPerPixel * Offset;
|
|
BltMemDst = (VOID*) (mBltLibFrameBuffer + Offset);
|
|
|
|
if (UseWideFill && (((UINTN) BltMemDst & 7) == 0)) {
|
|
VDEBUG ((EFI_D_INFO, "VideoFill (wide)\n"));
|
|
SizeInBytes = WidthInBytes;
|
|
if (SizeInBytes >= 8) {
|
|
SetMem64 (BltMemDst, SizeInBytes & ~7, WideFill);
|
|
SizeInBytes = SizeInBytes & 7;
|
|
}
|
|
if (SizeInBytes > 0) {
|
|
CopyMem (BltMemDst, (VOID*) &WideFill, SizeInBytes);
|
|
}
|
|
} else {
|
|
VDEBUG ((EFI_D_INFO, "VideoFill (not wide)\n"));
|
|
if (!LineBufferReady) {
|
|
CopyMem (mBltLibLineBuffer, &WideFill, mBltLibBytesPerPixel);
|
|
for (X = 1; X < Width; ) {
|
|
CopyMem(
|
|
(mBltLibLineBuffer + (X * mBltLibBytesPerPixel)),
|
|
mBltLibLineBuffer,
|
|
MIN (X, Width - X) * mBltLibBytesPerPixel
|
|
);
|
|
X = X + MIN (X, Width - X);
|
|
}
|
|
LineBufferReady = TRUE;
|
|
}
|
|
CopyMem (BltMemDst, mBltLibLineBuffer, WidthInBytes);
|
|
}
|
|
}
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation.
|
|
|
|
@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] 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 - The sizes were returned
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
BltLibVideoToBltBuffer (
|
|
OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer,
|
|
IN UINTN SourceX,
|
|
IN UINTN SourceY,
|
|
IN UINTN Width,
|
|
IN UINTN Height
|
|
)
|
|
{
|
|
return BltLibVideoToBltBufferEx (
|
|
BltBuffer,
|
|
SourceX,
|
|
SourceY,
|
|
0,
|
|
0,
|
|
Width,
|
|
Height,
|
|
0
|
|
);
|
|
}
|
|
|
|
|
|
/**
|
|
Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation
|
|
with extended parameters.
|
|
|
|
@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 - The sizes were returned
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
BltLibVideoToBltBufferEx (
|
|
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;
|
|
VOID *BltMemSrc;
|
|
VOID *BltMemDst;
|
|
UINTN X;
|
|
UINT32 Uint32;
|
|
UINTN Offset;
|
|
UINTN WidthInBytes;
|
|
|
|
//
|
|
// Video to BltBuffer: Source is Video, destination is BltBuffer
|
|
//
|
|
if (SourceY + Height > mBltLibHeight) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (SourceX + Width > mBltLibWidthInPixels) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (Width == 0 || Height == 0) {
|
|
return EFI_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 * mBltLibBytesPerPixel;
|
|
|
|
//
|
|
// Video to BltBuffer: Source is Video, destination is BltBuffer
|
|
//
|
|
for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY); SrcY++, DstY++) {
|
|
|
|
Offset = (SrcY * mBltLibWidthInPixels) + SourceX;
|
|
Offset = mBltLibBytesPerPixel * Offset;
|
|
BltMemSrc = (VOID *) (mBltLibFrameBuffer + Offset);
|
|
|
|
if (mPixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
|
|
BltMemDst =
|
|
(VOID *) (
|
|
(UINT8 *) BltBuffer +
|
|
(DstY * Delta) +
|
|
(DestinationX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))
|
|
);
|
|
} else {
|
|
BltMemDst = (VOID *) mBltLibLineBuffer;
|
|
}
|
|
|
|
CopyMem (BltMemDst, BltMemSrc, WidthInBytes);
|
|
|
|
if (mPixelFormat != 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 * mBltLibBytesPerPixel));
|
|
*(UINT32*) Blt =
|
|
(UINT32) (
|
|
(((Uint32 & mPixelBitMasks.RedMask) >> mPixelShl[0]) << mPixelShr[0]) |
|
|
(((Uint32 & mPixelBitMasks.GreenMask) >> mPixelShl[1]) << mPixelShr[1]) |
|
|
(((Uint32 & mPixelBitMasks.BlueMask) >> mPixelShl[2]) << mPixelShr[2])
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation.
|
|
|
|
@param[in] BltBuffer Output buffer for pixel color data
|
|
@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 - The sizes were returned
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
BltLibBufferToVideo (
|
|
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer,
|
|
IN UINTN DestinationX,
|
|
IN UINTN DestinationY,
|
|
IN UINTN Width,
|
|
IN UINTN Height
|
|
)
|
|
{
|
|
return BltLibBufferToVideoEx (
|
|
BltBuffer,
|
|
0,
|
|
0,
|
|
DestinationX,
|
|
DestinationY,
|
|
Width,
|
|
Height,
|
|
0
|
|
);
|
|
}
|
|
|
|
|
|
/**
|
|
Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation
|
|
with extended parameters.
|
|
|
|
@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 - The sizes were returned
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
BltLibBufferToVideoEx (
|
|
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;
|
|
VOID *BltMemSrc;
|
|
VOID *BltMemDst;
|
|
UINTN X;
|
|
UINT32 Uint32;
|
|
UINTN Offset;
|
|
UINTN WidthInBytes;
|
|
|
|
//
|
|
// BltBuffer to Video: Source is BltBuffer, destination is Video
|
|
//
|
|
if (DestinationY + Height > mBltLibHeight) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (DestinationX + Width > mBltLibWidthInPixels) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (Width == 0 || Height == 0) {
|
|
return EFI_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 * mBltLibBytesPerPixel;
|
|
|
|
for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {
|
|
|
|
Offset = (DstY * mBltLibWidthInPixels) + DestinationX;
|
|
Offset = mBltLibBytesPerPixel * Offset;
|
|
BltMemDst = (VOID*) (mBltLibFrameBuffer + Offset);
|
|
|
|
if (mPixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
|
|
BltMemSrc = (VOID *) ((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 * mBltLibBytesPerPixel)) =
|
|
(UINT32) (
|
|
(((Uint32 << mPixelShl[0]) >> mPixelShr[0]) & mPixelBitMasks.RedMask) |
|
|
(((Uint32 << mPixelShl[1]) >> mPixelShr[1]) & mPixelBitMasks.GreenMask) |
|
|
(((Uint32 << mPixelShl[2]) >> mPixelShr[2]) & mPixelBitMasks.BlueMask)
|
|
);
|
|
}
|
|
BltMemSrc = (VOID *) mBltLibLineBuffer;
|
|
}
|
|
|
|
CopyMem (BltMemDst, BltMemSrc, WidthInBytes);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
Performs a UEFI Graphics Output Protocol Blt Video to Video operation
|
|
|
|
@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 - The sizes were returned
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
BltLibVideoToVideo (
|
|
IN UINTN SourceX,
|
|
IN UINTN SourceY,
|
|
IN UINTN DestinationX,
|
|
IN UINTN DestinationY,
|
|
IN UINTN Width,
|
|
IN UINTN Height
|
|
)
|
|
{
|
|
VOID *BltMemSrc;
|
|
VOID *BltMemDst;
|
|
UINTN Offset;
|
|
UINTN WidthInBytes;
|
|
INTN LineStride;
|
|
|
|
//
|
|
// Video to Video: Source is Video, destination is Video
|
|
//
|
|
if (SourceY + Height > mBltLibHeight) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (SourceX + Width > mBltLibWidthInPixels) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (DestinationY + Height > mBltLibHeight) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (DestinationX + Width > mBltLibWidthInPixels) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (Width == 0 || Height == 0) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
WidthInBytes = Width * mBltLibBytesPerPixel;
|
|
|
|
Offset = (SourceY * mBltLibWidthInPixels) + SourceX;
|
|
Offset = mBltLibBytesPerPixel * Offset;
|
|
BltMemSrc = (VOID *) (mBltLibFrameBuffer + Offset);
|
|
|
|
Offset = (DestinationY * mBltLibWidthInPixels) + DestinationX;
|
|
Offset = mBltLibBytesPerPixel * Offset;
|
|
BltMemDst = (VOID *) (mBltLibFrameBuffer + Offset);
|
|
|
|
LineStride = mBltLibWidthInBytes;
|
|
if ((UINTN) BltMemDst > (UINTN) BltMemSrc) {
|
|
LineStride = -LineStride;
|
|
}
|
|
|
|
while (Height > 0) {
|
|
CopyMem (BltMemDst, BltMemSrc, WidthInBytes);
|
|
|
|
BltMemSrc = (VOID*) ((UINT8*) BltMemSrc + LineStride);
|
|
BltMemDst = (VOID*) ((UINT8*) BltMemDst + LineStride);
|
|
Height--;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
Returns the sizes related to the video device
|
|
|
|
@param[out] Width Width (in pixels)
|
|
@param[out] Height Height (in pixels)
|
|
|
|
@retval EFI_INVALID_PARAMETER - Invalid parameter passed in
|
|
@retval EFI_SUCCESS - The sizes were returned
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
BltLibGetSizes (
|
|
OUT UINTN *Width, OPTIONAL
|
|
OUT UINTN *Height OPTIONAL
|
|
)
|
|
{
|
|
if (Width != NULL) {
|
|
*Width = mBltLibWidthInPixels;
|
|
}
|
|
if (Height != NULL) {
|
|
*Height = mBltLibHeight;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|