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] CoordinateX The X coordinate of the image.
39 @param[in] CoordinateY The Y coordinate of the image.
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
:
206 case EdkiiPlatformLogoDisplayAttributeCenterTop
:
207 DestX
= (SizeOfX
- Width
) / 2;
211 case EdkiiPlatformLogoDisplayAttributeRightTop
:
212 DestX
= (SizeOfX
- Width
- CoordinateX
);
213 DestY
= CoordinateY
;;
216 case EdkiiPlatformLogoDisplayAttributeCenterRight
:
217 DestX
= (SizeOfX
- Width
- CoordinateX
);
218 DestY
= (SizeOfY
- Height
) / 2;
221 case EdkiiPlatformLogoDisplayAttributeRightBottom
:
222 DestX
= (SizeOfX
- Width
- CoordinateX
);
223 DestY
= (SizeOfY
- Height
- CoordinateY
);
226 case EdkiiPlatformLogoDisplayAttributeCenterBottom
:
227 DestX
= (SizeOfX
- Width
) / 2;
228 DestY
= (SizeOfY
- Height
- CoordinateY
);
231 case EdkiiPlatformLogoDisplayAttributeLeftBottom
:
233 DestY
= (SizeOfY
- Height
- CoordinateY
);
236 case EdkiiPlatformLogoDisplayAttributeCenterLeft
:
238 DestY
= (SizeOfY
- Height
) / 2;
241 case EdkiiPlatformLogoDisplayAttributeCenter
:
242 DestX
= (SizeOfX
- Width
) / 2;
243 DestY
= (SizeOfY
- Height
) / 2;
251 if ((DestX
>= 0) && (DestY
>= 0)) {
252 if (GraphicsOutput
!= NULL
) {
253 Status
= GraphicsOutput
->Blt (
263 Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
266 ASSERT (UgaDraw
!= NULL
);
267 Status
= UgaDraw
->Blt (
269 (EFI_UGA_PIXEL
*) Blt
,
270 EfiUgaBltBufferToVideo
,
277 Width
* sizeof (EFI_UGA_PIXEL
)
282 // Report displayed Logo information.
284 if (!EFI_ERROR (Status
)) {
287 if (LogoWidth
== 0) {
291 LogoDestX
= (UINTN
) DestX
;
292 LogoDestY
= (UINTN
) DestY
;
297 // Merge new logo with old one.
299 NewDestX
= MIN ((UINTN
) DestX
, LogoDestX
);
300 NewDestY
= MIN ((UINTN
) DestY
, LogoDestY
);
301 NewWidth
= MAX ((UINTN
) DestX
+ Width
, LogoDestX
+ LogoWidth
) - NewDestX
;
302 NewHeight
= MAX ((UINTN
) DestY
+ Height
, LogoDestY
+ LogoHeight
) - NewDestY
;
304 LogoDestX
= NewDestX
;
305 LogoDestY
= NewDestY
;
306 LogoWidth
= NewWidth
;
307 LogoHeight
= NewHeight
;
312 if (PlatformLogo
== NULL
) {
317 if (BootLogo
== NULL
|| NumberOfLogos
== 0) {
319 // No logo displayed.
329 // Advertise displayed Logo information.
331 if (NumberOfLogos
== 1) {
333 // Only one logo displayed, use its Blt buffer directly for BootLogo protocol.
336 Status
= EFI_SUCCESS
;
339 // More than one Logo displayed, get merged BltBuffer using VideoToBuffer operation.
346 // Ensure the LogoHeight * LogoWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow
348 if (LogoHeight
> MAX_UINTN
/ LogoWidth
/ sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)) {
349 return EFI_UNSUPPORTED
;
351 BufferSize
= LogoWidth
* LogoHeight
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
353 LogoBlt
= AllocatePool (BufferSize
);
354 if (LogoBlt
== NULL
) {
355 return EFI_OUT_OF_RESOURCES
;
358 if (GraphicsOutput
!= NULL
) {
359 Status
= GraphicsOutput
->Blt (
362 EfiBltVideoToBltBuffer
,
369 LogoWidth
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
372 Status
= UgaDraw
->Blt (
374 (EFI_UGA_PIXEL
*) LogoBlt
,
375 EfiUgaVideoToBltBuffer
,
382 LogoWidth
* sizeof (EFI_UGA_PIXEL
)
387 if (!EFI_ERROR (Status
)) {
388 BootLogo
->SetBootLogo (BootLogo
, LogoBlt
, LogoDestX
, LogoDestY
, LogoWidth
, LogoHeight
);
396 Use SystemTable Conout to turn on video based Simple Text Out consoles. The
397 Simple Text Out screens will now be synced up with all non video output devices
399 @retval EFI_SUCCESS UGA devices are back in text mode and synced up.
404 BootLogoDisableLogo (
410 // Enable Cursor on Screen
412 gST
->ConOut
->EnableCursor (gST
->ConOut
, TRUE
);
419 Update progress bar with title above it. It only works in Graphics mode.
421 @param TitleForeground Foreground color for Title.
422 @param TitleBackground Background color for Title.
423 @param Title Title above progress bar.
424 @param ProgressColor Progress bar color.
425 @param Progress Progress (0-100)
426 @param PreviousValue The previous value of the progress.
428 @retval EFI_STATUS Success update the progress bar
433 BootLogoUpdateProgress (
434 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground
,
435 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground
,
437 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor
,
439 IN UINTN PreviousValue
443 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
444 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
449 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color
;
457 if (Progress
> 100) {
458 return EFI_INVALID_PARAMETER
;
462 Status
= gBS
->HandleProtocol (gST
->ConsoleOutHandle
, &gEfiGraphicsOutputProtocolGuid
, (VOID
**) &GraphicsOutput
);
463 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
464 GraphicsOutput
= NULL
;
466 Status
= gBS
->HandleProtocol (gST
->ConsoleOutHandle
, &gEfiUgaDrawProtocolGuid
, (VOID
**) &UgaDraw
);
467 if (EFI_ERROR (Status
)) {
471 if (EFI_ERROR (Status
)) {
472 return EFI_UNSUPPORTED
;
477 if (GraphicsOutput
!= NULL
) {
478 SizeOfX
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
479 SizeOfY
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
480 } else if (UgaDraw
!= NULL
) {
481 Status
= UgaDraw
->GetMode (
488 if (EFI_ERROR (Status
)) {
489 return EFI_UNSUPPORTED
;
492 return EFI_UNSUPPORTED
;
495 BlockWidth
= SizeOfX
/ 100;
496 BlockHeight
= SizeOfY
/ 50;
501 PosY
= SizeOfY
* 48 / 50;
505 // Clear progress area
507 SetMem (&Color
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0x0);
509 if (GraphicsOutput
!= NULL
) {
510 Status
= GraphicsOutput
->Blt (
517 PosY
- EFI_GLYPH_HEIGHT
- 1,
519 SizeOfY
- (PosY
- EFI_GLYPH_HEIGHT
- 1),
520 SizeOfX
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
522 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
523 Status
= UgaDraw
->Blt (
525 (EFI_UGA_PIXEL
*) &Color
,
530 PosY
- EFI_GLYPH_HEIGHT
- 1,
532 SizeOfY
- (PosY
- EFI_GLYPH_HEIGHT
- 1),
533 SizeOfX
* sizeof (EFI_UGA_PIXEL
)
536 return EFI_UNSUPPORTED
;
540 // Show progress by drawing blocks
542 for (Index
= PreviousValue
; Index
< BlockNum
; Index
++) {
543 PosX
= Index
* BlockWidth
;
544 if (GraphicsOutput
!= NULL
) {
545 Status
= GraphicsOutput
->Blt (
555 (BlockWidth
) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
557 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
558 Status
= UgaDraw
->Blt (
560 (EFI_UGA_PIXEL
*) &ProgressColor
,
568 (BlockWidth
) * sizeof (EFI_UGA_PIXEL
)
571 return EFI_UNSUPPORTED
;
576 (SizeOfX
- StrLen (Title
) * EFI_GLYPH_WIDTH
) / 2,
577 PosY
- EFI_GLYPH_HEIGHT
- 1,