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
;
152 if (PlatformLogo
!= NULL
) {
154 // Get image from OEMBadging protocol.
156 Status
= PlatformLogo
->GetImage (
166 if (EFI_ERROR (Status
)) {
172 // Get the specified image from FV.
174 Status
= GetSectionFromAnyFv (Logo
, EFI_SECTION_RAW
, 0, (VOID
**) &ImageData
, &ImageSize
);
175 if (EFI_ERROR (Status
)) {
176 return EFI_UNSUPPORTED
;
184 Status
= DecodeImage (ImageFormat
, ImageData
, ImageSize
, &Blt
, &BltSize
, &Width
, &Height
);
185 FreePool (ImageData
);
186 if (EFI_ERROR (Status
)) {
189 // Directly return failure for single LOGO
198 // Calculate the display position according to Attribute.
201 case EdkiiPlatformLogoDisplayAttributeLeftTop
:
205 case EdkiiPlatformLogoDisplayAttributeCenterTop
:
206 DestX
= (SizeOfX
- Width
) / 2;
209 case EdkiiPlatformLogoDisplayAttributeRightTop
:
210 DestX
= SizeOfX
- Width
;
214 case EdkiiPlatformLogoDisplayAttributeCenterLeft
:
216 DestY
= (SizeOfY
- Height
) / 2;
218 case EdkiiPlatformLogoDisplayAttributeCenter
:
219 DestX
= (SizeOfX
- Width
) / 2;
220 DestY
= (SizeOfY
- Height
) / 2;
222 case EdkiiPlatformLogoDisplayAttributeCenterRight
:
223 DestX
= SizeOfX
- Width
;
224 DestY
= (SizeOfY
- Height
) / 2;
227 case EdkiiPlatformLogoDisplayAttributeLeftBottom
:
229 DestY
= SizeOfY
- Height
;
231 case EdkiiPlatformLogoDisplayAttributeCenterBottom
:
232 DestX
= (SizeOfX
- Width
) / 2;
233 DestY
= SizeOfY
- Height
;
235 case EdkiiPlatformLogoDisplayAttributeRightBottom
:
236 DestX
= SizeOfX
- Width
;
237 DestY
= SizeOfY
- Height
;
248 if ((DestX
>= 0) && (DestY
>= 0)) {
249 if (GraphicsOutput
!= NULL
) {
250 Status
= GraphicsOutput
->Blt (
260 Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
263 ASSERT (UgaDraw
!= NULL
);
264 Status
= UgaDraw
->Blt (
266 (EFI_UGA_PIXEL
*) Blt
,
267 EfiUgaBltBufferToVideo
,
274 Width
* sizeof (EFI_UGA_PIXEL
)
279 // Report displayed Logo information.
281 if (!EFI_ERROR (Status
)) {
284 if (LogoWidth
== 0) {
288 LogoDestX
= (UINTN
) DestX
;
289 LogoDestY
= (UINTN
) DestY
;
294 // Merge new logo with old one.
296 NewDestX
= MIN ((UINTN
) DestX
, LogoDestX
);
297 NewDestY
= MIN ((UINTN
) DestY
, LogoDestY
);
298 NewWidth
= MAX ((UINTN
) DestX
+ Width
, LogoDestX
+ LogoWidth
) - NewDestX
;
299 NewHeight
= MAX ((UINTN
) DestY
+ Height
, LogoDestY
+ LogoHeight
) - NewDestY
;
301 LogoDestX
= NewDestX
;
302 LogoDestY
= NewDestY
;
303 LogoWidth
= NewWidth
;
304 LogoHeight
= NewHeight
;
309 if (PlatformLogo
== NULL
) {
314 if (BootLogo
== NULL
|| NumberOfLogos
== 0) {
316 // No logo displayed.
326 // Advertise displayed Logo information.
328 if (NumberOfLogos
== 1) {
330 // Only one logo displayed, use its Blt buffer directly for BootLogo protocol.
333 Status
= EFI_SUCCESS
;
336 // More than one Logo displayed, get merged BltBuffer using VideoToBuffer operation.
343 // Ensure the LogoHeight * LogoWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow
345 if (LogoHeight
> MAX_UINTN
/ LogoWidth
/ sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)) {
346 return EFI_UNSUPPORTED
;
348 BufferSize
= LogoWidth
* LogoHeight
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
350 LogoBlt
= AllocatePool (BufferSize
);
351 if (LogoBlt
== NULL
) {
352 return EFI_OUT_OF_RESOURCES
;
355 if (GraphicsOutput
!= NULL
) {
356 Status
= GraphicsOutput
->Blt (
359 EfiBltVideoToBltBuffer
,
366 LogoWidth
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
369 Status
= UgaDraw
->Blt (
371 (EFI_UGA_PIXEL
*) LogoBlt
,
372 EfiUgaVideoToBltBuffer
,
379 LogoWidth
* sizeof (EFI_UGA_PIXEL
)
384 if (!EFI_ERROR (Status
)) {
385 BootLogo
->SetBootLogo (BootLogo
, LogoBlt
, LogoDestX
, LogoDestY
, LogoWidth
, LogoHeight
);
393 Use SystemTable Conout to turn on video based Simple Text Out consoles. The
394 Simple Text Out screens will now be synced up with all non video output devices
396 @retval EFI_SUCCESS UGA devices are back in text mode and synced up.
401 BootLogoDisableLogo (
407 // Enable Cursor on Screen
409 gST
->ConOut
->EnableCursor (gST
->ConOut
, TRUE
);
416 Update progress bar with title above it. It only works in Graphics mode.
418 @param TitleForeground Foreground color for Title.
419 @param TitleBackground Background color for Title.
420 @param Title Title above progress bar.
421 @param ProgressColor Progress bar color.
422 @param Progress Progress (0-100)
423 @param PreviousValue The previous value of the progress.
425 @retval EFI_STATUS Success update the progress bar
430 BootLogoUpdateProgress (
431 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground
,
432 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground
,
434 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor
,
436 IN UINTN PreviousValue
440 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
441 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
446 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color
;
454 if (Progress
> 100) {
455 return EFI_INVALID_PARAMETER
;
459 Status
= gBS
->HandleProtocol (gST
->ConsoleOutHandle
, &gEfiGraphicsOutputProtocolGuid
, (VOID
**) &GraphicsOutput
);
460 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
461 GraphicsOutput
= NULL
;
463 Status
= gBS
->HandleProtocol (gST
->ConsoleOutHandle
, &gEfiUgaDrawProtocolGuid
, (VOID
**) &UgaDraw
);
464 if (EFI_ERROR (Status
)) {
468 if (EFI_ERROR (Status
)) {
469 return EFI_UNSUPPORTED
;
474 if (GraphicsOutput
!= NULL
) {
475 SizeOfX
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
476 SizeOfY
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
477 } else if (UgaDraw
!= NULL
) {
478 Status
= UgaDraw
->GetMode (
485 if (EFI_ERROR (Status
)) {
486 return EFI_UNSUPPORTED
;
489 return EFI_UNSUPPORTED
;
492 BlockWidth
= SizeOfX
/ 100;
493 BlockHeight
= SizeOfY
/ 50;
498 PosY
= SizeOfY
* 48 / 50;
502 // Clear progress area
504 SetMem (&Color
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0x0);
506 if (GraphicsOutput
!= NULL
) {
507 Status
= GraphicsOutput
->Blt (
514 PosY
- EFI_GLYPH_HEIGHT
- 1,
516 SizeOfY
- (PosY
- EFI_GLYPH_HEIGHT
- 1),
517 SizeOfX
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
519 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
520 Status
= UgaDraw
->Blt (
522 (EFI_UGA_PIXEL
*) &Color
,
527 PosY
- EFI_GLYPH_HEIGHT
- 1,
529 SizeOfY
- (PosY
- EFI_GLYPH_HEIGHT
- 1),
530 SizeOfX
* sizeof (EFI_UGA_PIXEL
)
533 return EFI_UNSUPPORTED
;
537 // Show progress by drawing blocks
539 for (Index
= PreviousValue
; Index
< BlockNum
; Index
++) {
540 PosX
= Index
* BlockWidth
;
541 if (GraphicsOutput
!= NULL
) {
542 Status
= GraphicsOutput
->Blt (
552 (BlockWidth
) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
554 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
555 Status
= UgaDraw
->Blt (
557 (EFI_UGA_PIXEL
*) &ProgressColor
,
565 (BlockWidth
) * sizeof (EFI_UGA_PIXEL
)
568 return EFI_UNSUPPORTED
;
573 (SizeOfX
- StrLen (Title
) * EFI_GLYPH_WIDTH
) / 2,
574 PosY
- EFI_GLYPH_HEIGHT
- 1,