2 This library is only intended to be used by PlatformBootManagerLib
3 to show progress bar and LOGO.
5 Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials are licensed and made available under
7 the terms and conditions of the BSD License that accompanies this distribution.
8 The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <Protocol/SimpleTextOut.h>
18 #include <Protocol/PlatformLogo.h>
19 #include <Protocol/GraphicsOutput.h>
20 #include <Protocol/UgaDraw.h>
21 #include <Protocol/BootLogo.h>
22 #include <Library/BaseLib.h>
23 #include <Library/UefiLib.h>
24 #include <Library/BaseMemoryLib.h>
25 #include <Library/UefiBootServicesTableLib.h>
26 #include <Library/DxeServicesLib.h>
27 #include <Library/PcdLib.h>
28 #include <Library/MemoryAllocationLib.h>
29 #include <Library/DebugLib.h>
30 #include <Library/ImageDecoderLib.h>
33 Show LOGO on all consoles.
35 @param[in] ImageFormat Format of the image file.
36 @param[in] LogoFile The file name of logo to display.
37 @param[in] Attribute The display attributes of the image returned.
38 @param[in] OffsetX The X offset of the image regarding the Attribute.
39 @param[in] OffsetY The Y offset of the image regarding the Attribute.
41 @retval EFI_SUCCESS Logo was displayed.
42 @retval EFI_UNSUPPORTED Logo was not found or cannot be displayed.
47 IN IMAGE_FORMAT ImageFormat
,
49 IN EDKII_PLATFORM_LOGO_DISPLAY_ATTRIBUTE Attribute
,
55 EDKII_PLATFORM_LOGO_PROTOCOL
*PlatformLogo
;
66 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Blt
;
67 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
70 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
71 EFI_BOOT_LOGO_PROTOCOL
*BootLogo
;
73 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*LogoBlt
;
86 // Try to open GOP first
88 Status
= gBS
->HandleProtocol (gST
->ConsoleOutHandle
, &gEfiGraphicsOutputProtocolGuid
, (VOID
**) &GraphicsOutput
);
89 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
90 GraphicsOutput
= NULL
;
92 // Open GOP failed, try to open UGA
94 Status
= gBS
->HandleProtocol (gST
->ConsoleOutHandle
, &gEfiUgaDrawProtocolGuid
, (VOID
**) &UgaDraw
);
95 if (EFI_ERROR (Status
)) {
99 if (EFI_ERROR (Status
)) {
100 return EFI_UNSUPPORTED
;
103 Status
= gBS
->LocateProtocol (&gEdkiiPlatformLogoProtocolGuid
, NULL
, (VOID
**) &PlatformLogo
);
104 if (EFI_ERROR (Status
)) {
108 if ((Logo
== NULL
) && (PlatformLogo
== NULL
)) {
109 return EFI_UNSUPPORTED
;
113 // Try to open Boot Logo Protocol.
115 Status
= gBS
->LocateProtocol (&gEfiBootLogoProtocolGuid
, NULL
, (VOID
**) &BootLogo
);
116 if (EFI_ERROR (Status
)) {
121 // Erase Cursor from screen
123 gST
->ConOut
->EnableCursor (gST
->ConOut
, FALSE
);
125 if (GraphicsOutput
!= NULL
) {
126 SizeOfX
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
127 SizeOfY
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
130 ASSERT (UgaDraw
!= NULL
);
131 Status
= UgaDraw
->GetMode (UgaDraw
, &SizeOfX
, &SizeOfY
, &ColorDepth
, &RefreshRate
);
132 if (EFI_ERROR (Status
)) {
133 return EFI_UNSUPPORTED
;
154 if (PlatformLogo
!= NULL
) {
156 // Get image from OEMBadging protocol.
158 Status
= PlatformLogo
->GetImage (
168 if (EFI_ERROR (Status
)) {
174 // Get the specified image from FV.
176 Status
= GetSectionFromAnyFv (Logo
, EFI_SECTION_RAW
, 0, (VOID
**) &ImageData
, &ImageSize
);
177 if (EFI_ERROR (Status
)) {
178 return EFI_UNSUPPORTED
;
186 Status
= DecodeImage (ImageFormat
, ImageData
, ImageSize
, &Blt
, &BltSize
, &Width
, &Height
);
187 FreePool (ImageData
);
188 if (EFI_ERROR (Status
)) {
191 // Directly return failure for single LOGO
200 // Calculate the display position according to Attribute.
203 case EdkiiPlatformLogoDisplayAttributeLeftTop
:
207 case EdkiiPlatformLogoDisplayAttributeCenterTop
:
208 DestX
= (SizeOfX
- Width
) / 2;
211 case EdkiiPlatformLogoDisplayAttributeRightTop
:
212 DestX
= SizeOfX
- Width
;
216 case EdkiiPlatformLogoDisplayAttributeCenterLeft
:
218 DestY
= (SizeOfY
- Height
) / 2;
220 case EdkiiPlatformLogoDisplayAttributeCenter
:
221 DestX
= (SizeOfX
- Width
) / 2;
222 DestY
= (SizeOfY
- Height
) / 2;
224 case EdkiiPlatformLogoDisplayAttributeCenterRight
:
225 DestX
= SizeOfX
- Width
;
226 DestY
= (SizeOfY
- Height
) / 2;
229 case EdkiiPlatformLogoDisplayAttributeLeftBottom
:
231 DestY
= SizeOfY
- Height
;
233 case EdkiiPlatformLogoDisplayAttributeCenterBottom
:
234 DestX
= (SizeOfX
- Width
) / 2;
235 DestY
= SizeOfY
- Height
;
237 case EdkiiPlatformLogoDisplayAttributeRightBottom
:
238 DestX
= SizeOfX
- Width
;
239 DestY
= SizeOfY
- Height
;
250 if ((DestX
>= 0) && (DestY
>= 0)) {
251 if (GraphicsOutput
!= NULL
) {
252 Status
= GraphicsOutput
->Blt (
262 Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
265 ASSERT (UgaDraw
!= NULL
);
266 Status
= UgaDraw
->Blt (
268 (EFI_UGA_PIXEL
*) Blt
,
269 EfiUgaBltBufferToVideo
,
276 Width
* sizeof (EFI_UGA_PIXEL
)
281 // Report displayed Logo information.
283 if (!EFI_ERROR (Status
)) {
286 if (LogoWidth
== 0) {
290 LogoDestX
= (UINTN
) DestX
;
291 LogoDestY
= (UINTN
) DestY
;
296 // Merge new logo with old one.
298 NewDestX
= MIN ((UINTN
) DestX
, LogoDestX
);
299 NewDestY
= MIN ((UINTN
) DestY
, LogoDestY
);
300 NewWidth
= MAX ((UINTN
) DestX
+ Width
, LogoDestX
+ LogoWidth
) - NewDestX
;
301 NewHeight
= MAX ((UINTN
) DestY
+ Height
, LogoDestY
+ LogoHeight
) - NewDestY
;
303 LogoDestX
= NewDestX
;
304 LogoDestY
= NewDestY
;
305 LogoWidth
= NewWidth
;
306 LogoHeight
= NewHeight
;
311 if (PlatformLogo
== NULL
) {
316 if (BootLogo
== NULL
|| NumberOfLogos
== 0) {
318 // No logo displayed.
328 // Advertise displayed Logo information.
330 if (NumberOfLogos
== 1) {
332 // Only one logo displayed, use its Blt buffer directly for BootLogo protocol.
335 Status
= EFI_SUCCESS
;
338 // More than one Logo displayed, get merged BltBuffer using VideoToBuffer operation.
345 // Ensure the LogoHeight * LogoWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow
347 if (LogoHeight
> MAX_UINTN
/ LogoWidth
/ sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)) {
348 return EFI_UNSUPPORTED
;
350 BufferSize
= LogoWidth
* LogoHeight
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
352 LogoBlt
= AllocatePool (BufferSize
);
353 if (LogoBlt
== NULL
) {
354 return EFI_OUT_OF_RESOURCES
;
357 if (GraphicsOutput
!= NULL
) {
358 Status
= GraphicsOutput
->Blt (
361 EfiBltVideoToBltBuffer
,
368 LogoWidth
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
371 Status
= UgaDraw
->Blt (
373 (EFI_UGA_PIXEL
*) LogoBlt
,
374 EfiUgaVideoToBltBuffer
,
381 LogoWidth
* sizeof (EFI_UGA_PIXEL
)
386 if (!EFI_ERROR (Status
)) {
387 BootLogo
->SetBootLogo (BootLogo
, LogoBlt
, LogoDestX
, LogoDestY
, LogoWidth
, LogoHeight
);
395 Use SystemTable Conout to turn on video based Simple Text Out consoles. The
396 Simple Text Out screens will now be synced up with all non video output devices
398 @retval EFI_SUCCESS UGA devices are back in text mode and synced up.
403 BootLogoDisableLogo (
409 // Enable Cursor on Screen
411 gST
->ConOut
->EnableCursor (gST
->ConOut
, TRUE
);
418 Update progress bar with title above it. It only works in Graphics mode.
420 @param TitleForeground Foreground color for Title.
421 @param TitleBackground Background color for Title.
422 @param Title Title above progress bar.
423 @param ProgressColor Progress bar color.
424 @param Progress Progress (0-100)
425 @param PreviousValue The previous value of the progress.
427 @retval EFI_STATUS Success update the progress bar
432 BootLogoUpdateProgress (
433 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground
,
434 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground
,
436 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor
,
438 IN UINTN PreviousValue
442 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
443 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
448 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color
;
456 if (Progress
> 100) {
457 return EFI_INVALID_PARAMETER
;
461 Status
= gBS
->HandleProtocol (gST
->ConsoleOutHandle
, &gEfiGraphicsOutputProtocolGuid
, (VOID
**) &GraphicsOutput
);
462 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
463 GraphicsOutput
= NULL
;
465 Status
= gBS
->HandleProtocol (gST
->ConsoleOutHandle
, &gEfiUgaDrawProtocolGuid
, (VOID
**) &UgaDraw
);
466 if (EFI_ERROR (Status
)) {
470 if (EFI_ERROR (Status
)) {
471 return EFI_UNSUPPORTED
;
476 if (GraphicsOutput
!= NULL
) {
477 SizeOfX
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
478 SizeOfY
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
479 } else if (UgaDraw
!= NULL
) {
480 Status
= UgaDraw
->GetMode (
487 if (EFI_ERROR (Status
)) {
488 return EFI_UNSUPPORTED
;
491 return EFI_UNSUPPORTED
;
494 BlockWidth
= SizeOfX
/ 100;
495 BlockHeight
= SizeOfY
/ 50;
500 PosY
= SizeOfY
* 48 / 50;
504 // Clear progress area
506 SetMem (&Color
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0x0);
508 if (GraphicsOutput
!= NULL
) {
509 Status
= GraphicsOutput
->Blt (
516 PosY
- EFI_GLYPH_HEIGHT
- 1,
518 SizeOfY
- (PosY
- EFI_GLYPH_HEIGHT
- 1),
519 SizeOfX
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
521 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
522 Status
= UgaDraw
->Blt (
524 (EFI_UGA_PIXEL
*) &Color
,
529 PosY
- EFI_GLYPH_HEIGHT
- 1,
531 SizeOfY
- (PosY
- EFI_GLYPH_HEIGHT
- 1),
532 SizeOfX
* sizeof (EFI_UGA_PIXEL
)
535 return EFI_UNSUPPORTED
;
539 // Show progress by drawing blocks
541 for (Index
= PreviousValue
; Index
< BlockNum
; Index
++) {
542 PosX
= Index
* BlockWidth
;
543 if (GraphicsOutput
!= NULL
) {
544 Status
= GraphicsOutput
->Blt (
554 (BlockWidth
) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
556 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
557 Status
= UgaDraw
->Blt (
559 (EFI_UGA_PIXEL
*) &ProgressColor
,
567 (BlockWidth
) * sizeof (EFI_UGA_PIXEL
)
570 return EFI_UNSUPPORTED
;
575 (SizeOfX
- StrLen (Title
) * EFI_GLYPH_WIDTH
) / 2,
576 PosY
- EFI_GLYPH_HEIGHT
- 1,