2 This library is only intended to be used by PlatformBootManagerLib
3 to show progress bar and LOGO.
5 Copyright (c) 2011 - 2016, 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/GraphicsOutput.h>
18 #include <Protocol/SimpleTextOut.h>
19 #include <Protocol/PlatformLogo.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/PcdLib.h>
27 #include <Library/MemoryAllocationLib.h>
28 #include <Library/DebugLib.h>
31 Show LOGO returned from Edkii Platform Logo protocol on all consoles.
33 @retval EFI_SUCCESS Logo was displayed.
34 @retval EFI_UNSUPPORTED Logo was not found or cannot be displayed.
43 EDKII_PLATFORM_LOGO_PROTOCOL
*PlatformLogo
;
44 EDKII_PLATFORM_LOGO_DISPLAY_ATTRIBUTE Attribute
;
52 EFI_IMAGE_INPUT Image
;
53 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Blt
;
54 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
57 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
58 EFI_BOOT_LOGO_PROTOCOL
*BootLogo
;
60 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*LogoBlt
;
69 Status
= gBS
->LocateProtocol (&gEdkiiPlatformLogoProtocolGuid
, NULL
, (VOID
**) &PlatformLogo
);
70 if (EFI_ERROR (Status
)) {
71 return EFI_UNSUPPORTED
;
76 // Try to open GOP first
78 Status
= gBS
->HandleProtocol (gST
->ConsoleOutHandle
, &gEfiGraphicsOutputProtocolGuid
, (VOID
**) &GraphicsOutput
);
79 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
80 GraphicsOutput
= NULL
;
82 // Open GOP failed, try to open UGA
84 Status
= gBS
->HandleProtocol (gST
->ConsoleOutHandle
, &gEfiUgaDrawProtocolGuid
, (VOID
**) &UgaDraw
);
85 if (EFI_ERROR (Status
)) {
89 if (EFI_ERROR (Status
)) {
90 return EFI_UNSUPPORTED
;
94 // Try to open Boot Logo Protocol.
96 Status
= gBS
->LocateProtocol (&gEfiBootLogoProtocolGuid
, NULL
, (VOID
**) &BootLogo
);
97 if (EFI_ERROR (Status
)) {
102 // Erase Cursor from screen
104 gST
->ConOut
->EnableCursor (gST
->ConOut
, FALSE
);
106 if (GraphicsOutput
!= NULL
) {
107 SizeOfX
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
108 SizeOfY
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
111 ASSERT (UgaDraw
!= NULL
);
112 Status
= UgaDraw
->GetMode (UgaDraw
, &SizeOfX
, &SizeOfY
, &ColorDepth
, &RefreshRate
);
113 if (EFI_ERROR (Status
)) {
114 return EFI_UNSUPPORTED
;
131 // Get image from PlatformLogo protocol.
133 Status
= PlatformLogo
->GetImage (
141 if (EFI_ERROR (Status
)) {
151 // Calculate the display position according to Attribute.
154 case EdkiiPlatformLogoDisplayAttributeLeftTop
:
158 case EdkiiPlatformLogoDisplayAttributeCenterTop
:
159 DestX
= (SizeOfX
- Image
.Width
) / 2;
162 case EdkiiPlatformLogoDisplayAttributeRightTop
:
163 DestX
= SizeOfX
- Image
.Width
;
167 case EdkiiPlatformLogoDisplayAttributeCenterLeft
:
169 DestY
= (SizeOfY
- Image
.Height
) / 2;
171 case EdkiiPlatformLogoDisplayAttributeCenter
:
172 DestX
= (SizeOfX
- Image
.Width
) / 2;
173 DestY
= (SizeOfY
- Image
.Height
) / 2;
175 case EdkiiPlatformLogoDisplayAttributeCenterRight
:
176 DestX
= SizeOfX
- Image
.Width
;
177 DestY
= (SizeOfY
- Image
.Height
) / 2;
180 case EdkiiPlatformLogoDisplayAttributeLeftBottom
:
182 DestY
= SizeOfY
- Image
.Height
;
184 case EdkiiPlatformLogoDisplayAttributeCenterBottom
:
185 DestX
= (SizeOfX
- Image
.Width
) / 2;
186 DestY
= SizeOfY
- Image
.Height
;
188 case EdkiiPlatformLogoDisplayAttributeRightBottom
:
189 DestX
= SizeOfX
- Image
.Width
;
190 DestY
= SizeOfY
- Image
.Height
;
202 if ((DestX
>= 0) && (DestY
>= 0)) {
203 if (GraphicsOutput
!= NULL
) {
204 Status
= GraphicsOutput
->Blt (
214 Image
.Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
217 ASSERT (UgaDraw
!= NULL
);
218 Status
= UgaDraw
->Blt (
220 (EFI_UGA_PIXEL
*) Blt
,
221 EfiUgaBltBufferToVideo
,
228 Image
.Width
* sizeof (EFI_UGA_PIXEL
)
233 // Report displayed Logo information.
235 if (!EFI_ERROR (Status
)) {
238 if (NumberOfLogos
== 1) {
242 LogoDestX
= (UINTN
) DestX
;
243 LogoDestY
= (UINTN
) DestY
;
244 LogoWidth
= Image
.Width
;
245 LogoHeight
= Image
.Height
;
248 // Merge new logo with old one.
250 NewDestX
= MIN ((UINTN
) DestX
, LogoDestX
);
251 NewDestY
= MIN ((UINTN
) DestY
, LogoDestY
);
252 LogoWidth
= MAX ((UINTN
) DestX
+ Image
.Width
, LogoDestX
+ LogoWidth
) - NewDestX
;
253 LogoHeight
= MAX ((UINTN
) DestY
+ Image
.Height
, LogoDestY
+ LogoHeight
) - NewDestY
;
255 LogoDestX
= NewDestX
;
256 LogoDestY
= NewDestY
;
262 if (BootLogo
== NULL
|| NumberOfLogos
== 0) {
264 // No logo displayed.
274 // Advertise displayed Logo information.
276 if (NumberOfLogos
== 1) {
278 // Only one logo displayed, use its Blt buffer directly for BootLogo protocol.
281 Status
= EFI_SUCCESS
;
284 // More than one Logo displayed, get merged BltBuffer using VideoToBuffer operation.
291 // Ensure the LogoHeight * LogoWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow
293 if (LogoHeight
> MAX_UINTN
/ LogoWidth
/ sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)) {
294 return EFI_UNSUPPORTED
;
296 BufferSize
= LogoWidth
* LogoHeight
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
298 LogoBlt
= AllocatePool (BufferSize
);
299 if (LogoBlt
== NULL
) {
300 return EFI_OUT_OF_RESOURCES
;
303 if (GraphicsOutput
!= NULL
) {
304 Status
= GraphicsOutput
->Blt (
307 EfiBltVideoToBltBuffer
,
314 LogoWidth
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
317 Status
= UgaDraw
->Blt (
319 (EFI_UGA_PIXEL
*) LogoBlt
,
320 EfiUgaVideoToBltBuffer
,
327 LogoWidth
* sizeof (EFI_UGA_PIXEL
)
332 if (!EFI_ERROR (Status
)) {
333 BootLogo
->SetBootLogo (BootLogo
, LogoBlt
, LogoDestX
, LogoDestY
, LogoWidth
, LogoHeight
);
341 Use SystemTable Conout to turn on video based Simple Text Out consoles. The
342 Simple Text Out screens will now be synced up with all non video output devices
344 @retval EFI_SUCCESS UGA devices are back in text mode and synced up.
349 BootLogoDisableLogo (
355 // Enable Cursor on Screen
357 gST
->ConOut
->EnableCursor (gST
->ConOut
, TRUE
);
364 Update progress bar with title above it. It only works in Graphics mode.
366 @param TitleForeground Foreground color for Title.
367 @param TitleBackground Background color for Title.
368 @param Title Title above progress bar.
369 @param ProgressColor Progress bar color.
370 @param Progress Progress (0-100)
371 @param PreviousValue The previous value of the progress.
373 @retval EFI_STATUS Success update the progress bar
378 BootLogoUpdateProgress (
379 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground
,
380 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground
,
382 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor
,
384 IN UINTN PreviousValue
388 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
389 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
394 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color
;
402 if (Progress
> 100) {
403 return EFI_INVALID_PARAMETER
;
407 Status
= gBS
->HandleProtocol (gST
->ConsoleOutHandle
, &gEfiGraphicsOutputProtocolGuid
, (VOID
**) &GraphicsOutput
);
408 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
409 GraphicsOutput
= NULL
;
411 Status
= gBS
->HandleProtocol (gST
->ConsoleOutHandle
, &gEfiUgaDrawProtocolGuid
, (VOID
**) &UgaDraw
);
412 if (EFI_ERROR (Status
)) {
416 if (EFI_ERROR (Status
)) {
417 return EFI_UNSUPPORTED
;
422 if (GraphicsOutput
!= NULL
) {
423 SizeOfX
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
424 SizeOfY
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
425 } else if (UgaDraw
!= NULL
) {
426 Status
= UgaDraw
->GetMode (
433 if (EFI_ERROR (Status
)) {
434 return EFI_UNSUPPORTED
;
437 return EFI_UNSUPPORTED
;
440 BlockWidth
= SizeOfX
/ 100;
441 BlockHeight
= SizeOfY
/ 50;
446 PosY
= SizeOfY
* 48 / 50;
450 // Clear progress area
452 SetMem (&Color
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0x0);
454 if (GraphicsOutput
!= NULL
) {
455 Status
= GraphicsOutput
->Blt (
462 PosY
- EFI_GLYPH_HEIGHT
- 1,
464 SizeOfY
- (PosY
- EFI_GLYPH_HEIGHT
- 1),
465 SizeOfX
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
467 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
468 Status
= UgaDraw
->Blt (
470 (EFI_UGA_PIXEL
*) &Color
,
475 PosY
- EFI_GLYPH_HEIGHT
- 1,
477 SizeOfY
- (PosY
- EFI_GLYPH_HEIGHT
- 1),
478 SizeOfX
* sizeof (EFI_UGA_PIXEL
)
481 return EFI_UNSUPPORTED
;
485 // Show progress by drawing blocks
487 for (Index
= PreviousValue
; Index
< BlockNum
; Index
++) {
488 PosX
= Index
* BlockWidth
;
489 if (GraphicsOutput
!= NULL
) {
490 Status
= GraphicsOutput
->Blt (
500 (BlockWidth
) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
502 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
503 Status
= UgaDraw
->Blt (
505 (EFI_UGA_PIXEL
*) &ProgressColor
,
513 (BlockWidth
) * sizeof (EFI_UGA_PIXEL
)
516 return EFI_UNSUPPORTED
;
521 (SizeOfX
- StrLen (Title
) * EFI_GLYPH_WIDTH
) / 2,
522 PosY
- EFI_GLYPH_HEIGHT
- 1,