+++ /dev/null
-/** @file\r
-\r
- Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
- **/\r
-\r
-#include <PiDxe.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/DevicePathLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/UefiRuntimeServicesTableLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-\r
-#include <Guid/GlobalVariable.h>\r
-\r
-#include "LcdGraphicsOutputDxe.h"\r
-\r
-extern BOOLEAN mDisplayInitialized;\r
-\r
-//\r
-// Function Definitions\r
-//\r
-\r
-STATIC\r
-EFI_STATUS\r
-VideoCopyNoHorizontalOverlap (\r
- IN UINTN BitsPerPixel,\r
- IN volatile VOID *FrameBufferBase,\r
- IN UINT32 HorizontalResolution,\r
- IN UINTN SourceX,\r
- IN UINTN SourceY,\r
- IN UINTN DestinationX,\r
- IN UINTN DestinationY,\r
- IN UINTN Width,\r
- IN UINTN Height\r
- )\r
-{\r
- EFI_STATUS Status = EFI_SUCCESS;\r
- UINTN SourceLine;\r
- UINTN DestinationLine;\r
- UINTN WidthInBytes;\r
- UINTN LineCount;\r
- INTN Step;\r
- VOID *SourceAddr;\r
- VOID *DestinationAddr;\r
-\r
- if( DestinationY <= SourceY ) {\r
- // scrolling up (or horizontally but without overlap)\r
- SourceLine = SourceY;\r
- DestinationLine = DestinationY;\r
- Step = 1;\r
- } else {\r
- // scrolling down\r
- SourceLine = SourceY + Height;\r
- DestinationLine = DestinationY + Height;\r
- Step = -1;\r
- }\r
-\r
- WidthInBytes = Width * 2;\r
-\r
- for( LineCount = 0; LineCount < Height; LineCount++ ) {\r
- // Update the start addresses of source & destination using 16bit pointer arithmetic\r
- SourceAddr = (VOID *)((UINT16 *)FrameBufferBase + SourceLine * HorizontalResolution + SourceX );\r
- DestinationAddr = (VOID *)((UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationX);\r
-\r
- // Copy the entire line Y from video ram to the temp buffer\r
- CopyMem( DestinationAddr, SourceAddr, WidthInBytes);\r
-\r
- // Update the line numbers\r
- SourceLine += Step;\r
- DestinationLine += Step;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-VideoCopyHorizontalOverlap (\r
- IN UINTN BitsPerPixel,\r
- IN volatile VOID *FrameBufferBase,\r
- UINT32 HorizontalResolution,\r
- IN UINTN SourceX,\r
- IN UINTN SourceY,\r
- IN UINTN DestinationX,\r
- IN UINTN DestinationY,\r
- IN UINTN Width,\r
- IN UINTN Height\r
- )\r
-{\r
- EFI_STATUS Status = EFI_SUCCESS;\r
-\r
- UINT16 *PixelBuffer16bit;\r
- UINT16 *SourcePixel16bit;\r
- UINT16 *DestinationPixel16bit;\r
-\r
- UINT32 SourcePixelY;\r
- UINT32 DestinationPixelY;\r
- UINTN SizeIn16Bits;\r
-\r
- // Allocate a temporary buffer\r
- PixelBuffer16bit = (UINT16 *) AllocatePool((Height * Width) * sizeof(UINT16));\r
-\r
- if (PixelBuffer16bit == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto EXIT;\r
- }\r
-\r
- // Access each pixel inside the source area of the Video Memory and copy it to the temp buffer\r
-\r
- SizeIn16Bits = Width * 2;\r
-\r
- for (SourcePixelY = SourceY, DestinationPixel16bit = PixelBuffer16bit;\r
- SourcePixelY < SourceY + Height;\r
- SourcePixelY++, DestinationPixel16bit += Width)\r
- {\r
- // Calculate the source address:\r
- SourcePixel16bit = (UINT16 *)FrameBufferBase + SourcePixelY * HorizontalResolution + SourceX;\r
-\r
- // Copy the entire line Y from Video to the temp buffer\r
- CopyMem( (VOID *)DestinationPixel16bit, (CONST VOID *)SourcePixel16bit, SizeIn16Bits);\r
- }\r
-\r
- // Copy from the temp buffer into the destination area of the Video Memory\r
-\r
- for (DestinationPixelY = DestinationY, SourcePixel16bit = PixelBuffer16bit;\r
- DestinationPixelY < DestinationY + Height;\r
- DestinationPixelY++, SourcePixel16bit += Width)\r
- {\r
- // Calculate the target address:\r
- DestinationPixel16bit = (UINT16 *)FrameBufferBase + (DestinationPixelY * HorizontalResolution + DestinationX);\r
-\r
- // Copy the entire line Y from the temp buffer to Video\r
- CopyMem( (VOID *)DestinationPixel16bit, (CONST VOID *)SourcePixel16bit, SizeIn16Bits);\r
- }\r
-\r
- // Free the allocated memory\r
- FreePool((VOID *) PixelBuffer16bit);\r
-\r
-\r
-EXIT:\r
- return Status;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-BltVideoFill (\r
- IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,\r
- IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *EfiSourcePixel, OPTIONAL\r
- IN UINTN SourceX,\r
- IN UINTN SourceY,\r
- IN UINTN DestinationX,\r
- IN UINTN DestinationY,\r
- IN UINTN Width,\r
- IN UINTN Height,\r
- IN UINTN Delta OPTIONAL // Number of BYTES in a row of the BltBuffer\r
- )\r
-{\r
- EFI_PIXEL_BITMASK* PixelInformation;\r
- EFI_STATUS Status;\r
- UINT32 HorizontalResolution;\r
- VOID *FrameBufferBase;\r
- UINT16 *DestinationPixel16bit;\r
- UINT16 Pixel16bit;\r
- UINT32 DestinationPixelX;\r
- UINT32 DestinationLine;\r
-\r
- Status = EFI_SUCCESS;\r
- PixelInformation = &This->Mode->Info->PixelInformation;\r
- FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));\r
- HorizontalResolution = This->Mode->Info->HorizontalResolution;\r
-\r
- // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel\r
- Pixel16bit = (UINT16) (\r
- ( (EfiSourcePixel->Red << 8) & PixelInformation->RedMask )\r
- | ( (EfiSourcePixel->Green << 3) & PixelInformation->GreenMask )\r
- | ( (EfiSourcePixel->Blue >> 3) & PixelInformation->BlueMask )\r
- );\r
-\r
- // Copy the SourcePixel into every pixel inside the target rectangle\r
- for (DestinationLine = DestinationY;\r
- DestinationLine < DestinationY + Height;\r
- DestinationLine++)\r
- {\r
- for (DestinationPixelX = DestinationX;\r
- DestinationPixelX < DestinationX + Width;\r
- DestinationPixelX++)\r
- {\r
- // Calculate the target address:\r
- DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX;\r
-\r
- // Copy the pixel into the new target\r
- *DestinationPixel16bit = Pixel16bit;\r
- }\r
- }\r
-\r
-\r
- return Status;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-BltVideoToBltBuffer (\r
- IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,\r
- IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL\r
- IN UINTN SourceX,\r
- IN UINTN SourceY,\r
- IN UINTN DestinationX,\r
- IN UINTN DestinationY,\r
- IN UINTN Width,\r
- IN UINTN Height,\r
- IN UINTN Delta OPTIONAL // Number of BYTES in a row of the BltBuffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT32 HorizontalResolution;\r
- EFI_PIXEL_BITMASK *PixelInformation;\r
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL *EfiDestinationPixel;\r
- VOID *FrameBufferBase;\r
- UINT16 *SourcePixel16bit;\r
- UINT16 Pixel16bit;\r
- UINT32 SourcePixelX;\r
- UINT32 SourceLine;\r
- UINT32 DestinationPixelX;\r
- UINT32 DestinationLine;\r
- UINT32 BltBufferHorizontalResolution;\r
-\r
- Status = EFI_SUCCESS;\r
- PixelInformation = &This->Mode->Info->PixelInformation;\r
- HorizontalResolution = This->Mode->Info->HorizontalResolution;\r
- FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));\r
-\r
- if(( Delta != 0 ) && ( Delta != Width * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {\r
- // Delta is not zero and it is different from the width.\r
- // Divide it by the size of a pixel to find out the buffer's horizontal resolution.\r
- BltBufferHorizontalResolution = (UINT32) (Delta / sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
- } else {\r
- BltBufferHorizontalResolution = Width;\r
- }\r
-\r
- // Access each pixel inside the Video Memory\r
- for (SourceLine = SourceY, DestinationLine = DestinationY;\r
- SourceLine < SourceY + Height;\r
- SourceLine++, DestinationLine++)\r
- {\r
- for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;\r
- SourcePixelX < SourceX + Width;\r
- SourcePixelX++, DestinationPixelX++)\r
- {\r
- // Calculate the source and target addresses:\r
- SourcePixel16bit = (UINT16 *)FrameBufferBase + SourceLine * HorizontalResolution + SourcePixelX;\r
- EfiDestinationPixel = BltBuffer + DestinationLine * BltBufferHorizontalResolution + DestinationPixelX;\r
-\r
- // Snapshot the pixel from the video buffer once, to speed up the operation.\r
- // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.\r
- Pixel16bit = *SourcePixel16bit;\r
-\r
- // Copy the pixel into the new target\r
- EfiDestinationPixel->Red = (UINT8) ( (Pixel16bit & PixelInformation->RedMask ) >> 8 );\r
- EfiDestinationPixel->Green = (UINT8) ( (Pixel16bit & PixelInformation->GreenMask ) >> 3 );\r
- EfiDestinationPixel->Blue = (UINT8) ( (Pixel16bit & PixelInformation->BlueMask ) << 3 );\r
- }\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-BltBufferToVideo (\r
- IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,\r
- IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL\r
- IN UINTN SourceX,\r
- IN UINTN SourceY,\r
- IN UINTN DestinationX,\r
- IN UINTN DestinationY,\r
- IN UINTN Width,\r
- IN UINTN Height,\r
- IN UINTN Delta OPTIONAL // Number of BYTES in a row of the BltBuffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT32 HorizontalResolution;\r
- EFI_PIXEL_BITMASK *PixelInformation;\r
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL *EfiSourcePixel;\r
- VOID *FrameBufferBase;\r
- UINT16 *DestinationPixel16bit;\r
- UINT32 SourcePixelX;\r
- UINT32 SourceLine;\r
- UINT32 DestinationPixelX;\r
- UINT32 DestinationLine;\r
- UINT32 BltBufferHorizontalResolution;\r
-\r
- Status = EFI_SUCCESS;\r
- PixelInformation = &This->Mode->Info->PixelInformation;\r
- HorizontalResolution = This->Mode->Info->HorizontalResolution;\r
- FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));\r
-\r
- if(( Delta != 0 ) && ( Delta != Width * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {\r
- // Delta is not zero and it is different from the width.\r
- // Divide it by the size of a pixel to find out the buffer's horizontal resolution.\r
- BltBufferHorizontalResolution = (UINT32) (Delta / sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
- } else {\r
- BltBufferHorizontalResolution = Width;\r
- }\r
-\r
- // Access each pixel inside the BltBuffer Memory\r
- for (SourceLine = SourceY, DestinationLine = DestinationY;\r
- SourceLine < SourceY + Height;\r
- SourceLine++, DestinationLine++) {\r
-\r
- for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;\r
- SourcePixelX < SourceX + Width;\r
- SourcePixelX++, DestinationPixelX++)\r
- {\r
- // Calculate the source and target addresses:\r
- EfiSourcePixel = BltBuffer + SourceLine * BltBufferHorizontalResolution + SourcePixelX;\r
- DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX;\r
-\r
- // Copy the pixel into the new target\r
- // Only the most significant bits will be copied across:\r
- // To convert from 8 bits to 5 bits per pixel we throw away the 3 least significant bits\r
- *DestinationPixel16bit = (UINT16) (\r
- ( (EfiSourcePixel->Red << 8) & PixelInformation->RedMask )\r
- | ( (EfiSourcePixel->Green << 3) & PixelInformation->GreenMask )\r
- | ( (EfiSourcePixel->Blue >> 3) & PixelInformation->BlueMask )\r
- );\r
- }\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-BltVideoToVideo (\r
- IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,\r
- IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL\r
- IN UINTN SourceX,\r
- IN UINTN SourceY,\r
- IN UINTN DestinationX,\r
- IN UINTN DestinationY,\r
- IN UINTN Width,\r
- IN UINTN Height,\r
- IN UINTN Delta OPTIONAL // Number of BYTES in a row of the BltBuffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT32 HorizontalResolution;\r
- UINTN BitsPerPixel;\r
- VOID *FrameBufferBase;\r
-\r
- BitsPerPixel = 16;\r
-\r
- HorizontalResolution = This->Mode->Info->HorizontalResolution;\r
- FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));\r
-\r
- //\r
- // BltVideo to BltVideo:\r
- //\r
- // Source is the Video Memory,\r
- // Destination is the Video Memory\r
-\r
- FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));\r
-\r
- // The UEFI spec currently states:\r
- // "There is no limitation on the overlapping of the source and destination rectangles"\r
- // Therefore, we must be careful to avoid overwriting the source data\r
- if( SourceY == DestinationY ) {\r
- // Copying within the same height, e.g. horizontal shift\r
- if( SourceX == DestinationX ) {\r
- // Nothing to do\r
- Status = EFI_SUCCESS;\r
- } else if( ((SourceX>DestinationX)?(SourceX - DestinationX):(DestinationX - SourceX)) < Width ) {\r
- // There is overlap\r
- Status = VideoCopyHorizontalOverlap (BitsPerPixel, FrameBufferBase, HorizontalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height );\r
- } else {\r
- // No overlap\r
- Status = VideoCopyNoHorizontalOverlap (BitsPerPixel, FrameBufferBase, HorizontalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height );\r
- }\r
- } else {\r
- // Copying from different heights\r
- Status = VideoCopyNoHorizontalOverlap (BitsPerPixel, FrameBufferBase, HorizontalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height );\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-LcdGraphicsBlt (\r
- IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,\r
- IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL\r
- IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,\r
- IN UINTN SourceX,\r
- IN UINTN SourceY,\r
- IN UINTN DestinationX,\r
- IN UINTN DestinationY,\r
- IN UINTN Width,\r
- IN UINTN Height,\r
- IN UINTN Delta OPTIONAL // Number of BYTES in a row of the BltBuffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
- LCD_INSTANCE *Instance;\r
-\r
- Instance = LCD_INSTANCE_FROM_GOP_THIS(This);\r
-\r
- if (!mDisplayInitialized) {\r
- InitializeDisplay (Instance);\r
- }\r
-\r
- switch (BltOperation) {\r
- case EfiBltVideoFill:\r
- Status = BltVideoFill (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);\r
- break;\r
-\r
- case EfiBltVideoToBltBuffer:\r
- Status = BltVideoToBltBuffer (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);\r
- break;\r
-\r
- case EfiBltBufferToVideo:\r
- Status = BltBufferToVideo (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);\r
- break;\r
-\r
- case EfiBltVideoToVideo:\r
- Status = BltVideoToVideo (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);\r
- break;\r
-\r
- case EfiGraphicsOutputBltOperationMax:\r
- default:\r
- DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: Invalid Operation\n"));\r
- Status = EFI_INVALID_PARAMETER;\r
- break;\r
-}\r
-\r
- return Status;\r
-}\r