REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the MdeModulePkg 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: Liming Gao <gaoliming@byosoft.com.cn>
		
			
				
	
	
		
			739 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			739 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   FrameBufferBltLib - Library to perform blt operations on a frame buffer.
 | |
| 
 | |
|   Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include <Uefi/UefiBaseType.h>
 | |
| #include <Protocol/GraphicsOutput.h>
 | |
| 
 | |
| #include <Library/BaseLib.h>
 | |
| #include <Library/BaseMemoryLib.h>
 | |
| #include <Library/DebugLib.h>
 | |
| #include <Library/FrameBufferBltLib.h>
 | |
| 
 | |
| struct FRAME_BUFFER_CONFIGURE {
 | |
|   UINT32                       PixelsPerScanLine;
 | |
|   UINT32                       BytesPerPixel;
 | |
|   UINT32                       Width;
 | |
|   UINT32                       Height;
 | |
|   UINT8                        *FrameBuffer;
 | |
|   EFI_GRAPHICS_PIXEL_FORMAT    PixelFormat;
 | |
|   EFI_PIXEL_BITMASK            PixelMasks;
 | |
|   INT8                         PixelShl[4];    // R-G-B-Rsvd
 | |
|   INT8                         PixelShr[4];    // R-G-B-Rsvd
 | |
|   UINT8                        LineBuffer[0];
 | |
| };
 | |
| 
 | |
| CONST EFI_PIXEL_BITMASK  mRgbPixelMasks = {
 | |
|   0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000
 | |
| };
 | |
| 
 | |
| CONST EFI_PIXEL_BITMASK  mBgrPixelMasks = {
 | |
|   0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000
 | |
| };
 | |
| 
 | |
| /**
 | |
|   Initialize the bit mask in frame buffer configure.
 | |
| 
 | |
|   @param BitMask       The bit mask of pixel.
 | |
|   @param BytesPerPixel Size in bytes of pixel.
 | |
|   @param PixelShl      Left shift array.
 | |
|   @param PixelShr      Right shift array.
 | |
| **/
 | |
| VOID
 | |
| FrameBufferBltLibConfigurePixelFormat (
 | |
|   IN CONST EFI_PIXEL_BITMASK  *BitMask,
 | |
|   OUT UINT32                  *BytesPerPixel,
 | |
|   OUT INT8                    *PixelShl,
 | |
|   OUT INT8                    *PixelShr
 | |
|   )
 | |
