/** @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;
}