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