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 ASSERT (MergedMasks
!= 0);
69 mBltLibBytesPerPixel
= (UINTN
) ((HighBitSet32 (MergedMasks
) + 7) / 8);
71 DEBUG ((EFI_D_INFO
, "Bytes per pixel: %d\n", mBltLibBytesPerPixel
));
73 CopyMem (&mPixelBitMasks
, BitMask
, sizeof (*BitMask
));
78 Configure the FrameBufferLib instance
80 @param[in] FrameBuffer Pointer to the start of the frame buffer
81 @param[in] FrameBufferInfo Describes the frame buffer characteristics
83 @retval EFI_INVALID_PARAMETER - Invalid parameter
84 @retval EFI_UNSUPPORTED - The BltLib does not support this configuration
85 @retval EFI_SUCCESS - Blt operation success
92 IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*FrameBufferInfo
95 STATIC EFI_PIXEL_BITMASK RgbPixelMasks
=
96 { 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 };
97 STATIC EFI_PIXEL_BITMASK BgrPixelMasks
=
98 { 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 };
100 switch (FrameBufferInfo
->PixelFormat
) {
101 case PixelRedGreenBlueReserved8BitPerColor
:
102 ConfigurePixelBitMaskFormat (&RgbPixelMasks
);
104 case PixelBlueGreenRedReserved8BitPerColor
:
105 ConfigurePixelBitMaskFormat (&BgrPixelMasks
);
108 ConfigurePixelBitMaskFormat (&(FrameBufferInfo
->PixelInformation
));
111 ASSERT (FrameBufferInfo
->PixelFormat
!= PixelBltOnly
);
112 return EFI_UNSUPPORTED
;
115 return EFI_INVALID_PARAMETER
;
117 mPixelFormat
= FrameBufferInfo
->PixelFormat
;
119 mBltLibFrameBuffer
= (UINT8
*) FrameBuffer
;
120 mBltLibWidthInPixels
= (UINTN
) FrameBufferInfo
->HorizontalResolution
;
121 mBltLibHeight
= (UINTN
) FrameBufferInfo
->VerticalResolution
;
122 mBltLibWidthInBytes
= mBltLibWidthInPixels
* mBltLibBytesPerPixel
;
124 ASSERT (mBltLibWidthInBytes
< sizeof (mBltLibLineBuffer
));
131 Performs a UEFI Graphics Output Protocol Blt operation.
133 @param[in,out] BltBuffer - The data to transfer to screen
134 @param[in] BltOperation - The operation to perform
135 @param[in] SourceX - The X coordinate of the source for BltOperation
136 @param[in] SourceY - The Y coordinate of the source for BltOperation
137 @param[in] DestinationX - The X coordinate of the destination for BltOperation
138 @param[in] DestinationY - The Y coordinate of the destination for BltOperation
139 @param[in] Width - The width of a rectangle in the blt rectangle in pixels
140 @param[in] Height - The height of a rectangle in the blt rectangle in pixels
141 @param[in] Delta - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.
142 If a Delta of 0 is used, the entire BltBuffer will be operated on.
143 If a subrectangle of the BltBuffer is used, then Delta represents
144 the number of bytes in a row of the BltBuffer.
146 @retval EFI_DEVICE_ERROR - A hardware error occured
147 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
148 @retval EFI_SUCCESS - Blt operation success
154 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
155 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation
,
158 IN UINTN DestinationX
,
159 IN UINTN DestinationY
,
165 switch (BltOperation
) {
166 case EfiBltVideoToBltBuffer
:
167 return BltLibVideoToBltBufferEx (
178 case EfiBltVideoToVideo
:
179 return BltLibVideoToVideo (
188 case EfiBltVideoFill
:
189 return BltLibVideoFill (
197 case EfiBltBufferToVideo
:
198 return BltLibBufferToVideoEx (
209 return EFI_INVALID_PARAMETER
;
215 Performs a UEFI Graphics Output Protocol Blt Video Fill.
217 @param[in] Color Color to fill the region with
218 @param[in] DestinationX X location to start fill operation
219 @param[in] DestinationY Y location to start fill operation
220 @param[in] Width Width (in pixels) to fill
221 @param[in] Height Height to fill
223 @retval EFI_DEVICE_ERROR - A hardware error occured
224 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
225 @retval EFI_SUCCESS - The sizes were returned
231 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Color
,
232 IN UINTN DestinationX
,
233 IN UINTN DestinationY
,
246 BOOLEAN LineBufferReady
;
252 // BltBuffer to Video: Source is BltBuffer, destination is Video
254 if (DestinationY
+ Height
> mBltLibHeight
) {
255 DEBUG ((EFI_D_INFO
, "VideoFill: Past screen (Y)\n"));
256 return EFI_INVALID_PARAMETER
;
259 if (DestinationX
+ Width
> mBltLibWidthInPixels
) {
260 DEBUG ((EFI_D_INFO
, "VideoFill: Past screen (X)\n"));
261 return EFI_INVALID_PARAMETER
;
264 if (Width
== 0 || Height
== 0) {
265 DEBUG ((EFI_D_INFO
, "VideoFill: Width or Height is 0\n"));
266 return EFI_INVALID_PARAMETER
;
269 WidthInBytes
= Width
* mBltLibBytesPerPixel
;
271 Uint32
= *(UINT32
*) Color
;
274 (((Uint32
<< mPixelShl
[0]) >> mPixelShr
[0]) & mPixelBitMasks
.RedMask
) |
275 (((Uint32
<< mPixelShl
[1]) >> mPixelShr
[1]) & mPixelBitMasks
.GreenMask
) |
276 (((Uint32
<< mPixelShl
[2]) >> mPixelShr
[2]) & mPixelBitMasks
.BlueMask
)
278 VDEBUG ((EFI_D_INFO
, "VideoFill: color=0x%x, wide-fill=0x%x\n", Uint32
, WideFill
));
281 // If the size of the pixel data evenly divides the sizeof
282 // WideFill, then a wide fill operation can be used
285 if ((sizeof (WideFill
) % mBltLibBytesPerPixel
) == 0) {
286 for (X
= mBltLibBytesPerPixel
; X
< sizeof (WideFill
); X
++) {
287 ((UINT8
*)&WideFill
)[X
] = ((UINT8
*)&WideFill
)[X
% mBltLibBytesPerPixel
];
291 // If all the bytes in the pixel are the same value, then use
292 // a wide fill operation.
295 X
= 1, Uint8
= ((UINT8
*)&WideFill
)[0];
296 X
< mBltLibBytesPerPixel
;
298 if (Uint8
!= ((UINT8
*)&WideFill
)[X
]) {
304 SetMem ((VOID
*) &WideFill
, sizeof (WideFill
), Uint8
);
308 if (UseWideFill
&& (DestinationX
== 0) && (Width
== mBltLibWidthInPixels
)) {
309 VDEBUG ((EFI_D_INFO
, "VideoFill (wide, one-shot)\n"));
310 Offset
= DestinationY
* mBltLibWidthInPixels
;
311 Offset
= mBltLibBytesPerPixel
* Offset
;
312 BltMemDst
= (VOID
*) (mBltLibFrameBuffer
+ Offset
);
313 SizeInBytes
= WidthInBytes
* Height
;
314 if (SizeInBytes
>= 8) {
315 SetMem32 (BltMemDst
, SizeInBytes
& ~3, (UINT32
) WideFill
);
316 SizeInBytes
= SizeInBytes
& 3;
318 if (SizeInBytes
> 0) {
319 SetMem (BltMemDst
, SizeInBytes
, (UINT8
)(UINTN
) WideFill
);
322 LineBufferReady
= FALSE
;
323 for (DstY
= DestinationY
; DstY
< (Height
+ DestinationY
); DstY
++) {
324 Offset
= (DstY
* mBltLibWidthInPixels
) + DestinationX
;
325 Offset
= mBltLibBytesPerPixel
* Offset
;
326 BltMemDst
= (VOID
*) (mBltLibFrameBuffer
+ Offset
);
328 if (UseWideFill
&& (((UINTN
) BltMemDst
& 7) == 0)) {
329 VDEBUG ((EFI_D_INFO
, "VideoFill (wide)\n"));
330 SizeInBytes
= WidthInBytes
;
331 if (SizeInBytes
>= 8) {
332 SetMem64 (BltMemDst
, SizeInBytes
& ~7, WideFill
);
333 SizeInBytes
= SizeInBytes
& 7;
335 if (SizeInBytes
> 0) {
336 CopyMem (BltMemDst
, (VOID
*) &WideFill
, SizeInBytes
);
339 VDEBUG ((EFI_D_INFO
, "VideoFill (not wide)\n"));
340 if (!LineBufferReady
) {
341 CopyMem (mBltLibLineBuffer
, &WideFill
, mBltLibBytesPerPixel
);
342 for (X
= 1; X
< Width
; ) {
344 (mBltLibLineBuffer
+ (X
* mBltLibBytesPerPixel
)),
346 MIN (X
, Width
- X
) * mBltLibBytesPerPixel
348 X
= X
+ MIN (X
, Width
- X
);
350 BltMemSrc
= (VOID
*) mBltLibLineBuffer
;
351 LineBufferReady
= TRUE
;
353 CopyMem (BltMemDst
, mBltLibLineBuffer
, WidthInBytes
);
363 Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation.
365 @param[out] BltBuffer Output buffer for pixel color data
366 @param[in] SourceX X location within video
367 @param[in] SourceY Y location within video
368 @param[in] Width Width (in pixels)
369 @param[in] Height Height
371 @retval EFI_DEVICE_ERROR - A hardware error occured
372 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
373 @retval EFI_SUCCESS - The sizes were returned
378 BltLibVideoToBltBuffer (
379 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
,
386 return BltLibVideoToBltBufferEx (
400 Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation
401 with extended parameters.
403 @param[out] BltBuffer Output buffer for pixel color data
404 @param[in] SourceX X location within video
405 @param[in] SourceY Y location within video
406 @param[in] DestinationX X location within BltBuffer
407 @param[in] DestinationY Y location within BltBuffer
408 @param[in] Width Width (in pixels)
409 @param[in] Height Height
410 @param[in] Delta Number of bytes in a row of BltBuffer
412 @retval EFI_DEVICE_ERROR - A hardware error occured
413 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
414 @retval EFI_SUCCESS - The sizes were returned
419 BltLibVideoToBltBufferEx (
420 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
,
423 IN UINTN DestinationX
,
424 IN UINTN DestinationY
,
432 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Blt
;
441 // Video to BltBuffer: Source is Video, destination is BltBuffer
443 if (SourceY
+ Height
> mBltLibHeight
) {
444 return EFI_INVALID_PARAMETER
;
447 if (SourceX
+ Width
> mBltLibWidthInPixels
) {
448 return EFI_INVALID_PARAMETER
;
451 if (Width
== 0 || Height
== 0) {
452 return EFI_INVALID_PARAMETER
;
456 // If Delta is zero, then the entire BltBuffer is being used, so Delta
457 // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,
458 // the number of bytes in each row can be computed.
461 Delta
= Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
464 WidthInBytes
= Width
* mBltLibBytesPerPixel
;
467 // Video to BltBuffer: Source is Video, destination is BltBuffer
469 for (SrcY
= SourceY
, DstY
= DestinationY
; DstY
< (Height
+ DestinationY
); SrcY
++, DstY
++) {
471 Offset
= (SrcY
* mBltLibWidthInPixels
) + SourceX
;
472 Offset
= mBltLibBytesPerPixel
* Offset
;
473 BltMemSrc
= (VOID
*) (mBltLibFrameBuffer
+ Offset
);
475 if (mPixelFormat
== PixelBlueGreenRedReserved8BitPerColor
) {
478 (UINT8
*) BltBuffer
+
480 (DestinationX
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
))
483 BltMemDst
= (VOID
*) mBltLibLineBuffer
;
486 CopyMem (BltMemDst
, BltMemSrc
, WidthInBytes
);
488 if (mPixelFormat
!= PixelBlueGreenRedReserved8BitPerColor
) {
489 for (X
= 0; X
< Width
; X
++) {
490 Blt
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) ((UINT8
*) BltBuffer
+ (DstY
* Delta
) + (DestinationX
+ X
) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
491 Uint32
= *(UINT32
*) (mBltLibLineBuffer
+ (X
* mBltLibBytesPerPixel
));
494 (((Uint32
& mPixelBitMasks
.RedMask
) >> mPixelShl
[0]) << mPixelShr
[0]) |
495 (((Uint32
& mPixelBitMasks
.GreenMask
) >> mPixelShl
[1]) << mPixelShr
[1]) |
496 (((Uint32
& mPixelBitMasks
.BlueMask
) >> mPixelShl
[2]) << mPixelShr
[2])
507 Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation.
509 @param[in] BltBuffer Output buffer for pixel color data
510 @param[in] DestinationX X location within video
511 @param[in] DestinationY Y location within video
512 @param[in] Width Width (in pixels)
513 @param[in] Height Height
515 @retval EFI_DEVICE_ERROR - A hardware error occured
516 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
517 @retval EFI_SUCCESS - The sizes were returned
522 BltLibBufferToVideo (
523 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
,
524 IN UINTN DestinationX
,
525 IN UINTN DestinationY
,
530 return BltLibBufferToVideoEx (
544 Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation
545 with extended parameters.
547 @param[in] BltBuffer Output buffer for pixel color data
548 @param[in] SourceX X location within BltBuffer
549 @param[in] SourceY Y location within BltBuffer
550 @param[in] DestinationX X location within video
551 @param[in] DestinationY Y location within video
552 @param[in] Width Width (in pixels)
553 @param[in] Height Height
554 @param[in] Delta Number of bytes in a row of BltBuffer
556 @retval EFI_DEVICE_ERROR - A hardware error occured
557 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
558 @retval EFI_SUCCESS - The sizes were returned
563 BltLibBufferToVideoEx (
564 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
,
567 IN UINTN DestinationX
,
568 IN UINTN DestinationY
,
576 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Blt
;
585 // BltBuffer to Video: Source is BltBuffer, destination is Video
587 if (DestinationY
+ Height
> mBltLibHeight
) {
588 return EFI_INVALID_PARAMETER
;
591 if (DestinationX
+ Width
> mBltLibWidthInPixels
) {
592 return EFI_INVALID_PARAMETER
;
595 if (Width
== 0 || Height
== 0) {
596 return EFI_INVALID_PARAMETER
;
600 // If Delta is zero, then the entire BltBuffer is being used, so Delta
601 // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,
602 // the number of bytes in each row can be computed.
605 Delta
= Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
608 WidthInBytes
= Width
* mBltLibBytesPerPixel
;
610 for (SrcY
= SourceY
, DstY
= DestinationY
; SrcY
< (Height
+ SourceY
); SrcY
++, DstY
++) {
612 Offset
= (DstY
* mBltLibWidthInPixels
) + DestinationX
;
613 Offset
= mBltLibBytesPerPixel
* Offset
;
614 BltMemDst
= (VOID
*) (mBltLibFrameBuffer
+ Offset
);
616 if (mPixelFormat
== PixelBlueGreenRedReserved8BitPerColor
) {
617 BltMemSrc
= (VOID
*) ((UINT8
*) BltBuffer
+ (SrcY
* Delta
));
619 for (X
= 0; X
< Width
; X
++) {
621 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) (
622 (UINT8
*) BltBuffer
+
624 ((SourceX
+ X
) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
))
626 Uint32
= *(UINT32
*) Blt
;
627 *(UINT32
*) (mBltLibLineBuffer
+ (X
* mBltLibBytesPerPixel
)) =
629 (((Uint32
<< mPixelShl
[0]) >> mPixelShr
[0]) & mPixelBitMasks
.RedMask
) |
630 (((Uint32
<< mPixelShl
[1]) >> mPixelShr
[1]) & mPixelBitMasks
.GreenMask
) |
631 (((Uint32
<< mPixelShl
[2]) >> mPixelShr
[2]) & mPixelBitMasks
.BlueMask
)
634 BltMemSrc
= (VOID
*) mBltLibLineBuffer
;
637 CopyMem (BltMemDst
, BltMemSrc
, WidthInBytes
);
645 Performs a UEFI Graphics Output Protocol Blt Video to Video operation
647 @param[in] SourceX X location within video
648 @param[in] SourceY Y location within video
649 @param[in] DestinationX X location within video
650 @param[in] DestinationY Y location within video
651 @param[in] Width Width (in pixels)
652 @param[in] Height Height
654 @retval EFI_DEVICE_ERROR - A hardware error occured
655 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
656 @retval EFI_SUCCESS - The sizes were returned
664 IN UINTN DestinationX
,
665 IN UINTN DestinationY
,
677 // Video to Video: Source is Video, destination is Video
679 if (SourceY
+ Height
> mBltLibHeight
) {
680 return EFI_INVALID_PARAMETER
;
683 if (SourceX
+ Width
> mBltLibWidthInPixels
) {
684 return EFI_INVALID_PARAMETER
;
687 if (DestinationY
+ Height
> mBltLibHeight
) {
688 return EFI_INVALID_PARAMETER
;
691 if (DestinationX
+ Width
> mBltLibWidthInPixels
) {
692 return EFI_INVALID_PARAMETER
;
695 if (Width
== 0 || Height
== 0) {
696 return EFI_INVALID_PARAMETER
;
699 WidthInBytes
= Width
* mBltLibBytesPerPixel
;
701 Offset
= (SourceY
* mBltLibWidthInPixels
) + SourceX
;
702 Offset
= mBltLibBytesPerPixel
* Offset
;
703 BltMemSrc
= (VOID
*) (mBltLibFrameBuffer
+ Offset
);
705 Offset
= (DestinationY
* mBltLibWidthInPixels
) + DestinationX
;
706 Offset
= mBltLibBytesPerPixel
* Offset
;
707 BltMemDst
= (VOID
*) (mBltLibFrameBuffer
+ Offset
);
709 LineStride
= mBltLibWidthInBytes
;
710 if ((UINTN
) BltMemDst
> (UINTN
) BltMemSrc
) {
711 LineStride
= -LineStride
;
715 CopyMem (BltMemDst
, BltMemSrc
, WidthInBytes
);
717 BltMemSrc
= (VOID
*) ((UINT8
*) BltMemSrc
+ LineStride
);
718 BltMemDst
= (VOID
*) ((UINT8
*) BltMemDst
+ LineStride
);
727 Returns the sizes related to the video device
729 @param[out] Width Width (in pixels)
730 @param[out] Height Height (in pixels)
732 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
733 @retval EFI_SUCCESS - The sizes were returned
739 OUT UINTN
*Width
, OPTIONAL
740 OUT UINTN
*Height OPTIONAL
744 *Width
= mBltLibWidthInPixels
;
746 if (Height
!= NULL
) {
747 *Height
= mBltLibHeight
;