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