OptionRomPkg BltLibSample: Add sample application for BltLib
[mirror_edk2.git] / OptionRomPkg / Application / BltLibSample / BltLibSample.c
1 /** @file
2 Example program using BltLib
3
4 Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include <Uefi.h>
16 #include <Library/BltLib.h>
17 #include <Library/DebugLib.h>
18 #include <Library/UefiLib.h>
19 #include <Library/UefiApplicationEntryPoint.h>
20 #include <Library/UefiBootServicesTableLib.h>
21
22
23 UINT32
24 Rand32 (
25 VOID
26 )
27 {
28 UINTN Found;
29 UINTN Bits;
30 UINT64 Tsc1;
31 UINT64 Tsc2;
32 UINT64 TscBits;
33 UINT32 R32;
34
35 R32 = 0;
36 Found = 0;
37 Tsc1 = AsmReadTsc ();
38 Tsc2 = AsmReadTsc ();
39 do {
40 Tsc2 = AsmReadTsc ();
41 TscBits = Tsc2 ^ Tsc1;
42 Bits = HighBitSet64 (TscBits);
43 if (Bits > 0) {
44 Bits = Bits - 1;
45 }
46 R32 = (R32 << Bits) | RShiftU64 (LShiftU64 (TscBits, 64 - Bits), 64 - Bits);
47 Found = Found + Bits;
48 } while (Found < 32);
49
50 return R32;
51 }
52
53
54 VOID
55 TestFills (
56 VOID
57 )
58 {
59 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;
60 UINTN Loop;
61 UINTN X;
62 UINTN Y;
63 UINTN W;
64 UINTN H;
65 UINTN Width;
66 UINTN Height;
67
68 BltLibGetSizes (&Width, &Height);
69 for (Loop = 0; Loop < 10000; Loop++) {
70 W = Width - (Rand32 () % Width);
71 H = Height - (Rand32 () % Height);
72 if (W != Width) {
73 X = Rand32 () % (Width - W);
74 } else {
75 X = 0;
76 }
77 if (H != Height) {
78 Y = Rand32 () % (Height - H);
79 } else {
80 Y = 0;
81 }
82 *(UINT32*) (&Color) = Rand32 () & 0xffffff;
83 BltLibVideoFill (&Color, X, Y, W, H);
84 }
85 }
86
87
88 VOID
89 TestColor1 (
90 VOID
91 )
92 {
93 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;
94 UINTN X;
95 UINTN Y;
96 UINTN Width;
97 UINTN Height;
98
99 BltLibGetSizes (&Width, &Height);
100 *(UINT32*) (&Color) = 0;
101
102 for (Y = 0; Y < Height; Y++) {
103 for (X = 0; X < Width; X++) {
104 Color.Red = ((X * 0x100) / Width);
105 Color.Green = ((Y * 0x100) / Height);
106 Color.Blue = ((Y * 0x100) / Height);
107 BltLibVideoFill (&Color, X, Y, 1, 1);
108 }
109 }
110 }
111
112
113 UINT32
114 Uint32SqRt (
115 IN UINT32 Uint32
116 )
117 {
118 UINTN Mask;
119 UINT32 SqRt;
120 UINT32 SqRtMask;
121 UINT32 Squared;
122
123 if (Uint32 == 0) {
124 return 0;
125 }
126
127 for (SqRt = 0, Mask = 1 << (HighBitSet32 (Uint32) / 2);
128 Mask != 0;
129 Mask = Mask >> 1
130 ) {
131 SqRtMask = SqRt | Mask;
132 //DEBUG ((EFI_D_INFO, "Uint32=0x%x SqRtMask=0x%x\n", Uint32, SqRtMask));
133 Squared = (UINT32) (SqRtMask * SqRtMask);
134 if (Squared > Uint32) {
135 continue;
136 } else if (Squared < Uint32) {
137 SqRt = SqRtMask;
138 } else {
139 return SqRtMask;
140 }
141 }
142
143 return SqRt;
144 }
145
146
147 UINT32
148 Uint32Dist (
149 IN UINT32 X,
150 IN UINT32 Y
151 )
152 {
153 return Uint32SqRt ((X * X) + (Y * Y));
154 }
155
156 UINT32
157 GetTriColor (
158 IN UINT32 ColorDist,
159 IN UINT32 TriWidth
160 )
161 {
162 return (((TriWidth - ColorDist) * 0x100) / TriWidth);
163 //return (((TriWidth * TriWidth - ColorDist * ColorDist) * 0x100) / (TriWidth * TriWidth));
164 }
165
166 VOID
167 TestColor (
168 VOID
169 )
170 {
171 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;
172 UINTN X, Y;
173 UINTN X1, X2, X3;
174 UINTN Y1, Y2;
175 UINTN LineWidth, TriWidth, ScreenWidth;
176 UINTN TriHeight, ScreenHeight;
177 UINTN ColorDist;
178
179 BltLibGetSizes (&ScreenWidth, &ScreenHeight);
180 *(UINT32*) (&Color) = 0;
181 BltLibVideoFill (&Color, 0, 0, ScreenWidth, ScreenHeight);
182
183 TriWidth = DivU64x32 (MultU64x32 (11547005, ScreenHeight), 10000000);
184 TriHeight = DivU64x32 (MultU64x32 (8660254, ScreenWidth), 10000000);
185 if (TriWidth > ScreenWidth) {
186 DEBUG ((EFI_D_INFO, "TriWidth at %d was too big\n", TriWidth));
187 TriWidth = ScreenWidth;
188 } else if (TriHeight > ScreenHeight) {
189 DEBUG ((EFI_D_INFO, "TriHeight at %d was too big\n", TriHeight));
190 TriHeight = ScreenHeight;
191 }
192
193 DEBUG ((EFI_D_INFO, "Triangle Width: %d; Height: %d\n", TriWidth, TriHeight));
194
195 X1 = (ScreenWidth - TriWidth) / 2;
196 X3 = X1 + TriWidth - 1;
197 X2 = (X1 + X3) / 2;
198 Y2 = (ScreenHeight - TriHeight) / 2;
199 Y1 = Y2 + TriHeight - 1;
200
201 for (Y = Y2; Y <= Y1; Y++) {
202 LineWidth =
203 DivU64x32 (
204 MultU64x32 (11547005, (Y - Y2)),
205 20000000
206 );
207 for (X = X2 - LineWidth; X < (X2 + LineWidth); X++) {
208 ColorDist = Uint32Dist(X - X1, Y1 - Y);
209 Color.Red = GetTriColor (ColorDist, TriWidth);
210
211 ColorDist = Uint32Dist((X < X2) ? X2 - X : X - X2, Y - Y2);
212 Color.Green = GetTriColor (ColorDist, TriWidth);
213
214 ColorDist = Uint32Dist(X3 - X, Y1 - Y);
215 Color.Blue = GetTriColor (ColorDist, TriWidth);
216
217 BltLibVideoFill (&Color, X, Y, 1, 1);
218 }
219 }
220 }
221
222
223 /**
224 The user Entry Point for Application. The user code starts with this function
225 as the real entry point for the application.
226
227 @param[in] ImageHandle The firmware allocated handle for the EFI image.
228 @param[in] SystemTable A pointer to the EFI System Table.
229
230 @retval EFI_SUCCESS The entry point is executed successfully.
231 @retval other Some error occurs when executing this entry point.
232
233 **/
234 EFI_STATUS
235 EFIAPI
236 UefiMain (
237 IN EFI_HANDLE ImageHandle,
238 IN EFI_SYSTEM_TABLE *SystemTable
239 )
240 {
241 EFI_STATUS Status;
242 EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;
243
244 Status = gBS->HandleProtocol (
245 gST->ConsoleOutHandle,
246 &gEfiGraphicsOutputProtocolGuid,
247 (VOID **) &Gop
248 );
249 if (EFI_ERROR (Status)) {
250 return Status;
251 }
252
253 Status = BltLibConfigure (
254 (VOID*)(UINTN) Gop->Mode->FrameBufferBase,
255 Gop->Mode->Info
256 );
257 if (EFI_ERROR (Status)) {
258 return Status;
259 }
260
261 TestFills ();
262
263 TestColor ();
264
265 return EFI_SUCCESS;
266 }