/** @file Example program using BltLib Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include #include #include UINT64 ReadTimestamp ( VOID ) { #if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) return AsmReadTsc (); #else #error ReadTimestamp not supported for this architecture! #endif } UINT32 Rand32 ( VOID ) { UINTN Found; INTN Bits; UINT64 Tsc1; UINT64 Tsc2; UINT64 TscBits; UINT32 R32; R32 = 0; Found = 0; Tsc1 = ReadTimestamp (); Tsc2 = ReadTimestamp (); do { Tsc2 = ReadTimestamp (); TscBits = Tsc2 ^ Tsc1; Bits = HighBitSet64 (TscBits); if (Bits > 0) { Bits = Bits - 1; } R32 = (UINT32)((R32 << Bits) | RShiftU64 (LShiftU64 (TscBits, (UINTN) (64 - Bits)), (UINTN) (64 - Bits))); Found = Found + Bits; } while (Found < 32); return R32; } VOID TestFills ( VOID ) { EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color; UINTN Loop; UINTN X; UINTN Y; UINTN W; UINTN H; UINTN Width; UINTN Height; BltLibGetSizes (&Width, &Height); for (Loop = 0; Loop < 10000; Loop++) { W = Width - (Rand32 () % Width); H = Height - (Rand32 () % Height); if (W != Width) { X = Rand32 () % (Width - W); } else { X = 0; } if (H != Height) { Y = Rand32 () % (Height - H); } else { Y = 0; } *(UINT32*) (&Color) = Rand32 () & 0xffffff; BltLibVideoFill (&Color, X, Y, W, H); } } VOID TestColor1 ( VOID ) { EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color; UINTN X; UINTN Y; UINTN Width; UINTN Height; BltLibGetSizes (&Width, &Height); *(UINT32*) (&Color) = 0; for (Y = 0; Y < Height; Y++) { for (X = 0; X < Width; X++) { Color.Red = (UINT8) ((X * 0x100) / Width); Color.Green = (UINT8) ((Y * 0x100) / Height); Color.Blue = (UINT8) ((Y * 0x100) / Height); BltLibVideoFill (&Color, X, Y, 1, 1); } } } UINT32 Uint32SqRt ( IN UINT32 Uint32 ) { UINT32 Mask; UINT32 SqRt; UINT32 SqRtMask; UINT32 Squared; if (Uint32 == 0) { return 0; } for (SqRt = 0, Mask = (UINT32) (1 << (HighBitSet32 (Uint32) / 2)); Mask != 0; Mask = Mask >> 1 ) { SqRtMask = SqRt | Mask; //DEBUG ((EFI_D_INFO, "Uint32=0x%x SqRtMask=0x%x\n", Uint32, SqRtMask)); Squared = (UINT32) (SqRtMask * SqRtMask); if (Squared > Uint32) { continue; } else if (Squared < Uint32) { SqRt = SqRtMask; } else { return SqRtMask; } } return SqRt; } UINT32 Uint32Dist ( IN UINTN X, IN UINTN Y ) { return Uint32SqRt ((UINT32) ((X * X) + (Y * Y))); } UINT8 GetTriColor ( IN UINTN ColorDist, IN UINTN TriWidth ) { return (UINT8) (((TriWidth - ColorDist) * 0x100) / TriWidth); //return (((TriWidth * TriWidth - ColorDist * ColorDist) * 0x100) / (TriWidth * TriWidth)); } VOID TestColor ( VOID ) { EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color; UINTN X, Y; UINTN X1, X2, X3; UINTN Y1, Y2; UINTN LineWidth, TriWidth, ScreenWidth; UINTN TriHeight, ScreenHeight; UINT32 ColorDist; BltLibGetSizes (&ScreenWidth, &ScreenHeight); *(UINT32*) (&Color) = 0; BltLibVideoFill (&Color, 0, 0, ScreenWidth, ScreenHeight); TriWidth = (UINTN) DivU64x32 ( MultU64x32 (11547005, (UINT32) ScreenHeight), 10000000 ); TriHeight = (UINTN) DivU64x32 ( MultU64x32 (8660254, (UINT32) ScreenWidth), 10000000 ); if (TriWidth > ScreenWidth) { DEBUG ((EFI_D_INFO, "TriWidth at %d was too big\n", TriWidth)); TriWidth = ScreenWidth; } else if (TriHeight > ScreenHeight) { DEBUG ((EFI_D_INFO, "TriHeight at %d was too big\n", TriHeight)); TriHeight = ScreenHeight; } DEBUG ((EFI_D_INFO, "Triangle Width: %d; Height: %d\n", TriWidth, TriHeight)); X1 = (ScreenWidth - TriWidth) / 2; X3 = X1 + TriWidth - 1; X2 = (X1 + X3) / 2; Y2 = (ScreenHeight - TriHeight) / 2; Y1 = Y2 + TriHeight - 1; for (Y = Y2; Y <= Y1; Y++) { LineWidth = (UINTN) DivU64x32 ( MultU64x32 (11547005, (UINT32) (Y - Y2)), 20000000 ); for (X = X2 - LineWidth; X < (X2 + LineWidth); X++) { ColorDist = Uint32Dist(X - X1, Y1 - Y); Color.Red = GetTriColor (ColorDist, TriWidth); ColorDist = Uint32Dist((X < X2) ? X2 - X : X - X2, Y - Y2); Color.Green = GetTriColor (ColorDist, TriWidth); ColorDist = Uint32Dist(X3 - X, Y1 - Y); Color.Blue = GetTriColor (ColorDist, TriWidth); BltLibVideoFill (&Color, X, Y, 1, 1); } } } /** The user Entry Point for Application. The user code starts with this function as the real entry point for the application. @param[in] ImageHandle The firmware allocated handle for the EFI image. @param[in] SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS The entry point is executed successfully. @retval other Some error occurs when executing this entry point. **/ EFI_STATUS EFIAPI UefiMain ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop; Status = gBS->HandleProtocol ( gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &Gop ); if (EFI_ERROR (Status)) { return Status; } Status = BltLibConfigure ( (VOID*)(UINTN) Gop->Mode->FrameBufferBase, Gop->Mode->Info ); if (EFI_ERROR (Status)) { return Status; } TestFills (); TestColor (); return EFI_SUCCESS; }