On 06/30/16 07:09, Ruiyu Ni wrote: > This library provides interfaces to perform UEFI Graphics > Output Protocol Video BLT operations. > > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Ruiyu Ni <[email protected]> > Cc: Feng Tian <[email protected]> > Cc: Justen Jordan <[email protected]> > Cc: Laszlo Ersek <[email protected]> > --- > MdeModulePkg/Include/Library/FrameBufferBltLib.h | 94 +++ > .../Library/FrameBufferBltLib/FrameBufferBltLib.c | 704 > +++++++++++++++++++++ > .../FrameBufferBltLib/FrameBufferBltLib.inf | 34 + > MdeModulePkg/MdeModulePkg.dec | 4 + > MdeModulePkg/MdeModulePkg.dsc | 1 + > 5 files changed, 837 insertions(+) > create mode 100644 MdeModulePkg/Include/Library/FrameBufferBltLib.h > create mode 100644 MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.c > create mode 100644 > MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
In <http://thread.gmane.org/gmane.comp.bios.edk2.devel/13809/focus=13835> I made some comments; from them, the following seem to affect this patch: (1) use FRAMEBUFFER_CONFIGURE* rather than VOID* (3) FrameBufferBltLib.inf should get a new FILE_GUID (6) the git history should remain bisectable All of these have been addressed in this patch, so: Acked-by: Laszlo Ersek <[email protected]> (for this patch). Jordan requests that this patch be split in two: lib class header and lib instance (implementation). I agree that's a good idea: when you do it, please add my Acked-by to both of the resultant patches. Jordan also requests that you re-add the OvmfPkg patch. In the message linked above, I commented on that patch as well -- please consider those comments. I would like to see your new version of that patch before giving my R-b for it. Thanks! Laszlo > diff --git a/MdeModulePkg/Include/Library/FrameBufferBltLib.h > b/MdeModulePkg/Include/Library/FrameBufferBltLib.h > new file mode 100644 > index 0000000..c92eb94 > --- /dev/null > +++ b/MdeModulePkg/Include/Library/FrameBufferBltLib.h > @@ -0,0 +1,94 @@ > +/** @file > + Library for performing UEFI GOP Blt operations on a framebuffer > + > + Copyright (c) 2009 - 2016, 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. > + > +**/ > + > +#ifndef __FRAMEBUFFER_BLT_LIB__ > +#define __FRAMEBUFFER_BLT_LIB__ > + > +#include <Protocol/GraphicsOutput.h> > + > +// > +// Opaque structure for the frame buffer configure. > +// > +typedef struct FRAME_BUFFER_CONFIGURE FRAME_BUFFER_CONFIGURE; > + > +/** > + Create the configuration for a video frame buffer. > + > + The configuration is returned in the caller provided buffer. > + > + @param[in] FrameBuffer Pointer to the start of the frame buffer. > + @param[in] FrameBufferInfo Describes the frame buffer characteristics. > + @param[in,out] Configure The created configuration information. > + @param[in,out] ConfigureSize Size of the configuration information. > + > + @retval RETURN_SUCCESS The configuration was successful created. > + @retval RETURN_BUFFER_TOO_SMALL The Configure is to too small. The > required > + size is returned in ConfigureSize. > + @retval RETURN_UNSUPPORTED The requested mode is not supported by > + this implementaion. > +**/ > +RETURN_STATUS > +EFIAPI > +FrameBufferBltConfigure ( > + IN VOID *FrameBuffer, > + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, > + IN OUT FRAME_BUFFER_CONFIGURE *Configure, > + IN OUT UINTN *ConfigureSize > + ); > + > +/** > + Performs a UEFI Graphics Output Protocol Blt operation. > + > + @param[in] Configure Pointer to a configuration which was > successfully > + created by FrameBufferBltConfigure (). > + @param[in,out] BltBuffer The data to transfer to screen. > + @param[in] BltOperation The operation to perform. > + @param[in] SourceX The X coordinate of the source for > BltOperation. > + @param[in] SourceY The Y coordinate of the source for > BltOperation. > + @param[in] DestinationX The X coordinate of the destination for > + BltOperation. > + @param[in] DestinationY The Y coordinate of the destination for > + BltOperation. > + @param[in] Width The width of a rectangle in the blt rectangle > + in pixels. > + @param[in] Height The height of a rectangle in the blt rectangle > + in pixels. > + @param[in] Delta Not used for EfiBltVideoFill and > + EfiBltVideoToVideo operation. If a Delta of 0 > + is used, the entire BltBuffer will be operated > + on. If a subrectangle of the BltBuffer is > + used, then Delta represents the number of > + bytes in a row of the BltBuffer. > + > + @retval RETURN_INVALID_PARAMETER Invalid parameter were passed in. > + @retval RETURN_SUCCESS The Blt operation was performed > successfully. > +**/ > +RETURN_STATUS > +EFIAPI > +FrameBufferBlt ( > + IN FRAME_BUFFER_CONFIGURE *Configure, > + IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL > + IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, > + IN UINTN SourceX, > + IN UINTN SourceY, > + IN UINTN DestinationX, > + IN UINTN DestinationY, > + IN UINTN Width, > + IN UINTN Height, > + IN UINTN Delta > + ); > + > +#endif > diff --git a/MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.c > b/MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.c > new file mode 100644 > index 0000000..c9bb206 > --- /dev/null > +++ b/MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.c > @@ -0,0 +1,704 @@ > +/** @file > + FrameBufferBltLib - Library to perform blt operations on a frame buffer. > + > + Copyright (c) 2007 - 2016, 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 <Uefi/UefiBaseType.h> > +#include <Protocol/GraphicsOutput.h> > + > +#include <Library/BaseLib.h> > +#include <Library/BaseMemoryLib.h> > +#include <Library/DebugLib.h> > +#include <Library/FrameBufferBltLib.h> > + > +struct FRAME_BUFFER_CONFIGURE { > + UINTN ColorDepth; > + UINTN WidthInBytes; > + UINTN BytesPerPixel; > + UINTN WidthInPixels; > + UINTN Height; > + UINT8 LineBuffer[SIZE_4KB * sizeof > (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)]; > + UINT8 *FrameBuffer; > + EFI_GRAPHICS_PIXEL_FORMAT PixelFormat; > + EFI_PIXEL_BITMASK PixelMasks; > + INTN PixelShl[4]; // R-G-B-Rsvd > + INTN PixelShr[4]; // R-G-B-Rsvd > +}; > + > +CONST EFI_PIXEL_BITMASK mRgbPixelMasks = { > + 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 > +}; > + > +CONST EFI_PIXEL_BITMASK mBgrPixelMasks = { > + 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 > +}; > + > +/** > + Initialize the bit mask in frame buffer configure. > + > + @param Configure The frame buffer configure. > + @param BitMask The bit mask of pixel. > +**/ > +VOID > +ConfigurePixelBitMaskFormat ( > + IN FRAME_BUFFER_CONFIGURE *Configure, > + IN CONST 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); > + Configure->PixelShl[Loop] = HighBitSet32 (Masks[Loop]) - 23 + (Loop * 8); > + if (Configure->PixelShl[Loop] < 0) { > + Configure->PixelShr[Loop] = -Configure->PixelShl[Loop]; > + Configure->PixelShl[Loop] = 0; > + } else { > + Configure->PixelShr[Loop] = 0; > + } > + MergedMasks = (UINT32) (MergedMasks | Masks[Loop]); > + DEBUG ((EFI_D_VERBOSE, "%d: shl:%d shr:%d mask:%x\n", Loop, > + Configure->PixelShl[Loop], Configure->PixelShr[Loop], > Masks[Loop])); > + } > + MergedMasks = (UINT32) (MergedMasks | Masks[3]); > + > + ASSERT (MergedMasks != 0); > + Configure->BytesPerPixel = (UINTN) ((HighBitSet32 (MergedMasks) + 7) / 8); > + > + DEBUG ((EFI_D_VERBOSE, "Bytes per pixel: %d\n", Configure->BytesPerPixel)); > + > + CopyMem (&Configure->PixelMasks, BitMask, sizeof (*BitMask)); > +} > + > +/** > + Create the configuration for a video frame buffer. > + > + The configuration is returned in the caller provided buffer. > + > + @param[in] FrameBuffer Pointer to the start of the frame buffer. > + @param[in] FrameBufferInfo Describes the frame buffer characteristics. > + @param[in,out] Configure The created configuration information. > + @param[in,out] ConfigureSize Size of the configuration information. > + > + @retval RETURN_SUCCESS The configuration was successful created. > + @retval RETURN_BUFFER_TOO_SMALL The Configure is to too small. The > required > + size is returned in ConfigureSize. > + @retval RETURN_UNSUPPORTED The requested mode is not supported by > + this implementaion. > + > +**/ > +RETURN_STATUS > +EFIAPI > +FrameBufferBltConfigure ( > + IN VOID *FrameBuffer, > + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, > + IN OUT FRAME_BUFFER_CONFIGURE *Configure, > + IN OUT UINTN *ConfigureSize > + ) > +{ > + if (ConfigureSize == NULL) { > + return RETURN_INVALID_PARAMETER; > + } > + > + if (*ConfigureSize < sizeof (FRAME_BUFFER_CONFIGURE)) { > + *ConfigureSize = sizeof (FRAME_BUFFER_CONFIGURE); > + return RETURN_BUFFER_TOO_SMALL; > + } > + > + if (Configure == NULL) { > + return RETURN_INVALID_PARAMETER; > + } > + > + switch (FrameBufferInfo->PixelFormat) { > + case PixelRedGreenBlueReserved8BitPerColor: > + ConfigurePixelBitMaskFormat (Configure, &mRgbPixelMasks); > + break; > + > + case PixelBlueGreenRedReserved8BitPerColor: > + ConfigurePixelBitMaskFormat (Configure, &mBgrPixelMasks); > + break; > + > + case PixelBitMask: > + ConfigurePixelBitMaskFormat (Configure, > &(FrameBufferInfo->PixelInformation)); > + break; > + > + case PixelBltOnly: > + ASSERT (FrameBufferInfo->PixelFormat != PixelBltOnly); > + return RETURN_UNSUPPORTED; > + > + default: > + ASSERT (FALSE); > + return RETURN_INVALID_PARAMETER; > + } > + > + Configure->PixelFormat = FrameBufferInfo->PixelFormat; > + Configure->FrameBuffer = (UINT8*) FrameBuffer; > + Configure->WidthInPixels = (UINTN) FrameBufferInfo->HorizontalResolution; > + Configure->Height = (UINTN) FrameBufferInfo->VerticalResolution; > + Configure->WidthInBytes = Configure->WidthInPixels * > Configure->BytesPerPixel; > + > + ASSERT (Configure->WidthInBytes < sizeof (Configure->LineBuffer)); > + > + return RETURN_SUCCESS; > +} > + > +/** > + Performs a UEFI Graphics Output Protocol Blt Video Fill. > + > + @param[in] Configure Pointer to a configuration which was successfully > + created by FrameBufferBltConfigure (). > + @param[in] Color Color to fill the region with. > + @param[in] DestinationX X location to start fill operation. > + @param[in] DestinationY Y location to start fill operation. > + @param[in] Width Width (in pixels) to fill. > + @param[in] Height Height to fill. > + > + @retval RETURN_INVALID_PARAMETER Invalid parameter was passed in. > + @retval RETURN_SUCCESS The video was filled successfully. > + > +**/ > +EFI_STATUS > +FrameBufferBltLibVideoFill ( > + IN FRAME_BUFFER_CONFIGURE *Configure, > + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Color, > + IN UINTN DestinationX, > + IN UINTN DestinationY, > + IN UINTN Width, > + IN UINTN Height > + ) > +{ > + UINTN IndexX; > + UINTN IndexY; > + UINT8 *Destination; > + UINT8 Uint8; > + UINT32 Uint32; > + UINT64 WideFill; > + BOOLEAN UseWideFill; > + BOOLEAN LineBufferReady; > + UINTN Offset; > + UINTN WidthInBytes; > + UINTN SizeInBytes; > + > + // > + // BltBuffer to Video: Source is BltBuffer, destination is Video > + // > + if (DestinationY + Height > Configure->Height) { > + DEBUG ((EFI_D_VERBOSE, "VideoFill: Past screen (Y)\n")); > + return RETURN_INVALID_PARAMETER; > + } > + > + if (DestinationX + Width > Configure->WidthInPixels) { > + DEBUG ((EFI_D_VERBOSE, "VideoFill: Past screen (X)\n")); > + return RETURN_INVALID_PARAMETER; > + } > + > + if (Width == 0 || Height == 0) { > + DEBUG ((EFI_D_VERBOSE, "VideoFill: Width or Height is 0\n")); > + return RETURN_INVALID_PARAMETER; > + } > + > + WidthInBytes = Width * Configure->BytesPerPixel; > + > + Uint32 = *(UINT32*) Color; > + WideFill = > + (UINT32) ( > + (((Uint32 << Configure->PixelShl[0]) >> Configure->PixelShr[0]) & > + Configure->PixelMasks.RedMask) | > + (((Uint32 << Configure->PixelShl[1]) >> Configure->PixelShr[1]) & > + Configure->PixelMasks.GreenMask) | > + (((Uint32 << Configure->PixelShl[2]) >> Configure->PixelShr[2]) & > + Configure->PixelMasks.BlueMask) > + ); > + DEBUG ((EFI_D_VERBOSE, "VideoFill: color=0x%x, wide-fill=0x%x\n", > + Uint32, WideFill)); > + > + // > + // If the size of the pixel data evenly divides the sizeof > + // WideFill, then a wide fill operation can be used > + // > + UseWideFill = TRUE; > + if ((sizeof (WideFill) % Configure->BytesPerPixel) == 0) { > + for (IndexX = Configure->BytesPerPixel; IndexX < sizeof (WideFill); > IndexX++) { > + ((UINT8*) &WideFill)[IndexX] = ((UINT8*) &WideFill)[IndexX % > Configure->BytesPerPixel]; > + } > + } else { > + // > + // If all the bytes in the pixel are the same value, then use > + // a wide fill operation. > + // > + for ( > + IndexX = 1, Uint8 = ((UINT8*) &WideFill)[0]; > + IndexX < Configure->BytesPerPixel; > + IndexX++) { > + if (Uint8 != ((UINT8*) &WideFill)[IndexX]) { > + UseWideFill = FALSE; > + break; > + } > + } > + if (UseWideFill) { > + SetMem (&WideFill, sizeof (WideFill), Uint8); > + } > + } > + > + if (UseWideFill && (DestinationX == 0) && (Width == > Configure->WidthInPixels)) { > + DEBUG ((EFI_D_VERBOSE, "VideoFill (wide, one-shot)\n")); > + Offset = DestinationY * Configure->WidthInPixels; > + Offset = Configure->BytesPerPixel * Offset; > + Destination = Configure->FrameBuffer + Offset; > + SizeInBytes = WidthInBytes * Height; > + if (SizeInBytes >= 8) { > + SetMem32 (Destination, SizeInBytes & ~3, (UINT32) WideFill); > + SizeInBytes &= 3; > + } > + if (SizeInBytes > 0) { > + SetMem (Destination, SizeInBytes, (UINT8) (UINTN) WideFill); > + } > + } else { > + LineBufferReady = FALSE; > + for (IndexY = DestinationY; IndexY < (Height + DestinationY); IndexY++) { > + Offset = (IndexY * Configure->WidthInPixels) + DestinationX; > + Offset = Configure->BytesPerPixel * Offset; > + Destination = Configure->FrameBuffer + Offset; > + > + if (UseWideFill && (((UINTN) Destination & 7) == 0)) { > + DEBUG ((EFI_D_VERBOSE, "VideoFill (wide)\n")); > + SizeInBytes = WidthInBytes; > + if (SizeInBytes >= 8) { > + SetMem64 (Destination, SizeInBytes & ~7, WideFill); > + SizeInBytes &= 7; > + } > + if (SizeInBytes > 0) { > + CopyMem (Destination, &WideFill, SizeInBytes); > + } > + } else { > + DEBUG ((EFI_D_VERBOSE, "VideoFill (not wide)\n")); > + if (!LineBufferReady) { > + CopyMem (Configure->LineBuffer, &WideFill, > Configure->BytesPerPixel); > + for (IndexX = 1; IndexX < Width; ) { > + CopyMem ( > + (Configure->LineBuffer + (IndexX * Configure->BytesPerPixel)), > + Configure->LineBuffer, > + MIN (IndexX, Width - IndexX) * Configure->BytesPerPixel > + ); > + IndexX += MIN (IndexX, Width - IndexX); > + } > + LineBufferReady = TRUE; > + } > + CopyMem (Destination, Configure->LineBuffer, WidthInBytes); > + } > + } > + } > + > + return RETURN_SUCCESS; > +} > + > +/** > + Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation > + with extended parameters. > + > + @param[in] Configure Pointer to a configuration which was successfully > + created by FrameBufferBltConfigure (). > + @param[out] BltBuffer Output buffer for pixel color data. > + @param[in] SourceX X location within video. > + @param[in] SourceY Y location within video. > + @param[in] DestinationX X location within BltBuffer. > + @param[in] DestinationY Y location within BltBuffer. > + @param[in] Width Width (in pixels). > + @param[in] Height Height. > + @param[in] Delta Number of bytes in a row of BltBuffer. > + > + @retval RETURN_INVALID_PARAMETER Invalid parameter were passed in. > + @retval RETURN_SUCCESS The Blt operation was performed > successfully. > +**/ > +RETURN_STATUS > +FrameBufferBltLibVideoToBltBuffer ( > + IN FRAME_BUFFER_CONFIGURE *Configure, > + OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, > + IN UINTN SourceX, > + IN UINTN SourceY, > + IN UINTN DestinationX, > + IN UINTN DestinationY, > + IN UINTN Width, > + IN UINTN Height, > + IN UINTN Delta > + ) > +{ > + UINTN DstY; > + UINTN SrcY; > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; > + UINT8 *Source; > + UINT8 *Destination; > + UINTN IndexX; > + UINT32 Uint32; > + UINTN Offset; > + UINTN WidthInBytes; > + > + // > + // Video to BltBuffer: Source is Video, destination is BltBuffer > + // > + if (SourceY + Height > Configure->Height) { > + return RETURN_INVALID_PARAMETER; > + } > + > + if (SourceX + Width > Configure->WidthInPixels) { > + return RETURN_INVALID_PARAMETER; > + } > + > + if (Width == 0 || Height == 0) { > + return RETURN_INVALID_PARAMETER; > + } > + > + // > + // If Delta is zero, then the entire BltBuffer is being used, so Delta is > + // the number of bytes in each row of BltBuffer. Since BltBuffer is Width > + // pixels size, the number of bytes in each row can be computed. > + // > + if (Delta == 0) { > + Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL); > + } > + > + WidthInBytes = Width * Configure->BytesPerPixel; > + > + // > + // Video to BltBuffer: Source is Video, destination is BltBuffer > + // > + for (SrcY = SourceY, DstY = DestinationY; > + DstY < (Height + DestinationY); > + SrcY++, DstY++) { > + > + Offset = (SrcY * Configure->WidthInPixels) + SourceX; > + Offset = Configure->BytesPerPixel * Offset; > + Source = Configure->FrameBuffer + Offset; > + > + if (Configure->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) { > + Destination = (UINT8 *) BltBuffer + (DstY * Delta) + (DestinationX * > sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); > + } else { > + Destination = Configure->LineBuffer; > + } > + > + CopyMem (Destination, Source, WidthInBytes); > + > + if (Configure->PixelFormat != PixelBlueGreenRedReserved8BitPerColor) { > + for (IndexX = 0; IndexX < Width; IndexX++) { > + Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) > + ((UINT8 *) BltBuffer + (DstY * Delta) + > + (DestinationX + IndexX) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); > + Uint32 = *(UINT32*) (Configure->LineBuffer + (IndexX * > Configure->BytesPerPixel)); > + *(UINT32*) Blt = > + (UINT32) ( > + (((Uint32 & Configure->PixelMasks.RedMask) >> > + Configure->PixelShl[0]) << Configure->PixelShr[0]) | > + (((Uint32 & Configure->PixelMasks.GreenMask) >> > + Configure->PixelShl[1]) << Configure->PixelShr[1]) | > + (((Uint32 & Configure->PixelMasks.BlueMask) >> > + Configure->PixelShl[2]) << Configure->PixelShr[2]) > + ); > + } > + } > + } > + > + return RETURN_SUCCESS; > +} > + > +/** > + Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation > + with extended parameters. > + > + @param[in] Configure Pointer to a configuration which was successfully > + created by FrameBufferBltConfigure (). > + @param[in] BltBuffer Output buffer for pixel color data. > + @param[in] SourceX X location within BltBuffer. > + @param[in] SourceY Y location within BltBuffer. > + @param[in] DestinationX X location within video. > + @param[in] DestinationY Y location within video. > + @param[in] Width Width (in pixels). > + @param[in] Height Height. > + @param[in] Delta Number of bytes in a row of BltBuffer. > + > + @retval RETURN_INVALID_PARAMETER Invalid parameter were passed in. > + @retval RETURN_SUCCESS The Blt operation was performed > successfully. > +**/ > +RETURN_STATUS > +FrameBufferBltLibBufferToVideo ( > + IN FRAME_BUFFER_CONFIGURE *Configure, > + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, > + IN UINTN SourceX, > + IN UINTN SourceY, > + IN UINTN DestinationX, > + IN UINTN DestinationY, > + IN UINTN Width, > + IN UINTN Height, > + IN UINTN Delta > + ) > +{ > + UINTN DstY; > + UINTN SrcY; > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; > + UINT8 *Source; > + UINT8 *Destination; > + UINTN IndexX; > + UINT32 Uint32; > + UINTN Offset; > + UINTN WidthInBytes; > + > + // > + // BltBuffer to Video: Source is BltBuffer, destination is Video > + // > + if (DestinationY + Height > Configure->Height) { > + return RETURN_INVALID_PARAMETER; > + } > + > + if (DestinationX + Width > Configure->WidthInPixels) { > + return RETURN_INVALID_PARAMETER; > + } > + > + if (Width == 0 || Height == 0) { > + return RETURN_INVALID_PARAMETER; > + } > + > + // > + // If Delta is zero, then the entire BltBuffer is being used, so Delta is > + // the number of bytes in each row of BltBuffer. Since BltBuffer is Width > + // pixels size, the number of bytes in each row can be computed. > + // > + if (Delta == 0) { > + Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL); > + } > + > + WidthInBytes = Width * Configure->BytesPerPixel; > + > + for (SrcY = SourceY, DstY = DestinationY; > + SrcY < (Height + SourceY); > + SrcY++, DstY++) { > + > + Offset = (DstY * Configure->WidthInPixels) + DestinationX; > + Offset = Configure->BytesPerPixel * Offset; > + Destination = Configure->FrameBuffer + Offset; > + > + if (Configure->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) { > + Source = (UINT8 *) BltBuffer + (SrcY * Delta); > + } else { > + for (IndexX = 0; IndexX < Width; IndexX++) { > + Blt = > + (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ( > + (UINT8 *) BltBuffer + > + (SrcY * Delta) + > + ((SourceX + IndexX) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)) > + ); > + Uint32 = *(UINT32*) Blt; > + *(UINT32*) (Configure->LineBuffer + (IndexX * > Configure->BytesPerPixel)) = > + (UINT32) ( > + (((Uint32 << Configure->PixelShl[0]) >> > Configure->PixelShr[0]) & > + Configure->PixelMasks.RedMask) | > + (((Uint32 << Configure->PixelShl[1]) >> > Configure->PixelShr[1]) & > + Configure->PixelMasks.GreenMask) | > + (((Uint32 << Configure->PixelShl[2]) >> > Configure->PixelShr[2]) & > + Configure->PixelMasks.BlueMask) > + ); > + } > + Source = Configure->LineBuffer; > + } > + > + CopyMem (Destination, Source, WidthInBytes); > + } > + > + return RETURN_SUCCESS; > +} > + > +/** > + Performs a UEFI Graphics Output Protocol Blt Video to Video operation > + > + @param[in] Configure Pointer to a configuration which was successfully > + created by FrameBufferBltConfigure (). > + @param[in] SourceX X location within video. > + @param[in] SourceY Y location within video. > + @param[in] DestinationX X location within video. > + @param[in] DestinationY Y location within video. > + @param[in] Width Width (in pixels). > + @param[in] Height Height. > + > + @retval RETURN_INVALID_PARAMETER Invalid parameter were passed in. > + @retval RETURN_SUCCESS The Blt operation was performed > successfully. > +**/ > +RETURN_STATUS > +FrameBufferBltLibVideoToVideo ( > + IN FRAME_BUFFER_CONFIGURE *Configure, > + IN UINTN SourceX, > + IN UINTN SourceY, > + IN UINTN DestinationX, > + IN UINTN DestinationY, > + IN UINTN Width, > + IN UINTN Height > + ) > +{ > + UINT8 *Source; > + UINT8 *Destination; > + UINTN Offset; > + UINTN WidthInBytes; > + INTN LineStride; > + > + // > + // Video to Video: Source is Video, destination is Video > + // > + if (SourceY + Height > Configure->Height) { > + return RETURN_INVALID_PARAMETER; > + } > + > + if (SourceX + Width > Configure->WidthInPixels) { > + return RETURN_INVALID_PARAMETER; > + } > + > + if (DestinationY + Height > Configure->Height) { > + return RETURN_INVALID_PARAMETER; > + } > + > + if (DestinationX + Width > Configure->WidthInPixels) { > + return RETURN_INVALID_PARAMETER; > + } > + > + if (Width == 0 || Height == 0) { > + return RETURN_INVALID_PARAMETER; > + } > + > + WidthInBytes = Width * Configure->BytesPerPixel; > + > + Offset = (SourceY * Configure->WidthInPixels) + SourceX; > + Offset = Configure->BytesPerPixel * Offset; > + Source = Configure->FrameBuffer + Offset; > + > + Offset = (DestinationY * Configure->WidthInPixels) + DestinationX; > + Offset = Configure->BytesPerPixel * Offset; > + Destination = Configure->FrameBuffer + Offset; > + > + LineStride = Configure->WidthInBytes; > + if (Destination > Source) { > + // > + // Copy from last line to avoid source is corrupted by copying > + // > + Source += Height * LineStride; > + Destination += Height * LineStride; > + LineStride = -LineStride; > + } > + > + while (Height-- > 0) { > + CopyMem (Destination, Source, WidthInBytes); > + > + Source += LineStride; > + Destination += LineStride; > + } > + > + return RETURN_SUCCESS; > +} > + > +/** > + Performs a UEFI Graphics Output Protocol Blt operation. > + > + @param[in] Configure Pointer to a configuration which was > successfully > + created by FrameBufferBltConfigure (). > + @param[in,out] BltBuffer The data to transfer to screen. > + @param[in] BltOperation The operation to perform. > + @param[in] SourceX The X coordinate of the source for > BltOperation. > + @param[in] SourceY The Y coordinate of the source for > BltOperation. > + @param[in] DestinationX The X coordinate of the destination for > + BltOperation. > + @param[in] DestinationY The Y coordinate of the destination for > + BltOperation. > + @param[in] Width The width of a rectangle in the blt rectangle > + in pixels. > + @param[in] Height The height of a rectangle in the blt rectangle > + in pixels. > + @param[in] Delta Not used for EfiBltVideoFill and > + EfiBltVideoToVideo operation. If a Delta of 0 > + is used, the entire BltBuffer will be operated > + on. If a subrectangle of the BltBuffer is > + used, then Delta represents the number of > + bytes in a row of the BltBuffer. > + > + @retval RETURN_INVALID_PARAMETER Invalid parameter were passed in. > + @retval RETURN_SUCCESS The Blt operation was performed > successfully. > +**/ > +RETURN_STATUS > +EFIAPI > +FrameBufferBlt ( > + IN FRAME_BUFFER_CONFIGURE *Configure, > + IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL > + IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, > + IN UINTN SourceX, > + IN UINTN SourceY, > + IN UINTN DestinationX, > + IN UINTN DestinationY, > + IN UINTN Width, > + IN UINTN Height, > + IN UINTN Delta > + ) > +{ > + if (Configure == NULL) { > + return RETURN_INVALID_PARAMETER; > + } > + > + switch (BltOperation) { > + case EfiBltVideoToBltBuffer: > + return FrameBufferBltLibVideoToBltBuffer ( > + Configure, > + BltBuffer, > + SourceX, > + SourceY, > + DestinationX, > + DestinationY, > + Width, > + Height, > + Delta > + ); > + > + case EfiBltVideoToVideo: > + return FrameBufferBltLibVideoToVideo ( > + Configure, > + SourceX, > + SourceY, > + DestinationX, > + DestinationY, > + Width, > + Height > + ); > + > + case EfiBltVideoFill: > + return FrameBufferBltLibVideoFill ( > + Configure, > + BltBuffer, > + DestinationX, > + DestinationY, > + Width, > + Height > + ); > + > + case EfiBltBufferToVideo: > + return FrameBufferBltLibBufferToVideo ( > + Configure, > + BltBuffer, > + SourceX, > + SourceY, > + DestinationX, > + DestinationY, > + Width, > + Height, > + Delta > + ); > + > + default: > + return RETURN_INVALID_PARAMETER; > + } > +} > diff --git a/MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf > b/MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf > new file mode 100644 > index 0000000..57e4adb > --- /dev/null > +++ b/MdeModulePkg/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.<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. > +# > +## > + > +[Defines] > + INF_VERSION = 0x00010005 > + BASE_NAME = FrameBufferBltLib > + FILE_GUID = 243D3E8C-2780-4A25-9693-A410475BFCEC > + MODULE_TYPE = BASE > + VERSION_STRING = 1.0 > + LIBRARY_CLASS = FrameBufferBltLib > + > +[Sources.common] > + FrameBufferBltLib.c > + > +[LibraryClasses] > + BaseLib > + BaseMemoryLib > + DebugLib > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec > index 27efb37..eb1ca0d 100644 > --- a/MdeModulePkg/MdeModulePkg.dec > +++ b/MdeModulePkg/MdeModulePkg.dec > @@ -153,6 +153,10 @@ [LibraryClasses] > # > PciHostBridgeLib|Include/Library/PciHostBridgeLib.h > > + ## @libraryclass Provides an interface for performing UEFI Graphics > Output Protocol Video blt operations. > + ## > + FrameBufferBltLib|Include/Library/FrameBufferBltLib.h > + > [Guids] > ## MdeModule package token space guid > # Include/Guid/MdeModulePkgTokenSpace.h > diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc > index abce62d..63e1f91 100644 > --- a/MdeModulePkg/MdeModulePkg.dsc > +++ b/MdeModulePkg/MdeModulePkg.dsc > @@ -306,6 +306,7 @@ [Components] > MdeModulePkg/Library/DxeIpmiLibIpmiProtocol/DxeIpmiLibIpmiProtocol.inf > MdeModulePkg/Library/PeiIpmiLibIpmiPpi/PeiIpmiLibIpmiPpi.inf > > MdeModulePkg/Library/SmmIpmiLibSmmIpmiProtocol/SmmIpmiLibSmmIpmiProtocol.inf > + MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf > > MdeModulePkg/Universal/BdsDxe/BdsDxe.inf > MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf > _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