| {
 | |
|   UINT8   Index;
 | |
|   UINT32  *Masks;
 | |
|   UINT32  MergedMasks;
 | |
| 
 | |
|   ASSERT (BytesPerPixel != NULL);
 | |
| 
 | |
|   MergedMasks = 0;
 | |
|   Masks       = (UINT32 *)BitMask;
 | |
|   for (Index = 0; Index < 3; Index++) {
 | |
|     ASSERT ((MergedMasks & Masks[Index]) == 0);
 | |
| 
 | |
|     PixelShl[Index] = (INT8)HighBitSet32 (Masks[Index]) - 23 + (Index * 8);
 | |
|     if (PixelShl[Index] < 0) {
 | |
|       PixelShr[Index] = -PixelShl[Index];
 | |
|       PixelShl[Index] = 0;
 | |
|     } else {
 | |
|       PixelShr[Index] = 0;
 | |
|     }
 | |
| 
 | |
|     DEBUG ((
 | |
|       DEBUG_INFO,
 | |
|       "%d: shl:%d shr:%d mask:%x\n",
 | |
|       Index,
 | |
|       PixelShl[Index],
 | |
|       PixelShr[Index],
 | |
|       Masks[Index]
 | |
|       ));
 | |
| 
 | |
|     MergedMasks = (UINT32)(MergedMasks | Masks[Index]);
 | |
|   }
 | |
| 
 | |
|   MergedMasks = (UINT32)(MergedMasks | Masks[3]);
 | |
| 
 | |
|   ASSERT (MergedMasks != 0);
 | |
|   *BytesPerPixel = (UINT32)((HighBitSet32 (MergedMasks) + 7) / 8);
 | |
|   DEBUG ((DEBUG_INFO, "Bytes per pixel: %d\n", *BytesPerPixel));
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Create the configuration for a video frame buffer.
 | |
| 
 | |
|   The configuration is returned in the caller provided buffer.
 | |
| 
 | |
|   @param[in] FrameBuffer       Pointer to the start of the frame buffer.
 | |
|   @param[in] FrameBufferInfo   Describes the frame buffer characteristics.
 | |
|   @param[in,out] Configure     The created configuration information.
 | |
|   @param[in,out] ConfigureSize Size of the configuration information.
 | |
| 
 | |
|   @retval RETURN_SUCCESS            The configuration was successful created.
 | |
|   @retval RETURN_BUFFER_TOO_SMALL   The Configure is to too small. The required
 | |
|                                     size is returned in ConfigureSize.
 | |
|   @retval RETURN_UNSUPPORTED        The requested mode is not supported by
 | |
|                                     this implementaion.
 | |
| 
 | |
| **/
 | |
| RETURN_STATUS
 | |
| EFIAPI
 | |
| FrameBufferBltConfigure (
 | |
|   IN     VOID                                  *FrameBuffer,
 | |
|   IN     EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *FrameBufferInfo,
 | |
|   IN OUT FRAME_BUFFER_CONFIGURE                *Configure,
 | |
|   IN OUT UINTN                                 *ConfigureSize
 | |
|   )
 | |
| {
 | |
|   CONST EFI_PIXEL_BITMASK  *BitMask;
 | |
|   UINT32                   BytesPerPixel;
 | |
|   INT8                     PixelShl[4];
 | |
|   INT8                     PixelShr[4];
 | |
| 
 | |
|   if (ConfigureSize == NULL) {
 | |
|     return RETURN_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   switch (FrameBufferInfo->PixelFormat) {
 | |
|     case PixelRedGreenBlueReserved8BitPerColor:
 | |
|       BitMask = &mRgbPixelMasks;
 | |
|       break;
 | |
| 
 | |
|     case PixelBlueGreenRedReserved8BitPerColor:
 | |
|       BitMask = &mBgrPixelMasks;
 | |
|       break;
 | |
| 
 | |
|     case PixelBitMask:
 | |
|       BitMask = &FrameBufferInfo->PixelInformation;
 | |
|       break;
 | |
| 
 | |
|     case PixelBltOnly:
 | |
|       ASSERT (FrameBufferInfo->PixelFormat != PixelBltOnly);
 | |
|       return RETURN_UNSUPPORTED;
 | |
| 
 | |
|     default:
 | |
|       ASSERT (FALSE);
 | |
|       return RETURN_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   if (FrameBufferInfo->PixelsPerScanLine < FrameBufferInfo->HorizontalResolution) {
 | |
|     return RETURN_UNSUPPORTED;
 | |
|   }
 | |
| 
 | |
|   FrameBufferBltLibConfigurePixelFormat (BitMask, &BytesPerPixel, PixelShl, PixelShr);
 | |
| 
 | |
|   if (*ConfigureSize < sizeof (FRAME_BUFFER_CONFIGURE)
 | |
|       + FrameBufferInfo->HorizontalResolution * BytesPerPixel)
 | |
|   {
 | |
|     *ConfigureSize = sizeof (FRAME_BUFFER_CONFIGURE)
 | |
|                      + FrameBufferInfo->HorizontalResolution * BytesPerPixel;
 | |
|     return RETURN_BUFFER_TOO_SMALL;
 | |
|   }
 | |
| 
 | |
|   if (Configure == NULL) {
 | |
|     return RETURN_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   CopyMem (&Configure->PixelMasks, BitMask, sizeof (*BitMask));
 | |
|   CopyMem (Configure->PixelShl, PixelShl, sizeof (PixelShl));
 | |
|   CopyMem (Configure->PixelShr, PixelShr, sizeof (PixelShr));
 | |
|   Configure->BytesPerPixel     = BytesPerPixel;
 | |
|   Configure->PixelFormat       = FrameBufferInfo->PixelFormat;
 | |
|   Configure->FrameBuffer       = (UINT8 *)FrameBuffer;
 | |
|   Configure->Width             = FrameBufferInfo->HorizontalResolution;
 | |
|   Configure->Height            = FrameBufferInfo->VerticalResolution;
 | |
|   Configure->PixelsPerScanLine = FrameBufferInfo->PixelsPerScanLine;
 | |
| 
 | |
|   return RETURN_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Performs a UEFI Graphics Output Protocol Blt Video Fill.
 | |
| 
 | |
|   @param[in]  Configure     Pointer to a configuration which was successfully
 | |
|                             created by FrameBufferBltConfigure ().
 | |
|   @param[in]  Color         Color to fill the region with.
 | |
|   @param[in]  DestinationX  X location to start fill operation.
 | |
|   @param[in]  DestinationY  Y location to start fill operation.
 | |
|   @param[in]  Width         Width (in pixels) to fill.
 | |
|   @param[in]  Height        Height to fill.
 | |
| 
 | |
|   @retval  RETURN_INVALID_PARAMETER Invalid parameter was passed in.
 | |
|   @retval  RETURN_SUCCESS           The video was filled successfully.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| FrameBufferBltLibVideoFill (
 | |
|   IN  FRAME_BUFFER_CONFIGURE         *Configure,
 | |
|   IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *Color,
 | |
|   IN  UINTN                          DestinationX,
 | |
|   IN  UINTN                          DestinationY,
 | |
|   IN  UINTN                          Width,
 | |
|   IN  UINTN                          Height
 | |
|   )
 | |
| {
 | |
|   UINTN    IndexX;
 | |
|   UINTN    IndexY;
 | |
|   UINT8    *Destination;
 | |
|   UINT8    Uint8;
 | |
|   UINT32   Uint32;
 | |
|   UINT64   WideFill;
 | |
|   BOOLEAN  UseWideFill;
 | |
|   BOOLEAN  LineBufferReady;
 | |
|   UINTN    Offset;
 | |
|   UINTN    WidthInBytes;
 | |
|   UINTN    SizeInBytes;
 | |
| 
 | |
|   //
 | |
|   // BltBuffer to Video: Source is BltBuffer, destination is Video
 | |
|   //
 | |
|   if (DestinationY + Height > Configure->Height) {
 | |
|     DEBUG ((DEBUG_VERBOSE, "VideoFill: Past screen (Y)\n"));
 | |
|     return RETURN_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   if (DestinationX + Width > Configure->Width) {
 | |
|     DEBUG ((DEBUG_VERBOSE, "VideoFill: Past screen (X)\n"));
 | |
|     return RETURN_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   if ((Width == 0) || (Height == 0)) {
 | |
|     DEBUG ((DEBUG_VERBOSE, "VideoFill: Width or Height is 0\n"));
 | |
|     return RETURN_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   WidthInBytes = Width * Configure->BytesPerPixel;
 | |
| 
 | |
|   Uint32   = *(UINT32 *)Color;
 | |
|   WideFill =
 | |
|     (UINT32)(
 | |
|              (((Uint32 << Configure->PixelShl[0]) >> Configure->PixelShr[0]) &
 | |
|               Configure->PixelMasks.RedMask) |
 | |
|              (((Uint32 << Configure->PixelShl[1]) >> Configure->PixelShr[1]) &
 | |
|               Configure->PixelMasks.GreenMask) |
 | |
|              (((Uint32 << Configure->PixelShl[2]) >> Configure->PixelShr[2]) &
 | |
|               Configure->PixelMasks.BlueMask)
 | |
|              );
 | |
|   DEBUG ((
 | |
|     DEBUG_VERBOSE,
 | |
|     "VideoFill: color=0x%x, wide-fill=0x%x\n",
 | |
|     Uint32,
 | |
|     WideFill
 | |
|     ));
 | |
| 
 | |
|   //
 | |
|   // If the size of the pixel data evenly divides the sizeof
 | |
|   // WideFill, then a wide fill operation can be used
 | |
|   //
 | |
|   UseWideFill = TRUE;
 | |
|   if ((sizeof (WideFill) % Configure->BytesPerPixel) == 0) {
 | |
|     for (IndexX = Configure->BytesPerPixel; IndexX < sizeof (WideFill); IndexX++) {
 | |
|       ((UINT8 *)&WideFill)[IndexX] = ((UINT8 *)&WideFill)[IndexX % Configure->BytesPerPixel];
 | |
|     }
 | |
|   } else {
 | |
|     //
 | |
|     // If all the bytes in the pixel are the same value, then use
 | |
|     // a wide fill operation.
 | |
|     //
 | |
|     for (
 | |
|          IndexX = 1, Uint8 = ((UINT8 *)&WideFill)[0];
 | |
|          IndexX < Configure->BytesPerPixel;
 | |
|          IndexX++)
 | |
|     {
 | |
|       if (Uint8 != ((UINT8 *)&WideFill)[IndexX]) {
 | |
|         UseWideFill = FALSE;
 | |
|         break;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     if (UseWideFill) {
 | |
|       SetMem (&WideFill, sizeof (WideFill), Uint8);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (UseWideFill && (DestinationX == 0) && (Width == Configure->PixelsPerScanLine)) {
 | |
|     DEBUG ((DEBUG_VERBOSE, "VideoFill (wide, one-shot)\n"));
 | |
|     Offset      = DestinationY * Configure->PixelsPerScanLine;
 | |
|     Offset      = Configure->BytesPerPixel * Offset;
 | |
|     Destination = Configure->FrameBuffer + Offset;
 | |
|     SizeInBytes = WidthInBytes * Height;
 | |
|     if (SizeInBytes >= 8) {
 | |
|       SetMem32 (Destination, SizeInBytes & ~3, (UINT32)WideFill);
 | |
|       Destination += SizeInBytes & ~3;
 | |
|       SizeInBytes &= 3;
 | |
|     }
 | |
| 
 | |
|     if (SizeInBytes > 0) {
 | |
|       SetMem (Destination, SizeInBytes, (UINT8)(UINTN)WideFill);
 | |
|     }
 | |
|   } else {
 | |
|     LineBufferReady = FALSE;
 | |
|     for (IndexY = DestinationY; IndexY < (Height + DestinationY); IndexY++) {
 | |
|       Offset      = (IndexY * Configure->PixelsPerScanLine) + DestinationX;
 | |
|       Offset      = Configure->BytesPerPixel * Offset;
 | |
|       Destination = Configure->FrameBuffer + Offset;
 | |
| 
 | |
|       if (UseWideFill && (((UINTN)Destination & 7) == 0)) {
 | |
|         DEBUG ((DEBUG_VERBOSE, "VideoFill (wide)\n"));
 | |
|         SizeInBytes = WidthInBytes;
 | |
|         if (SizeInBytes >= 8) {
 | |
|           SetMem64 (Destination, SizeInBytes & ~7, WideFill);
 | |
|           Destination += SizeInBytes & ~7;
 | |
|           SizeInBytes &= 7;
 | |
|         }
 | |
| 
 | |
|         if (SizeInBytes > 0) {
 | |
|           CopyMem (Destination, &WideFill, SizeInBytes);
 | |
|         }
 | |
|       } else {
 | |
|         DEBUG ((DEBUG_VERBOSE, "VideoFill (not wide)\n"));
 | |
|         if (!LineBufferReady) {
 | |
|           CopyMem (Configure->LineBuffer, &WideFill, Configure->BytesPerPixel);
 | |
|           for (IndexX = 1; IndexX < Width; ) {
 | |
|             CopyMem (
 | |
|               (Configure->LineBuffer + (IndexX * Configure->BytesPerPixel)),
 | |
|               Configure->LineBuffer,
 | |
|               MIN (IndexX, Width - IndexX) * Configure->BytesPerPixel
 | |
|               );
 | |
|             IndexX += MIN (IndexX, Width - IndexX);
 | |
|           }
 | |
| 
 | |
|           LineBufferReady = TRUE;
 | |
|         }
 | |
| 
 | |
|         CopyMem (Destination, Configure->LineBuffer, WidthInBytes);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return RETURN_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation
 | |
|   with extended parameters.
 | |
| 
 | |
|   @param[in]  Configure     Pointer to a configuration which was successfully
 | |
|                             created by FrameBufferBltConfigure ().
 | |
|   @param[out] BltBuffer     Output buffer for pixel color data.
 | |
|   @param[in]  SourceX       X location within video.
 | |
|   @param[in]  SourceY       Y location within video.
 | |
|   @param[in]  DestinationX  X location within BltBuffer.
 | |
|   @param[in]  DestinationY  Y location within BltBuffer.
 | |
|   @param[in]  Width         Width (in pixels).
 | |
|   @param[in]  Height        Height.
 | |
|   @param[in]  Delta         Number of bytes in a row of BltBuffer.
 | |
| 
 | |
|   @retval RETURN_INVALID_PARAMETER Invalid parameter were passed in.
 | |
|   @retval RETURN_SUCCESS           The Blt operation was performed successfully.
 | |
| **/
 | |
| RETURN_STATUS
 | |
| FrameBufferBltLibVideoToBltBuffer (
 | |
|   IN     FRAME_BUFFER_CONFIGURE      *Configure,
 | |
|   OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *BltBuffer,
 | |
|   IN     UINTN                       SourceX,
 | |
|   IN     UINTN                       SourceY,
 | |
|   IN     UINTN                       DestinationX,
 | |
|   IN     UINTN                       DestinationY,
 | |
|   IN     UINTN                       Width,
 | |
|   IN     UINTN                       Height,
 | |
|   IN     UINTN                       Delta
 | |
|   )
 | |
| {
 | |
|   UINTN                          DstY;
 | |
|   UINTN                          SrcY;
 | |
|   EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *Blt;
 | |
|   UINT8                          *Source;
 | |
|   UINT8                          *Destination;
 | |
|   UINTN                          IndexX;
 | |
|   UINT32                         Uint32;
 | |
|   UINTN                          Offset;
 | |
|   UINTN                          WidthInBytes;
 | |
| 
 | |
|   //
 | |
|   // Video to BltBuffer: Source is Video, destination is BltBuffer
 | |
|   //
 | |
|   if (SourceY + Height > Configure->Height) {
 | |
|     return RETURN_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   if (SourceX + Width > Configure->Width) {
 | |
|     return RETURN_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   if ((Width == 0) || (Height == 0)) {
 | |
|     return RETURN_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // If Delta is zero, then the entire BltBuffer is being used, so Delta is
 | |
|   // the number of bytes in each row of BltBuffer. Since BltBuffer is Width
 | |
|   // pixels size, the number of bytes in each row can be computed.
 | |
|   //
 | |
|   if (Delta == 0) {
 | |
|     Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
 | |
|   }
 | |
| 
 | |
|   WidthInBytes = Width * Configure->BytesPerPixel;
 | |
| 
 | |
|   //
 | |
|   // Video to BltBuffer: Source is Video, destination is BltBuffer
 | |
|   //
 | |
|   for (SrcY = SourceY, DstY = DestinationY;
 | |
|        DstY < (Height + DestinationY);
 | |
|        SrcY++, DstY++)
 | |
|   {
 | |
|     Offset = (SrcY * Configure->PixelsPerScanLine) + SourceX;
 | |
|     Offset = Configure->BytesPerPixel * Offset;
 | |
|     Source = Configure->FrameBuffer + Offset;
 | |
| 
 | |
|     if (Configure->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
 | |
|       Destination = (UINT8 *)BltBuffer + (DstY * Delta) + (DestinationX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
 | |
|     } else {
 | |
|       Destination = Configure->LineBuffer;
 | |
|     }
 | |
| 
 | |
|     CopyMem (Destination, Source, WidthInBytes);
 | |
| 
 | |
|     if (Configure->PixelFormat != PixelBlueGreenRedReserved8BitPerColor) {
 | |
|       for (IndexX = 0; IndexX < Width; IndexX++) {
 | |
|         Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)
 | |
|               ((UINT8 *)BltBuffer + (DstY * Delta) +
 | |
|                (DestinationX + IndexX) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
 | |
|         Uint32         = *(UINT32 *)(Configure->LineBuffer + (IndexX * Configure->BytesPerPixel));
 | |
|         *(UINT32 *)Blt =
 | |
|           (UINT32)(
 | |
|                    (((Uint32 & Configure->PixelMasks.RedMask) >>
 | |
|                      Configure->PixelShl[0]) << Configure->PixelShr[0]) |
 | |
|                    (((Uint32 & Configure->PixelMasks.GreenMask) >>
 | |
|                      Configure->PixelShl[1]) << Configure->PixelShr[1]) |
 | |
|                    (((Uint32 & Configure->PixelMasks.BlueMask) >>
 | |
|                      Configure->PixelShl[2]) << Configure->PixelShr[2])
 | |
|                    );
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return RETURN_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation
 | |
|   with extended parameters.
 | |
| 
 | |
|   @param[in]  Configure     Pointer to a configuration which was successfully
 | |
|                             created by FrameBufferBltConfigure ().
 | |
|   @param[in]  BltBuffer     Output buffer for pixel color data.
 | |
|   @param[in]  SourceX       X location within BltBuffer.
 | |
|   @param[in]  SourceY       Y location within BltBuffer.
 | |
|   @param[in]  DestinationX  X location within video.
 | |
|   @param[in]  DestinationY  Y location within video.
 | |
|   @param[in]  Width         Width (in pixels).
 | |
|   @param[in]  Height        Height.
 | |
|   @param[in]  Delta         Number of bytes in a row of BltBuffer.
 | |
| 
 | |
|   @retval RETURN_INVALID_PARAMETER Invalid parameter were passed in.
 | |
|   @retval RETURN_SUCCESS           The Blt operation was performed successfully.
 | |
| **/
 | |
| RETURN_STATUS
 | |
| FrameBufferBltLibBufferToVideo (
 | |
|   IN  FRAME_BUFFER_CONFIGURE         *Configure,
 | |
|   IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *BltBuffer,
 | |
|   IN  UINTN                          SourceX,
 | |
|   IN  UINTN                          SourceY,
 | |
|   IN  UINTN                          DestinationX,
 | |
|   IN  UINTN                          DestinationY,
 | |
|   IN  UINTN                          Width,
 | |
|   IN  UINTN                          Height,
 | |
|   IN  UINTN                          Delta
 | |
|   )
 | |
| {
 | |
|   UINTN                          DstY;
 | |
|   UINTN                          SrcY;
 | |
|   EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *Blt;
 | |
|   UINT8                          *Source;
 | |
|   UINT8                          *Destination;
 | |
|   UINTN                          IndexX;
 | |
|   UINT32                         Uint32;
 | |
|   UINTN                          Offset;
 | |
|   UINTN                          WidthInBytes;
 | |
| 
 | |
|   //
 | |
|   // BltBuffer to Video: Source is BltBuffer, destination is Video
 | |
|   //
 | |
|   if (DestinationY + Height > Configure->Height) {
 | |
|     return RETURN_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   if (DestinationX + Width > Configure->Width) {
 | |
|     return RETURN_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   if ((Width == 0) || (Height == 0)) {
 | |
|     return RETURN_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // If Delta is zero, then the entire BltBuffer is being used, so Delta is
 | |
|   // the number of bytes in each row of BltBuffer. Since BltBuffer is Width
 | |
|   // pixels size, the number of bytes in each row can be computed.
 | |
|   //
 | |
|   if (Delta == 0) {
 | |
|     Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
 | |
|   }
 | |
| 
 | |
|   WidthInBytes = Width * Configure->BytesPerPixel;
 | |
| 
 | |
|   for (SrcY = SourceY, DstY = DestinationY;
 | |
|        SrcY < (Height + SourceY);
 | |
|        SrcY++, DstY++)
 | |
|   {
 | |
|     Offset      = (DstY * Configure->PixelsPerScanLine) + DestinationX;
 | |
|     Offset      = Configure->BytesPerPixel * Offset;
 | |
|     Destination = Configure->FrameBuffer + Offset;
 | |
| 
 | |
|     if (Configure->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
 | |
|       Source = (UINT8 *)BltBuffer + (SrcY * Delta) + SourceX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
 | |
|     } else {
 | |
|       for (IndexX = 0; IndexX < Width; IndexX++) {
 | |
|         Blt =
 | |
|           (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)(
 | |
|                                             (UINT8 *)BltBuffer +
 | |
|                                             (SrcY * Delta) +
 | |
|                                             ((SourceX + IndexX) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))
 | |
|                                             );
 | |
|         Uint32                                                                   = *(UINT32 *)Blt;
 | |
|         *(UINT32 *)(Configure->LineBuffer + (IndexX * Configure->BytesPerPixel)) =
 | |
|           (UINT32)(
 | |
|                    (((Uint32 << Configure->PixelShl[0]) >> Configure->PixelShr[0]) &
 | |
|                     Configure->PixelMasks.RedMask) |
 | |
|                    (((Uint32 << Configure->PixelShl[1]) >> Configure->PixelShr[1]) &
 | |
|                     Configure->PixelMasks.GreenMask) |
 | |
|                    (((Uint32 << Configure->PixelShl[2]) >> Configure->PixelShr[2]) &
 | |
|                     Configure->PixelMasks.BlueMask)
 | |
|                    );
 | |
|       }
 | |
| 
 | |
|       Source = Configure->LineBuffer;
 | |
|     }
 | |
| 
 | |
|     CopyMem (Destination, Source, WidthInBytes);
 | |
|   }
 | |
| 
 | |
|   return RETURN_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Performs a UEFI Graphics Output Protocol Blt Video to Video operation
 | |
| 
 | |
|   @param[in]  Configure     Pointer to a configuration which was successfully
 | |
|                             created by FrameBufferBltConfigure ().
 | |
|   @param[in]  SourceX       X location within video.
 | |
|   @param[in]  SourceY       Y location within video.
 | |
|   @param[in]  DestinationX  X location within video.
 | |
|   @param[in]  DestinationY  Y location within video.
 | |
|   @param[in]  Width         Width (in pixels).
 | |
|   @param[in]  Height        Height.
 | |
| 
 | |
|   @retval RETURN_INVALID_PARAMETER Invalid parameter were passed in.
 | |
|   @retval RETURN_SUCCESS           The Blt operation was performed successfully.
 | |
| **/
 | |
| RETURN_STATUS
 | |
| FrameBufferBltLibVideoToVideo (
 | |
|   IN  FRAME_BUFFER_CONFIGURE  *Configure,
 | |
|   IN  UINTN                   SourceX,
 | |
|   IN  UINTN                   SourceY,
 | |
|   IN  UINTN                   DestinationX,
 | |
|   IN  UINTN                   DestinationY,
 | |
|   IN  UINTN                   Width,
 | |
|   IN  UINTN                   Height
 | |
|   )
 | |
| {
 | |
|   UINT8  *Source;
 | |
|   UINT8  *Destination;
 | |
|   UINTN  Offset;
 | |
|   UINTN  WidthInBytes;
 | |
|   INTN   LineStride;
 | |
| 
 | |
|   //
 | |
|   // Video to Video: Source is Video, destination is Video
 | |
|   //
 | |
|   if (SourceY + Height > Configure->Height) {
 | |
|     return RETURN_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   if (SourceX + Width > Configure->Width) {
 | |
|     return RETURN_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   if (DestinationY + Height > Configure->Height) {
 | |
|     return RETURN_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   if (DestinationX + Width > Configure->Width) {
 | |
|     return RETURN_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   if ((Width == 0) || (Height == 0)) {
 | |
|     return RETURN_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   WidthInBytes = Width * Configure->BytesPerPixel;
 | |
| 
 | |
|   Offset = (SourceY * Configure->PixelsPerScanLine) + SourceX;
 | |
|   Offset = Configure->BytesPerPixel * Offset;
 | |
|   Source = Configure->FrameBuffer + Offset;
 | |
| 
 | |
|   Offset      = (DestinationY * Configure->PixelsPerScanLine) + DestinationX;
 | |
|   Offset      = Configure->BytesPerPixel * Offset;
 | |
|   Destination = Configure->FrameBuffer + Offset;
 | |
| 
 | |
|   LineStride = Configure->BytesPerPixel * Configure->PixelsPerScanLine;
 | |
|   if (Destination > Source) {
 | |
|     //
 | |
|     // Copy from last line to avoid source is corrupted by copying
 | |
|     //
 | |
|     Source      += Height * LineStride;
 | |
|     Destination += Height * LineStride;
 | |
|     LineStride   = -LineStride;
 | |
|   }
 | |
| 
 | |
|   while (Height-- > 0) {
 | |
|     CopyMem (Destination, Source, WidthInBytes);
 | |
| 
 | |
|     Source      += LineStride;
 | |
|     Destination += LineStride;
 | |
|   }
 | |
| 
 | |
|   return RETURN_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Performs a UEFI Graphics Output Protocol Blt operation.
 | |
| 
 | |
|   @param[in]     Configure    Pointer to a configuration which was successfully
 | |
|                               created by FrameBufferBltConfigure ().
 | |
|   @param[in,out] BltBuffer    The data to transfer to screen.
 | |
|   @param[in]     BltOperation The operation to perform.
 | |
|   @param[in]     SourceX      The X coordinate of the source for BltOperation.
 | |
|   @param[in]     SourceY      The Y coordinate of the source for BltOperation.
 | |
|   @param[in]     DestinationX The X coordinate of the destination for
 | |
|                               BltOperation.
 | |
|   @param[in]     DestinationY The Y coordinate of the destination for
 | |
|                               BltOperation.
 | |
|   @param[in]     Width        The width of a rectangle in the blt rectangle
 | |
|                               in pixels.
 | |
|   @param[in]     Height       The height of a rectangle in the blt rectangle
 | |
|                               in pixels.
 | |
|   @param[in]     Delta        Not used for EfiBltVideoFill and
 | |
|                               EfiBltVideoToVideo operation. If a Delta of 0
 | |
|                               is used, the entire BltBuffer will be operated
 | |
|                               on. If a subrectangle of the BltBuffer is
 | |
|                               used, then Delta represents the number of
 | |
|                               bytes in a row of the BltBuffer.
 | |
| 
 | |
|   @retval RETURN_INVALID_PARAMETER Invalid parameter were passed in.
 | |
|   @retval RETURN_SUCCESS           The Blt operation was performed successfully.
 | |
| **/
 | |
| RETURN_STATUS
 | |
| EFIAPI
 | |
| FrameBufferBlt (
 | |
|   IN     FRAME_BUFFER_CONFIGURE             *Configure,
 | |
|   IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL      *BltBuffer  OPTIONAL,
 | |
|   IN     EFI_GRAPHICS_OUTPUT_BLT_OPERATION  BltOperation,
 | |
|   IN     UINTN                              SourceX,
 | |
|   IN     UINTN                              SourceY,
 | |
|   IN     UINTN                              DestinationX,
 | |
|   IN     UINTN                              DestinationY,
 | |
|   IN     UINTN                              Width,
 | |
|   IN     UINTN                              Height,
 | |
|   IN     UINTN                              Delta
 | |
|   )
 | |
| {
 | |
|   if (Configure == NULL) {
 | |
|     return RETURN_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   switch (BltOperation) {
 | |
|     case EfiBltVideoToBltBuffer:
 | |
|       return FrameBufferBltLibVideoToBltBuffer (
 | |
|                Configure,
 | |
|                BltBuffer,
 | |
|                SourceX,
 | |
|                SourceY,
 | |
|                DestinationX,
 | |
|                DestinationY,
 | |
|                Width,
 | |
|                Height,
 | |
|                Delta
 | |
|                );
 | |
| 
 | |
|     case EfiBltVideoToVideo:
 | |
|       return FrameBufferBltLibVideoToVideo (
 | |
|                Configure,
 | |
|                SourceX,
 | |
|                SourceY,
 | |
|                DestinationX,
 | |
|                DestinationY,
 | |
|                Width,
 | |
|                Height
 | |
|                );
 | |
| 
 | |
|     case EfiBltVideoFill:
 | |
|       return FrameBufferBltLibVideoFill (
 | |
|                Configure,
 | |
|                BltBuffer,
 | |
|                DestinationX,
 | |
|                DestinationY,
 | |
|                Width,
 | |
|                Height
 | |
|                );
 | |
| 
 | |
|     case EfiBltBufferToVideo:
 | |
|       return FrameBufferBltLibBufferToVideo (
 | |
|                Configure,
 | |
|                BltBuffer,
 | |
|                SourceX,
 | |
|                SourceY,
 | |
|                DestinationX,
 | |
|                DestinationY,
 | |
|                Width,
 | |
|                Height,
 | |
|                Delta
 | |
|                );
 | |
| 
 | |
|     default:
 | |
|       return RETURN_INVALID_PARAMETER;
 | |
|   }
 | |
| }
 |