2 FrameBufferBltLib - Library to perform blt operations on a frame buffer.
4 Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include <Library/BaseLib.h>
11 #include <Library/BaseMemoryLib.h>
12 #include <Library/BltLib.h>
13 #include <Library/DebugLib.h>
21 #define MAX_LINE_BUFFER_SIZE (SIZE_4KB * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))
23 UINTN mBltLibColorDepth
;
24 UINTN mBltLibWidthInBytes
;
25 UINTN mBltLibBytesPerPixel
;
26 UINTN mBltLibWidthInPixels
;
28 UINT8 mBltLibLineBuffer
[MAX_LINE_BUFFER_SIZE
];
29 UINT8
*mBltLibFrameBuffer
;
30 EFI_GRAPHICS_PIXEL_FORMAT mPixelFormat
;
31 EFI_PIXEL_BITMASK mPixelBitMasks
;
32 INTN mPixelShl
[4]; // R-G-B-Rsvd
33 INTN mPixelShr
[4]; // R-G-B-Rsvd
37 ConfigurePixelBitMaskFormat (
38 IN EFI_PIXEL_BITMASK
*BitMask
46 Masks
= (UINT32
*) BitMask
;
47 for (Loop
= 0; Loop
< 3; Loop
++) {
48 ASSERT ((Loop
== 3) || (Masks
[Loop
] != 0));
49 ASSERT ((MergedMasks
& Masks
[Loop
]) == 0);
50 mPixelShl
[Loop
] = HighBitSet32 (Masks
[Loop
]) - 23 + (Loop
* 8);
51 if (mPixelShl
[Loop
] < 0) {
52 mPixelShr
[Loop
] = -mPixelShl
[Loop
];
57 MergedMasks
= (UINT32
) (MergedMasks
| Masks
[Loop
]);
58 DEBUG ((EFI_D_INFO
, "%d: shl:%d shr:%d mask:%x\n", Loop
, mPixelShl
[Loop
], mPixelShr
[Loop
], Masks
[Loop
]));
60 MergedMasks
= (UINT32
) (MergedMasks
| Masks
[3]);
62 ASSERT (MergedMasks
!= 0);
63 mBltLibBytesPerPixel
= (UINTN
) ((HighBitSet32 (MergedMasks
) + 7) / 8);
65 DEBUG ((EFI_D_INFO
, "Bytes per pixel: %d\n", mBltLibBytesPerPixel
));
67 CopyMem (&mPixelBitMasks
, BitMask
, sizeof (*BitMask
));
72 Configure the FrameBufferLib instance
74 @param[in] FrameBuffer Pointer to the start of the frame buffer
75 @param[in] FrameBufferInfo Describes the frame buffer characteristics
77 @retval EFI_INVALID_PARAMETER - Invalid parameter
78 @retval EFI_UNSUPPORTED - The BltLib does not support this configuration
79 @retval EFI_SUCCESS - Blt operation success
86 IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*FrameBufferInfo
89 STATIC EFI_PIXEL_BITMASK RgbPixelMasks
=
90 { 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 };
91 STATIC EFI_PIXEL_BITMASK BgrPixelMasks
=
92 { 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 };
94 switch (FrameBufferInfo
->PixelFormat
) {
95 case PixelRedGreenBlueReserved8BitPerColor
:
96 ConfigurePixelBitMaskFormat (&RgbPixelMasks
);
98 case PixelBlueGreenRedReserved8BitPerColor
:
99 ConfigurePixelBitMaskFormat (&BgrPixelMasks
);
102 ConfigurePixelBitMaskFormat (&(FrameBufferInfo
->PixelInformation
));
105 ASSERT (FrameBufferInfo
->PixelFormat
!= PixelBltOnly
);
106 return EFI_UNSUPPORTED
;
109 return EFI_INVALID_PARAMETER
;
111 mPixelFormat
= FrameBufferInfo
->PixelFormat
;
113 mBltLibFrameBuffer
= (UINT8
*) FrameBuffer
;
114 mBltLibWidthInPixels
= (UINTN
) FrameBufferInfo
->HorizontalResolution
;
115 mBltLibHeight
= (UINTN
) FrameBufferInfo
->VerticalResolution
;
116 mBltLibWidthInBytes
= mBltLibWidthInPixels
* mBltLibBytesPerPixel
;
118 ASSERT (mBltLibWidthInBytes
< sizeof (mBltLibLineBuffer
));
125 Performs a UEFI Graphics Output Protocol Blt operation.
127 @param[in,out] BltBuffer - The data to transfer to screen
128 @param[in] BltOperation - The operation to perform
129 @param[in] SourceX - The X coordinate of the source for BltOperation
130 @param[in] SourceY - The Y coordinate of the source for BltOperation
131 @param[in] DestinationX - The X coordinate of the destination for BltOperation
132 @param[in] DestinationY - The Y coordinate of the destination for BltOperation
133 @param[in] Width - The width of a rectangle in the blt rectangle in pixels
134 @param[in] Height - The height of a rectangle in the blt rectangle in pixels
135 @param[in] Delta - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.
136 If a Delta of 0 is used, the entire BltBuffer will be operated on.
137 If a subrectangle of the BltBuffer is used, then Delta represents
138 the number of bytes in a row of the BltBuffer.
140 @retval EFI_DEVICE_ERROR - A hardware error occured
141 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
142 @retval EFI_SUCCESS - Blt operation success
148 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
149 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation
,
152 IN UINTN DestinationX
,
153 IN UINTN DestinationY
,
159 switch (BltOperation
) {
160 case EfiBltVideoToBltBuffer
:
161 return BltLibVideoToBltBufferEx (
172 case EfiBltVideoToVideo
:
173 return BltLibVideoToVideo (
182 case EfiBltVideoFill
:
183 return BltLibVideoFill (
191 case EfiBltBufferToVideo
:
192 return BltLibBufferToVideoEx (
203 return EFI_INVALID_PARAMETER
;
209 Performs a UEFI Graphics Output Protocol Blt Video Fill.
211 @param[in] Color Color to fill the region with
212 @param[in] DestinationX X location to start fill operation
213 @param[in] DestinationY Y location to start fill operation
214 @param[in] Width Width (in pixels) to fill
215 @param[in] Height Height to fill
217 @retval EFI_DEVICE_ERROR - A hardware error occured
218 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
219 @retval EFI_SUCCESS - The sizes were returned
225 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Color
,
226 IN UINTN DestinationX
,
227 IN UINTN DestinationY
,
239 BOOLEAN LineBufferReady
;
245 // BltBuffer to Video: Source is BltBuffer, destination is Video
247 if (DestinationY
+ Height
> mBltLibHeight
) {
248 DEBUG ((EFI_D_INFO
, "VideoFill: Past screen (Y)\n"));
249 return EFI_INVALID_PARAMETER
;
252 if (DestinationX
+ Width
> mBltLibWidthInPixels
) {
253 DEBUG ((EFI_D_INFO
, "VideoFill: Past screen (X)\n"));
254 return EFI_INVALID_PARAMETER
;
257 if (Width
== 0 || Height
== 0) {
258 DEBUG ((EFI_D_INFO
, "VideoFill: Width or Height is 0\n"));
259 return EFI_INVALID_PARAMETER
;
262 WidthInBytes
= Width
* mBltLibBytesPerPixel
;
264 Uint32
= *(UINT32
*) Color
;
267 (((Uint32
<< mPixelShl
[0]) >> mPixelShr
[0]) & mPixelBitMasks
.RedMask
) |
268 (((Uint32
<< mPixelShl
[1]) >> mPixelShr
[1]) & mPixelBitMasks
.GreenMask
) |
269 (((Uint32
<< mPixelShl
[2]) >> mPixelShr
[2]) & mPixelBitMasks
.BlueMask
)
271 VDEBUG ((EFI_D_INFO
, "VideoFill: color=0x%x, wide-fill=0x%x\n", Uint32
, WideFill
));
274 // If the size of the pixel data evenly divides the sizeof
275 // WideFill, then a wide fill operation can be used
278 if ((sizeof (WideFill
) % mBltLibBytesPerPixel
) == 0) {
279 for (X
= mBltLibBytesPerPixel
; X
< sizeof (WideFill
); X
++) {
280 ((UINT8
*)&WideFill
)[X
] = ((UINT8
*)&WideFill
)[X
% mBltLibBytesPerPixel
];
284 // If all the bytes in the pixel are the same value, then use
285 // a wide fill operation.
288 X
= 1, Uint8
= ((UINT8
*)&WideFill
)[0];
289 X
< mBltLibBytesPerPixel
;
291 if (Uint8
!= ((UINT8
*)&WideFill
)[X
]) {
297 SetMem ((VOID
*) &WideFill
, sizeof (WideFill
), Uint8
);
301 if (UseWideFill
&& (DestinationX
== 0) && (Width
== mBltLibWidthInPixels
)) {
302 VDEBUG ((EFI_D_INFO
, "VideoFill (wide, one-shot)\n"));
303 Offset
= DestinationY
* mBltLibWidthInPixels
;
304 Offset
= mBltLibBytesPerPixel
* Offset
;
305 BltMemDst
= (VOID
*) (mBltLibFrameBuffer
+ Offset
);
306 SizeInBytes
= WidthInBytes
* Height
;
307 if (SizeInBytes
>= 8) {
308 SetMem32 (BltMemDst
, SizeInBytes
& ~3, (UINT32
) WideFill
);
309 SizeInBytes
= SizeInBytes
& 3;
311 if (SizeInBytes
> 0) {
312 SetMem (BltMemDst
, SizeInBytes
, (UINT8
)(UINTN
) WideFill
);
315 LineBufferReady
= FALSE
;
316 for (DstY
= DestinationY
; DstY
< (Height
+ DestinationY
); DstY
++) {
317 Offset
= (DstY
* mBltLibWidthInPixels
) + DestinationX
;
318 Offset
= mBltLibBytesPerPixel
* Offset
;
319 BltMemDst
= (VOID
*) (mBltLibFrameBuffer
+ Offset
);
321 if (UseWideFill
&& (((UINTN
) BltMemDst
& 7) == 0)) {
322 VDEBUG ((EFI_D_INFO
, "VideoFill (wide)\n"));
323 SizeInBytes
= WidthInBytes
;
324 if (SizeInBytes
>= 8) {
325 SetMem64 (BltMemDst
, SizeInBytes
& ~7, WideFill
);
326 SizeInBytes
= SizeInBytes
& 7;
328 if (SizeInBytes
> 0) {
329 CopyMem (BltMemDst
, (VOID
*) &WideFill
, SizeInBytes
);
332 VDEBUG ((EFI_D_INFO
, "VideoFill (not wide)\n"));
333 if (!LineBufferReady
) {
334 CopyMem (mBltLibLineBuffer
, &WideFill
, mBltLibBytesPerPixel
);
335 for (X
= 1; X
< Width
; ) {
337 (mBltLibLineBuffer
+ (X
* mBltLibBytesPerPixel
)),
339 MIN (X
, Width
- X
) * mBltLibBytesPerPixel
341 X
= X
+ MIN (X
, Width
- X
);
343 LineBufferReady
= TRUE
;
345 CopyMem (BltMemDst
, mBltLibLineBuffer
, WidthInBytes
);
355 Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation.
357 @param[out] BltBuffer Output buffer for pixel color data
358 @param[in] SourceX X location within video
359 @param[in] SourceY Y location within video
360 @param[in] Width Width (in pixels)
361 @param[in] Height Height
363 @retval EFI_DEVICE_ERROR - A hardware error occured
364 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
365 @retval EFI_SUCCESS - The sizes were returned
370 BltLibVideoToBltBuffer (
371 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
,
378 return BltLibVideoToBltBufferEx (
392 Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation
393 with extended parameters.
395 @param[out] BltBuffer Output buffer for pixel color data
396 @param[in] SourceX X location within video
397 @param[in] SourceY Y location within video
398 @param[in] DestinationX X location within BltBuffer
399 @param[in] DestinationY Y location within BltBuffer
400 @param[in] Width Width (in pixels)
401 @param[in] Height Height
402 @param[in] Delta Number of bytes in a row of BltBuffer
404 @retval EFI_DEVICE_ERROR - A hardware error occured
405 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
406 @retval EFI_SUCCESS - The sizes were returned
411 BltLibVideoToBltBufferEx (
412 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
,
415 IN UINTN DestinationX
,
416 IN UINTN DestinationY
,
424 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Blt
;
433 // Video to BltBuffer: Source is Video, destination is BltBuffer
435 if (SourceY
+ Height
> mBltLibHeight
) {
436 return EFI_INVALID_PARAMETER
;
439 if (SourceX
+ Width
> mBltLibWidthInPixels
) {
440 return EFI_INVALID_PARAMETER
;
443 if (Width
== 0 || Height
== 0) {
444 return EFI_INVALID_PARAMETER
;
448 // If Delta is zero, then the entire BltBuffer is being used, so Delta
449 // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,
450 // the number of bytes in each row can be computed.
453 Delta
= Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
456 WidthInBytes
= Width
* mBltLibBytesPerPixel
;
459 // Video to BltBuffer: Source is Video, destination is BltBuffer
461 for (SrcY
= SourceY
, DstY
= DestinationY
; DstY
< (Height
+ DestinationY
); SrcY
++, DstY
++) {
463 Offset
= (SrcY
* mBltLibWidthInPixels
) + SourceX
;
464 Offset
= mBltLibBytesPerPixel
* Offset
;
465 BltMemSrc
= (VOID
*) (mBltLibFrameBuffer
+ Offset
);
467 if (mPixelFormat
== PixelBlueGreenRedReserved8BitPerColor
) {
470 (UINT8
*) BltBuffer
+
472 (DestinationX
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
))
475 BltMemDst
= (VOID
*) mBltLibLineBuffer
;
478 CopyMem (BltMemDst
, BltMemSrc
, WidthInBytes
);
480 if (mPixelFormat
!= PixelBlueGreenRedReserved8BitPerColor
) {
481 for (X
= 0; X
< Width
; X
++) {
482 Blt
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) ((UINT8
*) BltBuffer
+ (DstY
* Delta
) + (DestinationX
+ X
) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
483 Uint32
= *(UINT32
*) (mBltLibLineBuffer
+ (X
* mBltLibBytesPerPixel
));
486 (((Uint32
& mPixelBitMasks
.RedMask
) >> mPixelShl
[0]) << mPixelShr
[0]) |
487 (((Uint32
& mPixelBitMasks
.GreenMask
) >> mPixelShl
[1]) << mPixelShr
[1]) |
488 (((Uint32
& mPixelBitMasks
.BlueMask
) >> mPixelShl
[2]) << mPixelShr
[2])
499 Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation.
501 @param[in] BltBuffer Output buffer for pixel color data
502 @param[in] DestinationX X location within video
503 @param[in] DestinationY Y location within video
504 @param[in] Width Width (in pixels)
505 @param[in] Height Height
507 @retval EFI_DEVICE_ERROR - A hardware error occured
508 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
509 @retval EFI_SUCCESS - The sizes were returned
514 BltLibBufferToVideo (
515 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
,
516 IN UINTN DestinationX
,
517 IN UINTN DestinationY
,
522 return BltLibBufferToVideoEx (
536 Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation
537 with extended parameters.
539 @param[in] BltBuffer Output buffer for pixel color data
540 @param[in] SourceX X location within BltBuffer
541 @param[in] SourceY Y location within BltBuffer
542 @param[in] DestinationX X location within video
543 @param[in] DestinationY Y location within video
544 @param[in] Width Width (in pixels)
545 @param[in] Height Height
546 @param[in] Delta Number of bytes in a row of BltBuffer
548 @retval EFI_DEVICE_ERROR - A hardware error occured
549 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
550 @retval EFI_SUCCESS - The sizes were returned
555 BltLibBufferToVideoEx (
556 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
,
559 IN UINTN DestinationX
,
560 IN UINTN DestinationY
,
568 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Blt
;
577 // BltBuffer to Video: Source is BltBuffer, destination is Video
579 if (DestinationY
+ Height
> mBltLibHeight
) {
580 return EFI_INVALID_PARAMETER
;
583 if (DestinationX
+ Width
> mBltLibWidthInPixels
) {
584 return EFI_INVALID_PARAMETER
;
587 if (Width
== 0 || Height
== 0) {
588 return EFI_INVALID_PARAMETER
;
592 // If Delta is zero, then the entire BltBuffer is being used, so Delta
593 // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,
594 // the number of bytes in each row can be computed.
597 Delta
= Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
600 WidthInBytes
= Width
* mBltLibBytesPerPixel
;
602 for (SrcY
= SourceY
, DstY
= DestinationY
; SrcY
< (Height
+ SourceY
); SrcY
++, DstY
++) {
604 Offset
= (DstY
* mBltLibWidthInPixels
) + DestinationX
;
605 Offset
= mBltLibBytesPerPixel
* Offset
;
606 BltMemDst
= (VOID
*) (mBltLibFrameBuffer
+ Offset
);
608 if (mPixelFormat
== PixelBlueGreenRedReserved8BitPerColor
) {
609 BltMemSrc
= (VOID
*) ((UINT8
*) BltBuffer
+ (SrcY
* Delta
));
611 for (X
= 0; X
< Width
; X
++) {
613 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) (
614 (UINT8
*) BltBuffer
+
616 ((SourceX
+ X
) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
))
618 Uint32
= *(UINT32
*) Blt
;
619 *(UINT32
*) (mBltLibLineBuffer
+ (X
* mBltLibBytesPerPixel
)) =
621 (((Uint32
<< mPixelShl
[0]) >> mPixelShr
[0]) & mPixelBitMasks
.RedMask
) |
622 (((Uint32
<< mPixelShl
[1]) >> mPixelShr
[1]) & mPixelBitMasks
.GreenMask
) |
623 (((Uint32
<< mPixelShl
[2]) >> mPixelShr
[2]) & mPixelBitMasks
.BlueMask
)
626 BltMemSrc
= (VOID
*) mBltLibLineBuffer
;
629 CopyMem (BltMemDst
, BltMemSrc
, WidthInBytes
);
637 Performs a UEFI Graphics Output Protocol Blt Video to Video operation
639 @param[in] SourceX X location within video
640 @param[in] SourceY Y location within video
641 @param[in] DestinationX X location within video
642 @param[in] DestinationY Y location within video
643 @param[in] Width Width (in pixels)
644 @param[in] Height Height
646 @retval EFI_DEVICE_ERROR - A hardware error occured
647 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
648 @retval EFI_SUCCESS - The sizes were returned
656 IN UINTN DestinationX
,
657 IN UINTN DestinationY
,
669 // Video to Video: Source is Video, destination is Video
671 if (SourceY
+ Height
> mBltLibHeight
) {
672 return EFI_INVALID_PARAMETER
;
675 if (SourceX
+ Width
> mBltLibWidthInPixels
) {
676 return EFI_INVALID_PARAMETER
;
679 if (DestinationY
+ Height
> mBltLibHeight
) {
680 return EFI_INVALID_PARAMETER
;
683 if (DestinationX
+ Width
> mBltLibWidthInPixels
) {
684 return EFI_INVALID_PARAMETER
;
687 if (Width
== 0 || Height
== 0) {
688 return EFI_INVALID_PARAMETER
;
691 WidthInBytes
= Width
* mBltLibBytesPerPixel
;
693 Offset
= (SourceY
* mBltLibWidthInPixels
) + SourceX
;
694 Offset
= mBltLibBytesPerPixel
* Offset
;
695 BltMemSrc
= (VOID
*) (mBltLibFrameBuffer
+ Offset
);
697 Offset
= (DestinationY
* mBltLibWidthInPixels
) + DestinationX
;
698 Offset
= mBltLibBytesPerPixel
* Offset
;
699 BltMemDst
= (VOID
*) (mBltLibFrameBuffer
+ Offset
);
701 LineStride
= mBltLibWidthInBytes
;
702 if ((UINTN
) BltMemDst
> (UINTN
) BltMemSrc
) {
703 LineStride
= -LineStride
;
707 CopyMem (BltMemDst
, BltMemSrc
, WidthInBytes
);
709 BltMemSrc
= (VOID
*) ((UINT8
*) BltMemSrc
+ LineStride
);
710 BltMemDst
= (VOID
*) ((UINT8
*) BltMemDst
+ LineStride
);
719 Returns the sizes related to the video device
721 @param[out] Width Width (in pixels)
722 @param[out] Height Height (in pixels)
724 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
725 @retval EFI_SUCCESS - The sizes were returned
731 OUT UINTN
*Width
, OPTIONAL
732 OUT UINTN
*Height OPTIONAL
736 *Width
= mBltLibWidthInPixels
;
738 if (Height
!= NULL
) {
739 *Height
= mBltLibHeight
;