TianoCore EDK2 master
Loading...
Searching...
No Matches
BootLogoLib.c
Go to the documentation of this file.
1
11#include <Uefi.h>
15#include <Protocol/UgaDraw.h>
16#include <Protocol/BootLogo.h>
17#include <Protocol/BootLogo2.h>
18#include <Library/BaseLib.h>
19#include <Library/UefiLib.h>
22#include <Library/PcdLib.h>
24#include <Library/DebugLib.h>
25
33EFIAPI
35 VOID
36 )
37{
38 EFI_STATUS Status;
39 EDKII_PLATFORM_LOGO_PROTOCOL *PlatformLogo;
40 EDKII_PLATFORM_LOGO_DISPLAY_ATTRIBUTE Attribute;
41 INTN OffsetX;
42 INTN OffsetY;
43 UINT32 SizeOfX;
44 UINT32 SizeOfY;
45 INTN DestX;
46 INTN DestY;
47 UINT32 Instance;
48 EFI_IMAGE_INPUT Image;
50 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
51 UINT32 ColorDepth;
52 UINT32 RefreshRate;
53 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
54 EFI_BOOT_LOGO_PROTOCOL *BootLogo;
56 UINTN NumberOfLogos;
58 UINTN LogoDestX;
59 UINTN LogoDestY;
60 UINTN LogoHeight;
61 UINTN LogoWidth;
62 UINTN NewDestX;
63 UINTN NewDestY;
64 UINTN BufferSize;
65
66 Status = gBS->LocateProtocol (&gEdkiiPlatformLogoProtocolGuid, NULL, (VOID **)&PlatformLogo);
67 if (EFI_ERROR (Status)) {
68 return EFI_UNSUPPORTED;
69 }
70
71 UgaDraw = NULL;
72 //
73 // Try to open GOP first
74 //
75 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **)&GraphicsOutput);
76 if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {
77 GraphicsOutput = NULL;
78 //
79 // Open GOP failed, try to open UGA
80 //
81 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **)&UgaDraw);
82 if (EFI_ERROR (Status)) {
83 UgaDraw = NULL;
84 }
85 }
86
87 if (EFI_ERROR (Status)) {
88 return EFI_UNSUPPORTED;
89 }
90
91 //
92 // Try to open Boot Logo Protocol.
93 //
94 Status = gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **)&BootLogo);
95 if (EFI_ERROR (Status)) {
96 BootLogo = NULL;
97 }
98
99 //
100 // Try to open Boot Logo 2 Protocol.
101 //
102 Status = gBS->LocateProtocol (&gEdkiiBootLogo2ProtocolGuid, NULL, (VOID **)&BootLogo2);
103 if (EFI_ERROR (Status)) {
104 BootLogo2 = NULL;
105 }
106
107 //
108 // Erase Cursor from screen
109 //
110 gST->ConOut->EnableCursor (gST->ConOut, FALSE);
111
112 if (GraphicsOutput != NULL) {
113 SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;
114 SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;
115 } else {
116 ASSERT (UgaDraw != NULL);
117 Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);
118 if (EFI_ERROR (Status)) {
119 return EFI_UNSUPPORTED;
120 }
121 }
122
123 Blt = NULL;
124 NumberOfLogos = 0;
125 LogoDestX = 0;
126 LogoDestY = 0;
127 LogoHeight = 0;
128 LogoWidth = 0;
129 NewDestX = 0;
130 NewDestY = 0;
131 Instance = 0;
132 DestX = 0;
133 DestY = 0;
134 while (TRUE) {
135 //
136 // Get image from PlatformLogo protocol.
137 //
138 Status = PlatformLogo->GetImage (
139 PlatformLogo,
140 &Instance,
141 &Image,
142 &Attribute,
143 &OffsetX,
144 &OffsetY
145 );
146 if (EFI_ERROR (Status)) {
147 break;
148 }
149
150 if (Blt != NULL) {
151 FreePool (Blt);
152 }
153
154 Blt = Image.Bitmap;
155
156 //
157 // Calculate the display position according to Attribute.
158 //
159 switch (Attribute) {
160 case EdkiiPlatformLogoDisplayAttributeLeftTop:
161 DestX = 0;
162 DestY = 0;
163 break;
164 case EdkiiPlatformLogoDisplayAttributeCenterTop:
165 DestX = (SizeOfX - Image.Width) / 2;
166 DestY = 0;
167 break;
168 case EdkiiPlatformLogoDisplayAttributeRightTop:
169 DestX = SizeOfX - Image.Width;
170 DestY = 0;
171 break;
172
173 case EdkiiPlatformLogoDisplayAttributeCenterLeft:
174 DestX = 0;
175 DestY = (SizeOfY - Image.Height) / 2;
176 break;
177 case EdkiiPlatformLogoDisplayAttributeCenter:
178 DestX = (SizeOfX - Image.Width) / 2;
179 DestY = (SizeOfY - Image.Height) / 2;
180 break;
181 case EdkiiPlatformLogoDisplayAttributeCenterRight:
182 DestX = SizeOfX - Image.Width;
183 DestY = (SizeOfY - Image.Height) / 2;
184 break;
185
186 case EdkiiPlatformLogoDisplayAttributeLeftBottom:
187 DestX = 0;
188 DestY = SizeOfY - Image.Height;
189 break;
190 case EdkiiPlatformLogoDisplayAttributeCenterBottom:
191 DestX = (SizeOfX - Image.Width) / 2;
192 DestY = SizeOfY - Image.Height;
193 break;
194 case EdkiiPlatformLogoDisplayAttributeRightBottom:
195 DestX = SizeOfX - Image.Width;
196 DestY = SizeOfY - Image.Height;
197 break;
198
199 default:
200 ASSERT (FALSE);
201 continue;
202 break;
203 }
204
205 DestX += OffsetX;
206 DestY += OffsetY;
207
208 if ((DestX >= 0) && (DestY >= 0)) {
209 if (GraphicsOutput != NULL) {
210 Status = GraphicsOutput->Blt (
211 GraphicsOutput,
212 Blt,
214 0,
215 0,
216 (UINTN)DestX,
217 (UINTN)DestY,
218 Image.Width,
219 Image.Height,
220 Image.Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
221 );
222 } else {
223 ASSERT (UgaDraw != NULL);
224 Status = UgaDraw->Blt (
225 UgaDraw,
226 (EFI_UGA_PIXEL *)Blt,
228 0,
229 0,
230 (UINTN)DestX,
231 (UINTN)DestY,
232 Image.Width,
233 Image.Height,
234 Image.Width * sizeof (EFI_UGA_PIXEL)
235 );
236 }
237
238 //
239 // Report displayed Logo information.
240 //
241 if (!EFI_ERROR (Status)) {
242 NumberOfLogos++;
243
244 if (NumberOfLogos == 1) {
245 //
246 // The first Logo.
247 //
248 LogoDestX = (UINTN)DestX;
249 LogoDestY = (UINTN)DestY;
250 LogoWidth = Image.Width;
251 LogoHeight = Image.Height;
252 } else {
253 //
254 // Merge new logo with old one.
255 //
256 NewDestX = MIN ((UINTN)DestX, LogoDestX);
257 NewDestY = MIN ((UINTN)DestY, LogoDestY);
258 LogoWidth = MAX ((UINTN)DestX + Image.Width, LogoDestX + LogoWidth) - NewDestX;
259 LogoHeight = MAX ((UINTN)DestY + Image.Height, LogoDestY + LogoHeight) - NewDestY;
260
261 LogoDestX = NewDestX;
262 LogoDestY = NewDestY;
263 }
264 }
265 }
266 }
267
268 if (((BootLogo == NULL) && (BootLogo2 == NULL)) || (NumberOfLogos == 0)) {
269 //
270 // No logo displayed.
271 //
272 if (Blt != NULL) {
273 FreePool (Blt);
274 }
275
276 return Status;
277 }
278
279 //
280 // Advertise displayed Logo information.
281 //
282 if (NumberOfLogos == 1) {
283 //
284 // Only one logo displayed, use its Blt buffer directly for BootLogo protocol.
285 //
286 LogoBlt = Blt;
287 Status = EFI_SUCCESS;
288 } else {
289 //
290 // More than one Logo displayed, get merged BltBuffer using VideoToBuffer operation.
291 //
292 if (Blt != NULL) {
293 FreePool (Blt);
294 }
295
296 //
297 // Ensure the LogoHeight * LogoWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow
298 //
299 if (LogoHeight > MAX_UINTN / LogoWidth / sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)) {
300 return EFI_UNSUPPORTED;
301 }
302
303 BufferSize = LogoWidth * LogoHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
304
305 LogoBlt = AllocatePool (BufferSize);
306 if (LogoBlt == NULL) {
307 return EFI_OUT_OF_RESOURCES;
308 }
309
310 if (GraphicsOutput != NULL) {
311 Status = GraphicsOutput->Blt (
312 GraphicsOutput,
313 LogoBlt,
315 LogoDestX,
316 LogoDestY,
317 0,
318 0,
319 LogoWidth,
320 LogoHeight,
321 LogoWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
322 );
323 } else {
324 Status = UgaDraw->Blt (
325 UgaDraw,
326 (EFI_UGA_PIXEL *)LogoBlt,
328 LogoDestX,
329 LogoDestY,
330 0,
331 0,
332 LogoWidth,
333 LogoHeight,
334 LogoWidth * sizeof (EFI_UGA_PIXEL)
335 );
336 }
337 }
338
339 if (!EFI_ERROR (Status)) {
340 //
341 // Attempt to register logo with Boot Logo 2 Protocol first
342 //
343 if (BootLogo2 != NULL) {
344 Status = BootLogo2->SetBootLogo (BootLogo2, LogoBlt, LogoDestX, LogoDestY, LogoWidth, LogoHeight);
345 }
346
347 //
348 // If Boot Logo 2 Protocol is not available or registration with Boot Logo 2
349 // Protocol failed, then attempt to register logo with Boot Logo Protocol
350 //
351 if (EFI_ERROR (Status) && (BootLogo != NULL)) {
352 Status = BootLogo->SetBootLogo (BootLogo, LogoBlt, LogoDestX, LogoDestY, LogoWidth, LogoHeight);
353 }
354
355 //
356 // Status of this function is EFI_SUCCESS even if registration with Boot
357 // Logo 2 Protocol or Boot Logo Protocol fails.
358 //
359 Status = EFI_SUCCESS;
360 }
361
362 FreePool (LogoBlt);
363
364 return Status;
365}
366
375EFIAPI
377 VOID
378 )
379{
380 //
381 // Enable Cursor on Screen
382 //
383 gST->ConOut->EnableCursor (gST->ConOut, TRUE);
384 return EFI_SUCCESS;
385}
386
402EFIAPI
404 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground,
405 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground,
406 IN CHAR16 *Title,
407 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor,
408 IN UINTN Progress,
409 IN UINTN PreviousValue
410 )
411{
412 EFI_STATUS Status;
413 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
414 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
415 UINT32 SizeOfX;
416 UINT32 SizeOfY;
417 UINT32 ColorDepth;
418 UINT32 RefreshRate;
420 UINTN BlockHeight;
421 UINTN BlockWidth;
422 UINTN BlockNum;
423 UINTN PosX;
424 UINTN PosY;
425 UINTN Index;
426
427 if (Progress > 100) {
428 return EFI_INVALID_PARAMETER;
429 }
430
431 UgaDraw = NULL;
432 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **)&GraphicsOutput);
433 if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {
434 GraphicsOutput = NULL;
435
436 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **)&UgaDraw);
437 if (EFI_ERROR (Status)) {
438 UgaDraw = NULL;
439 }
440 }
441
442 if (EFI_ERROR (Status)) {
443 return EFI_UNSUPPORTED;
444 }
445
446 SizeOfX = 0;
447 SizeOfY = 0;
448 if (GraphicsOutput != NULL) {
449 SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;
450 SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;
451 } else if (UgaDraw != NULL) {
452 Status = UgaDraw->GetMode (
453 UgaDraw,
454 &SizeOfX,
455 &SizeOfY,
456 &ColorDepth,
457 &RefreshRate
458 );
459 if (EFI_ERROR (Status)) {
460 return EFI_UNSUPPORTED;
461 }
462 } else {
463 return EFI_UNSUPPORTED;
464 }
465
466 BlockWidth = SizeOfX / 100;
467 BlockHeight = SizeOfY / 50;
468
469 BlockNum = Progress;
470
471 PosX = 0;
472 PosY = SizeOfY * 48 / 50;
473
474 if (BlockNum == 0) {
475 //
476 // Clear progress area
477 //
478 SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
479
480 if (GraphicsOutput != NULL) {
481 Status = GraphicsOutput->Blt (
482 GraphicsOutput,
483 &Color,
485 0,
486 0,
487 0,
488 PosY - EFI_GLYPH_HEIGHT - 1,
489 SizeOfX,
490 SizeOfY - (PosY - EFI_GLYPH_HEIGHT - 1),
491 SizeOfX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
492 );
493 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
494 Status = UgaDraw->Blt (
495 UgaDraw,
496 (EFI_UGA_PIXEL *)&Color,
498 0,
499 0,
500 0,
501 PosY - EFI_GLYPH_HEIGHT - 1,
502 SizeOfX,
503 SizeOfY - (PosY - EFI_GLYPH_HEIGHT - 1),
504 SizeOfX * sizeof (EFI_UGA_PIXEL)
505 );
506 } else {
507 return EFI_UNSUPPORTED;
508 }
509 }
510
511 //
512 // Show progress by drawing blocks
513 //
514 for (Index = PreviousValue; Index < BlockNum; Index++) {
515 PosX = Index * BlockWidth;
516 if (GraphicsOutput != NULL) {
517 Status = GraphicsOutput->Blt (
518 GraphicsOutput,
519 &ProgressColor,
521 0,
522 0,
523 PosX,
524 PosY,
525 BlockWidth - 1,
526 BlockHeight,
527 (BlockWidth) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
528 );
529 } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
530 Status = UgaDraw->Blt (
531 UgaDraw,
532 (EFI_UGA_PIXEL *)&ProgressColor,
534 0,
535 0,
536 PosX,
537 PosY,
538 BlockWidth - 1,
539 BlockHeight,
540 (BlockWidth) * sizeof (EFI_UGA_PIXEL)
541 );
542 } else {
543 return EFI_UNSUPPORTED;
544 }
545 }
546
547 PrintXY (
548 (SizeOfX - StrLen (Title) * EFI_GLYPH_WIDTH) / 2,
549 PosY - EFI_GLYPH_HEIGHT - 1,
550 &TitleForeground,
551 &TitleBackground,
552 Title
553 );
554
555 return EFI_SUCCESS;
556}
UINT64 UINTN
INT64 INTN
UINTN EFIAPI StrLen(IN CONST CHAR16 *String)
Definition: String.c:30
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
Definition: SetMemWrapper.c:38
EFI_STATUS EFIAPI BootLogoUpdateProgress(IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground, IN CHAR16 *Title, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor, IN UINTN Progress, IN UINTN PreviousValue)
Definition: BootLogoLib.c:403
EFI_STATUS EFIAPI BootLogoDisableLogo(VOID)
Definition: BootLogoLib.c:376
EFI_STATUS EFIAPI BootLogoEnableLogo(VOID)
Definition: BootLogoLib.c:34
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define MIN(a, b)
Definition: Base.h:1007
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define MAX(a, b)
Definition: Base.h:992
@ EfiBltVideoToBltBuffer
@ EfiBltBufferToVideo
@ EfiBltVideoFill
#define FeaturePcdGet(TokenName)
Definition: PcdLib.h:50
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_SYSTEM_TABLE * gST
EFI_BOOT_SERVICES * gBS
UINTN EFIAPI PrintXY(IN UINTN PointX, IN UINTN PointY, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *ForeGround OPTIONAL, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BackGround OPTIONAL, IN CONST CHAR16 *Format,...)
Definition: UefiLibPrint.c:617
@ EfiUgaVideoToBltBuffer
Definition: UgaDraw.h:89
@ EfiUgaBltBufferToVideo
Definition: UgaDraw.h:96
@ EfiUgaVideoFill
Definition: UgaDraw.h:84
EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE * Mode
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION * Info
EFI_HANDLE ConsoleOutHandle
Definition: UefiSpec.h:2059
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL * ConOut
Definition: UefiSpec.h:2064