REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the ArmPlatformPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Andrew Fish <afish@apple.com>
		
			
				
	
	
		
			900 lines
		
	
	
		
			35 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			900 lines
		
	
	
		
			35 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
| 
 | |
|  Copyright (c) 2011 - 2020, Arm Limited. All rights reserved.<BR>
 | |
|  SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
|  **/
 | |
| 
 | |
| #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;
 | |
|   UINTN       SourceLine;
 | |
|   UINTN       DestinationLine;
 | |
|   UINTN       WidthInBytes;
 | |
|   UINTN       LineCount;
 | |
|   INTN        Step;
 | |
|   VOID        *SourceAddr;
 | |
|   VOID        *DestinationAddr;
 | |
| 
 | |
|   Status = EFI_SUCCESS;
 | |
| 
 | |
|   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;
 | |
|   }
 | |
| 
 | |
|   switch (BitsPerPixel) {
 | |
|     case LcdBitsPerPixel_24:
 | |
| 
 | |
|       WidthInBytes = Width * 4;
 | |
| 
 | |
|       for ( LineCount = 0; LineCount < Height; LineCount++ ) {
 | |
|         // Update the start addresses of source & destination using 32bit pointer arithmetic
 | |
|         SourceAddr      = (VOID *)((UINT32 *)FrameBufferBase + SourceLine      * HorizontalResolution + SourceX);
 | |
|         DestinationAddr = (VOID *)((UINT32 *)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;
 | |
|       }
 | |
| 
 | |
|       break;
 | |
| 
 | |
|     case LcdBitsPerPixel_16_555:
 | |
|     case LcdBitsPerPixel_16_565:
 | |
|     case LcdBitsPerPixel_12_444:
 | |
| 
 | |
|       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;
 | |
|       }
 | |
| 
 | |
|       break;
 | |
| 
 | |
|     case LcdBitsPerPixel_8:
 | |
|     case LcdBitsPerPixel_4:
 | |
|     case LcdBitsPerPixel_2:
 | |
|     case LcdBitsPerPixel_1:
 | |
|     default:
 | |
|       // Can't handle this case
 | |
|       DEBUG ((DEBUG_ERROR, "ArmVeGraphics_Blt: EfiBltVideoToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel));
 | |
|       Status = EFI_INVALID_PARAMETER;
 | |
|       goto EXIT;
 | |
|       // break;
 | |
|   }
 | |
| 
 | |
| EXIT:
 | |
|   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;
 | |
| 
 | |
|   UINT32  *PixelBuffer32bit;
 | |
|   UINT32  *SourcePixel32bit;
 | |
|   UINT32  *DestinationPixel32bit;
 | |
| 
 | |
|   UINT16  *PixelBuffer16bit;
 | |
|   UINT16  *SourcePixel16bit;
 | |
|   UINT16  *DestinationPixel16bit;
 | |
| 
 | |
|   UINT32  SourcePixelY;
 | |
|   UINT32  DestinationPixelY;
 | |
|   UINTN   SizeIn32Bits;
 | |
|   UINTN   SizeIn16Bits;
 | |
| 
 | |
|   Status = EFI_SUCCESS;
 | |
| 
 | |
|   switch (BitsPerPixel) {
 | |
|     case LcdBitsPerPixel_24:
 | |
|       // Allocate a temporary buffer
 | |
| 
 | |
|       PixelBuffer32bit = (UINT32 *)AllocatePool ((Height * Width) * sizeof (UINT32));
 | |
| 
 | |
|       if (PixelBuffer32bit == NULL) {
 | |
|         Status = EFI_OUT_OF_RESOURCES;
 | |
|         goto EXIT;
 | |
|       }
 | |
| 
 | |
|       SizeIn32Bits = Width * 4;
 | |
| 
 | |
|       // Copy from the video ram (source region) to a temp buffer
 | |
|       for (SourcePixelY = SourceY, DestinationPixel32bit = PixelBuffer32bit;
 | |
|            SourcePixelY < SourceY + Height;
 | |
|            SourcePixelY++, DestinationPixel32bit += Width)
 | |
|       {
 | |
|         // Update the start address of line Y (source)
 | |
|         SourcePixel32bit = (UINT32 *)FrameBufferBase + SourcePixelY * HorizontalResolution + SourceX;
 | |
| 
 | |
|         // Copy the entire line Y from video ram to the temp buffer
 | |
|         CopyMem ((VOID *)DestinationPixel32bit, (CONST VOID *)SourcePixel32bit, SizeIn32Bits);
 | |
|       }
 | |
| 
 | |
|       // Copy from the temp buffer to the video ram (destination region)
 | |
|       for (DestinationPixelY = DestinationY, SourcePixel32bit = PixelBuffer32bit;
 | |
|            DestinationPixelY < DestinationY + Height;
 | |
|            DestinationPixelY++, SourcePixel32bit += Width)
 | |
|       {
 | |
|         // Update the start address of line Y (target)
 | |
|         DestinationPixel32bit = (UINT32 *)FrameBufferBase + DestinationPixelY * HorizontalResolution + DestinationX;
 | |
| 
 | |
|         // Copy the entire line Y from the temp buffer to video ram
 | |
|         CopyMem ((VOID *)DestinationPixel32bit, (CONST VOID *)SourcePixel32bit, SizeIn32Bits);
 | |
|       }
 | |
| 
 | |
|       // Free up the allocated memory
 | |
|       FreePool ((VOID *)PixelBuffer32bit);
 | |
| 
 | |
|       break;
 | |
| 
 | |
|     case LcdBitsPerPixel_16_555:
 | |
|     case LcdBitsPerPixel_16_565:
 | |
|     case LcdBitsPerPixel_12_444:
 | |
|       // 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);
 | |
| 
 | |
|       break;
 | |
| 
 | |
|     case LcdBitsPerPixel_8:
 | |
|     case LcdBitsPerPixel_4:
 | |
|     case LcdBitsPerPixel_2:
 | |
|     case LcdBitsPerPixel_1:
 | |
|     default:
 | |
|       // Can't handle this case
 | |
|       DEBUG ((DEBUG_ERROR, "ArmVeGraphics_Blt: EfiBltVideoToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel));
 | |
|       Status = EFI_INVALID_PARAMETER;
 | |
|       goto EXIT;
 | |
|       // break;
 | |
|   }
 | |
| 
 | |
| 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;
 | |
|   LCD_BPP            BitsPerPixel;
 | |
|   VOID               *FrameBufferBase;
 | |
|   VOID               *DestinationAddr;
 | |
|   UINT16             *DestinationPixel16bit;
 | |
|   UINT16             Pixel16bit;
 | |
|   UINT32             DestinationPixelX;
 | |
|   UINT32             DestinationLine;
 | |
|   UINTN              WidthInBytes;
 | |
| 
 | |
|   Status               = EFI_SUCCESS;
 | |
|   PixelInformation     = &This->Mode->Info->PixelInformation;
 | |
|   FrameBufferBase      = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
 | |
|   HorizontalResolution = This->Mode->Info->HorizontalResolution;
 | |
| 
 | |
|   LcdPlatformGetBpp (This->Mode->Mode, &BitsPerPixel);
 | |
| 
 | |
|   switch (BitsPerPixel) {
 | |
|     case LcdBitsPerPixel_24:
 | |
|       WidthInBytes = Width * 4;
 | |
| 
 | |
|       // Copy the SourcePixel into every pixel inside the target rectangle
 | |
|       for (DestinationLine = DestinationY;
 | |
|            DestinationLine < DestinationY + Height;
 | |
|            DestinationLine++)
 | |
|       {
 | |
|         // Calculate the target address using 32bit pointer arithmetic:
 | |
|         DestinationAddr = (VOID *)((UINT32 *)FrameBufferBase + DestinationLine * HorizontalResolution  + DestinationX);
 | |
| 
 | |
|         // Fill the entire line
 | |
|         SetMem32 (DestinationAddr, WidthInBytes, *((UINT32 *)EfiSourcePixel));
 | |
|       }
 | |
| 
 | |
|       break;
 | |
| 
 | |
|     case LcdBitsPerPixel_16_555:
 | |
|       // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
 | |
|       Pixel16bit = (UINT16)(
 | |
|                             ((EfiSourcePixel->Red      <<  7) & PixelInformation->RedMask)
 | |
|                             | ((EfiSourcePixel->Green    <<  2) & PixelInformation->GreenMask)
 | |
|                             | ((EfiSourcePixel->Blue     >>  3) & PixelInformation->BlueMask)
 | |
|                             //      | ( 0                           & PixelInformation->ReservedMask )
 | |
|                             );
 | |
| 
 | |
|       // 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;
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       break;
 | |
| 
 | |
|     case LcdBitsPerPixel_16_565:
 | |
|       // 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;
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       break;
 | |
| 
 | |
|     case LcdBitsPerPixel_12_444:
 | |
|       // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
 | |
|       Pixel16bit = (UINT16)(
 | |
|                             ((EfiSourcePixel->Red      >> 4) & PixelInformation->RedMask)
 | |
|                             | ((EfiSourcePixel->Green) & PixelInformation->GreenMask)
 | |
|                             | ((EfiSourcePixel->Blue     << 4) & 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;
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       break;
 | |
| 
 | |
|     case LcdBitsPerPixel_8:
 | |
|     case LcdBitsPerPixel_4:
 | |
|     case LcdBitsPerPixel_2:
 | |
|     case LcdBitsPerPixel_1:
 | |
|     default:
 | |
|       // Can't handle this case
 | |
|       DEBUG ((DEBUG_ERROR, "LcdGraphicsBlt: EfiBltVideoFill: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel));
 | |
|       Status = EFI_INVALID_PARAMETER;
 | |
|       break;
 | |
|   }
 | |
| 
 | |
|   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;
 | |
|   LCD_BPP                        BitsPerPixel;
 | |
|   EFI_PIXEL_BITMASK              *PixelInformation;
 | |
|   EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *EfiDestinationPixel;
 | |
|   VOID                           *FrameBufferBase;
 | |
|   VOID                           *SourceAddr;
 | |
|   VOID                           *DestinationAddr;
 | |
|   UINT16                         *SourcePixel16bit;
 | |
|   UINT16                         Pixel16bit;
 | |
|   UINT32                         SourcePixelX;
 | |
|   UINT32                         SourceLine;
 | |
|   UINT32                         DestinationPixelX;
 | |
|   UINT32                         DestinationLine;
 | |
|   UINT32                         BltBufferHorizontalResolution;
 | |
|   UINTN                          WidthInBytes;
 | |
| 
 | |
|   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;
 | |
|   }
 | |
| 
 | |
|   LcdPlatformGetBpp (This->Mode->Mode, &BitsPerPixel);
 | |
| 
 | |
|   switch (BitsPerPixel) {
 | |
|     case LcdBitsPerPixel_24:
 | |
|       WidthInBytes = Width * 4;
 | |
| 
 | |
|       // Access each line inside the Video Memory
 | |
|       for (SourceLine = SourceY, DestinationLine = DestinationY;
 | |
|            SourceLine < SourceY + Height;
 | |
|            SourceLine++, DestinationLine++)
 | |
|       {
 | |
|         // Calculate the source and target addresses using 32bit pointer arithmetic:
 | |
|         SourceAddr      = (VOID *)((UINT32 *)FrameBufferBase + SourceLine      * HorizontalResolution          + SourceX);
 | |
|         DestinationAddr = (VOID *)((UINT32 *)BltBuffer       + DestinationLine * BltBufferHorizontalResolution + DestinationX);
 | |
| 
 | |
|         // Copy the entire line
 | |
|         CopyMem (DestinationAddr, SourceAddr, WidthInBytes);
 | |
|       }
 | |
| 
 | |
|       break;
 | |
| 
 | |
|     case LcdBitsPerPixel_16_555:
 | |
|       // 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) >>  7);
 | |
|           EfiDestinationPixel->Green = (UINT8)((Pixel16bit & PixelInformation->GreenMask) >>  2);
 | |
|           EfiDestinationPixel->Blue  = (UINT8)((Pixel16bit & PixelInformation->BlueMask) <<  3);
 | |
|           // EfiDestinationPixel->Reserved = (UINT8) 0;
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       break;
 | |
| 
 | |
|     case LcdBitsPerPixel_16_565:
 | |
|       // 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
 | |
|           // There is no info for the Reserved byte, so we set it to zero
 | |
|           EfiDestinationPixel->Red   = (UINT8)((Pixel16bit & PixelInformation->RedMask) >> 8);
 | |
|           EfiDestinationPixel->Green = (UINT8)((Pixel16bit & PixelInformation->GreenMask) >> 3);
 | |
|           EfiDestinationPixel->Blue  = (UINT8)((Pixel16bit & PixelInformation->BlueMask) << 3);
 | |
|           // EfiDestinationPixel->Reserved = (UINT8) 0;
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       break;
 | |
| 
 | |
|     case LcdBitsPerPixel_12_444:
 | |
|       // 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) >> 4);
 | |
|           EfiDestinationPixel->Green = (UINT8)((Pixel16bit & PixelInformation->GreenMask));
 | |
|           EfiDestinationPixel->Blue  = (UINT8)((Pixel16bit & PixelInformation->BlueMask) << 4);
 | |
|           // EfiDestinationPixel->Reserved = (UINT8) 0;
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       break;
 | |
| 
 | |
|     case LcdBitsPerPixel_8:
 | |
|     case LcdBitsPerPixel_4:
 | |
|     case LcdBitsPerPixel_2:
 | |
|     case LcdBitsPerPixel_1:
 | |
|     default:
 | |
|       // Can't handle this case
 | |
|       DEBUG ((DEBUG_ERROR, "LcdGraphicsBlt: EfiBltVideoToBltBuffer: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel));
 | |
|       Status = EFI_INVALID_PARAMETER;
 | |
|       break;
 | |
|   }
 | |
| 
 | |
|   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;
 | |
|   LCD_BPP                        BitsPerPixel;
 | |
|   EFI_PIXEL_BITMASK              *PixelInformation;
 | |
|   EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *EfiSourcePixel;
 | |
|   VOID                           *FrameBufferBase;
 | |
|   VOID                           *SourceAddr;
 | |
|   VOID                           *DestinationAddr;
 | |
|   UINT16                         *DestinationPixel16bit;
 | |
|   UINT32                         SourcePixelX;
 | |
|   UINT32                         SourceLine;
 | |
|   UINT32                         DestinationPixelX;
 | |
|   UINT32                         DestinationLine;
 | |
|   UINT32                         BltBufferHorizontalResolution;
 | |
|   UINTN                          WidthInBytes;
 | |
| 
 | |
|   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;
 | |
|   }
 | |
| 
 | |
|   LcdPlatformGetBpp (This->Mode->Mode, &BitsPerPixel);
 | |
| 
 | |
|   switch (BitsPerPixel) {
 | |
|     case LcdBitsPerPixel_24:
 | |
|       WidthInBytes = Width * 4;
 | |
| 
 | |
|       // Access each pixel inside the BltBuffer Memory
 | |
|       for (SourceLine = SourceY, DestinationLine = DestinationY;
 | |
|            SourceLine < SourceY + Height;
 | |
|            SourceLine++, DestinationLine++)
 | |
|       {
 | |
|         // Calculate the source and target addresses using 32bit pointer arithmetic:
 | |
|         SourceAddr      = (VOID *)((UINT32 *)BltBuffer       + SourceLine      * BltBufferHorizontalResolution + SourceX);
 | |
|         DestinationAddr = (VOID *)((UINT32 *)FrameBufferBase + DestinationLine * HorizontalResolution          + DestinationX);
 | |
| 
 | |
|         // Copy the entire row Y
 | |
|         CopyMem (DestinationAddr, SourceAddr, WidthInBytes);
 | |
|       }
 | |
| 
 | |
|       break;
 | |
| 
 | |
|     case LcdBitsPerPixel_16_555:
 | |
|       // 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      <<  7) & PixelInformation->RedMask)
 | |
|                                             | ((EfiSourcePixel->Green    <<  2) & PixelInformation->GreenMask)
 | |
|                                             | ((EfiSourcePixel->Blue     >>  3) & PixelInformation->BlueMask)
 | |
|                                             //            | ( 0                                & PixelInformation->ReservedMask )
 | |
|                                             );
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       break;
 | |
| 
 | |
|     case LcdBitsPerPixel_16_565:
 | |
|       // 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 or 6 bits per pixel we throw away the 3 or 2  least significant bits
 | |
|           // There is no room for the Reserved byte so we ignore that completely
 | |
|           *DestinationPixel16bit = (UINT16)(
 | |
|                                             ((EfiSourcePixel->Red      <<  8) & PixelInformation->RedMask)
 | |
|                                             | ((EfiSourcePixel->Green    <<  3) & PixelInformation->GreenMask)
 | |
|                                             | ((EfiSourcePixel->Blue     >>  3) & PixelInformation->BlueMask)
 | |
|                                             );
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       break;
 | |
| 
 | |
|     case LcdBitsPerPixel_12_444:
 | |
|       // 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      << 4) & PixelInformation->RedMask)
 | |
|                                             | ((EfiSourcePixel->Green) & PixelInformation->GreenMask)
 | |
|                                             | ((EfiSourcePixel->Blue     >> 4) & PixelInformation->BlueMask)
 | |
|                                             //            | ( 0                               & PixelInformation->ReservedMask )
 | |
|                                             );
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       break;
 | |
| 
 | |
|     case LcdBitsPerPixel_8:
 | |
|     case LcdBitsPerPixel_4:
 | |
|     case LcdBitsPerPixel_2:
 | |
|     case LcdBitsPerPixel_1:
 | |
|     default:
 | |
|       // Can't handle this case
 | |
|       DEBUG ((DEBUG_ERROR, "LcdGraphicsBlt: EfiBltBufferToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel));
 | |
|       Status = EFI_INVALID_PARAMETER;
 | |
|       break;
 | |
|   }
 | |
| 
 | |
|   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;
 | |
|   LCD_BPP     BitsPerPixel;
 | |
|   VOID        *FrameBufferBase;
 | |
| 
 | |
|   HorizontalResolution = This->Mode->Info->HorizontalResolution;
 | |
|   FrameBufferBase      = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
 | |
| 
 | |
|   //
 | |
|   // BltVideo to BltVideo:
 | |
|   //
 | |
|   //  Source is the Video Memory,
 | |
|   //  Destination is the Video Memory
 | |
| 
 | |
|   LcdPlatformGetBpp (This->Mode->Mode, &BitsPerPixel);
 | |
|   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;
 | |
| }
 | |
| 
 | |
| /***************************************
 | |
|  * GraphicsOutput Protocol function, mapping to
 | |
|  * EFI_GRAPHICS_OUTPUT_PROTOCOL.Blt
 | |
|  *
 | |
|  * PRESUMES: 1 pixel = 4 bytes (32bits)
 | |
|  *  ***************************************/
 | |
| 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;
 | |
|   UINT32        HorizontalResolution;
 | |
|   UINT32        VerticalResolution;
 | |
|   LCD_INSTANCE  *Instance;
 | |
| 
 | |
|   Instance = LCD_INSTANCE_FROM_GOP_THIS (This);
 | |
| 
 | |
|   // Setup the hardware if not already done
 | |
|   if (!mDisplayInitialized) {
 | |
|     Status = InitializeDisplay (Instance);
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       goto EXIT;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   HorizontalResolution = This->Mode->Info->HorizontalResolution;
 | |
|   VerticalResolution   = This->Mode->Info->VerticalResolution;
 | |
| 
 | |
|   DEBUG ((
 | |
|     DEBUG_INFO,
 | |
|     "LcdGraphicsBlt (BltOperation:%d,DestX:%d,DestY:%d,Width:%d,Height:%d) res(%d,%d)\n",
 | |
|     BltOperation,
 | |
|     DestinationX,
 | |
|     DestinationY,
 | |
|     Width,
 | |
|     Height,
 | |
|     HorizontalResolution,
 | |
|     VerticalResolution
 | |
|     ));
 | |
| 
 | |
|   // Check we have reasonable parameters
 | |
|   if ((Width == 0) || (Height == 0)) {
 | |
|     DEBUG ((DEBUG_ERROR, "LcdGraphicsBlt: ERROR - Invalid dimension: Zero size area.\n"));
 | |
|     Status = EFI_INVALID_PARAMETER;
 | |
|     goto EXIT;
 | |
|   }
 | |
| 
 | |
|   if ((BltOperation == EfiBltVideoFill) || (BltOperation == EfiBltBufferToVideo) || (BltOperation == EfiBltVideoToBltBuffer)) {
 | |
|     ASSERT (BltBuffer != NULL);
 | |
|   }
 | |
| 
 | |
|   /*if ((DestinationX >= HorizontalResolution) || (DestinationY >= VerticalResolution)) {
 | |
|     DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: ERROR - Invalid destination.\n" ));
 | |
|     Status = EFI_INVALID_PARAMETER;
 | |
|     goto EXIT;
 | |
|   }*/
 | |
| 
 | |
|   // If we are reading data out of the video buffer, check that the source area is within the display limits
 | |
|   if ((BltOperation == EfiBltVideoToBltBuffer) || (BltOperation == EfiBltVideoToVideo)) {
 | |
|     if ((SourceY + Height > VerticalResolution) || (SourceX + Width > HorizontalResolution)) {
 | |
|       DEBUG ((DEBUG_INFO, "LcdGraphicsBlt: ERROR - Invalid source resolution.\n"));
 | |
|       DEBUG ((DEBUG_INFO, "                      - SourceY=%d + Height=%d > VerticalResolution=%d.\n", SourceY, Height, VerticalResolution));
 | |
|       DEBUG ((DEBUG_INFO, "                      - SourceX=%d + Width=%d > HorizontalResolution=%d.\n", SourceX, Width, HorizontalResolution));
 | |
|       Status = EFI_INVALID_PARAMETER;
 | |
|       goto EXIT;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   // If we are writing data into the video buffer, that the destination area is within the display limits
 | |
|   if ((BltOperation == EfiBltVideoFill) || (BltOperation == EfiBltBufferToVideo) || (BltOperation == EfiBltVideoToVideo)) {
 | |
|     if ((DestinationY + Height > VerticalResolution) || (DestinationX + Width > HorizontalResolution)) {
 | |
|       DEBUG ((DEBUG_INFO, "LcdGraphicsBlt: ERROR - Invalid destination resolution.\n"));
 | |
|       DEBUG ((DEBUG_INFO, "                      - DestinationY=%d + Height=%d > VerticalResolution=%d.\n", DestinationY, Height, VerticalResolution));
 | |
|       DEBUG ((DEBUG_INFO, "                      - DestinationX=%d + Width=%d > HorizontalResolution=%d.\n", DestinationX, Width, HorizontalResolution));
 | |
|       Status = EFI_INVALID_PARAMETER;
 | |
|       goto EXIT;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Perform the Block Transfer Operation
 | |
|   //
 | |
| 
 | |
|   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;
 | |
|   }
 | |
| 
 | |
| EXIT:
 | |
|   return Status;
 | |
| }
 |