diff --git a/Pixel3XL/Pixel3XL.dsc b/Pixel3XL/Pixel3XL.dsc index f48841d..8b2f58f 100644 --- a/Pixel3XL/Pixel3XL.dsc +++ b/Pixel3XL/Pixel3XL.dsc @@ -63,6 +63,9 @@ TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf + # SimpleFbDxe + FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf + [LibraryClasses.common.SEC] PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf diff --git a/Pixel3XL/SimpleFbDxe/SimpleFbDxe.c b/Pixel3XL/SimpleFbDxe/SimpleFbDxe.c index 04ef090..ed331b6 100644 --- a/Pixel3XL/SimpleFbDxe/SimpleFbDxe.c +++ b/Pixel3XL/SimpleFbDxe/SimpleFbDxe.c @@ -10,6 +10,7 @@ #include #include #include +#include /// Defines /* @@ -19,20 +20,8 @@ #define VNBYTES(bpix) (1 << (bpix)) / 8 #define VNBITS(bpix) (1 << (bpix)) -#define POS_TO_FB(posX, posY) ((UINT8 *) \ - ((UINTN)This->Mode->FrameBufferBase + \ - (posY) * This->Mode->Info->PixelsPerScanLine * \ - FB_BYTES_PER_PIXEL + \ - (posX) * FB_BYTES_PER_PIXEL)) - #define FB_BITS_PER_PIXEL (32) #define FB_BYTES_PER_PIXEL (FB_BITS_PER_PIXEL / 8) -#define DISPLAYDXE_PHYSICALADDRESS32(_x_) (UINTN)((_x_) & 0xFFFFFFFF) - -#define DISPLAYDXE_RED_MASK 0xFF0000 -#define DISPLAYDXE_GREEN_MASK 0x00FF00 -#define DISPLAYDXE_BLUE_MASK 0x0000FF -#define DISPLAYDXE_ALPHA_MASK 0x000000 /* * Bits per pixel selector. Each value n is such that the bits-per-pixel is @@ -77,6 +66,9 @@ DISPLAY_DEVICE_PATH mDisplayDevicePath = /// Declares +STATIC FRAME_BUFFER_CONFIGURE *mFrameBufferBltLibConfigure; +STATIC UINTN mFrameBufferBltLibConfigureSize; + STATIC EFI_STATUS EFIAPI @@ -114,22 +106,6 @@ DisplayBlt IN UINTN Delta OPTIONAL ); -/* Display Blit function */ -static void DisplayDxeBltInternal -( - UINT8 *pSrc, - UINT8 *pDst, - UINTN uSrcX, - UINTN uSrcY, - UINTN uSrcWidth, - UINTN uSrcHeight, - UINTN uSrcStride, - UINTN uDstX, - UINTN uDstY, - UINTN uDstStride, - UINTN uBytesPerPixel -); - STATIC EFI_GRAPHICS_OUTPUT_PROTOCOL mDisplay = { DisplayQueryMode, DisplaySetMode, @@ -137,44 +113,6 @@ STATIC EFI_GRAPHICS_OUTPUT_PROTOCOL mDisplay = { NULL }; -static void DisplayDxeBltInternal -( - UINT8 *pSrc, - UINT8 *pDst, - UINTN uSrcX, - UINTN uSrcY, - UINTN uSrcWidth, - UINTN uSrcHeight, - UINTN uSrcStride, - UINTN uDstX, - UINTN uDstY, - UINTN uDstStride, - UINTN uBytesPerPixel - ) -{ - UINT32 uI = 0; - UINT32 uSrcWidthBytes = uSrcWidth * uBytesPerPixel; - - /* move src pointer to start of src rectangle */ - pSrc += (uSrcY * uSrcStride) + (uSrcX * uBytesPerPixel); - - /* move dest pointer to start of dest rectangle */ - pDst += (uDstY * uDstStride) + (uDstX * uBytesPerPixel); - - /* Blit Operation - * - * We use MDP_OSAL_MEMCPY which invokes Neon memcpy (kr_memcpy.asm) - * This memcpy supports overlapped src and dst buffers but copying may not be optimal in the overlap case - */ - for (uI = 0; uI < uSrcHeight; ++uI) - { - gBS->CopyMem((VOID*) pDst, (VOID*) pSrc, uSrcWidthBytes); - - pDst += uDstStride; - pSrc += uSrcStride; - } -} - STATIC EFI_STATUS EFIAPI @@ -233,184 +171,25 @@ DisplayBlt IN UINTN Delta OPTIONAL ) { - EFI_STATUS Status = EFI_SUCCESS; + RETURN_STATUS Status; + EFI_TPL Tpl; + // + // We have to raise to TPL_NOTIFY, so we make an atomic write to the frame buffer. + // We would not want a timer based event (Cursor, ...) to come in while we are + // doing this operation. + // + Tpl = gBS->RaiseTPL (TPL_NOTIFY); + Status = FrameBufferBlt ( + mFrameBufferBltLibConfigure, + BltBuffer, + BltOperation, + SourceX, SourceY, + DestinationX, DestinationY, Width, Height, + Delta + ); + gBS->RestoreTPL (Tpl); - if (NULL == This) - { - Status = EFI_INVALID_PARAMETER; - } - else - { - switch (BltOperation) - { - case EfiBltBufferToVideo: - { - UINT8 *pSrcBuffer = (UINT8*) BltBuffer; - UINT8 *pDstBuffer = (UINT8*) DISPLAYDXE_PHYSICALADDRESS32(mDisplay.Mode->FrameBufferBase); - UINTN SrcStride, DstStride, CopyWidth, CopyHeight; - - if (((DestinationX + Width) > mDisplay.Mode->Info->HorizontalResolution) || - ((DestinationY + Height) > mDisplay.Mode->Info->VerticalResolution)) - { - return EFI_INVALID_PARAMETER; - } - - CopyWidth = Width; - CopyHeight = Height; - - /* Video buffer stride in bytes, consider padding as well */ - DstStride = mDisplay.Mode->Info->PixelsPerScanLine * FB_BYTES_PER_PIXEL; - - /* Src buffer stride in bytes. Delta is valid when X or Y is not 0 */ - SrcStride = Width * FB_BYTES_PER_PIXEL; - if (Delta != 0) - { - SrcStride = Delta; - } - - DisplayDxeBltInternal(pSrcBuffer, - pDstBuffer, - SourceX, - SourceY, - CopyWidth, - CopyHeight, - SrcStride, - DestinationX, - DestinationY, - DstStride, - FB_BYTES_PER_PIXEL); - - Status = EFI_SUCCESS; - } - break; - - case EfiBltVideoToBltBuffer: - { - UINT8 *pSrcBuffer = (UINT8*) BltBuffer; - UINT8 *pDstBuffer = (UINT8*) DISPLAYDXE_PHYSICALADDRESS32(mDisplay.Mode->FrameBufferBase); - UINTN SrcStride, DstStride, CopyWidth, CopyHeight; - - if (((SourceX + Width) > mDisplay.Mode->Info->HorizontalResolution) || - ((SourceY + Height) > mDisplay.Mode->Info->VerticalResolution)) - { - return EFI_INVALID_PARAMETER; - } - - CopyWidth = Width; - CopyHeight = Height; - - /* Video buffer stride in bytes, consider padding as well */ - SrcStride = mDisplay.Mode->Info->PixelsPerScanLine * FB_BYTES_PER_PIXEL; - - /* Buffer stride in bytes. Delta is valid when X or Y is not 0 */ - DstStride = Width * FB_BYTES_PER_PIXEL; - if (Delta != 0) - { - DstStride = Delta; - } - - DisplayDxeBltInternal(pSrcBuffer, - pDstBuffer, - SourceX, - SourceY, - CopyWidth, - CopyHeight, - SrcStride, - DestinationX, - DestinationY, - DstStride, - FB_BYTES_PER_PIXEL); - - Status = EFI_SUCCESS; - } - break; - - case EfiBltVideoFill: - { - UINT32 SrcPixel = *(UINT32*) BltBuffer; - UINT32 *pDstBuffer = (UINT32*) DISPLAYDXE_PHYSICALADDRESS32(mDisplay.Mode->FrameBufferBase); - UINTN DstStride, CopyWidth, CopyHeight; - UINT32 x,y; - - if (((DestinationX + Width) > mDisplay.Mode->Info->HorizontalResolution) || - ((DestinationY + Height) > mDisplay.Mode->Info->VerticalResolution)) - { - return EFI_INVALID_PARAMETER; - } - - CopyWidth = Width; - CopyHeight = Height; - - /* Video buffer stride in bytes, consider padding as well */ - DstStride = mDisplay.Mode->Info->PixelsPerScanLine * FB_BYTES_PER_PIXEL; - - /* Adjust Destination location */ - pDstBuffer = (UINT32*)(((UINT8*)pDstBuffer) + (DestinationY * DstStride) + DestinationX * FB_BYTES_PER_PIXEL); - - /* Do the actual blitting */ - for (y = 0; y < CopyHeight; y++) - { - for (x = 0; x < CopyWidth; x++) - { - pDstBuffer[x] = SrcPixel; - } - - /* Increment by stride number of bytes */ - pDstBuffer = (UINT32*)((UINT8*)pDstBuffer + DstStride); - } - Status = EFI_SUCCESS; - } - break; - - case EfiBltVideoToVideo: - { - UINT8 *pSrcBuffer = (UINT8*) DISPLAYDXE_PHYSICALADDRESS32(mDisplay.Mode->FrameBufferBase); - UINT8 *pDstBuffer = (UINT8*) DISPLAYDXE_PHYSICALADDRESS32(mDisplay.Mode->FrameBufferBase); - UINTN Stride, CopyWidth, CopyHeight; - - if (((SourceX + Width) > mDisplay.Mode->Info->HorizontalResolution)) - Width = mDisplay.Mode->Info->HorizontalResolution - SourceX; - - if (((SourceY + Height) > mDisplay.Mode->Info->VerticalResolution)) - Height = mDisplay.Mode->Info->VerticalResolution - SourceY; - - if (((DestinationX + Width) > mDisplay.Mode->Info->HorizontalResolution)) - Width = mDisplay.Mode->Info->HorizontalResolution - DestinationX; - - if (((DestinationY + Height) > mDisplay.Mode->Info->VerticalResolution)) - Height = mDisplay.Mode->Info->VerticalResolution - DestinationY; - - CopyWidth = Width; - CopyHeight = Height; - - /* Video buffer stride in bytes, consider padding as well */ - Stride = mDisplay.Mode->Info->PixelsPerScanLine * FB_BYTES_PER_PIXEL; - - DisplayDxeBltInternal(pSrcBuffer, - pDstBuffer, - SourceX, - SourceY, - CopyWidth, - CopyHeight, - Stride, - DestinationX, - DestinationY, - Stride, - FB_BYTES_PER_PIXEL); - - Status = EFI_SUCCESS; - - } - break; - - default: - DEBUG ((EFI_D_ERROR, "SimpleFbDxe: BltOperation not supported\n")); - Status = RETURN_INVALID_PARAMETER; - break; - } - } - - return Status; + return RETURN_ERROR (Status) ? EFI_INVALID_PARAMETER : EFI_SUCCESS; } EFI_STATUS @@ -486,6 +265,33 @@ SimpleFbDxeInitialize mDisplay.Mode->FrameBufferBase = FrameBufferAddress; mDisplay.Mode->FrameBufferSize = FrameBufferSize; + // + // Create the FrameBufferBltLib configuration. + // + Status = FrameBufferBltConfigure ( + (VOID *) (UINTN) mDisplay.Mode->FrameBufferBase, + mDisplay.Mode->Info, + mFrameBufferBltLibConfigure, + &mFrameBufferBltLibConfigureSize + ); + if (Status == RETURN_BUFFER_TOO_SMALL) { + mFrameBufferBltLibConfigure = AllocatePool (mFrameBufferBltLibConfigureSize); + if (mFrameBufferBltLibConfigure != NULL) { + Status = FrameBufferBltConfigure ( + (VOID *) (UINTN) mDisplay.Mode->FrameBufferBase, + mDisplay.Mode->Info, + mFrameBufferBltLibConfigure, + &mFrameBufferBltLibConfigureSize + ); + } + } + ASSERT_EFI_ERROR (Status); + + // zhuowei: clear the screen to black + // UEFI standard requires this, since text is white - see OvmfPkg/QemuVideoDxe/Gop.c + ZeroMem((void*)FrameBufferAddress, FrameBufferSize); + // zhuowei: end + /* Register handle */ Status = gBS->InstallMultipleProtocolInterfaces( &hUEFIDisplayHandle, @@ -497,10 +303,6 @@ SimpleFbDxeInitialize ASSERT_EFI_ERROR (Status); - // zhuowei: clear the screen - ZeroMem((void*)FrameBufferAddress, FrameBufferSize); - // zhuowei: end - return Status; } diff --git a/Pixel3XL/SimpleFbDxe/SimpleFbDxe.inf b/Pixel3XL/SimpleFbDxe/SimpleFbDxe.inf index 82763c0..36c64f1 100644 --- a/Pixel3XL/SimpleFbDxe/SimpleFbDxe.inf +++ b/Pixel3XL/SimpleFbDxe/SimpleFbDxe.inf @@ -27,6 +27,7 @@ BaseMemoryLib DebugLib PcdLib + FrameBufferBltLib [Protocols] gEfiGraphicsOutputProtocolGuid ## PRODUCES