2 FrameBufferBltLib - Library to perform blt operations on a frame buffer.
4 Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
5 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
,
245 BOOLEAN LineBufferReady
;
251 // BltBuffer to Video: Source is BltBuffer, destination is Video
253 if (DestinationY
+ Height
> mBltLibHeight
) {
254 DEBUG ((EFI_D_INFO
, "VideoFill: Past screen (Y)\n"));
255 return EFI_INVALID_PARAMETER
;
258 if (DestinationX
+ Width
> mBltLibWidthInPixels
) {
259 DEBUG ((EFI_D_INFO
, "VideoFill: Past screen (X)\n"));
260 return EFI_INVALID_PARAMETER
;
263 if (Width
== 0 || Height
== 0) {
264 DEBUG ((EFI_D_INFO
, "VideoFill: Width or Height is 0\n"));
265 return EFI_INVALID_PARAMETER
;
268 WidthInBytes
= Width
* mBltLibBytesPerPixel
;
270 Uint32
= *(UINT32
*) Color
;
273 (((Uint32
<< mPixelShl
[0]) >> mPixelShr
[0]) & mPixelBitMasks
.RedMask
) |
274 (((Uint32
<< mPixelShl
[1]) >> mPixelShr
[1]) & mPixelBitMasks
.GreenMask
) |
275 (((Uint32
<< mPixelShl
[2]) >> mPixelShr
[2]) & mPixelBitMasks
.BlueMask
)
277 VDEBUG ((EFI_D_INFO
, "VideoFill: color=0x%x, wide-fill=0x%x\n", Uint32
, WideFill
));
280 // If the size of the pixel data evenly divides the sizeof
281 // WideFill, then a wide fill operation can be used
284 if ((sizeof (WideFill
) % mBltLibBytesPerPixel
) == 0) {
285 for (X
= mBltLibBytesPerPixel
; X
< sizeof (WideFill
); X
++) {
286 ((UINT8
*)&WideFill
)[X
] = ((UINT8
*)&WideFill
)[X
% mBltLibBytesPerPixel
];
290 // If all the bytes in the pixel are the same value, then use
291 // a wide fill operation.
294 X
= 1, Uint8
= ((UINT8
*)&WideFill
)[0];
295 X
< mBltLibBytesPerPixel
;
297 if (Uint8
!= ((UINT8
*)&WideFill
)[X
]) {
303 SetMem ((VOID
*) &WideFill
, sizeof (WideFill
), Uint8
);
307 if (UseWideFill
&& (DestinationX
== 0) && (Width
== mBltLibWidthInPixels
)) {
308 VDEBUG ((EFI_D_INFO
, "VideoFill (wide, one-shot)\n"));
309 Offset
= DestinationY
* mBltLibWidthInPixels
;
310 Offset
= mBltLibBytesPerPixel
* Offset
;
311 BltMemDst
= (VOID
*) (mBltLibFrameBuffer
+ Offset
);
312 SizeInBytes
= WidthInBytes
* Height
;
313 if (SizeInBytes
>= 8) {
314 SetMem32 (BltMemDst
, SizeInBytes
& ~3, (UINT32
) WideFill
);
315 SizeInBytes
= SizeInBytes
& 3;
317 if (SizeInBytes
> 0) {
318 SetMem (BltMemDst
, SizeInBytes
, (UINT8
)(UINTN
) WideFill
);
321 LineBufferReady
= FALSE
;
322 for (DstY
= DestinationY
; DstY
< (Height
+ DestinationY
); DstY
++) {
323 Offset
= (DstY
* mBltLibWidthInPixels
) + DestinationX
;
324 Offset
= mBltLibBytesPerPixel
* Offset
;
325 BltMemDst
= (VOID
*) (mBltLibFrameBuffer
+ Offset
);
327 if (UseWideFill
&& (((UINTN
) BltMemDst
& 7) == 0)) {
328 VDEBUG ((EFI_D_INFO
, "VideoFill (wide)\n"));
329 SizeInBytes
= WidthInBytes
;
330 if (SizeInBytes
>= 8) {
331 SetMem64 (BltMemDst
, SizeInBytes
& ~7, WideFill
);
332 SizeInBytes
= SizeInBytes
& 7;
334 if (SizeInBytes
> 0) {
335 CopyMem (BltMemDst
, (VOID
*) &WideFill
, SizeInBytes
);
338 VDEBUG ((EFI_D_INFO
, "VideoFill (not wide)\n"));
339 if (!LineBufferReady
) {
340 CopyMem (mBltLibLineBuffer
, &WideFill
, mBltLibBytesPerPixel
);
341 for (X
= 1; X
< Width
; ) {
343 (mBltLibLineBuffer
+ (X
* mBltLibBytesPerPixel
)),
345 MIN (X
, Width
- X
) * mBltLibBytesPerPixel
347 X
= X
+ MIN (X
, Width
- X
);
349 LineBufferReady
= TRUE
;
351 CopyMem (BltMemDst
, mBltLibLineBuffer
, WidthInBytes
);
361 Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation.
363 @param[out] BltBuffer Output buffer for pixel color data
364 @param[in] SourceX X location within video
365 @param[in] SourceY Y location within video
366 @param[in] Width Width (in pixels)
367 @param[in] Height Height
369 @retval EFI_DEVICE_ERROR - A hardware error occured
370 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
371 @retval EFI_SUCCESS - The sizes were returned
376 BltLibVideoToBltBuffer (
377 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
,
384 return BltLibVideoToBltBufferEx (
398 Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation
399 with extended parameters.
401 @param[out] BltBuffer Output buffer for pixel color data
402 @param[in] SourceX X location within video
403 @param[in] SourceY Y location within video
404 @param[in] DestinationX X location within BltBuffer
405 @param[in] DestinationY Y location within BltBuffer
406 @param[in] Width Width (in pixels)
407 @param[in] Height Height
408 @param[in] Delta Number of bytes in a row of BltBuffer
410 @retval EFI_DEVICE_ERROR - A hardware error occured
411 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
412 @retval EFI_SUCCESS - The sizes were returned
417 BltLibVideoToBltBufferEx (
418 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
,
421 IN UINTN DestinationX
,
422 IN UINTN DestinationY
,
430 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Blt
;
439 // Video to BltBuffer: Source is Video, destination is BltBuffer
441 if (SourceY
+ Height
> mBltLibHeight
) {
442 return EFI_INVALID_PARAMETER
;
445 if (SourceX
+ Width
> mBltLibWidthInPixels
) {
446 return EFI_INVALID_PARAMETER
;
449 if (Width
== 0 || Height
== 0) {
450 return EFI_INVALID_PARAMETER
;
454 // If Delta is zero, then the entire BltBuffer is being used, so Delta
455 // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,
456 // the number of bytes in each row can be computed.
459 Delta
= Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
462 WidthInBytes
= Width
* mBltLibBytesPerPixel
;
465 // Video to BltBuffer: Source is Video, destination is BltBuffer
467 for (SrcY
= SourceY
, DstY
= DestinationY
; DstY
< (Height
+ DestinationY
); SrcY
++, DstY
++) {
469 Offset
= (SrcY
* mBltLibWidthInPixels
) + SourceX
;
470 Offset
= mBltLibBytesPerPixel
* Offset
;
471 BltMemSrc
= (VOID
*) (mBltLibFrameBuffer
+ Offset
);
473 if (mPixelFormat
== PixelBlueGreenRedReserved8BitPerColor
) {
476 (UINT8
*) BltBuffer
+
478 (DestinationX
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
))
481 BltMemDst
= (VOID
*) mBltLibLineBuffer
;
484 CopyMem (BltMemDst
, BltMemSrc
, WidthInBytes
);
486 if (mPixelFormat
!= PixelBlueGreenRedReserved8BitPerColor
) {
487 for (X
= 0; X
< Width
; X
++) {
488 Blt
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) ((UINT8
*) BltBuffer
+ (DstY
* Delta
) + (DestinationX
+ X
) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
489 Uint32
= *(UINT32
*) (mBltLibLineBuffer
+ (X
* mBltLibBytesPerPixel
));
492 (((Uint32
& mPixelBitMasks
.RedMask
) >> mPixelShl
[0]) << mPixelShr
[0]) |
493 (((Uint32
& mPixelBitMasks
.GreenMask
) >> mPixelShl
[1]) << mPixelShr
[1]) |
494 (((Uint32
& mPixelBitMasks
.BlueMask
) >> mPixelShl
[2]) << mPixelShr
[2])
505 Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation.
507 @param[in] BltBuffer Output buffer for pixel color data
508 @param[in] DestinationX X location within video
509 @param[in] DestinationY Y location within video
510 @param[in] Width Width (in pixels)
511 @param[in] Height Height
513 @retval EFI_DEVICE_ERROR - A hardware error occured
514 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
515 @retval EFI_SUCCESS - The sizes were returned
520 BltLibBufferToVideo (
521 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
,
522 IN UINTN DestinationX
,
523 IN UINTN DestinationY
,
528 return BltLibBufferToVideoEx (
542 Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation
543 with extended parameters.
545 @param[in] BltBuffer Output buffer for pixel color data
546 @param[in] SourceX X location within BltBuffer
547 @param[in] SourceY Y location within BltBuffer
548 @param[in] DestinationX X location within video
549 @param[in] DestinationY Y location within video
550 @param[in] Width Width (in pixels)
551 @param[in] Height Height
552 @param[in] Delta Number of bytes in a row of BltBuffer
554 @retval EFI_DEVICE_ERROR - A hardware error occured
555 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
556 @retval EFI_SUCCESS - The sizes were returned
561 BltLibBufferToVideoEx (
562 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
,
565 IN UINTN DestinationX
,
566 IN UINTN DestinationY
,
574 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Blt
;
583 // BltBuffer to Video: Source is BltBuffer, destination is Video
585 if (DestinationY
+ Height
> mBltLibHeight
) {
586 return EFI_INVALID_PARAMETER
;
589 if (DestinationX
+ Width
> mBltLibWidthInPixels
) {
590 return EFI_INVALID_PARAMETER
;
593 if (Width
== 0 || Height
== 0) {
594 return EFI_INVALID_PARAMETER
;
598 // If Delta is zero, then the entire BltBuffer is being used, so Delta
599 // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,
600 // the number of bytes in each row can be computed.
603 Delta
= Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
606 WidthInBytes
= Width
* mBltLibBytesPerPixel
;
608 for (SrcY
= SourceY
, DstY
= DestinationY
; SrcY
< (Height
+ SourceY
); SrcY
++, DstY
++) {
610 Offset
= (DstY
* mBltLibWidthInPixels
) + DestinationX
;
611 Offset
= mBltLibBytesPerPixel
* Offset
;
612 BltMemDst
= (VOID
*) (mBltLibFrameBuffer
+ Offset
);
614 if (mPixelFormat
== PixelBlueGreenRedReserved8BitPerColor
) {
615 BltMemSrc
= (VOID
*) ((UINT8
*) BltBuffer
+ (SrcY
* Delta
));
617 for (X
= 0; X
< Width
; X
++) {
619 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) (
620 (UINT8
*) BltBuffer
+
622 ((SourceX
+ X
) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
))
624 Uint32
= *(UINT32
*) Blt
;
625 *(UINT32
*) (mBltLibLineBuffer
+ (X
* mBltLibBytesPerPixel
)) =
627 (((Uint32
<< mPixelShl
[0]) >> mPixelShr
[0]) & mPixelBitMasks
.RedMask
) |
628 (((Uint32
<< mPixelShl
[1]) >> mPixelShr
[1]) & mPixelBitMasks
.GreenMask
) |
629 (((Uint32
<< mPixelShl
[2]) >> mPixelShr
[2]) & mPixelBitMasks
.BlueMask
)
632 BltMemSrc
= (VOID
*) mBltLibLineBuffer
;
635 CopyMem (BltMemDst
, BltMemSrc
, WidthInBytes
);
643 Performs a UEFI Graphics Output Protocol Blt Video to Video operation
645 @param[in] SourceX X location within video
646 @param[in] SourceY Y location within video
647 @param[in] DestinationX X location within video
648 @param[in] DestinationY Y location within video
649 @param[in] Width Width (in pixels)
650 @param[in] Height Height
652 @retval EFI_DEVICE_ERROR - A hardware error occured
653 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
654 @retval EFI_SUCCESS - The sizes were returned
662 IN UINTN DestinationX
,
663 IN UINTN DestinationY
,
675 // Video to Video: Source is Video, destination is Video
677 if (SourceY
+ Height
> mBltLibHeight
) {
678 return EFI_INVALID_PARAMETER
;
681 if (SourceX
+ Width
> mBltLibWidthInPixels
) {
682 return EFI_INVALID_PARAMETER
;
685 if (DestinationY
+ Height
> mBltLibHeight
) {
686 return EFI_INVALID_PARAMETER
;
689 if (DestinationX
+ Width
> mBltLibWidthInPixels
) {
690 return EFI_INVALID_PARAMETER
;
693 if (Width
== 0 || Height
== 0) {
694 return EFI_INVALID_PARAMETER
;
697 WidthInBytes
= Width
* mBltLibBytesPerPixel
;
699 Offset
= (SourceY
* mBltLibWidthInPixels
) + SourceX
;
700 Offset
= mBltLibBytesPerPixel
* Offset
;
701 BltMemSrc
= (VOID
*) (mBltLibFrameBuffer
+ Offset
);
703 Offset
= (DestinationY
* mBltLibWidthInPixels
) + DestinationX
;
704 Offset
= mBltLibBytesPerPixel
* Offset
;
705 BltMemDst
= (VOID
*) (mBltLibFrameBuffer
+ Offset
);
707 LineStride
= mBltLibWidthInBytes
;
708 if ((UINTN
) BltMemDst
> (UINTN
) BltMemSrc
) {
709 LineStride
= -LineStride
;
713 CopyMem (BltMemDst
, BltMemSrc
, WidthInBytes
);
715 BltMemSrc
= (VOID
*) ((UINT8
*) BltMemSrc
+ LineStride
);
716 BltMemDst
= (VOID
*) ((UINT8
*) BltMemDst
+ LineStride
);
725 Returns the sizes related to the video device
727 @param[out] Width Width (in pixels)
728 @param[out] Height Height (in pixels)
730 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in
731 @retval EFI_SUCCESS - The sizes were returned
737 OUT UINTN
*Width
, OPTIONAL
738 OUT UINTN
*Height OPTIONAL
742 *Width
= mBltLibWidthInPixels
;
744 if (Height
!= NULL
) {
745 *Height
= mBltLibHeight
;