2 FrameBufferBltLib - Library to perform blt operations on a frame buffer.
4 Copyright (c) 2007 - 2011, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include <Library/BaseLib.h>
17 #include <Library/BaseMemoryLib.h>
18 #include <Library/BltLib.h>
19 #include <Library/DebugLib.h>
27 #define MAX_LINE_BUFFER_SIZE (SIZE_4KB * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))
29 UINTN mBltLibColorDepth
;
30 UINTN mBltLibWidthInBytes
;
31 UINTN mBltLibBytesPerPixel
;
32 UINTN mBltLibWidthInPixels
;
34 UINT8 mBltLibLineBuffer
[MAX_LINE_BUFFER_SIZE
];
35 UINT8
*mBltLibFrameBuffer
;
36 EFI_GRAPHICS_PIXEL_FORMAT mPixelFormat
;
37 EFI_PIXEL_BITMASK mPixelBitMasks
;
38 INTN mPixelShl
[4]; // R-G-B-Rsvd
39 INTN mPixelShr
[4]; // R-G-B-Rsvd
43 ConfigurePixelBitMaskFormat (
44 IN EFI_PIXEL_BITMASK
*BitMask
52 Masks
= (UINT32
*) BitMask
;
53 for (Loop
= 0; Loop
< 3; Loop
++) {
54 ASSERT ((Loop
== 3) || (Masks
[Loop
] != 0));
55 ASSERT ((MergedMasks
& Masks
[Loop
]) == 0);
56 mPixelShl
[Loop
] = HighBitSet32 (Masks
[Loop
]) - 23 + (Loop
* 8);
57 if (mPixelShl
[Loop
] < 0) {
58 mPixelShr
[Loop
] = -mPixelShl
[Loop
];
63 MergedMasks
= (UINT32
) (MergedMasks
| Masks
[Loop
]);
64 DEBUG ((EFI_D_INFO
, "%d: shl:%d shr:%d mask:%x\n", Loop
, mPixelShl
[Loop
], mPixelShr
[Loop
], Masks
[Loop
]));
66 MergedMasks
= (UINT32
) (MergedMasks
| Masks
[3]);
68 mBltLibBytesPerPixel
= HighBitSet32 (MergedMasks
);
69 ASSERT (mBltLibBytesPerPixel
>= 0);
70 mBltLibBytesPerPixel
= (mBltLibBytesPerPixel
+ 7) / 8;
72 DEBUG ((EFI_D_INFO
, "Bytes per pixel: %d\n", mBltLibBytesPerPixel
));
74 CopyMem (&mPixelBitMasks
, BitMask
, sizeof (*BitMask
));
79 Configure the FrameBufferLib instance
81 @param[in] FrameBuffer Pointer to the start of the frame buffer
82 @param[in] FrameBufferInfo Describes the frame buffer characteristics
84 @retval EFI_INVALID_PARAMETER - Invalid parameter
85 @retval EFI_UNSUPPORTED - The BltLib does not support this configuration
86 @retval EFI_SUCCESS - Blt operation success
93 IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*FrameBufferInfo
96 STATIC EFI_PIXEL_BITMASK RgbPixelMasks
=
97 { 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 };
98 STATIC EFI_PIXEL_BITMASK BgrPixelMasks
=
99 { 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 };
101 switch (FrameBufferInfo
->PixelFormat
) {
102 case PixelRedGreenBlueReserved8BitPerColor
:
103 ConfigurePixelBitMaskFormat (&RgbPixelMasks
);
105 case PixelBlueGreenRedReserved8BitPerColor
:
106 ConfigurePixelBitMaskFormat (&BgrPixelMasks
);
109 ConfigurePixelBitMaskFormat (&(FrameBufferInfo
->PixelInformation
));
112 ASSERT (FrameBufferInfo
->PixelFormat
!= PixelBltOnly
);
113 return EFI_UNSUPPORTED
;
116 return EFI_INVALID_PARAMETER
;
118 mPixelFormat
= FrameBufferInfo
->PixelFormat
;
120 mBltLibFrameBuffer
= (UINT8
*) FrameBuffer
;
121 mBltLibWidthInPixels
= (UINTN
) FrameBufferInfo
->HorizontalResolution
;
122 mBltLibHeight
= (UINTN
) FrameBufferInfo
->VerticalResolution
;
123 mBltLibWidthInBytes
= mBltLibWidthInPixels
* mBltLibBytesPerPixel
;
125 ASSERT (mBltLibWidthInBytes
< sizeof (mBltLibLineBuffer
));
132 Performs a UEFI Graphics Output Protocol Blt operation.
134 @param[in,out] BltBuffer - The data to transfer to screen
135 @param[in] BltOperation - The operation to perform
136 @param[in] SourceX - The X coordinate of the source for BltOperation
137 @param[in] SourceY - The Y coordinate of the source for BltOperation
138 @param[in] DestinationX - The X coordinate of the destination for BltOperation
139 @param[in] DestinationY - The Y coordinate of the destination for BltOperation
140 @param[in] Width - The width of a rectangle in the blt rectangle in pixels
141 @param[in] Height - The height of a rectangle in the blt rectangle in pixels
142 @param[in] Delta - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.
143 If a Delta of 0 is used, the entire BltBuffer will be operated on.
144 If a subrectangle of the BltBuffer is used, then Delta represents
145 the number of bytes in a row of the BltBuffer.
147 @retval EFI_DEVICE_ERROR - A hardware error occured
148 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
149 @retval EFI_SUCCESS - Blt operation success
155 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
156 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation
,
159 IN UINTN DestinationX
,
160 IN UINTN DestinationY
,
166 switch (BltOperation
) {
167 case EfiBltVideoToBltBuffer
:
168 return BltLibVideoToBltBufferEx (
179 case EfiBltVideoToVideo
:
180 return BltLibVideoToVideo (
189 case EfiBltVideoFill
:
190 return BltLibVideoFill (
198 case EfiBltBufferToVideo
:
199 return BltLibBufferToVideoEx (
210 return EFI_INVALID_PARAMETER
;
216 Performs a UEFI Graphics Output Protocol Blt Video Fill.
218 @param[in] Color Color to fill the region with
219 @param[in] DestinationX X location to start fill operation
220 @param[in] DestinationY Y location to start fill operation
221 @param[in] Width Width (in pixels) to fill
222 @param[in] Height Height to fill
224 @retval EFI_DEVICE_ERROR - A hardware error occured
225 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
226 @retval EFI_SUCCESS - The sizes were returned
232 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Color
,
233 IN UINTN DestinationX
,
234 IN UINTN DestinationY
,
247 BOOLEAN LineBufferReady
;
253 // BltBuffer to Video: Source is BltBuffer, destination is Video
255 if (DestinationY
+ Height
> mBltLibHeight
) {
256 DEBUG ((EFI_D_INFO
, "VideoFill: Past screen (Y)\n"));
257 return EFI_INVALID_PARAMETER
;
260 if (DestinationX
+ Width
> mBltLibWidthInPixels
) {
261 DEBUG ((EFI_D_INFO
, "VideoFill: Past screen (X)\n"));
262 return EFI_INVALID_PARAMETER
;
265 if (Width
== 0 || Height
== 0) {
266 DEBUG ((EFI_D_INFO
, "VideoFill: Width or Height is 0\n"));
267 return EFI_INVALID_PARAMETER
;
270 WidthInBytes
= Width
* mBltLibBytesPerPixel
;
272 Uint32
= *(UINT32
*) Color
;
275 (((Uint32
<< mPixelShl
[0]) >> mPixelShr
[0]) & mPixelBitMasks
.RedMask
) |
276 (((Uint32
<< mPixelShl
[1]) >> mPixelShr
[1]) & mPixelBitMasks
.GreenMask
) |
277 (((Uint32
<< mPixelShl
[2]) >> mPixelShr
[2]) & mPixelBitMasks
.BlueMask
)
279 VDEBUG ((EFI_D_INFO
, "VideoFill: color=0x%x, wide-fill=0x%x\n", Uint32
, WideFill
));
282 // If the size of the pixel data evenly divides the sizeof
283 // WideFill, then a wide fill operation can be used
286 if ((sizeof (WideFill
) % mBltLibBytesPerPixel
) == 0) {
287 for (X
= mBltLibBytesPerPixel
; X
< sizeof (WideFill
); X
++) {
288 ((UINT8
*)&WideFill
)[X
] = ((UINT8
*)&WideFill
)[X
% mBltLibBytesPerPixel
];
292 // If all the bytes in the pixel are the same value, then use
293 // a wide fill operation.
296 X
= 1, Uint8
= ((UINT8
*)&WideFill
)[0];
297 X
< mBltLibBytesPerPixel
;
299 if (Uint8
!= ((UINT8
*)&WideFill
)[X
]) {
305 SetMem ((VOID
*) &WideFill
, sizeof (WideFill
), Uint8
);
309 if (UseWideFill
&& (DestinationX
== 0) && (Width
== mBltLibWidthInPixels
)) {
310 VDEBUG ((EFI_D_INFO
, "VideoFill (wide, one-shot)\n"));
311 Offset
= DestinationY
* mBltLibWidthInPixels
;
312 Offset
= mBltLibBytesPerPixel
* Offset
;
313 BltMemDst
= (VOID
*) (mBltLibFrameBuffer
+ Offset
);
314 SizeInBytes
= WidthInBytes
* Height
;
315 if (SizeInBytes
>= 8) {
316 SetMem32 (BltMemDst
, SizeInBytes
& ~3, (UINT32
) WideFill
);
317 SizeInBytes
= SizeInBytes
& 3;
319 if (SizeInBytes
> 0) {
320 SetMem (BltMemDst
, SizeInBytes
, (UINT8
)(UINTN
) WideFill
);
323 LineBufferReady
= FALSE
;
324 for (DstY
= DestinationY
; DstY
< (Height
+ DestinationY
); DstY
++) {
325 Offset
= (DstY
* mBltLibWidthInPixels
) + DestinationX
;
326 Offset
= mBltLibBytesPerPixel
* Offset
;
327 BltMemDst
= (VOID
*) (mBltLibFrameBuffer
+ Offset
);
329 if (UseWideFill
&& (((UINTN
) BltMemDst
& 7) == 0)) {
330 VDEBUG ((EFI_D_INFO
, "VideoFill (wide)\n"));
331 SizeInBytes
= WidthInBytes
;
332 if (SizeInBytes
>= 8) {
333 SetMem64 (BltMemDst
, SizeInBytes
& ~7, WideFill
);
334 SizeInBytes
= SizeInBytes
& 7;
336 if (SizeInBytes
> 0) {
337 CopyMem (BltMemDst
, (VOID
*) &WideFill
, SizeInBytes
);
340 VDEBUG ((EFI_D_INFO
, "VideoFill (not wide)\n"));
341 if (!LineBufferReady
) {
342 CopyMem (mBltLibLineBuffer
, &WideFill
, mBltLibBytesPerPixel
);
343 for (X
= 1; X
< Width
; ) {
345 (mBltLibLineBuffer
+ (X
* mBltLibBytesPerPixel
)),
347 MIN (X
, Width
- X
) * mBltLibBytesPerPixel
349 X
= X
+ MIN (X
, Width
- X
);
351 BltMemSrc
= (VOID
*) mBltLibLineBuffer
;
352 LineBufferReady
= TRUE
;
354 CopyMem (BltMemDst
, mBltLibLineBuffer
, WidthInBytes
);
364 Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation.
366 @param[out] BltBuffer Output buffer for pixel color data
367 @param[in] SourceX X location within video
368 @param[in] SourceY Y location within video
369 @param[in] Width Width (in pixels)
370 @param[in] Height Height
372 @retval EFI_DEVICE_ERROR - A hardware error occured
373 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
374 @retval EFI_SUCCESS - The sizes were returned
379 BltLibVideoToBltBuffer (
380 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
,
387 return BltLibVideoToBltBufferEx (
401 Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation
402 with extended parameters.
404 @param[out] BltBuffer Output buffer for pixel color data
405 @param[in] SourceX X location within video
406 @param[in] SourceY Y location within video
407 @param[in] DestinationX X location within BltBuffer
408 @param[in] DestinationY Y location within BltBuffer
409 @param[in] Width Width (in pixels)
410 @param[in] Height Height
411 @param[in] Delta Number of bytes in a row of BltBuffer
413 @retval EFI_DEVICE_ERROR - A hardware error occured
414 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
415 @retval EFI_SUCCESS - The sizes were returned
420 BltLibVideoToBltBufferEx (
421 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
,
424 IN UINTN DestinationX
,
425 IN UINTN DestinationY
,
433 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Blt
;
442 // Video to BltBuffer: Source is Video, destination is BltBuffer
444 if (SourceY
+ Height
> mBltLibHeight
) {
445 return EFI_INVALID_PARAMETER
;
448 if (SourceX
+ Width
> mBltLibWidthInPixels
) {
449 return EFI_INVALID_PARAMETER
;
452 if (Width
== 0 || Height
== 0) {
453 return EFI_INVALID_PARAMETER
;
457 // If Delta is zero, then the entire BltBuffer is being used, so Delta
458 // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,
459 // the number of bytes in each row can be computed.
462 Delta
= Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
465 WidthInBytes
= Width
* mBltLibBytesPerPixel
;
468 // Video to BltBuffer: Source is Video, destination is BltBuffer
470 for (SrcY
= SourceY
, DstY
= DestinationY
; DstY
< (Height
+ DestinationY
); SrcY
++, DstY
++) {
472 Offset
= (SrcY
* mBltLibWidthInPixels
) + SourceX
;
473 Offset
= mBltLibBytesPerPixel
* Offset
;
474 BltMemSrc
= (VOID
*) (mBltLibFrameBuffer
+ Offset
);
476 if (mPixelFormat
== PixelBlueGreenRedReserved8BitPerColor
) {
479 (UINT8
*) BltBuffer
+
481 (DestinationX
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
))
484 BltMemDst
= (VOID
*) mBltLibLineBuffer
;
487 CopyMem (BltMemDst
, BltMemSrc
, WidthInBytes
);
489 if (mPixelFormat
!= PixelBlueGreenRedReserved8BitPerColor
) {
490 for (X
= 0; X
< Width
; X
++) {
491 Blt
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) ((UINT8
*) BltBuffer
+ (DstY
* Delta
) + (DestinationX
+ X
) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
492 Uint32
= *(UINT32
*) (mBltLibLineBuffer
+ (X
* mBltLibBytesPerPixel
));
495 (((Uint32
& mPixelBitMasks
.RedMask
) >> mPixelShl
[0]) << mPixelShr
[0]) |
496 (((Uint32
& mPixelBitMasks
.GreenMask
) >> mPixelShl
[1]) << mPixelShr
[1]) |
497 (((Uint32
& mPixelBitMasks
.BlueMask
) >> mPixelShl
[2]) << mPixelShr
[2])
508 Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation.
510 @param[in] BltBuffer Output buffer for pixel color data
511 @param[in] DestinationX X location within video
512 @param[in] DestinationY Y location within video
513 @param[in] Width Width (in pixels)
514 @param[in] Height Height
516 @retval EFI_DEVICE_ERROR - A hardware error occured
517 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
518 @retval EFI_SUCCESS - The sizes were returned
523 BltLibBufferToVideo (
524 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
,
525 IN UINTN DestinationX
,
526 IN UINTN DestinationY
,
531 return BltLibBufferToVideoEx (
545 Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation
546 with extended parameters.
548 @param[in] BltBuffer Output buffer for pixel color data
549 @param[in] SourceX X location within BltBuffer
550 @param[in] SourceY Y location within BltBuffer
551 @param[in] DestinationX X location within video
552 @param[in] DestinationY Y location within video
553 @param[in] Width Width (in pixels)
554 @param[in] Height Height
555 @param[in] Delta Number of bytes in a row of BltBuffer
557 @retval EFI_DEVICE_ERROR - A hardware error occured
558 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
559 @retval EFI_SUCCESS - The sizes were returned
564 BltLibBufferToVideoEx (
565 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
,
568 IN UINTN DestinationX
,
569 IN UINTN DestinationY
,
577 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Blt
;
586 // BltBuffer to Video: Source is BltBuffer, destination is Video
588 if (DestinationY
+ Height
> mBltLibHeight
) {
589 return EFI_INVALID_PARAMETER
;
592 if (DestinationX
+ Width
> mBltLibWidthInPixels
) {
593 return EFI_INVALID_PARAMETER
;
596 if (Width
== 0 || Height
== 0) {
597 return EFI_INVALID_PARAMETER
;
601 // If Delta is zero, then the entire BltBuffer is being used, so Delta
602 // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,
603 // the number of bytes in each row can be computed.
606 Delta
= Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
609 WidthInBytes
= Width
* mBltLibBytesPerPixel
;
611 for (SrcY
= SourceY
, DstY
= DestinationY
; SrcY
< (Height
+ SourceY
); SrcY
++, DstY
++) {
613 Offset
= (DstY
* mBltLibWidthInPixels
) + DestinationX
;
614 Offset
= mBltLibBytesPerPixel
* Offset
;
615 BltMemDst
= (VOID
*) (mBltLibFrameBuffer
+ Offset
);
617 if (mPixelFormat
== PixelBlueGreenRedReserved8BitPerColor
) {
618 BltMemSrc
= (VOID
*) ((UINT8
*) BltBuffer
+ (SrcY
* Delta
));
620 for (X
= 0; X
< Width
; X
++) {
622 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) (
623 (UINT8
*) BltBuffer
+
625 ((SourceX
+ X
) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
))
627 Uint32
= *(UINT32
*) Blt
;
628 *(UINT32
*) (mBltLibLineBuffer
+ (X
* mBltLibBytesPerPixel
)) =
630 (((Uint32
<< mPixelShl
[0]) >> mPixelShr
[0]) & mPixelBitMasks
.RedMask
) |
631 (((Uint32
<< mPixelShl
[1]) >> mPixelShr
[1]) & mPixelBitMasks
.GreenMask
) |
632 (((Uint32
<< mPixelShl
[2]) >> mPixelShr
[2]) & mPixelBitMasks
.BlueMask
)
635 BltMemSrc
= (VOID
*) mBltLibLineBuffer
;
638 CopyMem (BltMemDst
, BltMemSrc
, WidthInBytes
);
646 Performs a UEFI Graphics Output Protocol Blt Video to Video operation
648 @param[in] SourceX X location within video
649 @param[in] SourceY Y location within video
650 @param[in] DestinationX X location within video
651 @param[in] DestinationY Y location within video
652 @param[in] Width Width (in pixels)
653 @param[in] Height Height
655 @retval EFI_DEVICE_ERROR - A hardware error occured
656 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
657 @retval EFI_SUCCESS - The sizes were returned
665 IN UINTN DestinationX
,
666 IN UINTN DestinationY
,
678 // Video to Video: Source is Video, destination is Video
680 if (SourceY
+ Height
> mBltLibHeight
) {
681 return EFI_INVALID_PARAMETER
;
684 if (SourceX
+ Width
> mBltLibWidthInPixels
) {
685 return EFI_INVALID_PARAMETER
;
688 if (DestinationY
+ Height
> mBltLibHeight
) {
689 return EFI_INVALID_PARAMETER
;
692 if (DestinationX
+ Width
> mBltLibWidthInPixels
) {
693 return EFI_INVALID_PARAMETER
;
696 if (Width
== 0 || Height
== 0) {
697 return EFI_INVALID_PARAMETER
;
700 WidthInBytes
= Width
* mBltLibBytesPerPixel
;
702 Offset
= (SourceY
* mBltLibWidthInPixels
) + SourceX
;
703 Offset
= mBltLibBytesPerPixel
* Offset
;
704 BltMemSrc
= (VOID
*) (mBltLibFrameBuffer
+ Offset
);
706 Offset
= (DestinationY
* mBltLibWidthInPixels
) + DestinationX
;
707 Offset
= mBltLibBytesPerPixel
* Offset
;
708 BltMemDst
= (VOID
*) (mBltLibFrameBuffer
+ Offset
);
710 LineStride
= mBltLibWidthInBytes
;
711 if ((UINTN
) BltMemDst
> (UINTN
) BltMemSrc
) {
712 LineStride
= -LineStride
;
716 CopyMem (BltMemDst
, BltMemSrc
, WidthInBytes
);
718 BltMemSrc
= (VOID
*) ((UINT8
*) BltMemSrc
+ LineStride
);
719 BltMemDst
= (VOID
*) ((UINT8
*) BltMemDst
+ LineStride
);
728 Returns the sizes related to the video device
730 @param[out] Width Width (in pixels)
731 @param[out] Height Height (in pixels)
733 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
734 @retval EFI_SUCCESS - The sizes were returned
740 OUT UINTN
*Width
, OPTIONAL
741 OUT UINTN
*Height OPTIONAL
745 *Width
= mBltLibWidthInPixels
;
747 if (Height
!= NULL
) {
748 *Height
= mBltLibHeight
;