10#include <Uefi/UefiBaseType.h>
11#include <Protocol/GraphicsOutput.h>
13#include <Library/BaseLib.h>
14#include <Library/BaseMemoryLib.h>
15#include <Library/DebugLib.h>
21 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000
25 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000
39 IN CONST EFI_PIXEL_BITMASK *BitMask,
40 OUT UINT32 *BytesPerPixel,
49 ASSERT (BytesPerPixel != NULL);
52 Masks = (UINT32 *)BitMask;
53 for (Index = 0; Index < 3; Index++) {
54 ASSERT ((MergedMasks & Masks[Index]) == 0);
56 PixelShl[Index] = (INT8)HighBitSet32 (Masks[Index]) - 23 + (Index * 8);
57 if (PixelShl[Index] < 0) {
58 PixelShr[Index] = -PixelShl[Index];
66 "OCBLT: %d: shl:%d shr:%d mask:%x\n",
73 MergedMasks = (UINT32)(MergedMasks | Masks[Index]);
76 MergedMasks = (UINT32)(MergedMasks | Masks[3]);
79 *BytesPerPixel = (UINT32)((HighBitSet32 (MergedMasks) + 7) / 8);
80 DEBUG ((DEBUG_INFO,
"OCBLT: Bytes per pixel: %d\n", *BytesPerPixel));
102 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Color,
103 IN UINTN DestinationX,
104 IN UINTN DestinationY,
115 BOOLEAN LineBufferReady;
123 if (DestinationY + Height > Configure->RotatedHeight) {
124 DEBUG ((DEBUG_VERBOSE,
"OCBLT: Past screen (Y)\n"));
125 return RETURN_INVALID_PARAMETER;
128 if (DestinationX + Width > Configure->RotatedWidth) {
129 DEBUG ((DEBUG_VERBOSE,
"OCBLT: Past screen (X)\n"));
130 return RETURN_INVALID_PARAMETER;
133 if ((Width == 0) || (Height == 0)) {
134 DEBUG ((DEBUG_VERBOSE,
"OCBLT: Width or Height is 0\n"));
135 return RETURN_INVALID_PARAMETER;
138 if (Configure->Rotation == 90) {
146 DestinationX = Configure->Width - DestinationY - Width;
148 }
else if (Configure->Rotation == 180) {
152 DestinationX = Configure->Width - DestinationX - Width;
153 DestinationY = Configure->Height - DestinationY - Height;
154 }
else if (Configure->Rotation == 270) {
163 DestinationX = DestinationY;
164 DestinationY = Configure->Height - Tmp - Height;
169 Uint32 = *(UINT32 *)Color;
172 (((Uint32 << Configure->PixelShl[0]) >> Configure->PixelShr[0]) &
173 Configure->PixelMasks.RedMask) |
174 (((Uint32 << Configure->PixelShl[1]) >> Configure->PixelShr[1]) &
175 Configure->PixelMasks.GreenMask) |
176 (((Uint32 << Configure->PixelShl[2]) >> Configure->PixelShr[2]) &
177 Configure->PixelMasks.BlueMask)
179 DEBUG ((DEBUG_VERBOSE,
"OCBLT: color=0x%x, wide-fill=0x%x\n", Uint32, WideFill));
186 ((UINT8 *)&WideFill)[IndexX] = ((UINT8 *)&WideFill)[IndexX %
BYTES_PER_PIXEL];
189 if ((DestinationX == 0) && (Width == Configure->PixelsPerScanLine)) {
190 DEBUG ((DEBUG_VERBOSE,
"OCBLT: VideoFill (wide, one-shot)\n"));
191 Offset = DestinationY * Configure->PixelsPerScanLine;
193 Destination = Configure->FrameBuffer + Offset;
194 SizeInBytes = WidthInBytes * Height;
195 if (SizeInBytes >= 8) {
196 SetMem32 (Destination, SizeInBytes & ~3, (UINT32)WideFill);
197 Destination += SizeInBytes & ~3;
201 if (SizeInBytes > 0) {
202 SetMem (Destination, SizeInBytes, (UINT8)(UINTN)WideFill);
205 LineBufferReady = FALSE;
206 for (IndexY = DestinationY; IndexY < (Height + DestinationY); IndexY++) {
207 Offset = (IndexY * Configure->PixelsPerScanLine) + DestinationX;
209 Destination = Configure->FrameBuffer + Offset;
211 if (((UINTN)Destination & 7) == 0) {
212 DEBUG ((DEBUG_VERBOSE,
"OCBLT: VideoFill (wide)\n"));
213 SizeInBytes = WidthInBytes;
214 if (SizeInBytes >= 8) {
215 SetMem64 (Destination, SizeInBytes & ~7, WideFill);
216 Destination += SizeInBytes & ~7;
220 if (SizeInBytes > 0) {
221 CopyMem (Destination, &WideFill, SizeInBytes);
224 DEBUG ((DEBUG_VERBOSE,
"OCBLT: VideoFill (not wide)\n"));
225 if (!LineBufferReady) {
227 for (IndexX = 1; IndexX < Width; ) {
230 Configure->LineBuffer,
233 IndexX +=
MIN (IndexX, Width - IndexX);
236 LineBufferReady = TRUE;
239 CopyMem (Destination, Configure->LineBuffer, WidthInBytes);
244 return RETURN_SUCCESS;
269 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer,
272 IN UINTN DestinationX,
273 IN UINTN DestinationY,
282 if (SourceY + Height > Configure->RotatedHeight) {
283 return RETURN_INVALID_PARAMETER;
286 if (SourceX + Width > Configure->RotatedWidth) {
287 return RETURN_INVALID_PARAMETER;
290 if ((Width == 0) || (Height == 0)) {
291 return RETURN_INVALID_PARAMETER;
305 switch (Configure->Rotation) {
359 return RETURN_SUCCESS;
384 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer,
387 IN UINTN DestinationX,
388 IN UINTN DestinationY,
397 if (DestinationY + Height > Configure->RotatedHeight) {
398 return RETURN_INVALID_PARAMETER;
401 if (DestinationX + Width > Configure->RotatedWidth) {
402 return RETURN_INVALID_PARAMETER;
405 if ((Width == 0) || (Height == 0)) {
406 return RETURN_INVALID_PARAMETER;
420 switch (Configure->Rotation) {
474 return RETURN_SUCCESS;
498 IN UINTN DestinationX,
499 IN UINTN DestinationY,
514 if (SourceY + Height > Configure->RotatedHeight) {
515 return RETURN_INVALID_PARAMETER;
518 if (SourceX + Width > Configure->RotatedWidth) {
519 return RETURN_INVALID_PARAMETER;
522 if (DestinationY + Height > Configure->RotatedHeight) {
523 return RETURN_INVALID_PARAMETER;
526 if (DestinationX + Width > Configure->RotatedWidth) {
527 return RETURN_INVALID_PARAMETER;
530 if ((Width == 0) || (Height == 0)) {
531 return RETURN_INVALID_PARAMETER;
534 if (Configure->Rotation == 90) {
542 DestinationX = Configure->Width - DestinationY - Width;
545 SourceX = Configure->Width - SourceY - Width;
547 }
else if (Configure->Rotation == 180) {
551 DestinationX = Configure->Width - DestinationX - Width;
552 DestinationY = Configure->Height - DestinationY - Height;
553 SourceX = Configure->Width - SourceX - Width;
554 SourceY = Configure->Height - SourceY - Height;
555 }
else if (Configure->Rotation == 270) {
563 DestinationX = DestinationY;
564 DestinationY = Configure->Height - Tmp - Height;
567 SourceY = Configure->Height - Tmp - Height;
572 Offset = (SourceY * Configure->PixelsPerScanLine) + SourceX;
574 Source = Configure->FrameBuffer + Offset;
576 Offset = (DestinationY * Configure->PixelsPerScanLine) + DestinationX;
578 Destination = Configure->FrameBuffer + Offset;
581 if (Destination > Source) {
585 Source += Height * LineStride;
586 Destination += Height * LineStride;
587 LineStride = -LineStride;
590 while (Height-- > 0) {
591 CopyMem (Destination, Source, WidthInBytes);
593 Source += LineStride;
594 Destination += LineStride;
597 return RETURN_SUCCESS;
603 IN VOID *FrameBuffer,
604 IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo,
607 IN OUT UINTN *ConfigureSize
610 CONST EFI_PIXEL_BITMASK *BitMask;
611 UINT32 BytesPerPixel;
617 if (ConfigureSize == NULL) {
618 return RETURN_INVALID_PARAMETER;
621 switch (FrameBufferInfo->PixelFormat) {
622 case PixelRedGreenBlueReserved8BitPerColor:
626 case PixelBlueGreenRedReserved8BitPerColor:
631 BitMask = &FrameBufferInfo->PixelInformation;
635 ASSERT (FrameBufferInfo->PixelFormat != PixelBltOnly);
636 return RETURN_UNSUPPORTED;
640 return RETURN_INVALID_PARAMETER;
643 if (FrameBufferInfo->PixelsPerScanLine < FrameBufferInfo->HorizontalResolution) {
644 return RETURN_UNSUPPORTED;
649 if (BytesPerPixel !=
sizeof (UINT32)) {
650 return RETURN_UNSUPPORTED;
654 + FrameBufferInfo->HorizontalResolution * sizeof (UINT32))
657 + FrameBufferInfo->HorizontalResolution * sizeof (UINT32);
658 return RETURN_BUFFER_TOO_SMALL;
661 if (Configure == NULL) {
662 return RETURN_INVALID_PARAMETER;
665 CopyMem (&Configure->PixelMasks, BitMask, sizeof (*BitMask));
666 CopyMem (Configure->PixelShl, PixelShl, sizeof (PixelShl));
667 CopyMem (Configure->PixelShr, PixelShr, sizeof (PixelShr));
668 Configure->PixelFormat = FrameBufferInfo->PixelFormat;
669 Configure->FrameBuffer = (UINT8 *)FrameBuffer;
670 Configure->Width = FrameBufferInfo->HorizontalResolution;
671 Configure->Height = FrameBufferInfo->VerticalResolution;
672 Configure->PixelsPerScanLine = FrameBufferInfo->PixelsPerScanLine;
673 Configure->Rotation = Rotation;
675 if ((Rotation == 90) || (Rotation == 270)) {
676 Configure->RotatedWidth = FrameBufferInfo->VerticalResolution;
677 Configure->RotatedHeight = FrameBufferInfo->HorizontalResolution;
679 Configure->RotatedWidth = FrameBufferInfo->HorizontalResolution;
680 Configure->RotatedHeight = FrameBufferInfo->VerticalResolution;
683 return RETURN_SUCCESS;
690 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL,
691 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
694 IN UINTN DestinationX,
695 IN UINTN DestinationY,
701 ASSERT (Configure != NULL);
703 switch (BltOperation) {
704 case EfiBltVideoToBltBuffer:
717 case EfiBltVideoToVideo:
728 case EfiBltVideoFill:
738 case EfiBltBufferToVideo:
752 return RETURN_INVALID_PARAMETER;
RETURN_STATUS BlitLibBufferToVideo180(IN OC_BLIT_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 DeltaPixels)
RETURN_STATUS BlitLibBufferToVideo90(IN OC_BLIT_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 DeltaPixels)
RETURN_STATUS BlitLibBufferToVideo270(IN OC_BLIT_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 DeltaPixels)
RETURN_STATUS BlitLibBufferToVideo0(IN OC_BLIT_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 DeltaPixels)
RETURN_STATUS BlitLibVideoToBuffer90(IN OC_BLIT_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 DeltaPixels)
RETURN_STATUS BlitLibVideoToBuffer270(IN OC_BLIT_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 DeltaPixels)
RETURN_STATUS BlitLibVideoToBuffer0(IN OC_BLIT_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 DeltaPixels)
RETURN_STATUS BlitLibVideoToBuffer180(IN OC_BLIT_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 DeltaPixels)
STATIC EFI_STATUS BlitLibVideoFill(IN OC_BLIT_CONFIGURE *Configure, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Color, IN UINTN DestinationX, IN UINTN DestinationY, IN UINTN Width, IN UINTN Height)
STATIC VOID BlitLibConfigurePixelFormat(IN CONST EFI_PIXEL_BITMASK *BitMask, OUT UINT32 *BytesPerPixel, OUT INT8 *PixelShl, OUT INT8 *PixelShr)
STATIC RETURN_STATUS BlitLibVideoToVideo(IN OC_BLIT_CONFIGURE *Configure, IN UINTN SourceX, IN UINTN SourceY, IN UINTN DestinationX, IN UINTN DestinationY, IN UINTN Width, IN UINTN Height)
STATIC RETURN_STATUS BlitLibVideoToBuffer(IN OC_BLIT_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)
RETURN_STATUS EFIAPI OcBlitRender(IN OC_BLIT_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)
STATIC RETURN_STATUS BlitLibBufferToVideo(IN OC_BLIT_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)
RETURN_STATUS EFIAPI OcBlitConfigure(IN VOID *FrameBuffer, IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, IN UINT32 Rotation, IN OUT OC_BLIT_CONFIGURE *Configure, IN OUT UINTN *ConfigureSize)
STATIC CONST EFI_PIXEL_BITMASK mBgrPixelMasks
STATIC CONST EFI_PIXEL_BITMASK mRgbPixelMasks
STATIC_ASSERT(BYTES_PER_PIXEL==sizeof(UINT32), "Non 4-byte pixels are unsupported!")
struct OC_BLIT_CONFIGURE OC_BLIT_CONFIGURE
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)