From af1a266670d040d2f4083ff309d732d648afba2a Mon Sep 17 00:00:00 2001 From: Angelos Mouzakitis Date: Tue, 10 Oct 2023 14:33:42 +0000 Subject: Add submodule dependency files Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec --- .../DisplayUpdateProgressLibGraphics.c | 458 +++++++++++++++++++++ .../DisplayUpdateProgressLibGraphics.inf | 43 ++ .../DisplayUpdateProgressLibGraphics.uni | 13 + 3 files changed, 514 insertions(+) create mode 100644 roms/edk2/MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.c create mode 100644 roms/edk2/MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.inf create mode 100644 roms/edk2/MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.uni (limited to 'roms/edk2/MdeModulePkg/Library/DisplayUpdateProgressLibGraphics') diff --git a/roms/edk2/MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.c b/roms/edk2/MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.c new file mode 100644 index 000000000..5f3ae6ab7 --- /dev/null +++ b/roms/edk2/MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.c @@ -0,0 +1,458 @@ +/** @file + Provides services to display completion progress of a firmware update on a + graphical console that supports the Graphics Output Protocol. + + Copyright (c) 2016, Microsoft Corporation. All rights reserved.
+ Copyright (c) 2018, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +// +// Values in percent of of logo height. +// +#define LOGO_BOTTOM_PADDING 20 +#define PROGRESS_BLOCK_HEIGHT 10 + +// +// Graphics Output Protocol instance to display progress bar +// +EFI_GRAPHICS_OUTPUT_PROTOCOL *mGop = NULL; + +// +// Set to 100 percent so it is reset on first call. +// +UINTN mPreviousProgress = 100; + +// +// Display coordinates for the progress bar. +// +UINTN mStartX = 0; +UINTN mStartY = 0; + +// +// Width and height of the progress bar. +// +UINTN mBlockWidth = 0; +UINTN mBlockHeight = 0; + +// +// GOP bitmap of the progress bar. Initialized on every new progress of 100% +// +EFI_GRAPHICS_OUTPUT_BLT_PIXEL *mBlockBitmap; + +// +// GOP bitmap of the progress bar backround. Initialized once. +// +EFI_GRAPHICS_OUTPUT_BLT_PIXEL *mProgressBarBackground; + +// +// Default mask used to detect the left, right , top, and bottom of logo. Only +// green and blue pixels are used for logo detection. +// +const EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION mLogoDetectionColorMask = { + { + 0xFF, // Blue + 0xFF, // Green + 0x00, // Red + 0x00 // Reserved + } +}; + +// +// Background color of progress bar. Grey. +// +const EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION mProgressBarBackgroundColor = { + { + 0x80, // Blue + 0x80, // Green + 0x80, // Red + 0x00 // Reserved + } +}; + +// +// Default color of progress completion. White. +// +const EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION mProgressBarDefaultColor = { + { + 0xFF, // Blue + 0xFF, // Green + 0xFF, // Red + 0x00 // Reserved + } +}; + +// +// Set to TRUE if a valid Graphics Output Protocol is found and the progress +// bar fits under the boot logo using the current graphics mode. +// +BOOLEAN mGraphicsGood = FALSE; + +/** + Internal function used to find the bounds of the white logo (on black or + red background). + + These bounds are then computed to find the block size, 0%, 100%, etc. + +**/ +VOID +FindDim ( + VOID + ) +{ + EFI_STATUS Status; + INTN LogoX; + INTN LogoStartX; + INTN LogoEndX; + INTN LogoY; + INTN LogoStartY; + INTN LogoEndY; + UINTN OffsetX; // Logo screen coordinate + UINTN OffsetY; // Logo screen coordinate + UINTN Width; // Width of logo in pixels + UINTN Height; // Height of logo in pixels + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Logo; + EDKII_BOOT_LOGO2_PROTOCOL *BootLogo; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION *Pixel; + + Logo = NULL; + BootLogo = NULL; + + // + // Return if a Graphics Output Protocol ha snot been found. + // + if (mGop == NULL) { + DEBUG ((DEBUG_ERROR, "No GOP found. No progress bar support. \n")); + return; + } + + // + // Get boot logo protocol so we know where on the screen to grab + // + Status = gBS->LocateProtocol ( + &gEdkiiBootLogo2ProtocolGuid, + NULL, + (VOID **)&BootLogo + ); + if ((BootLogo == NULL) || (EFI_ERROR (Status))) { + DEBUG ((DEBUG_ERROR, "Failed to locate gEdkiiBootLogo2ProtocolGuid. No Progress bar support. \n", Status)); + return; + } + + // + // Get logo location and size + // + Status = BootLogo->GetBootLogo ( + BootLogo, + &Logo, + &OffsetX, + &OffsetY, + &Width, + &Height + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed to Get Boot Logo Status = %r. No Progress bar support. \n", Status)); + return; + } + + // + // Within logo buffer find where the actual logo starts/ends + // + LogoEndX = 0; + LogoEndY = 0; + + // + // Find left side of logo in logo coordinates + // + for (LogoX = 0, LogoStartX = Width; LogoX < LogoStartX; LogoX++) { + Pixel = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION *)(Logo + LogoX); + for (LogoY = 0; LogoY < (INTN)Height; LogoY++) { + if ((Pixel->Raw & mLogoDetectionColorMask.Raw) != 0x0) { + LogoStartX = LogoX; + // + // For loop searches from right side back to this column. + // + LogoEndX = LogoX; + DEBUG ((DEBUG_INFO, "StartX found at (%d, %d) Color is: 0x%X \n", LogoX, LogoY, Pixel->Raw)); + break; + } + Pixel = Pixel + Width; + } + } + + // + // Find right side of logo + // + for (LogoX = Width - 1; LogoX >= LogoEndX; LogoX--) { + Pixel = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION *)(Logo + LogoX); + for (LogoY = 0; LogoY < (INTN)Height; LogoY++) { + if ((Pixel->Raw & mLogoDetectionColorMask.Raw) != 0x0) { + LogoEndX = LogoX; + DEBUG ((DEBUG_INFO, "EndX found at (%d, %d) Color is: 0x%X \n", LogoX, LogoY, Pixel->Raw)); + break; + } + Pixel = Pixel + Width; + } + } + + // + // Compute mBlockWidth + // + mBlockWidth = ((LogoEndX - LogoStartX) + 99) / 100; + + // + // Adjust mStartX based on block width so it is centered under logo + // + mStartX = LogoStartX + OffsetX - (((mBlockWidth * 100) - (LogoEndX - LogoStartX)) / 2); + DEBUG ((DEBUG_INFO, "mBlockWidth set to 0x%X\n", mBlockWidth)); + DEBUG ((DEBUG_INFO, "mStartX set to 0x%X\n", mStartX)); + + // + // Find the top of the logo + // + for (LogoY = 0, LogoStartY = Height; LogoY < LogoStartY; LogoY++) { + Pixel = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION *)(Logo + (Width * LogoY)); + for (LogoX = 0; LogoX < (INTN)Width; LogoX++) { + //not black or red + if ((Pixel->Raw & mLogoDetectionColorMask.Raw) != 0x0) { + LogoStartY = LogoY; + LogoEndY = LogoY; //for next loop will search from bottom side back to this row. + DEBUG ((DEBUG_INFO, "StartY found at (%d, %d) Color is: 0x%X \n", LogoX, LogoY, Pixel->Raw)); + break; + } + Pixel++; + } + } + + // + // Find the bottom of the logo + // + for (LogoY = Height - 1; LogoY >= LogoEndY; LogoY--) { + Pixel = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION *)(Logo + (Width * LogoY)); + for (LogoX = 0; LogoX < (INTN)Width; LogoX++) { + if ((Pixel->Raw & mLogoDetectionColorMask.Raw) != 0x0) { + LogoEndY = LogoY; + DEBUG ((DEBUG_INFO, "EndY found at (%d, %d) Color is: 0x%X \n", LogoX, LogoY, Pixel->Raw)); + break; + } + Pixel++; + } + } + + // + // Compute bottom padding (distance between logo bottom and progress bar) + // + mStartY = (((LogoEndY - LogoStartY) * LOGO_BOTTOM_PADDING) / 100) + LogoEndY + OffsetY; + + // + // Compute progress bar height + // + mBlockHeight = (((LogoEndY - LogoStartY) * PROGRESS_BLOCK_HEIGHT) / 100); + + DEBUG ((DEBUG_INFO, "mBlockHeight set to 0x%X\n", mBlockHeight)); + + // + // Create progress bar background (one time init). + // + mProgressBarBackground = AllocatePool (mBlockWidth * 100 * mBlockHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); + if (mProgressBarBackground == NULL) { + DEBUG ((DEBUG_ERROR, "Failed to allocate progress bar background\n")); + return; + } + + // + // Fill the progress bar with the background color + // + SetMem32 ( + mProgressBarBackground, + (mBlockWidth * 100 * mBlockHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)), + mProgressBarBackgroundColor.Raw + ); + + // + // Allocate mBlockBitmap + // + mBlockBitmap = AllocatePool (mBlockWidth * mBlockHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); + if (mBlockBitmap == NULL) { + FreePool (mProgressBarBackground); + DEBUG ((DEBUG_ERROR, "Failed to allocate block\n")); + return; + } + + // + // Check screen width and height and make sure it fits. + // + if ((mBlockHeight > Height) || (mBlockWidth > Width) || (mBlockHeight < 1) || (mBlockWidth < 1)) { + DEBUG ((DEBUG_ERROR, "DisplayUpdateProgressLib - Progress - Failed to get valid width and height.\n")); + DEBUG ((DEBUG_ERROR, "DisplayUpdateProgressLib - Progress - mBlockHeight: 0x%X mBlockWidth: 0x%X.\n", mBlockHeight, mBlockWidth)); + FreePool (mProgressBarBackground); + FreePool (mBlockBitmap); + return; + } + + mGraphicsGood = TRUE; +} + +/** + Function indicates the current completion progress of a firmware update. + Platform may override with its own specific function. + + @param[in] Completion A value between 0 and 100 indicating the current + completion progress of a firmware update. This + value must the the same or higher than previous + calls to this service. The first call of 0 or a + value of 0 after reaching a value of 100 resets + the progress indicator to 0. + @param[in] Color Color of the progress indicator. Only used when + Completion is 0 to set the color of the progress + indicator. If Color is NULL, then the default color + is used. + + @retval EFI_SUCCESS Progress displayed successfully. + @retval EFI_INVALID_PARAMETER Completion is not in range 0..100. + @retval EFI_INVALID_PARAMETER Completion is less than Completion value from + a previous call to this service. + @retval EFI_NOT_READY The device used to indicate progress is not + available. +**/ +EFI_STATUS +EFIAPI +DisplayUpdateProgress ( + IN UINTN Completion, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION *Color OPTIONAL + ) +{ + EFI_STATUS Status; + UINTN PreX; + UINTN Index; + + // + // Check range + // + if (Completion > 100) { + return EFI_INVALID_PARAMETER; + } + + // + // Check to see if this Completion percentage has already been displayed + // + if (Completion == mPreviousProgress) { + return EFI_SUCCESS; + } + + // + // Find Graphics Output Protocol if not already set. 1 time. + // + if (mGop == NULL) { + Status = gBS->HandleProtocol ( + gST->ConsoleOutHandle, + &gEfiGraphicsOutputProtocolGuid, + (VOID**)&mGop + ); + if (EFI_ERROR (Status)) { + Status = gBS->LocateProtocol (&gEfiGraphicsOutputProtocolGuid, NULL, (VOID **)&mGop); + if (EFI_ERROR (Status)) { + mGop = NULL; + DEBUG ((DEBUG_ERROR, "Show Progress Function could not locate GOP. Status = %r\n", Status)); + return EFI_NOT_READY; + } + } + + // + // Run once + // + FindDim (); + } + + // + // Make sure a valid start, end, and size info are available (find the Logo) + // + if (!mGraphicsGood) { + DEBUG ((DEBUG_INFO, "Graphics Not Good. Not doing any onscreen visual display\n")); + return EFI_NOT_READY; + } + + // + // Do special init on first call of each progress session + // + if (mPreviousProgress == 100) { + // + // Draw progress bar background + // + mGop->Blt ( + mGop, + mProgressBarBackground, + EfiBltBufferToVideo, + 0, + 0, + mStartX, + mStartY, + (mBlockWidth * 100), + mBlockHeight, + 0 + ); + + DEBUG ((DEBUG_VERBOSE, "Color is 0x%X\n", + (Color == NULL) ? mProgressBarDefaultColor.Raw : Color->Raw + )); + + // + // Update block bitmap with correct color + // + SetMem32 ( + mBlockBitmap, + (mBlockWidth * mBlockHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)), + (Color == NULL) ? mProgressBarDefaultColor.Raw : Color->Raw + ); + + // + // Clear previous + // + mPreviousProgress = 0; + } + + // + // Can not update progress bar if Completion is less than previous + // + if (Completion < mPreviousProgress) { + DEBUG ((DEBUG_WARN, "WARNING: Completion (%d) should not be lesss than Previous (%d)!!!\n", Completion, mPreviousProgress)); + return EFI_INVALID_PARAMETER; + } + + PreX = ((mPreviousProgress * mBlockWidth) + mStartX); + for (Index = 0; Index < (Completion - mPreviousProgress); Index++) { + // + // Show progress by coloring new area + // + mGop->Blt ( + mGop, + mBlockBitmap, + EfiBltBufferToVideo, + 0, + 0, + PreX, + mStartY, + mBlockWidth, + mBlockHeight, + 0 + ); + PreX += mBlockWidth; + } + + mPreviousProgress = Completion; + + return EFI_SUCCESS; +} diff --git a/roms/edk2/MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.inf b/roms/edk2/MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.inf new file mode 100644 index 000000000..175b7e434 --- /dev/null +++ b/roms/edk2/MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.inf @@ -0,0 +1,43 @@ +## @file +# Provides services to display completion progress of a firmware update on a +# graphical console that supports the Graphics Output Protocol. +# +# Copyright (c) 2016, Microsoft Corporation, All rights reserved.
+# Copyright (c) 2018, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DisplayUpdateProgressLibGraphics + MODULE_UNI_FILE = DisplayUpdateProgressLibGraphics.uni + FILE_GUID = 319E9E37-B2D6-4699-90F3-B8B72B6D4CBD + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = DisplayUpdateProgressLib|DXE_DRIVER UEFI_DRIVER UEFI_APPLICATION + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + DisplayUpdateProgressLibGraphics.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseMemoryLib + DebugLib + MemoryAllocationLib + UefiBootServicesTableLib + BaseLib + UefiLib + +[Protocols] + gEfiGraphicsOutputProtocolGuid # CONSUMES + gEdkiiBootLogo2ProtocolGuid # CONSUMES diff --git a/roms/edk2/MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.uni b/roms/edk2/MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.uni new file mode 100644 index 000000000..7e8e48f5f --- /dev/null +++ b/roms/edk2/MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.uni @@ -0,0 +1,13 @@ +// /** @file +// Provides services to display completion progress of a firmware update on a +// graphical console that supports the Graphics Output Protocol. +// +// Copyright (c) 2018, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "Provides services to display completion progress of a firmware update on a graphical console that supports the Graphics Output Protocol." + +#string STR_MODULE_DESCRIPTION #language en-US "Provides services to display completion progress of a firmware update on a graphical console that supports the Graphics Output Protocol." -- cgit