The BltConfigure() API caches the video frame buffer meta data which forbids the library to be implemented to support re-entry.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ruiyu Ni <ruiyu...@intel.com> Cc: Laszlo Ersek <ler...@redhat.com> Cc: Jordan Justen <jordan.l.jus...@intel.com> --- .../Application/BltLibSample/BltLibSample.c | 129 +++--- OptionRomPkg/Include/Library/BltLib.h | 151 +++--- .../Library/FrameBufferBltLib/FrameBufferBltLib.c | 514 +++++++++++---------- OptionRomPkg/Library/GopBltLib/GopBltLib.c | 289 ++++++------ OvmfPkg/QemuVideoDxe/Gop.c | 13 +- 5 files changed, 576 insertions(+), 520 deletions(-) diff --git a/OptionRomPkg/Application/BltLibSample/BltLibSample.c b/OptionRomPkg/Application/BltLibSample/BltLibSample.c index 333b054..3c7e392 100644 --- a/OptionRomPkg/Application/BltLibSample/BltLibSample.c +++ b/OptionRomPkg/Application/BltLibSample/BltLibSample.c @@ -18,6 +18,7 @@ #include <Library/UefiLib.h> #include <Library/UefiApplicationEntryPoint.h> #include <Library/UefiBootServicesTableLib.h> +#include <Library/MemoryAllocationLib.h> UINT64 @@ -68,8 +69,8 @@ Rand32 ( VOID TestFills ( - UINT32 HorizontalResolution, - UINT32 VerticalResolution + IN VOID *FrameBuffer, + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo ) { EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color; @@ -79,44 +80,45 @@ TestFills ( UINTN W; UINTN H; - for (Loop = 0; Loop < 10000; Loop++) { - W = HorizontalResolution - (Rand32 () % HorizontalResolution); - H = VerticalResolution - (Rand32 () % VerticalResolution); - if (W != HorizontalResolution) { - X = Rand32 () % (HorizontalResolution - W); + for (Loop = 0; Loop < 1000; Loop++) { + W = FrameBufferInfo->HorizontalResolution - (Rand32 () % FrameBufferInfo->HorizontalResolution); + H = FrameBufferInfo->VerticalResolution - (Rand32 () % FrameBufferInfo->VerticalResolution); + if (W != FrameBufferInfo->HorizontalResolution) { + X = Rand32 () % (FrameBufferInfo->HorizontalResolution - W); } else { X = 0; } - if (H != VerticalResolution) { - Y = Rand32 () % (VerticalResolution - H); + if (H != FrameBufferInfo->VerticalResolution) { + Y = Rand32 () % (FrameBufferInfo->VerticalResolution - H); } else { Y = 0; } *(UINT32*) (&Color) = Rand32 () & 0xffffff; - BltVideoFill (&Color, X, Y, W, H); + BltVideoFill (FrameBuffer, FrameBufferInfo, &Color, X, Y, W, H); } } VOID TestColor1 ( - UINT32 HorizontalResolution, - UINT32 VerticalResolution + IN VOID *FrameBuffer, + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo ) { - EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer; UINTN X; UINTN Y; - *(UINT32*) (&Color) = 0; + BltBuffer = AllocatePool (sizeof (*BltBuffer) * FrameBufferInfo->HorizontalResolution); + ASSERT (BltBuffer != NULL); - for (Y = 0; Y < VerticalResolution; Y++) { - for (X = 0; X < HorizontalResolution; X++) { - Color.Red = (UINT8) ((X * 0x100) / HorizontalResolution); - Color.Green = (UINT8) ((Y * 0x100) / VerticalResolution); - Color.Blue = (UINT8) ((Y * 0x100) / VerticalResolution); - BltVideoFill (&Color, X, Y, 1, 1); + for (Y = 0; Y < FrameBufferInfo->VerticalResolution; Y++) { + for (X = 0; X < FrameBufferInfo->HorizontalResolution; X++) { + BltBuffer[X].Red = (UINT8) ((X * 0x100) / FrameBufferInfo->HorizontalResolution); + BltBuffer[X].Green = (UINT8) ((Y * 0x100) / FrameBufferInfo->VerticalResolution); + BltBuffer[X].Blue = (UINT8) ((Y * 0x100) / FrameBufferInfo->VerticalResolution); } + BltBufferToVideo (FrameBuffer, FrameBufferInfo, BltBuffer, 0, 0, 0, Y, FrameBufferInfo->HorizontalResolution, 1, 0); } } @@ -176,8 +178,8 @@ GetTriColor ( VOID TestColor ( - UINT32 HorizontalResolution, - UINT32 VerticalResolution + IN VOID *FrameBuffer, + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo ) { EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color; @@ -187,34 +189,38 @@ TestColor ( UINTN LineWidth, TriWidth; UINTN TriHeight; UINT32 ColorDist; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer; *(UINT32*) (&Color) = 0; - BltVideoFill (&Color, 0, 0, HorizontalResolution, VerticalResolution); + BltVideoFill (FrameBuffer, FrameBufferInfo, &Color, 0, 0, FrameBufferInfo->HorizontalResolution, FrameBufferInfo->VerticalResolution); TriWidth = (UINTN) DivU64x32 ( - MultU64x32 (11547005, (UINT32) VerticalResolution), + MultU64x32 (11547005, FrameBufferInfo->HorizontalResolution), 10000000 ); TriHeight = (UINTN) DivU64x32 ( - MultU64x32 (8660254, (UINT32) HorizontalResolution), + MultU64x32 (8660254, FrameBufferInfo->VerticalResolution), 10000000 ); - if (TriWidth > HorizontalResolution) { + if (TriWidth > FrameBufferInfo->HorizontalResolution) { DEBUG ((EFI_D_INFO, "TriWidth at %d was too big\n", TriWidth)); - TriWidth = HorizontalResolution; - } else if (TriHeight > VerticalResolution) { + TriWidth = FrameBufferInfo->HorizontalResolution; + } else if (TriHeight > FrameBufferInfo->VerticalResolution) { DEBUG ((EFI_D_INFO, "TriHeight at %d was too big\n", TriHeight)); - TriHeight = VerticalResolution; + TriHeight = FrameBufferInfo->VerticalResolution; } DEBUG ((EFI_D_INFO, "Triangle Width: %d; Height: %d\n", TriWidth, TriHeight)); - X1 = (HorizontalResolution - TriWidth) / 2; + X1 = (FrameBufferInfo->HorizontalResolution - TriWidth) / 2; X3 = X1 + TriWidth - 1; X2 = (X1 + X3) / 2; - Y2 = (VerticalResolution - TriHeight) / 2; + Y2 = (FrameBufferInfo->VerticalResolution - TriHeight) / 2; Y1 = Y2 + TriHeight - 1; + BltBuffer = AllocatePool (sizeof (*BltBuffer) * FrameBufferInfo->HorizontalResolution); + ASSERT (BltBuffer != NULL); + for (Y = Y2; Y <= Y1; Y++) { LineWidth = (UINTN) DivU64x32 ( @@ -223,26 +229,25 @@ TestColor ( ); for (X = X2 - LineWidth; X < (X2 + LineWidth); X++) { ColorDist = Uint32Dist(X - X1, Y1 - Y); - Color.Red = GetTriColor (ColorDist, TriWidth); + BltBuffer[X - (X2 - LineWidth)].Red = GetTriColor (ColorDist, TriWidth); ColorDist = Uint32Dist((X < X2) ? X2 - X : X - X2, Y - Y2); - Color.Green = GetTriColor (ColorDist, TriWidth); + BltBuffer[X - (X2 - LineWidth)].Green = GetTriColor (ColorDist, TriWidth); ColorDist = Uint32Dist(X3 - X, Y1 - Y); - Color.Blue = GetTriColor (ColorDist, TriWidth); - - BltVideoFill (&Color, X, Y, 1, 1); + BltBuffer[X - (X2 - LineWidth)].Blue = GetTriColor (ColorDist, TriWidth); } + BltBufferToVideo (FrameBuffer, FrameBufferInfo, BltBuffer, 0, 0, X2 - LineWidth, Y, LineWidth * 2, 1, 0); } - + FreePool (BltBuffer); gBS->Stall (1000 * 1000); } VOID -TestMove1 ( - UINT32 HorizontalResolution, - UINT32 VerticalResolution +TestMove ( + IN VOID *FrameBuffer, + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo ) { EFI_GRAPHICS_OUTPUT_BLT_PIXEL Blue; @@ -251,18 +256,18 @@ TestMove1 ( UINTN Width; UINTN Height; - *(UINT32 *) &Black = 0; Width = 100; Height = 20; - BltVideoFill (&Black, 0, 0, HorizontalResolution, VerticalResolution); + *(UINT32 *) &Black = 0; + BltVideoFill (FrameBuffer, FrameBufferInfo, &Black, 0, 0, FrameBufferInfo->HorizontalResolution, FrameBufferInfo->VerticalResolution); *(UINT32 *) &Blue = 0; Blue.Blue = 0xff; - BltVideoFill (&Blue, 0, 0, Width, Height); + BltVideoFill (FrameBuffer, FrameBufferInfo, &Blue, 0, 0, Width, Height); - for (X = 1, Y = 1; X < HorizontalResolution && Y < VerticalResolution; X++, Y++) { - BltVideoToVideo (X - 1, Y - 1, X, Y, Width, Height); + for (X = 1, Y = 1; X < FrameBufferInfo->HorizontalResolution && Y < FrameBufferInfo->VerticalResolution; X++, Y++) { + BltVideoToVideo (FrameBuffer, FrameBufferInfo, X - 1, Y - 1, X, Y, Width, Height); gBS->Stall (100); } gBS->Stall (1000 * 1000 * 2); @@ -298,19 +303,25 @@ UefiMain ( return Status; } - Status = BltConfigure ( - (VOID*)(UINTN) Gop->Mode->FrameBufferBase, - Gop->Mode->Info - ); - if (EFI_ERROR (Status)) { - return Status; - } - - TestFills (Gop->Mode->Info->HorizontalResolution, Gop->Mode->Info->VerticalResolution); - - TestColor (Gop->Mode->Info->HorizontalResolution, Gop->Mode->Info->VerticalResolution); - - TestMove1 (Gop->Mode->Info->HorizontalResolution, Gop->Mode->Info->VerticalResolution); - + TestMove ( + (VOID *) (UINTN) Gop->Mode->FrameBufferBase, + Gop->Mode->Info + ); + + TestFills ( + (VOID *) (UINTN) Gop->Mode->FrameBufferBase, + Gop->Mode->Info + ); + + TestColor ( + (VOID *) (UINTN) Gop->Mode->FrameBufferBase, + Gop->Mode->Info + ); + gBS->Stall (3 * 1000 * 1000); + + TestColor1 ( + (VOID *) (UINTN) Gop->Mode->FrameBufferBase, + Gop->Mode->Info + ); return EFI_SUCCESS; } diff --git a/OptionRomPkg/Include/Library/BltLib.h b/OptionRomPkg/Include/Library/BltLib.h index 230dac2..65ea9d4 100644 --- a/OptionRomPkg/Include/Library/BltLib.h +++ b/OptionRomPkg/Include/Library/BltLib.h @@ -17,41 +17,27 @@ #include <Protocol/GraphicsOutput.h> - -/** - Configure the BltLib for a frame-buffer - - @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 passed in - @retval EFI_SUCCESS - Blt operation success - -**/ -EFI_STATUS -EFIAPI -BltConfigure ( - IN VOID *FrameBuffer, - IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo - ); - /** 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 + @param[in] FrameBuffer Pointer to the start of the frame buffer + @param[in] FrameBufferInfo Describes the frame buffer characteristics + @param[in] Color Color to fill the region with + @param[in] DestinationX X location to start fill operation + @param[in] DestinationY Y location to start fill operation + @param[in] Width Width (in pixels) to fill + @param[in] Height Height to fill - @retval EFI_DEVICE_ERROR - A hardware error occured - @retval EFI_INVALID_PARAMETER - Invalid parameter passed in - @retval EFI_SUCCESS - Blt operation success + @retval EFI_DEVICE_ERROR A hardware error occured + @retval EFI_INVALID_PARAMETER Invalid parameter passed in + @retval EFI_SUCCESS Blt operation success **/ EFI_STATUS EFIAPI BltVideoFill ( + IN VOID *FrameBuffer, + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Color, IN UINTN DestinationX, IN UINTN DestinationY, @@ -62,82 +48,93 @@ BltVideoFill ( /** 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] DestinationX X location within BltBuffer - @param[in] DestinationY Y location within BltBuffer - @param[in] Width Width (in pixels) - @param[in] Height Height - @param[in] Delta Number of bytes in a row of BltBuffer - - @retval EFI_DEVICE_ERROR - A hardware error occured - @retval EFI_INVALID_PARAMETER - Invalid parameter passed in - @retval EFI_SUCCESS - Blt operation success + @param[in] FrameBuffer Pointer to the start of the frame buffer + @param[in] FrameBufferInfo Describes the frame buffer characteristics + @param[out] BltBuffer Output buffer for pixel color data + @param[in] SourceX X location within video + @param[in] SourceY Y location within video + @param[in] DestinationX X location within BltBuffer + @param[in] DestinationY Y location within BltBuffer + @param[in] Width Width (in pixels) + @param[in] Height Height + @param[in] Delta Number of bytes in a row of BltBuffer + + @retval EFI_DEVICE_ERROR A hardware error occured + @retval EFI_INVALID_PARAMETER Invalid parameter passed in + @retval EFI_SUCCESS Blt operation success **/ EFI_STATUS EFIAPI BltVideoToBuffer ( - 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 + IN VOID *FrameBuffer, + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, + OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta ); /** Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation. - @param[in] BltBuffer Output buffer for pixel color data - @param[in] SourceX X location within BltBuffer - @param[in] SourceY Y location within BltBuffer - @param[in] DestinationX X location within video - @param[in] DestinationY Y location within video - @param[in] Width Width (in pixels) - @param[in] Height Height - @param[in] Delta Number of bytes in a row of BltBuffer - - @retval EFI_DEVICE_ERROR - A hardware error occured - @retval EFI_INVALID_PARAMETER - Invalid parameter passed in - @retval EFI_SUCCESS - Blt operation success + @param[in] FrameBuffer Pointer to the start of the frame buffer + @param[in] FrameBufferInfo Describes the frame buffer characteristics + @param[in] BltBuffer Output buffer for pixel color data + @param[in] SourceX X location within BltBuffer + @param[in] SourceY Y location within BltBuffer + @param[in] DestinationX X location within video + @param[in] DestinationY Y location within video + @param[in] Width Width (in pixels) + @param[in] Height Height + @param[in] Delta Number of bytes in a row of BltBuffer + + @retval EFI_DEVICE_ERROR A hardware error occured + @retval EFI_INVALID_PARAMETER Invalid parameter passed in + @retval EFI_SUCCESS Blt operation success **/ EFI_STATUS EFIAPI BltBufferToVideo ( - IN 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 + IN VOID *FrameBuffer, + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta ); - /** - Performs a UEFI Graphics Output Protocol Blt Video to Video operation + 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 + @param[in] FrameBuffer Pointer to the start of the frame buffer + @param[in] FrameBufferInfo Describes the frame buffer characteristics + @param[in] SourceX X location within video + @param[in] SourceY Y location within video + @param[in] DestinationX X location within video + @param[in] DestinationY Y location within video + @param[in] Width Width (in pixels) + @param[in] Height Height - @retval EFI_DEVICE_ERROR - A hardware error occured - @retval EFI_INVALID_PARAMETER - Invalid parameter passed in - @retval EFI_SUCCESS - Blt operation success + @retval EFI_DEVICE_ERROR A hardware error occured + @retval EFI_INVALID_PARAMETER Invalid parameter passed in + @retval EFI_SUCCESS Blt operation success **/ EFI_STATUS EFIAPI BltVideoToVideo ( + IN VOID *FrameBuffer, + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, IN UINTN SourceX, IN UINTN SourceY, IN UINTN DestinationX, diff --git a/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.c b/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.c index 8b0d2bd..977f852 100644 --- a/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.c +++ b/OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.c @@ -16,7 +16,6 @@ #include <Library/BaseLib.h> #include <Library/BaseMemoryLib.h> #include <Library/DebugLib.h> -#include <Library/BltLib.h> #include <Protocol/GraphicsOutput.h> #if 0 @@ -27,100 +26,101 @@ #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 +UINT8 mBltLibLineBuffer[MAX_LINE_BUFFER_SIZE]; +EFI_PIXEL_BITMASK mBltLibRgbPixelMasks = {0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000}; +EFI_PIXEL_BITMASK mBltLibBgrPixelMasks = {0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000}; + +EFI_STATUS +BltLibParsePixelFormat ( + IN EFI_GRAPHICS_PIXEL_FORMAT PixelFormat, + IN EFI_PIXEL_BITMASK *PixelInformation, + OUT UINT8 *PixelShl, + OUT UINT8 *PixelShr, + OUT UINT32 *PixelMask, + OUT UINT8 *BytesPerPixel ) { - UINTN Loop; - UINT32 *Masks; - UINT32 MergedMasks; + UINTN Index; + UINT32 MergedMasks; + UINT32 *Mask; - 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]); + switch (PixelFormat) { + case PixelRedGreenBlueReserved8BitPerColor: + return BltLibParsePixelFormat (PixelBitMask, &mBltLibRgbPixelMasks, PixelShl, PixelShr, PixelMask, BytesPerPixel); - ASSERT (MergedMasks != 0); - mBltLibBytesPerPixel = (UINTN) ((HighBitSet32 (MergedMasks) + 7) / 8); + case PixelBlueGreenRedReserved8BitPerColor: + return BltLibParsePixelFormat (PixelBitMask, &mBltLibBgrPixelMasks, PixelShl, PixelShr, PixelMask, BytesPerPixel); - DEBUG ((EFI_D_INFO, "Bytes per pixel: %d\n", mBltLibBytesPerPixel)); + case PixelBitMask: + break; - CopyMem (&mPixelBitMasks, BitMask, sizeof (*BitMask)); -} + default: + return EFI_INVALID_PARAMETER; + } -/** - Configure the FrameBufferLib instance + MergedMasks = 0; + Mask = (UINT32 *) PixelInformation; + for (Index = 0; Index < 4; Index++) { + // + // Only ReservedMask can be 0 + // + if (Index != 3 && Mask[Index] == 0) { + return EFI_INVALID_PARAMETER; + } + // + // The Mask of each color shouldn't overlap + // + if ((MergedMasks & Mask[Index]) != 0) { + return EFI_INVALID_PARAMETER; + } + MergedMasks |= Mask[Index]; + + if (PixelShl != NULL && PixelShr != NULL) { + PixelShl[Index] = (UINT8) (HighBitSet32 (Mask[Index]) - 23 + (Index * 8)); + PixelShl[Index] %= 32; + if ((INT8) PixelShl[Index] < 0) { + PixelShr[Index] = -PixelShl[Index]; + PixelShl[Index] = 0; + } else { + PixelShr[Index] = 0; + } + VDEBUG ((EFI_D_INFO, "%d: shl:%d shr:%d mask:%x\n", Index, PixelShl[Index], PixelShr[Index], Mask[Index])); + } + } + if (PixelMask != NULL) { + CopyMem (PixelMask, PixelInformation, sizeof (EFI_PIXEL_BITMASK)); + } - @param[in] FrameBuffer Pointer to the start of the frame buffer - @param[in] FrameBufferInfo Describes the frame buffer characteristics + if (BytesPerPixel != NULL) { + *BytesPerPixel = (UINT8) ((HighBitSet32 (MergedMasks) + 7) / 8); + VDEBUG ((EFI_D_INFO, "Bytes per pixel: %d\n", *BytesPerPixel)); + } - @retval EFI_INVALID_PARAMETER - Invalid parameter - @retval EFI_UNSUPPORTED - The BltLib does not support this configuration - @retval EFI_SUCCESS - Blt operation success + return EFI_SUCCESS; +} -**/ EFI_STATUS -EFIAPI -BltConfigure ( - IN VOID *FrameBuffer, - IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo +BltLibVerifyLocation ( + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, + IN UINTN X, + IN UINTN Y, + IN UINTN Width, + IN UINTN Height ) { - 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); + if ((X >= FrameBufferInfo->HorizontalResolution) || + (Width > FrameBufferInfo->HorizontalResolution - X) + ) { + VDEBUG ((EFI_D_INFO, "VideoFill: Past screen (X)\n")); 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)); + if ((Y >= FrameBufferInfo->VerticalResolution) || + (Height > FrameBufferInfo->VerticalResolution - Y) + ) { + VDEBUG ((EFI_D_INFO, "VideoFill: Past screen (Y)\n")); + return EFI_INVALID_PARAMETER; + } return EFI_SUCCESS; } @@ -128,20 +128,24 @@ BltConfigure ( /** 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 + @param[in] FrameBuffer Pointer to the start of the frame buffer + @param[in] FrameBufferInfo Describes the frame buffer characteristics + @param[in] Color Color to fill the region with + @param[in] DestinationX X location to start fill operation + @param[in] DestinationY Y location to start fill operation + @param[in] Width Width (in pixels) to fill + @param[in] Height Height to fill - @retval EFI_DEVICE_ERROR - A hardware error occured - @retval EFI_INVALID_PARAMETER - Invalid parameter passed in - @retval EFI_SUCCESS - The sizes were returned + @retval EFI_DEVICE_ERROR A hardware error occured + @retval EFI_INVALID_PARAMETER Invalid parameter passed in + @retval EFI_SUCCESS Blt operation success **/ EFI_STATUS EFIAPI BltVideoFill ( + IN VOID *FrameBuffer, + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Color, IN UINTN DestinationX, IN UINTN DestinationY, @@ -149,6 +153,7 @@ BltVideoFill ( IN UINTN Height ) { + EFI_STATUS Status; UINTN Y; UINT8 *Destination; UINTN X; @@ -160,34 +165,32 @@ BltVideoFill ( 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; + UINT8 PixelShr[4]; + UINT8 PixelShl[4]; + UINT32 PixelMask[4]; + UINT8 BytesPerPixel; + + Status = BltLibVerifyLocation (FrameBufferInfo, DestinationX, DestinationY, Width, Height); + if (EFI_ERROR (Status)) { + return Status; } - if (Width == 0 || Height == 0) { - DEBUG ((EFI_D_INFO, "VideoFill: Width or Height is 0\n")); - return EFI_INVALID_PARAMETER; + Status = BltLibParsePixelFormat ( + FrameBufferInfo->PixelFormat, + &FrameBufferInfo->PixelInformation, + PixelShr, PixelShl, PixelMask, &BytesPerPixel + ); + if (EFI_ERROR (Status)) { + return Status; } - WidthInBytes = Width * mBltLibBytesPerPixel; + WidthInBytes = Width * BytesPerPixel; - 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) - ); + Uint32 = *(UINT32 *) Color; + WideFill = (((Uint32 << PixelShl[0]) >> PixelShr[0]) & PixelMask[0]) | + (((Uint32 << PixelShl[1]) >> PixelShr[1]) & PixelMask[1]) | + (((Uint32 << PixelShl[2]) >> PixelShr[2]) & PixelMask[2]) | + (((Uint32 << PixelShl[3]) >> PixelShr[3]) & PixelMask[3]); VDEBUG ((EFI_D_INFO, "VideoFill: color=0x%x, wide-fill=0x%x\n", Uint32, WideFill)); // @@ -195,20 +198,17 @@ BltVideoFill ( // 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]; + if (sizeof (WideFill) % BytesPerPixel == 0) { + for (X = BytesPerPixel; X < sizeof (WideFill); X++) { + ((UINT8 *) &WideFill)[X] = ((UINT8 *) &WideFill)[X % BytesPerPixel]; } } else { // // If all the bytes in the pixel are the same value, then use // a wide fill operation. // - for ( - X = 1, Uint8 = ((UINT8*)&WideFill)[0]; - X < mBltLibBytesPerPixel; - X++) { - if (Uint8 != ((UINT8*)&WideFill)[X]) { + for (X = 1, Uint8 = ((UINT8*) &WideFill)[0]; X < BytesPerPixel; X++) { + if (Uint8 != ((UINT8*) &WideFill)[X]) { UseWideFill = FALSE; break; } @@ -218,31 +218,31 @@ BltVideoFill ( } } - if (UseWideFill && (DestinationX == 0) && (Width == mBltLibWidthInPixels)) { + if (UseWideFill && (DestinationX == 0) && (Width == FrameBufferInfo->HorizontalResolution)) { VDEBUG ((EFI_D_INFO, "VideoFill (wide, one-shot)\n")); - Offset = DestinationY * mBltLibWidthInPixels; - Offset = mBltLibBytesPerPixel * Offset; - Destination = mBltLibFrameBuffer + Offset; + Offset = DestinationY * FrameBufferInfo->PixelsPerScanLine * BytesPerPixel; + Destination = (UINT8 *) FrameBuffer + Offset; SizeInBytes = WidthInBytes * Height; if (SizeInBytes >= 8) { - SetMem32 (Destination, SizeInBytes & ~3, (UINT32) WideFill); - SizeInBytes &= 3; + SetMem64 (Destination, SizeInBytes & ~7, WideFill); + Destination += (SizeInBytes & ~7); + SizeInBytes &= 7; } if (SizeInBytes > 0) { - SetMem (Destination, SizeInBytes, (UINT8)(UINTN) WideFill); + CopyMem (Destination, &WideFill, SizeInBytes); } } else { LineBufferReady = FALSE; for (Y = DestinationY; Y < (Height + DestinationY); Y++) { - Offset = (Y * mBltLibWidthInPixels) + DestinationX; - Offset = mBltLibBytesPerPixel * Offset; - Destination = mBltLibFrameBuffer + Offset; + Offset = ((Y * FrameBufferInfo->PixelsPerScanLine) + DestinationX) * BytesPerPixel; + Destination = (UINT8 *) FrameBuffer + Offset; if (UseWideFill && (((UINTN) Destination & 7) == 0)) { VDEBUG ((EFI_D_INFO, "VideoFill (wide)\n")); SizeInBytes = WidthInBytes; if (SizeInBytes >= 8) { SetMem64 (Destination, SizeInBytes & ~7, WideFill); + Destination += (SizeInBytes & ~7); SizeInBytes &= 7; } if (SizeInBytes > 0) { @@ -251,12 +251,12 @@ BltVideoFill ( } else { VDEBUG ((EFI_D_INFO, "VideoFill (not wide)\n")); if (!LineBufferReady) { - CopyMem (mBltLibLineBuffer, &WideFill, mBltLibBytesPerPixel); + CopyMem (mBltLibLineBuffer, &WideFill, BytesPerPixel); for (X = 1; X < Width; ) { - CopyMem( - (mBltLibLineBuffer + (X * mBltLibBytesPerPixel)), + CopyMem ( + (mBltLibLineBuffer + (X * BytesPerPixel)), mBltLibLineBuffer, - MIN (X, Width - X) * mBltLibBytesPerPixel + MIN (X, Width - X) * BytesPerPixel ); X += MIN (X, Width - X); } @@ -273,33 +273,38 @@ BltVideoFill ( /** 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] 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 + @param[in] FrameBuffer Pointer to the start of the frame buffer + @param[in] FrameBufferInfo Describes the frame buffer characteristics + @param[out] BltBuffer Output buffer for pixel color data + @param[in] SourceX X location within video + @param[in] SourceY Y location within video + @param[in] DestinationX X location within BltBuffer + @param[in] DestinationY Y location within BltBuffer + @param[in] Width Width (in pixels) + @param[in] Height Height + @param[in] Delta Number of bytes in a row of BltBuffer + + @retval EFI_DEVICE_ERROR A hardware error occured + @retval EFI_INVALID_PARAMETER Invalid parameter passed in + @retval EFI_SUCCESS Blt operation success **/ EFI_STATUS EFIAPI BltVideoToBuffer ( - 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 + IN VOID *FrameBuffer, + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, + OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta ) { + EFI_STATUS Status; UINTN DstY; UINTN SrcY; EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; @@ -309,22 +314,27 @@ BltVideoToBuffer ( UINT32 Uint32; UINTN Offset; UINTN WidthInBytes; + UINT8 PixelShr[4]; + UINT8 PixelShl[4]; + UINT32 PixelMask[4]; + UINT8 BytesPerPixel; // // Video to BltBuffer: Source is Video, destination is BltBuffer // - if (SourceY + Height > mBltLibHeight) { - return EFI_INVALID_PARAMETER; - } - - if (SourceX + Width > mBltLibWidthInPixels) { - return EFI_INVALID_PARAMETER; + Status = BltLibVerifyLocation (FrameBufferInfo, SourceX, SourceY, Width, Height); + if (EFI_ERROR (Status)) { + return Status; } - if (Width == 0 || Height == 0) { - return EFI_INVALID_PARAMETER; + Status = BltLibParsePixelFormat ( + FrameBufferInfo->PixelFormat, + &FrameBufferInfo->PixelInformation, + PixelShl, PixelShr, PixelMask, &BytesPerPixel + ); + if (EFI_ERROR (Status)) { + return Status; } - // // If Delta is zero, then the entire BltBuffer is being used, so Delta // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size, @@ -334,18 +344,17 @@ BltVideoToBuffer ( Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL); } - WidthInBytes = Width * mBltLibBytesPerPixel; + WidthInBytes = Width * BytesPerPixel; // // Video to BltBuffer: Source is Video, destination is BltBuffer // - for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY); SrcY++, DstY++) { + for (SrcY = SourceY, DstY = DestinationY; DstY < (DestinationY + Height); SrcY++, DstY++) { - Offset = (SrcY * mBltLibWidthInPixels) + SourceX; - Offset = mBltLibBytesPerPixel * Offset; - Source = mBltLibFrameBuffer + Offset; + Offset = ((SrcY * FrameBufferInfo->PixelsPerScanLine) + SourceX) * BytesPerPixel; + Source = (UINT8 *) FrameBuffer + Offset; - if (mPixelFormat == PixelBlueGreenRedReserved8BitPerColor) { + if (FrameBufferInfo->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) { Destination = (UINT8 *) BltBuffer + (DstY * Delta) + (DestinationX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); } else { Destination = mBltLibLineBuffer; @@ -353,16 +362,14 @@ BltVideoToBuffer ( CopyMem (Destination, Source, WidthInBytes); - if (mPixelFormat != PixelBlueGreenRedReserved8BitPerColor) { + if (FrameBufferInfo->PixelFormat != PixelBlueGreenRedReserved8BitPerColor) { for (X = 0; X < Width; X++) { - Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer + (DstY * Delta) + (DestinationX + X) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); - Uint32 = *(UINT32*) (mBltLibLineBuffer + (X * 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]) - ); + Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer + (DstY * Delta) + (DestinationX + X) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); + Uint32 = * (UINT32 *) (mBltLibLineBuffer + (X * BytesPerPixel)); + *(UINT32*) Blt = (((Uint32 & PixelMask[0]) >> PixelShl[0]) << PixelShr[0]) | + (((Uint32 & PixelMask[1]) >> PixelShl[1]) << PixelShr[1]) | + (((Uint32 & PixelMask[2]) >> PixelShl[2]) << PixelShr[2]) | + (((Uint32 & PixelMask[3]) >> PixelShl[3]) << PixelShr[3]); } } } @@ -373,33 +380,38 @@ BltVideoToBuffer ( /** Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation. - @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 + @param[in] FrameBuffer Pointer to the start of the frame buffer + @param[in] FrameBufferInfo Describes the frame buffer characteristics + @param[in] BltBuffer Output buffer for pixel color data + @param[in] SourceX X location within BltBuffer + @param[in] SourceY Y location within BltBuffer + @param[in] DestinationX X location within video + @param[in] DestinationY Y location within video + @param[in] Width Width (in pixels) + @param[in] Height Height + @param[in] Delta Number of bytes in a row of BltBuffer + + @retval EFI_DEVICE_ERROR A hardware error occured + @retval EFI_INVALID_PARAMETER Invalid parameter passed in + @retval EFI_SUCCESS Blt operation success **/ EFI_STATUS EFIAPI BltBufferToVideo ( - IN 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 + IN VOID *FrameBuffer, + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta ) { + EFI_STATUS Status; UINTN DstY; UINTN SrcY; EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; @@ -409,22 +421,27 @@ BltBufferToVideo ( UINT32 Uint32; UINTN Offset; UINTN WidthInBytes; + UINT8 PixelShr[4]; + UINT8 PixelShl[4]; + UINT32 PixelMask[4]; + UINT8 BytesPerPixel; // // BltBuffer to Video: Source is BltBuffer, destination is Video // - if (DestinationY + Height > mBltLibHeight) { - return EFI_INVALID_PARAMETER; - } - - if (DestinationX + Width > mBltLibWidthInPixels) { - return EFI_INVALID_PARAMETER; + Status = BltLibVerifyLocation (FrameBufferInfo, DestinationX, DestinationY, Width, Height); + if (EFI_ERROR (Status)) { + return Status; } - if (Width == 0 || Height == 0) { - return EFI_INVALID_PARAMETER; + Status = BltLibParsePixelFormat ( + FrameBufferInfo->PixelFormat, + &FrameBufferInfo->PixelInformation, + PixelShl, PixelShr, PixelMask, &BytesPerPixel + ); + if (EFI_ERROR (Status)) { + return Status; } - // // If Delta is zero, then the entire BltBuffer is being used, so Delta // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size, @@ -434,15 +451,14 @@ BltBufferToVideo ( Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL); } - WidthInBytes = Width * mBltLibBytesPerPixel; + WidthInBytes = Width * BytesPerPixel; for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) { - Offset = (DstY * mBltLibWidthInPixels) + DestinationX; - Offset = mBltLibBytesPerPixel * Offset; - Destination = mBltLibFrameBuffer + Offset; + Offset = ((DstY * FrameBufferInfo->PixelsPerScanLine) + DestinationX) * BytesPerPixel; + Destination = (UINT8 *) FrameBuffer + Offset; - if (mPixelFormat == PixelBlueGreenRedReserved8BitPerColor) { + if (FrameBufferInfo->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) { Source = (UINT8 *) BltBuffer + (SrcY * Delta); } else { for (X = 0; X < Width; X++) { @@ -453,12 +469,11 @@ BltBufferToVideo ( ((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) - ); + *(UINT32*) (mBltLibLineBuffer + (X * BytesPerPixel)) = + (((Uint32 << PixelShl[0]) >> PixelShr[0]) & PixelMask[0]) | + (((Uint32 << PixelShl[1]) >> PixelShr[1]) & PixelMask[1]) | + (((Uint32 << PixelShl[2]) >> PixelShr[2]) & PixelMask[2]) | + (((Uint32 << PixelShl[3]) >> PixelShr[3]) & PixelMask[3]); } Source = mBltLibLineBuffer; } @@ -470,23 +485,27 @@ BltBufferToVideo ( } /** - Performs a UEFI Graphics Output Protocol Blt Video to Video operation + 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 + @param[in] FrameBuffer Pointer to the start of the frame buffer + @param[in] FrameBufferInfo Describes the frame buffer characteristics + @param[in] SourceX X location within video + @param[in] SourceY Y location within video + @param[in] DestinationX X location within video + @param[in] DestinationY Y location within video + @param[in] Width Width (in pixels) + @param[in] Height Height - @retval EFI_DEVICE_ERROR - A hardware error occured - @retval EFI_INVALID_PARAMETER - Invalid parameter passed in - @retval EFI_SUCCESS - The sizes were returned + @retval EFI_DEVICE_ERROR A hardware error occured + @retval EFI_INVALID_PARAMETER Invalid parameter passed in + @retval EFI_SUCCESS Blt operation success **/ EFI_STATUS EFIAPI BltVideoToVideo ( + IN VOID *FrameBuffer, + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, IN UINTN SourceX, IN UINTN SourceY, IN UINTN DestinationX, @@ -495,46 +514,45 @@ BltVideoToVideo ( IN UINTN Height ) { + EFI_STATUS Status; UINT8 *Source; UINT8 *Destination; UINTN Offset; UINTN WidthInBytes; INTN LineStride; + UINT8 BytesPerPixel; // // Video to Video: Source is Video, destination is Video // - if (SourceY + Height > mBltLibHeight) { - return EFI_INVALID_PARAMETER; + Status = BltLibVerifyLocation (FrameBufferInfo, SourceX, SourceY, Width, Height); + if (EFI_ERROR (Status)) { + return Status; } - if (SourceX + Width > mBltLibWidthInPixels) { - return EFI_INVALID_PARAMETER; + Status = BltLibVerifyLocation (FrameBufferInfo, DestinationX, DestinationY, Width, Height); + if (EFI_ERROR (Status)) { + return Status; } - 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; + Status = BltLibParsePixelFormat ( + FrameBufferInfo->PixelFormat, + &FrameBufferInfo->PixelInformation, + NULL, NULL, NULL, &BytesPerPixel + ); + if (EFI_ERROR (Status)) { + return Status; } - WidthInBytes = Width * mBltLibBytesPerPixel; + WidthInBytes = Width * BytesPerPixel; - Offset = (SourceY * mBltLibWidthInPixels) + SourceX; - Offset = mBltLibBytesPerPixel * Offset; - Source = mBltLibFrameBuffer + Offset; + Offset = ((SourceY * FrameBufferInfo->PixelsPerScanLine) + SourceX) * BytesPerPixel; + Source = (UINT8 *) FrameBuffer + Offset; - Offset = (DestinationY * mBltLibWidthInPixels) + DestinationX; - Offset = mBltLibBytesPerPixel * Offset; - Destination = mBltLibFrameBuffer + Offset; + Offset = ((DestinationY * FrameBufferInfo->PixelsPerScanLine) + DestinationX) * BytesPerPixel; + Destination = (UINT8 *) FrameBuffer + Offset; - LineStride = mBltLibWidthInBytes; + LineStride = FrameBufferInfo->PixelsPerScanLine * BytesPerPixel; if (Destination > Source) { // // Copy from last line to avoid source is corrupted by copying diff --git a/OptionRomPkg/Library/GopBltLib/GopBltLib.c b/OptionRomPkg/Library/GopBltLib/GopBltLib.c index 8f598f2..486690f 100644 --- a/OptionRomPkg/Library/GopBltLib/GopBltLib.c +++ b/OptionRomPkg/Library/GopBltLib/GopBltLib.c @@ -12,34 +12,26 @@ **/ -#include "PiDxe.h" +#include <Uefi.h> #include <Protocol/GraphicsOutput.h> #include <Library/BaseLib.h> #include <Library/BaseMemoryLib.h> -#include <Library/BltLib.h> #include <Library/DebugLib.h> #include <Library/MemoryAllocationLib.h> #include <Library/UefiBootServicesTableLib.h> -EFI_GRAPHICS_OUTPUT_PROTOCOL *mGop = NULL; - - /** - Configure the FrameBufferLib instance + Look for the GOP instance based on the FrameBuffer and the FrameBufferInfo. @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 - + @return The found GOP instance. **/ -EFI_STATUS -EFIAPI -BltConfigure ( +EFI_GRAPHICS_OUTPUT_PROTOCOL * +BltLibFindGopInstance ( IN VOID *FrameBuffer, IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo ) @@ -50,6 +42,8 @@ BltConfigure ( UINTN Index; EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop; + Gop = NULL; + Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiGraphicsOutputProtocolGuid, @@ -57,97 +51,113 @@ BltConfigure ( &HandleCount, &HandleBuffer ); - if (!EFI_ERROR (Status)) { - for (Index = 0; Index < HandleCount; Index++) { - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiGraphicsOutputProtocolGuid, - (VOID*) &Gop - ); - if (!EFI_ERROR (Status) && - (FrameBuffer == (VOID*)(UINTN) Gop->Mode->FrameBufferBase)) { - mGop = Gop; - FreePool (HandleBuffer); - return EFI_SUCCESS; - } - } + if (EFI_ERROR (Status)) { + return NULL; + } - FreePool (HandleBuffer); + for (Index = 0; Index < HandleCount; Index++) { + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiGraphicsOutputProtocolGuid, + (VOID **) &Gop + ); + if (!EFI_ERROR (Status) && + (FrameBuffer == (VOID *) (UINTN) Gop->Mode->FrameBufferBase) && + (CompareMem (FrameBufferInfo, Gop->Mode->Info, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION)) == 0) + ) { + break; + } } - return EFI_UNSUPPORTED; -} + FreePool (HandleBuffer); + if (Index == HandleCount) { + return NULL; + } else { + return Gop; + } +} /** 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. + @param[in] FrameBuffer Pointer to the start of the frame buffer + @param[in] FrameBufferInfo Describes the frame buffer characteristics + @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 + @retval EFI_DEVICE_ERROR A hardware error occured + @retval EFI_INVALID_PARAMETER Invalid parameter passed in + @retval EFI_SUCCESS Blt operation success **/ EFI_STATUS -InternalGopBltCommon ( - 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 +BltLibGopBltCommon ( + IN VOID *FrameBuffer, + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, + 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 ) { - if (mGop == NULL) { - return EFI_DEVICE_ERROR; + EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop; + + Gop = BltLibFindGopInstance (FrameBuffer, FrameBufferInfo); + if (Gop == NULL) { + return EFI_INVALID_PARAMETER; } - return mGop->Blt ( - mGop, - BltBuffer, - BltOperation, - SourceX, - SourceY, - DestinationX, - DestinationY, - Width, - Height, - Delta - ); + return Gop->Blt ( + Gop, + BltBuffer, + BltOperation, + SourceX, + SourceY, + DestinationX, + DestinationY, + Width, + Height, + Delta + ); } /** 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 + @param[in] FrameBuffer Pointer to the start of the frame buffer + @param[in] FrameBufferInfo Describes the frame buffer characteristics + @param[in] Color Color to fill the region with + @param[in] DestinationX X location to start fill operation + @param[in] DestinationY Y location to start fill operation + @param[in] Width Width (in pixels) to fill + @param[in] Height Height to fill - @retval EFI_DEVICE_ERROR - A hardware error occured - @retval EFI_INVALID_PARAMETER - Invalid parameter passed in - @retval EFI_SUCCESS - The sizes were returned + @retval EFI_DEVICE_ERROR A hardware error occured + @retval EFI_INVALID_PARAMETER Invalid parameter passed in + @retval EFI_SUCCESS Blt operation success **/ EFI_STATUS EFIAPI BltVideoFill ( + IN VOID *FrameBuffer, + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Color, IN UINTN DestinationX, IN UINTN DestinationY, @@ -155,7 +165,9 @@ BltVideoFill ( IN UINTN Height ) { - return InternalGopBltCommon ( + return BltLibGopBltCommon ( + FrameBuffer, + FrameBufferInfo, Color, EfiBltVideoFill, 0, @@ -168,38 +180,43 @@ BltVideoFill ( ); } - /** 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] 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 + @param[in] FrameBuffer Pointer to the start of the frame buffer + @param[in] FrameBufferInfo Describes the frame buffer characteristics + @param[out] BltBuffer Output buffer for pixel color data + @param[in] SourceX X location within video + @param[in] SourceY Y location within video + @param[in] DestinationX X location within BltBuffer + @param[in] DestinationY Y location within BltBuffer + @param[in] Width Width (in pixels) + @param[in] Height Height + @param[in] Delta Number of bytes in a row of BltBuffer + + @retval EFI_DEVICE_ERROR A hardware error occured + @retval EFI_INVALID_PARAMETER Invalid parameter passed in + @retval EFI_SUCCESS Blt operation success **/ EFI_STATUS EFIAPI BltVideoToBuffer ( - 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 + IN VOID *FrameBuffer, + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, + OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta ) { - return InternalGopBltCommon ( + return BltLibGopBltCommon ( + FrameBuffer, + FrameBufferInfo, BltBuffer, EfiBltVideoToBltBuffer, SourceX, @@ -212,38 +229,43 @@ BltVideoToBuffer ( ); } - /** Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation. - @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 + @param[in] FrameBuffer Pointer to the start of the frame buffer + @param[in] FrameBufferInfo Describes the frame buffer characteristics + @param[in] BltBuffer Output buffer for pixel color data + @param[in] SourceX X location within BltBuffer + @param[in] SourceY Y location within BltBuffer + @param[in] DestinationX X location within video + @param[in] DestinationY Y location within video + @param[in] Width Width (in pixels) + @param[in] Height Height + @param[in] Delta Number of bytes in a row of BltBuffer + + @retval EFI_DEVICE_ERROR A hardware error occured + @retval EFI_INVALID_PARAMETER Invalid parameter passed in + @retval EFI_SUCCESS Blt operation success **/ EFI_STATUS EFIAPI BltBufferToVideo ( - IN 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 + IN VOID *FrameBuffer, + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta ) { - return InternalGopBltCommon ( + return BltLibGopBltCommon ( + FrameBuffer, + FrameBufferInfo, BltBuffer, EfiBltBufferToVideo, SourceX, @@ -256,25 +278,28 @@ BltBufferToVideo ( ); } - /** - Performs a UEFI Graphics Output Protocol Blt Video to Video operation + 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 + @param[in] FrameBuffer Pointer to the start of the frame buffer + @param[in] FrameBufferInfo Describes the frame buffer characteristics + @param[in] SourceX X location within video + @param[in] SourceY Y location within video + @param[in] DestinationX X location within video + @param[in] DestinationY Y location within video + @param[in] Width Width (in pixels) + @param[in] Height Height - @retval EFI_DEVICE_ERROR - A hardware error occured - @retval EFI_INVALID_PARAMETER - Invalid parameter passed in - @retval EFI_SUCCESS - The sizes were returned + @retval EFI_DEVICE_ERROR A hardware error occured + @retval EFI_INVALID_PARAMETER Invalid parameter passed in + @retval EFI_SUCCESS Blt operation success **/ EFI_STATUS EFIAPI BltVideoToVideo ( + IN VOID *FrameBuffer, + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, IN UINTN SourceX, IN UINTN SourceY, IN UINTN DestinationX, @@ -283,7 +308,9 @@ BltVideoToVideo ( IN UINTN Height ) { - return InternalGopBltCommon ( + return BltLibGopBltCommon ( + FrameBuffer, + FrameBufferInfo, NULL, EfiBltVideoToVideo, SourceX, diff --git a/OvmfPkg/QemuVideoDxe/Gop.c b/OvmfPkg/QemuVideoDxe/Gop.c index 131e5c1..65fecf9 100644 --- a/OvmfPkg/QemuVideoDxe/Gop.c +++ b/OvmfPkg/QemuVideoDxe/Gop.c @@ -201,11 +201,6 @@ Routine Description: QemuVideoCompleteModeData (Private, This->Mode); - BltConfigure ( - (VOID*)(UINTN) This->Mode->FrameBufferBase, - This->Mode->Info - ); - return EFI_SUCCESS; } @@ -264,6 +259,8 @@ Returns: switch (BltOperation) { case EfiBltVideoToBltBuffer: Status = BltVideoToBuffer ( + (VOID *) (UINTN) This->Mode->FrameBufferBase, + This->Mode->Info, BltBuffer, SourceX, SourceY, @@ -277,6 +274,8 @@ Returns: case EfiBltVideoToVideo: Status = BltVideoToVideo ( + (VOID *) (UINTN) This->Mode->FrameBufferBase, + This->Mode->Info, SourceX, SourceY, DestinationX, @@ -288,6 +287,8 @@ Returns: case EfiBltVideoFill: Status = BltVideoFill ( + (VOID *) (UINTN) This->Mode->FrameBufferBase, + This->Mode->Info, BltBuffer, DestinationX, DestinationY, @@ -298,6 +299,8 @@ Returns: case EfiBltBufferToVideo: Status = BltBufferToVideo ( + (VOID *) (UINTN) This->Mode->FrameBufferBase, + This->Mode->Info, BltBuffer, SourceX, SourceY, -- 1.9.5.msysgit.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel