/** @file\r
FrameBufferBltLib - Library to perform blt operations on a frame buffer.\r
\r
- Copyright (c) 2007 - 2016, Intel Corporation. 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
+ Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include <Library/FrameBufferBltLib.h>\r
\r
struct FRAME_BUFFER_CONFIGURE {\r
- UINTN ColorDepth;\r
- UINTN WidthInBytes;\r
- UINTN BytesPerPixel;\r
- UINTN WidthInPixels;\r
- UINTN Height;\r
- UINT8 LineBuffer[SIZE_4KB * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)];\r
+ UINT32 PixelsPerScanLine;\r
+ UINT32 BytesPerPixel;\r
+ UINT32 Width;\r
+ UINT32 Height;\r
UINT8 *FrameBuffer;\r
EFI_GRAPHICS_PIXEL_FORMAT PixelFormat;\r
EFI_PIXEL_BITMASK PixelMasks;\r
- INTN PixelShl[4]; // R-G-B-Rsvd\r
- INTN PixelShr[4]; // R-G-B-Rsvd\r
+ INT8 PixelShl[4]; // R-G-B-Rsvd\r
+ INT8 PixelShr[4]; // R-G-B-Rsvd\r
+ UINT8 LineBuffer[0];\r
};\r
\r
CONST EFI_PIXEL_BITMASK mRgbPixelMasks = {\r
/**\r
Initialize the bit mask in frame buffer configure.\r
\r
- @param Configure The frame buffer configure.\r
- @param BitMask The bit mask of pixel.\r
+ @param BitMask The bit mask of pixel.\r
+ @param BytesPerPixel Size in bytes of pixel.\r
+ @param PixelShl Left shift array.\r
+ @param PixelShr Right shift array.\r
**/\r
VOID\r
-ConfigurePixelBitMaskFormat (\r
- IN FRAME_BUFFER_CONFIGURE *Configure,\r
- IN CONST EFI_PIXEL_BITMASK *BitMask\r
+FrameBufferBltLibConfigurePixelFormat (\r
+ IN CONST EFI_PIXEL_BITMASK *BitMask,\r
+ OUT UINT32 *BytesPerPixel,\r
+ OUT INT8 *PixelShl,\r
+ OUT INT8 *PixelShr\r
)\r
{\r
- UINTN Loop;\r
+ UINT8 Index;\r
UINT32 *Masks;\r
UINT32 MergedMasks;\r
\r
+ ASSERT (BytesPerPixel != NULL);\r
+\r
MergedMasks = 0;\r
Masks = (UINT32*) BitMask;\r
- for (Loop = 0; Loop < 3; Loop++) {\r
- ASSERT ((Loop == 3) || (Masks[Loop] != 0));\r
- ASSERT ((MergedMasks & Masks[Loop]) == 0);\r
- Configure->PixelShl[Loop] = HighBitSet32 (Masks[Loop]) - 23 + (Loop * 8);\r
- if (Configure->PixelShl[Loop] < 0) {\r
- Configure->PixelShr[Loop] = -Configure->PixelShl[Loop];\r
- Configure->PixelShl[Loop] = 0;\r
+ for (Index = 0; Index < 3; Index++) {\r
+ ASSERT ((MergedMasks & Masks[Index]) == 0);\r
+\r
+ PixelShl[Index] = (INT8) HighBitSet32 (Masks[Index]) - 23 + (Index * 8);\r
+ if (PixelShl[Index] < 0) {\r
+ PixelShr[Index] = -PixelShl[Index];\r
+ PixelShl[Index] = 0;\r
} else {\r
- Configure->PixelShr[Loop] = 0;\r
+ PixelShr[Index] = 0;\r
}\r
- MergedMasks = (UINT32) (MergedMasks | Masks[Loop]);\r
- DEBUG ((EFI_D_VERBOSE, "%d: shl:%d shr:%d mask:%x\n", Loop,\r
- Configure->PixelShl[Loop], Configure->PixelShr[Loop], Masks[Loop]));\r
+ DEBUG ((DEBUG_INFO, "%d: shl:%d shr:%d mask:%x\n", Index,\r
+ PixelShl[Index], PixelShr[Index], Masks[Index]));\r
+\r
+ MergedMasks = (UINT32) (MergedMasks | Masks[Index]);\r
}\r
MergedMasks = (UINT32) (MergedMasks | Masks[3]);\r
\r
ASSERT (MergedMasks != 0);\r
- Configure->BytesPerPixel = (UINTN) ((HighBitSet32 (MergedMasks) + 7) / 8);\r
-\r
- DEBUG ((EFI_D_VERBOSE, "Bytes per pixel: %d\n", Configure->BytesPerPixel));\r
-\r
- CopyMem (&Configure->PixelMasks, BitMask, sizeof (*BitMask));\r
+ *BytesPerPixel = (UINT32) ((HighBitSet32 (MergedMasks) + 7) / 8);\r
+ DEBUG ((DEBUG_INFO, "Bytes per pixel: %d\n", *BytesPerPixel));\r
}\r
\r
/**\r
IN OUT UINTN *ConfigureSize\r
)\r
{\r
- if (ConfigureSize == NULL) {\r
- return RETURN_INVALID_PARAMETER;\r
- }\r
-\r
- if (*ConfigureSize < sizeof (FRAME_BUFFER_CONFIGURE)) {\r
- *ConfigureSize = sizeof (FRAME_BUFFER_CONFIGURE);\r
- return RETURN_BUFFER_TOO_SMALL;\r
- }\r
+ CONST EFI_PIXEL_BITMASK *BitMask;\r
+ UINT32 BytesPerPixel;\r
+ INT8 PixelShl[4];\r
+ INT8 PixelShr[4];\r
\r
- if (Configure == NULL) {\r
+ if (ConfigureSize == NULL) {\r
return RETURN_INVALID_PARAMETER;\r
}\r
\r
switch (FrameBufferInfo->PixelFormat) {\r
case PixelRedGreenBlueReserved8BitPerColor:\r
- ConfigurePixelBitMaskFormat (Configure, &mRgbPixelMasks);\r
+ BitMask = &mRgbPixelMasks;\r
break;\r
\r
case PixelBlueGreenRedReserved8BitPerColor:\r
- ConfigurePixelBitMaskFormat (Configure, &mBgrPixelMasks);\r
+ BitMask = &mBgrPixelMasks;\r
break;\r
\r
case PixelBitMask:\r
- ConfigurePixelBitMaskFormat (Configure, &(FrameBufferInfo->PixelInformation));\r
+ BitMask = &FrameBufferInfo->PixelInformation;\r
break;\r
\r
case PixelBltOnly:\r
return RETURN_INVALID_PARAMETER;\r
}\r
\r
- Configure->PixelFormat = FrameBufferInfo->PixelFormat;\r
- Configure->FrameBuffer = (UINT8*) FrameBuffer;\r
- Configure->WidthInPixels = (UINTN) FrameBufferInfo->HorizontalResolution;\r
- Configure->Height = (UINTN) FrameBufferInfo->VerticalResolution;\r
- Configure->WidthInBytes = Configure->WidthInPixels * Configure->BytesPerPixel;\r
+ if (FrameBufferInfo->PixelsPerScanLine < FrameBufferInfo->HorizontalResolution) {\r
+ return RETURN_UNSUPPORTED;\r
+ }\r
+\r
+ FrameBufferBltLibConfigurePixelFormat (BitMask, &BytesPerPixel, PixelShl, PixelShr);\r
+\r
+ if (*ConfigureSize < sizeof (FRAME_BUFFER_CONFIGURE)\r
+ + FrameBufferInfo->HorizontalResolution * BytesPerPixel) {\r
+ *ConfigureSize = sizeof (FRAME_BUFFER_CONFIGURE)\r
+ + FrameBufferInfo->HorizontalResolution * BytesPerPixel;\r
+ return RETURN_BUFFER_TOO_SMALL;\r
+ }\r
+\r
+ if (Configure == NULL) {\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
\r
- ASSERT (Configure->WidthInBytes < sizeof (Configure->LineBuffer));\r
+ CopyMem (&Configure->PixelMasks, BitMask, sizeof (*BitMask));\r
+ CopyMem (Configure->PixelShl, PixelShl, sizeof (PixelShl));\r
+ CopyMem (Configure->PixelShr, PixelShr, sizeof (PixelShr));\r
+ Configure->BytesPerPixel = BytesPerPixel;\r
+ Configure->PixelFormat = FrameBufferInfo->PixelFormat;\r
+ Configure->FrameBuffer = (UINT8*) FrameBuffer;\r
+ Configure->Width = FrameBufferInfo->HorizontalResolution;\r
+ Configure->Height = FrameBufferInfo->VerticalResolution;\r
+ Configure->PixelsPerScanLine = FrameBufferInfo->PixelsPerScanLine;\r
\r
return RETURN_SUCCESS;\r
}\r
return RETURN_INVALID_PARAMETER;\r
}\r
\r
- if (DestinationX + Width > Configure->WidthInPixels) {\r
+ if (DestinationX + Width > Configure->Width) {\r
DEBUG ((EFI_D_VERBOSE, "VideoFill: Past screen (X)\n"));\r
return RETURN_INVALID_PARAMETER;\r
}\r
}\r
}\r
\r
- if (UseWideFill && (DestinationX == 0) && (Width == Configure->WidthInPixels)) {\r
+ if (UseWideFill && (DestinationX == 0) && (Width == Configure->PixelsPerScanLine)) {\r
DEBUG ((EFI_D_VERBOSE, "VideoFill (wide, one-shot)\n"));\r
- Offset = DestinationY * Configure->WidthInPixels;\r
+ Offset = DestinationY * Configure->PixelsPerScanLine;\r
Offset = Configure->BytesPerPixel * Offset;\r
Destination = Configure->FrameBuffer + Offset;\r
SizeInBytes = WidthInBytes * Height;\r
if (SizeInBytes >= 8) {\r
SetMem32 (Destination, SizeInBytes & ~3, (UINT32) WideFill);\r
+ Destination += SizeInBytes & ~3;\r
SizeInBytes &= 3;\r
}\r
if (SizeInBytes > 0) {\r
} else {\r
LineBufferReady = FALSE;\r
for (IndexY = DestinationY; IndexY < (Height + DestinationY); IndexY++) {\r
- Offset = (IndexY * Configure->WidthInPixels) + DestinationX;\r
+ Offset = (IndexY * Configure->PixelsPerScanLine) + DestinationX;\r
Offset = Configure->BytesPerPixel * Offset;\r
Destination = Configure->FrameBuffer + Offset;\r
\r
SizeInBytes = WidthInBytes;\r
if (SizeInBytes >= 8) {\r
SetMem64 (Destination, SizeInBytes & ~7, WideFill);\r
+ Destination += SizeInBytes & ~7;\r
SizeInBytes &= 7;\r
}\r
if (SizeInBytes > 0) {\r
return RETURN_INVALID_PARAMETER;\r
}\r
\r
- if (SourceX + Width > Configure->WidthInPixels) {\r
+ if (SourceX + Width > Configure->Width) {\r
return RETURN_INVALID_PARAMETER;\r
}\r
\r
DstY < (Height + DestinationY);\r
SrcY++, DstY++) {\r
\r
- Offset = (SrcY * Configure->WidthInPixels) + SourceX;\r
+ Offset = (SrcY * Configure->PixelsPerScanLine) + SourceX;\r
Offset = Configure->BytesPerPixel * Offset;\r
Source = Configure->FrameBuffer + Offset;\r
\r
return RETURN_INVALID_PARAMETER;\r
}\r
\r
- if (DestinationX + Width > Configure->WidthInPixels) {\r
+ if (DestinationX + Width > Configure->Width) {\r
return RETURN_INVALID_PARAMETER;\r
}\r
\r
SrcY < (Height + SourceY);\r
SrcY++, DstY++) {\r
\r
- Offset = (DstY * Configure->WidthInPixels) + DestinationX;\r
+ Offset = (DstY * Configure->PixelsPerScanLine) + DestinationX;\r
Offset = Configure->BytesPerPixel * Offset;\r
Destination = Configure->FrameBuffer + Offset;\r
\r
return RETURN_INVALID_PARAMETER;\r
}\r
\r
- if (SourceX + Width > Configure->WidthInPixels) {\r
+ if (SourceX + Width > Configure->Width) {\r
return RETURN_INVALID_PARAMETER;\r
}\r
\r
return RETURN_INVALID_PARAMETER;\r
}\r
\r
- if (DestinationX + Width > Configure->WidthInPixels) {\r
+ if (DestinationX + Width > Configure->Width) {\r
return RETURN_INVALID_PARAMETER;\r
}\r
\r
\r
WidthInBytes = Width * Configure->BytesPerPixel;\r
\r
- Offset = (SourceY * Configure->WidthInPixels) + SourceX;\r
+ Offset = (SourceY * Configure->PixelsPerScanLine) + SourceX;\r
Offset = Configure->BytesPerPixel * Offset;\r
Source = Configure->FrameBuffer + Offset;\r
\r
- Offset = (DestinationY * Configure->WidthInPixels) + DestinationX;\r
+ Offset = (DestinationY * Configure->PixelsPerScanLine) + DestinationX;\r
Offset = Configure->BytesPerPixel * Offset;\r
Destination = Configure->FrameBuffer + Offset;\r
\r
- LineStride = Configure->WidthInBytes;\r
+ LineStride = Configure->BytesPerPixel * Configure->PixelsPerScanLine;\r
if (Destination > Source) {\r
//\r
// Copy from last line to avoid source is corrupted by copying\r