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
)) {
145 if (EFI_ERROR (Status
)) {
155 // Calculate the display position according to Attribute.
158 case EdkiiPlatformLogoDisplayAttributeLeftTop
:
162 case EdkiiPlatformLogoDisplayAttributeCenterTop
:
163 DestX
= (SizeOfX
- Image
.Width
) / 2;
166 case EdkiiPlatformLogoDisplayAttributeRightTop
:
167 DestX
= SizeOfX
- Image
.Width
;
171 case EdkiiPlatformLogoDisplayAttributeCenterLeft
:
173 DestY
= (SizeOfY
- Image
.Height
) / 2;
175 case EdkiiPlatformLogoDisplayAttributeCenter
:
176 DestX
= (SizeOfX
- Image
.Width
) / 2;
177 DestY
= (SizeOfY
- Image
.Height
) / 2;
179 case EdkiiPlatformLogoDisplayAttributeCenterRight
:
180 DestX
= SizeOfX
- Image
.Width
;
181 DestY
= (SizeOfY
- Image
.Height
) / 2;
184 case EdkiiPlatformLogoDisplayAttributeLeftBottom
:
186 DestY
= SizeOfY
- Image
.Height
;
188 case EdkiiPlatformLogoDisplayAttributeCenterBottom
:
189 DestX
= (SizeOfX
- Image
.Width
) / 2;
190 DestY
= SizeOfY
- Image
.Height
;
192 case EdkiiPlatformLogoDisplayAttributeRightBottom
:
193 DestX
= SizeOfX
- Image
.Width
;
194 DestY
= SizeOfY
- Image
.Height
;
206 if ((DestX
>= 0) && (DestY
>= 0)) {
207 if (GraphicsOutput
!= NULL
) {
208 Status
= GraphicsOutput
->Blt (
218 Image
.Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
221 ASSERT (UgaDraw
!= NULL
);
222 Status
= UgaDraw
->Blt (
224 (EFI_UGA_PIXEL
*) Blt
,
225 EfiUgaBltBufferToVideo
,
232 Image
.Width
* sizeof (EFI_UGA_PIXEL
)
237 // Report displayed Logo information.
239 if (!EFI_ERROR (Status
)) {
242 if (NumberOfLogos
== 1) {
246 LogoDestX
= (UINTN
) DestX
;
247 LogoDestY
= (UINTN
) DestY
;
248 LogoWidth
= Image
.Width
;
249 LogoHeight
= Image
.Height
;
252 // Merge new logo with old one.
254 NewDestX
= MIN ((UINTN
) DestX
, LogoDestX
);
255 NewDestY
= MIN ((UINTN
) DestY
, LogoDestY
);
256 LogoWidth
= MAX ((UINTN
) DestX
+ Image
.Width
, LogoDestX
+ LogoWidth
) - NewDestX
;
257 LogoHeight
= MAX ((UINTN
) DestY
+ Image
.Height
, LogoDestY
+ LogoHeight
) - NewDestY
;
259 LogoDestX
= NewDestX
;
260 LogoDestY
= NewDestY
;
266 if (BootLogo
== NULL
|| NumberOfLogos
== 0) {
268 // No logo displayed.
278 // Advertise displayed Logo information.
280 if (NumberOfLogos
== 1) {
282 // Only one logo displayed, use its Blt buffer directly for BootLogo protocol.
285 Status
= EFI_SUCCESS
;
288 // More than one Logo displayed, get merged BltBuffer using VideoToBuffer operation.
295 // Ensure the LogoHeight * LogoWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow
297 if (LogoHeight
> MAX_UINTN
/ LogoWidth
/ sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)) {
298 return EFI_UNSUPPORTED
;
300 BufferSize
= LogoWidth
* LogoHeight
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
302 LogoBlt
= AllocatePool (BufferSize
);
303 if (LogoBlt
== NULL
) {
304 return EFI_OUT_OF_RESOURCES
;
307 if (GraphicsOutput
!= NULL
) {
308 Status
= GraphicsOutput
->Blt (
311 EfiBltVideoToBltBuffer
,
318 LogoWidth
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
321 Status
= UgaDraw
->Blt (
323 (EFI_UGA_PIXEL
*) LogoBlt
,
324 EfiUgaVideoToBltBuffer
,
331 LogoWidth
* sizeof (EFI_UGA_PIXEL
)
336 if (!EFI_ERROR (Status
)) {
337 BootLogo
->SetBootLogo (BootLogo
, LogoBlt
, LogoDestX
, LogoDestY
, LogoWidth
, LogoHeight
);
345 Use SystemTable Conout to turn on video based Simple Text Out consoles. The
346 Simple Text Out screens will now be synced up with all non video output devices
348 @retval EFI_SUCCESS UGA devices are back in text mode and synced up.
353 BootLogoDisableLogo (
359 // Enable Cursor on Screen
361 gST
->ConOut
->EnableCursor (gST
->ConOut
, TRUE
);
368 Update progress bar with title above it. It only works in Graphics mode.
370 @param TitleForeground Foreground color for Title.
371 @param TitleBackground Background color for Title.
372 @param Title Title above progress bar.
373 @param ProgressColor Progress bar color.
374 @param Progress Progress (0-100)
375 @param PreviousValue The previous value of the progress.
377 @retval EFI_STATUS Success update the progress bar
382 BootLogoUpdateProgress (
383 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground
,
384 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground
,
386 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor
,
388 IN UINTN PreviousValue
392 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
393 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
398 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color
;
406 if (Progress
> 100) {
407 return EFI_INVALID_PARAMETER
;
411 Status
= gBS
->HandleProtocol (gST
->ConsoleOutHandle
, &gEfiGraphicsOutputProtocolGuid
, (VOID
**) &GraphicsOutput
);
412 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
413 GraphicsOutput
= NULL
;
415 Status
= gBS
->HandleProtocol (gST
->ConsoleOutHandle
, &gEfiUgaDrawProtocolGuid
, (VOID
**) &UgaDraw
);
416 if (EFI_ERROR (Status
)) {
420 if (EFI_ERROR (Status
)) {
421 return EFI_UNSUPPORTED
;
426 if (GraphicsOutput
!= NULL
) {
427 SizeOfX
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
428 SizeOfY
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
429 } else if (UgaDraw
!= NULL
) {
430 Status
= UgaDraw
->GetMode (
437 if (EFI_ERROR (Status
)) {
438 return EFI_UNSUPPORTED
;
441 return EFI_UNSUPPORTED
;
444 BlockWidth
= SizeOfX
/ 100;
445 BlockHeight
= SizeOfY
/ 50;
450 PosY
= SizeOfY
* 48 / 50;
454 // Clear progress area
456 SetMem (&Color
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0x0);
458 if (GraphicsOutput
!= NULL
) {
459 Status
= GraphicsOutput
->Blt (
466 PosY
- EFI_GLYPH_HEIGHT
- 1,
468 SizeOfY
- (PosY
- EFI_GLYPH_HEIGHT
- 1),
469 SizeOfX
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
471 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
472 Status
= UgaDraw
->Blt (
474 (EFI_UGA_PIXEL
*) &Color
,
479 PosY
- EFI_GLYPH_HEIGHT
- 1,
481 SizeOfY
- (PosY
- EFI_GLYPH_HEIGHT
- 1),
482 SizeOfX
* sizeof (EFI_UGA_PIXEL
)
485 return EFI_UNSUPPORTED
;
489 // Show progress by drawing blocks
491 for (Index
= PreviousValue
; Index
< BlockNum
; Index
++) {
492 PosX
= Index
* BlockWidth
;
493 if (GraphicsOutput
!= NULL
) {
494 Status
= GraphicsOutput
->Blt (
504 (BlockWidth
) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
506 } else if (FeaturePcdGet (PcdUgaConsumeSupport
)) {
507 Status
= UgaDraw
->Blt (
509 (EFI_UGA_PIXEL
*) &ProgressColor
,
517 (BlockWidth
) * sizeof (EFI_UGA_PIXEL
)
520 return EFI_UNSUPPORTED
;
525 (SizeOfX
- StrLen (Title
) * EFI_GLYPH_WIDTH
) / 2,
526 PosY
- EFI_GLYPH_HEIGHT
- 1,