From 7e2ccccace24636f29ddc210b94606abd4c7e42b Mon Sep 17 00:00:00 2001 From: kx Date: Tue, 4 Jun 2024 06:43:08 +0300 Subject: Renormalized end-of-lines from master@27b044605cd5f6b33a3d231576003850b3fe305b --- .../DisplayUpdateProgressLibGraphics.c | 928 ++++++++++----------- 1 file changed, 464 insertions(+), 464 deletions(-) (limited to 'MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.c') diff --git a/MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.c b/MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.c index 6b012fed35..4392d8d0c3 100644 --- a/MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.c +++ b/MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.c @@ -1,464 +1,464 @@ -/** @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 Status = %r. 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; -} +/** @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 Status = %r. 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; +} -- cgit v1.2.3