e5e1d2e2 |
1 | /** @file\r |
2 | FrameBufferBltLib - Library to perform blt operations on a frame buffer.\r |
3 | \r |
4 | Copyright (c) 2007 - 2011, Intel Corporation\r |
5 | All rights reserved. This program and the accompanying materials\r |
6 | are licensed and made available under the terms and conditions of the BSD License\r |
7 | which accompanies this distribution. The full text of the license may be found at\r |
8 | http://opensource.org/licenses/bsd-license.php\r |
9 | \r |
10 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r |
11 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r |
12 | \r |
13 | **/\r |
14 | \r |
15 | #include "PiDxe.h"\r |
16 | #include <Library/BaseLib.h>\r |
17 | #include <Library/BaseMemoryLib.h>\r |
18 | #include <Library/BltLib.h>\r |
19 | #include <Library/DebugLib.h>\r |
20 | \r |
21 | #if 0\r |
22 | #define VDEBUG DEBUG\r |
23 | #else\r |
24 | #define VDEBUG(x)\r |
25 | #endif\r |
26 | \r |
27 | #define MAX_LINE_BUFFER_SIZE (SIZE_4KB * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))\r |
28 | \r |
29 | UINTN mBltLibColorDepth;\r |
30 | UINTN mBltLibWidthInBytes;\r |
31 | UINTN mBltLibBytesPerPixel;\r |
32 | UINTN mBltLibWidthInPixels;\r |
33 | UINTN mBltLibHeight;\r |
34 | UINT8 mBltLibLineBuffer[MAX_LINE_BUFFER_SIZE];\r |
35 | UINT8 *mBltLibFrameBuffer;\r |
36 | EFI_GRAPHICS_PIXEL_FORMAT mPixelFormat;\r |
37 | EFI_PIXEL_BITMASK mPixelBitMasks;\r |
38 | INTN mPixelShl[4]; // R-G-B-Rsvd\r |
39 | INTN mPixelShr[4]; // R-G-B-Rsvd\r |
40 | \r |
41 | \r |
42 | VOID\r |
43 | ConfigurePixelBitMaskFormat (\r |
44 | IN EFI_PIXEL_BITMASK *BitMask\r |
45 | )\r |
46 | {\r |
47 | UINTN Loop;\r |
48 | UINT32 *Masks;\r |
49 | UINT32 MergedMasks;\r |
50 | \r |
51 | MergedMasks = 0;\r |
52 | Masks = (UINT32*) BitMask;\r |
53 | for (Loop = 0; Loop < 3; Loop++) {\r |
54 | ASSERT ((Loop == 3) || (Masks[Loop] != 0));\r |
55 | ASSERT ((MergedMasks & Masks[Loop]) == 0);\r |
56 | mPixelShl[Loop] = HighBitSet32 (Masks[Loop]) - 23 + (Loop * 8);\r |
57 | if (mPixelShl[Loop] < 0) {\r |
58 | mPixelShr[Loop] = -mPixelShl[Loop];\r |
59 | mPixelShl[Loop] = 0;\r |
60 | } else {\r |
61 | mPixelShr[Loop] = 0;\r |
62 | }\r |
63 | MergedMasks = (UINT32) (MergedMasks | Masks[Loop]);\r |
64 | DEBUG ((EFI_D_INFO, "%d: shl:%d shr:%d mask:%x\n", Loop, mPixelShl[Loop], mPixelShr[Loop], Masks[Loop]));\r |
65 | }\r |
66 | MergedMasks = (UINT32) (MergedMasks | Masks[3]);\r |
67 | \r |
68 | mBltLibBytesPerPixel = HighBitSet32 (MergedMasks);\r |
69 | ASSERT (mBltLibBytesPerPixel >= 0);\r |
70 | mBltLibBytesPerPixel = (mBltLibBytesPerPixel + 7) / 8;\r |
71 | \r |
72 | DEBUG ((EFI_D_INFO, "Bytes per pixel: %d\n", mBltLibBytesPerPixel));\r |
73 | \r |
74 | CopyMem (&mPixelBitMasks, BitMask, sizeof (*BitMask));\r |
75 | }\r |
76 | \r |
77 | \r |
78 | /**\r |
79 | Configure the FrameBufferLib instance\r |
80 | \r |
81 | @param[in] FrameBuffer Pointer to the start of the frame buffer\r |
82 | @param[in] FrameBufferInfo Describes the frame buffer characteristics\r |
83 | \r |
84 | @retval EFI_INVALID_PARAMETER - Invalid parameter\r |
85 | @retval EFI_UNSUPPORTED - The BltLib does not support this configuration\r |
86 | @retval EFI_SUCCESS - Blt operation success\r |
87 | \r |
88 | **/\r |
89 | EFI_STATUS\r |
90 | EFIAPI\r |
91 | BltLibConfigure (\r |
92 | IN VOID *FrameBuffer,\r |
93 | IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo\r |
94 | )\r |
95 | {\r |
96 | STATIC EFI_PIXEL_BITMASK RgbPixelMasks =\r |
97 | { 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 };\r |
98 | STATIC EFI_PIXEL_BITMASK BgrPixelMasks =\r |
99 | { 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 };\r |
100 | \r |
101 | switch (FrameBufferInfo->PixelFormat) {\r |
102 | case PixelRedGreenBlueReserved8BitPerColor:\r |
103 | ConfigurePixelBitMaskFormat (&RgbPixelMasks);\r |
104 | break;\r |
105 | case PixelBlueGreenRedReserved8BitPerColor:\r |
106 | ConfigurePixelBitMaskFormat (&BgrPixelMasks);\r |
107 | break;\r |
108 | case PixelBitMask:\r |
109 | ConfigurePixelBitMaskFormat (&(FrameBufferInfo->PixelInformation));\r |
110 | break;\r |
111 | case PixelBltOnly:\r |
112 | ASSERT (FrameBufferInfo->PixelFormat != PixelBltOnly);\r |
113 | return EFI_UNSUPPORTED;\r |
114 | default:\r |
115 | ASSERT (FALSE);\r |
116 | return EFI_INVALID_PARAMETER;\r |
117 | }\r |
118 | mPixelFormat = FrameBufferInfo->PixelFormat;\r |
119 | \r |
120 | mBltLibFrameBuffer = (UINT8*) FrameBuffer;\r |
121 | mBltLibWidthInPixels = (UINTN) FrameBufferInfo->HorizontalResolution;\r |
122 | mBltLibHeight = (UINTN) FrameBufferInfo->VerticalResolution;\r |
123 | mBltLibWidthInBytes = mBltLibWidthInPixels * mBltLibBytesPerPixel;\r |
124 | \r |
125 | ASSERT (mBltLibWidthInBytes < sizeof (mBltLibLineBuffer));\r |
126 | \r |
127 | return EFI_SUCCESS;\r |
128 | }\r |
129 | \r |
130 | \r |
131 | /**\r |
132 | Performs a UEFI Graphics Output Protocol Blt operation.\r |
133 | \r |
134 | @param[in,out] BltBuffer - The data to transfer to screen\r |
135 | @param[in] BltOperation - The operation to perform\r |
136 | @param[in] SourceX - The X coordinate of the source for BltOperation\r |
137 | @param[in] SourceY - The Y coordinate of the source for BltOperation\r |
138 | @param[in] DestinationX - The X coordinate of the destination for BltOperation\r |
139 | @param[in] DestinationY - The Y coordinate of the destination for BltOperation\r |
140 | @param[in] Width - The width of a rectangle in the blt rectangle in pixels\r |
141 | @param[in] Height - The height of a rectangle in the blt rectangle in pixels\r |
142 | @param[in] Delta - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.\r |
143 | If a Delta of 0 is used, the entire BltBuffer will be operated on.\r |
144 | If a subrectangle of the BltBuffer is used, then Delta represents\r |
145 | the number of bytes in a row of the BltBuffer.\r |
146 | \r |
147 | @retval EFI_DEVICE_ERROR - A hardware error occured\r |
148 | @retval EFI_INVALID_PARAMETER - Invalid parameter passed in\r |
149 | @retval EFI_SUCCESS - Blt operation success\r |
150 | \r |
151 | **/\r |
152 | EFI_STATUS\r |
153 | EFIAPI\r |
154 | BltLibGopBlt (\r |
155 | IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL\r |
156 | IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,\r |
157 | IN UINTN SourceX,\r |
158 | IN UINTN SourceY,\r |
159 | IN UINTN DestinationX,\r |
160 | IN UINTN DestinationY,\r |
161 | IN UINTN Width,\r |
162 | IN UINTN Height,\r |
163 | IN UINTN Delta\r |
164 | )\r |
165 | {\r |
166 | switch (BltOperation) {\r |
167 | case EfiBltVideoToBltBuffer:\r |
168 | return BltLibVideoToBltBufferEx (\r |
169 | BltBuffer,\r |
170 | SourceX,\r |
171 | SourceY,\r |
172 | DestinationX,\r |
173 | DestinationY,\r |
174 | Width,\r |
175 | Height,\r |
176 | Delta\r |
177 | );\r |
178 | \r |
179 | case EfiBltVideoToVideo:\r |
180 | return BltLibVideoToVideo (\r |
181 | SourceX,\r |
182 | SourceY,\r |
183 | DestinationX,\r |
184 | DestinationY,\r |
185 | Width,\r |
186 | Height\r |
187 | );\r |
188 | \r |
189 | case EfiBltVideoFill:\r |
190 | return BltLibVideoFill (\r |
191 | BltBuffer,\r |
192 | DestinationX,\r |
193 | DestinationY,\r |
194 | Width,\r |
195 | Height\r |
196 | );\r |
197 | \r |
198 | case EfiBltBufferToVideo:\r |
199 | return BltLibBufferToVideoEx (\r |
200 | BltBuffer,\r |
201 | SourceX,\r |
202 | SourceY,\r |
203 | DestinationX,\r |
204 | DestinationY,\r |
205 | Width,\r |
206 | Height,\r |
207 | Delta\r |
208 | );\r |
209 | default:\r |
210 | return EFI_INVALID_PARAMETER;\r |
211 | }\r |
212 | }\r |
213 | \r |
214 | \r |
215 | /**\r |
216 | Performs a UEFI Graphics Output Protocol Blt Video Fill.\r |
217 | \r |
218 | @param[in] Color Color to fill the region with\r |
219 | @param[in] DestinationX X location to start fill operation\r |
220 | @param[in] DestinationY Y location to start fill operation\r |
221 | @param[in] Width Width (in pixels) to fill\r |
222 | @param[in] Height Height to fill\r |
223 | \r |
224 | @retval EFI_DEVICE_ERROR - A hardware error occured\r |
225 | @retval EFI_INVALID_PARAMETER - Invalid parameter passed in\r |
226 | @retval EFI_SUCCESS - The sizes were returned\r |
227 | \r |
228 | **/\r |
229 | EFI_STATUS\r |
230 | EFIAPI\r |
231 | BltLibVideoFill (\r |
232 | IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Color,\r |
233 | IN UINTN DestinationX,\r |
234 | IN UINTN DestinationY,\r |
235 | IN UINTN Width,\r |
236 | IN UINTN Height\r |
237 | )\r |
238 | {\r |
239 | UINTN DstY;\r |
240 | VOID *BltMemSrc;\r |
241 | VOID *BltMemDst;\r |
242 | UINTN X;\r |
243 | UINT8 Uint8;\r |
244 | UINT32 Uint32;\r |
245 | UINT64 WideFill;\r |
246 | BOOLEAN UseWideFill;\r |
247 | BOOLEAN LineBufferReady;\r |
248 | UINTN Offset;\r |
249 | UINTN WidthInBytes;\r |
250 | UINTN SizeInBytes;\r |
251 | \r |
252 | //\r |
253 | // BltBuffer to Video: Source is BltBuffer, destination is Video\r |
254 | //\r |
255 | if (DestinationY + Height > mBltLibHeight) {\r |
256 | DEBUG ((EFI_D_INFO, "VideoFill: Past screen (Y)\n"));\r |
257 | return EFI_INVALID_PARAMETER;\r |
258 | }\r |
259 | \r |
260 | if (DestinationX + Width > mBltLibWidthInPixels) {\r |
261 | DEBUG ((EFI_D_INFO, "VideoFill: Past screen (X)\n"));\r |
262 | return EFI_INVALID_PARAMETER;\r |
263 | }\r |
264 | \r |
265 | if (Width == 0 || Height == 0) {\r |
266 | DEBUG ((EFI_D_INFO, "VideoFill: Width or Height is 0\n"));\r |
267 | return EFI_INVALID_PARAMETER;\r |
268 | }\r |
269 | \r |
270 | WidthInBytes = Width * mBltLibBytesPerPixel;\r |
271 | \r |
272 | Uint32 = *(UINT32*) Color;\r |
273 | WideFill =\r |
274 | (UINT32) (\r |
275 | (((Uint32 << mPixelShl[0]) >> mPixelShr[0]) & mPixelBitMasks.RedMask) |\r |
276 | (((Uint32 << mPixelShl[1]) >> mPixelShr[1]) & mPixelBitMasks.GreenMask) |\r |
277 | (((Uint32 << mPixelShl[2]) >> mPixelShr[2]) & mPixelBitMasks.BlueMask)\r |
278 | );\r |
279 | VDEBUG ((EFI_D_INFO, "VideoFill: color=0x%x, wide-fill=0x%x\n", Uint32, WideFill));\r |
280 | \r |
281 | //\r |
282 | // If the size of the pixel data evenly divides the sizeof\r |
283 | // WideFill, then a wide fill operation can be used\r |
284 | //\r |
285 | UseWideFill = TRUE;\r |
286 | if ((sizeof (WideFill) % mBltLibBytesPerPixel) == 0) {\r |
287 | for (X = mBltLibBytesPerPixel; X < sizeof (WideFill); X++) {\r |
288 | ((UINT8*)&WideFill)[X] = ((UINT8*)&WideFill)[X % mBltLibBytesPerPixel];\r |
289 | }\r |
290 | } else {\r |
291 | //\r |
292 | // If all the bytes in the pixel are the same value, then use\r |
293 | // a wide fill operation.\r |
294 | //\r |
295 | for (\r |
296 | X = 1, Uint8 = ((UINT8*)&WideFill)[0];\r |
297 | X < mBltLibBytesPerPixel;\r |
298 | X++) {\r |
299 | if (Uint8 != ((UINT8*)&WideFill)[X]) {\r |
300 | UseWideFill = FALSE;\r |
301 | break;\r |
302 | }\r |
303 | }\r |
304 | if (UseWideFill) {\r |
305 | SetMem ((VOID*) &WideFill, sizeof (WideFill), Uint8);\r |
306 | }\r |
307 | }\r |
308 | \r |
309 | if (UseWideFill && (DestinationX == 0) && (Width == mBltLibWidthInPixels)) {\r |
310 | VDEBUG ((EFI_D_INFO, "VideoFill (wide, one-shot)\n"));\r |
311 | Offset = DestinationY * mBltLibWidthInPixels;\r |
312 | Offset = mBltLibBytesPerPixel * Offset;\r |
313 | BltMemDst = (VOID*) (mBltLibFrameBuffer + Offset);\r |
314 | SizeInBytes = WidthInBytes * Height;\r |
315 | if (SizeInBytes >= 8) {\r |
316 | SetMem32 (BltMemDst, SizeInBytes & ~3, (UINT32) WideFill);\r |
317 | SizeInBytes = SizeInBytes & 3;\r |
318 | }\r |
319 | if (SizeInBytes > 0) {\r |
320 | SetMem (BltMemDst, SizeInBytes, (UINT8)(UINTN) WideFill);\r |
321 | }\r |
322 | } else {\r |
323 | LineBufferReady = FALSE;\r |
324 | for (DstY = DestinationY; DstY < (Height + DestinationY); DstY++) {\r |
325 | Offset = (DstY * mBltLibWidthInPixels) + DestinationX;\r |
326 | Offset = mBltLibBytesPerPixel * Offset;\r |
327 | BltMemDst = (VOID*) (mBltLibFrameBuffer + Offset);\r |
328 | \r |
329 | if (UseWideFill && (((UINTN) BltMemDst & 7) == 0)) {\r |
330 | VDEBUG ((EFI_D_INFO, "VideoFill (wide)\n"));\r |
331 | SizeInBytes = WidthInBytes;\r |
332 | if (SizeInBytes >= 8) {\r |
333 | SetMem64 (BltMemDst, SizeInBytes & ~7, WideFill);\r |
334 | SizeInBytes = SizeInBytes & 7;\r |
335 | }\r |
336 | if (SizeInBytes > 0) {\r |
337 | CopyMem (BltMemDst, (VOID*) &WideFill, SizeInBytes);\r |
338 | }\r |
339 | } else {\r |
340 | VDEBUG ((EFI_D_INFO, "VideoFill (not wide)\n"));\r |
341 | if (!LineBufferReady) {\r |
342 | CopyMem (mBltLibLineBuffer, &WideFill, mBltLibBytesPerPixel);\r |
343 | for (X = 1; X < Width; ) {\r |
344 | CopyMem(\r |
345 | (mBltLibLineBuffer + (X * mBltLibBytesPerPixel)),\r |
346 | mBltLibLineBuffer,\r |
347 | MIN (X, Width - X) * mBltLibBytesPerPixel\r |
348 | );\r |
349 | X = X + MIN (X, Width - X);\r |
350 | }\r |
351 | BltMemSrc = (VOID *) mBltLibLineBuffer;\r |
352 | LineBufferReady = TRUE;\r |
353 | }\r |
354 | CopyMem (BltMemDst, mBltLibLineBuffer, WidthInBytes);\r |
355 | }\r |
356 | }\r |
357 | }\r |
358 | \r |
359 | return EFI_SUCCESS;\r |
360 | }\r |
361 | \r |
362 | \r |
363 | /**\r |
364 | Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation.\r |
365 | \r |
366 | @param[out] BltBuffer Output buffer for pixel color data\r |
367 | @param[in] SourceX X location within video\r |
368 | @param[in] SourceY Y location within video\r |
369 | @param[in] Width Width (in pixels)\r |
370 | @param[in] Height Height\r |
371 | \r |
372 | @retval EFI_DEVICE_ERROR - A hardware error occured\r |
373 | @retval EFI_INVALID_PARAMETER - Invalid parameter passed in\r |
374 | @retval EFI_SUCCESS - The sizes were returned\r |
375 | \r |
376 | **/\r |
377 | EFI_STATUS\r |
378 | EFIAPI\r |
379 | BltLibVideoToBltBuffer (\r |
380 | OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer,\r |
381 | IN UINTN SourceX,\r |
382 | IN UINTN SourceY,\r |
383 | IN UINTN Width,\r |
384 | IN UINTN Height\r |
385 | )\r |
386 | {\r |
387 | return BltLibVideoToBltBufferEx (\r |
388 | BltBuffer,\r |
389 | SourceX,\r |
390 | SourceY,\r |
391 | 0,\r |
392 | 0,\r |
393 | Width,\r |
394 | Height,\r |
395 | 0\r |
396 | );\r |
397 | }\r |
398 | \r |
399 | \r |
400 | /**\r |
401 | Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation\r |
402 | with extended parameters.\r |
403 | \r |
404 | @param[out] BltBuffer Output buffer for pixel color data\r |
405 | @param[in] SourceX X location within video\r |
406 | @param[in] SourceY Y location within video\r |
407 | @param[in] DestinationX X location within BltBuffer\r |
408 | @param[in] DestinationY Y location within BltBuffer\r |
409 | @param[in] Width Width (in pixels)\r |
410 | @param[in] Height Height\r |
411 | @param[in] Delta Number of bytes in a row of BltBuffer\r |
412 | \r |
413 | @retval EFI_DEVICE_ERROR - A hardware error occured\r |
414 | @retval EFI_INVALID_PARAMETER - Invalid parameter passed in\r |
415 | @retval EFI_SUCCESS - The sizes were returned\r |
416 | \r |
417 | **/\r |
418 | EFI_STATUS\r |
419 | EFIAPI\r |
420 | BltLibVideoToBltBufferEx (\r |
421 | OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer,\r |
422 | IN UINTN SourceX,\r |
423 | IN UINTN SourceY,\r |
424 | IN UINTN DestinationX,\r |
425 | IN UINTN DestinationY,\r |
426 | IN UINTN Width,\r |
427 | IN UINTN Height,\r |
428 | IN UINTN Delta\r |
429 | )\r |
430 | {\r |
431 | UINTN DstY;\r |
432 | UINTN SrcY;\r |
433 | EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r |
434 | VOID *BltMemSrc;\r |
435 | VOID *BltMemDst;\r |
436 | UINTN X;\r |
437 | UINT32 Uint32;\r |
438 | UINTN Offset;\r |
439 | UINTN WidthInBytes;\r |
440 | \r |
441 | //\r |
442 | // Video to BltBuffer: Source is Video, destination is BltBuffer\r |
443 | //\r |
444 | if (SourceY + Height > mBltLibHeight) {\r |
445 | return EFI_INVALID_PARAMETER;\r |
446 | }\r |
447 | \r |
448 | if (SourceX + Width > mBltLibWidthInPixels) {\r |
449 | return EFI_INVALID_PARAMETER;\r |
450 | }\r |
451 | \r |
452 | if (Width == 0 || Height == 0) {\r |
453 | return EFI_INVALID_PARAMETER;\r |
454 | }\r |
455 | \r |
456 | //\r |
457 | // If Delta is zero, then the entire BltBuffer is being used, so Delta\r |
458 | // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,\r |
459 | // the number of bytes in each row can be computed.\r |
460 | //\r |
461 | if (Delta == 0) {\r |
462 | Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r |
463 | }\r |
464 | \r |
465 | WidthInBytes = Width * mBltLibBytesPerPixel;\r |
466 | \r |
467 | //\r |
468 | // Video to BltBuffer: Source is Video, destination is BltBuffer\r |
469 | //\r |
470 | for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY); SrcY++, DstY++) {\r |
471 | \r |
472 | Offset = (SrcY * mBltLibWidthInPixels) + SourceX;\r |
473 | Offset = mBltLibBytesPerPixel * Offset;\r |
474 | BltMemSrc = (VOID *) (mBltLibFrameBuffer + Offset);\r |
475 | \r |
476 | if (mPixelFormat == PixelBlueGreenRedReserved8BitPerColor) {\r |
477 | BltMemDst =\r |
478 | (VOID *) (\r |
479 | (UINT8 *) BltBuffer +\r |
480 | (DstY * Delta) +\r |
481 | (DestinationX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))\r |
482 | );\r |
483 | } else {\r |
484 | BltMemDst = (VOID *) mBltLibLineBuffer;\r |
485 | }\r |
486 | \r |
487 | CopyMem (BltMemDst, BltMemSrc, WidthInBytes);\r |
488 | \r |
489 | if (mPixelFormat != PixelBlueGreenRedReserved8BitPerColor) {\r |
490 | for (X = 0; X < Width; X++) {\r |
491 | Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer + (DstY * Delta) + (DestinationX + X) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r |
492 | Uint32 = *(UINT32*) (mBltLibLineBuffer + (X * mBltLibBytesPerPixel));\r |
493 | *(UINT32*) Blt =\r |
494 | (UINT32) (\r |
495 | (((Uint32 & mPixelBitMasks.RedMask) >> mPixelShl[0]) << mPixelShr[0]) |\r |
496 | (((Uint32 & mPixelBitMasks.GreenMask) >> mPixelShl[1]) << mPixelShr[1]) |\r |
497 | (((Uint32 & mPixelBitMasks.BlueMask) >> mPixelShl[2]) << mPixelShr[2])\r |
498 | );\r |
499 | }\r |
500 | }\r |
501 | }\r |
502 | \r |
503 | return EFI_SUCCESS;\r |
504 | }\r |
505 | \r |
506 | \r |
507 | /**\r |
508 | Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation.\r |
509 | \r |
510 | @param[in] BltBuffer Output buffer for pixel color data\r |
511 | @param[in] DestinationX X location within video\r |
512 | @param[in] DestinationY Y location within video\r |
513 | @param[in] Width Width (in pixels)\r |
514 | @param[in] Height Height\r |
515 | \r |
516 | @retval EFI_DEVICE_ERROR - A hardware error occured\r |
517 | @retval EFI_INVALID_PARAMETER - Invalid parameter passed in\r |
518 | @retval EFI_SUCCESS - The sizes were returned\r |
519 | \r |
520 | **/\r |
521 | EFI_STATUS\r |
522 | EFIAPI\r |
523 | BltLibBufferToVideo (\r |
524 | IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer,\r |
525 | IN UINTN DestinationX,\r |
526 | IN UINTN DestinationY,\r |
527 | IN UINTN Width,\r |
528 | IN UINTN Height\r |
529 | )\r |
530 | {\r |
531 | return BltLibBufferToVideoEx (\r |
532 | BltBuffer,\r |
533 | 0,\r |
534 | 0,\r |
535 | DestinationX,\r |
536 | DestinationY,\r |
537 | Width,\r |
538 | Height,\r |
539 | 0\r |
540 | );\r |
541 | }\r |
542 | \r |
543 | \r |
544 | /**\r |
545 | Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation\r |
546 | with extended parameters.\r |
547 | \r |
548 | @param[in] BltBuffer Output buffer for pixel color data\r |
549 | @param[in] SourceX X location within BltBuffer\r |
550 | @param[in] SourceY Y location within BltBuffer\r |
551 | @param[in] DestinationX X location within video\r |
552 | @param[in] DestinationY Y location within video\r |
553 | @param[in] Width Width (in pixels)\r |
554 | @param[in] Height Height\r |
555 | @param[in] Delta Number of bytes in a row of BltBuffer\r |
556 | \r |
557 | @retval EFI_DEVICE_ERROR - A hardware error occured\r |
558 | @retval EFI_INVALID_PARAMETER - Invalid parameter passed in\r |
559 | @retval EFI_SUCCESS - The sizes were returned\r |
560 | \r |
561 | **/\r |
562 | EFI_STATUS\r |
563 | EFIAPI\r |
564 | BltLibBufferToVideoEx (\r |
565 | IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer,\r |
566 | IN UINTN SourceX,\r |
567 | IN UINTN SourceY,\r |
568 | IN UINTN DestinationX,\r |
569 | IN UINTN DestinationY,\r |
570 | IN UINTN Width,\r |
571 | IN UINTN Height,\r |
572 | IN UINTN Delta\r |
573 | )\r |
574 | {\r |
575 | UINTN DstY;\r |
576 | UINTN SrcY;\r |
577 | EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r |
578 | VOID *BltMemSrc;\r |
579 | VOID *BltMemDst;\r |
580 | UINTN X;\r |
581 | UINT32 Uint32;\r |
582 | UINTN Offset;\r |
583 | UINTN WidthInBytes;\r |
584 | \r |
585 | //\r |
586 | // BltBuffer to Video: Source is BltBuffer, destination is Video\r |
587 | //\r |
588 | if (DestinationY + Height > mBltLibHeight) {\r |
589 | return EFI_INVALID_PARAMETER;\r |
590 | }\r |
591 | \r |
592 | if (DestinationX + Width > mBltLibWidthInPixels) {\r |
593 | return EFI_INVALID_PARAMETER;\r |
594 | }\r |
595 | \r |
596 | if (Width == 0 || Height == 0) {\r |
597 | return EFI_INVALID_PARAMETER;\r |
598 | }\r |
599 | \r |
600 | //\r |
601 | // If Delta is zero, then the entire BltBuffer is being used, so Delta\r |
602 | // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,\r |
603 | // the number of bytes in each row can be computed.\r |
604 | //\r |
605 | if (Delta == 0) {\r |
606 | Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r |
607 | }\r |
608 | \r |
609 | WidthInBytes = Width * mBltLibBytesPerPixel;\r |
610 | \r |
611 | for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {\r |
612 | \r |
613 | Offset = (DstY * mBltLibWidthInPixels) + DestinationX;\r |
614 | Offset = mBltLibBytesPerPixel * Offset;\r |
615 | BltMemDst = (VOID*) (mBltLibFrameBuffer + Offset);\r |
616 | \r |
617 | if (mPixelFormat == PixelBlueGreenRedReserved8BitPerColor) {\r |
618 | BltMemSrc = (VOID *) (UINT8 *) BltBuffer + (SrcY * Delta);\r |
619 | } else {\r |
620 | for (X = 0; X < Width; X++) {\r |
621 | Blt =\r |
622 | (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) (\r |
623 | (UINT8 *) BltBuffer +\r |
624 | (SrcY * Delta) +\r |
625 | ((SourceX + X) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))\r |
626 | );\r |
627 | Uint32 = *(UINT32*) Blt;\r |
628 | *(UINT32*) (mBltLibLineBuffer + (X * mBltLibBytesPerPixel)) =\r |
629 | (UINT32) (\r |
630 | (((Uint32 << mPixelShl[0]) >> mPixelShr[0]) & mPixelBitMasks.RedMask) |\r |
631 | (((Uint32 << mPixelShl[1]) >> mPixelShr[1]) & mPixelBitMasks.GreenMask) |\r |
632 | (((Uint32 << mPixelShl[2]) >> mPixelShr[2]) & mPixelBitMasks.BlueMask)\r |
633 | );\r |
634 | }\r |
635 | BltMemSrc = (VOID *) mBltLibLineBuffer;\r |
636 | }\r |
637 | \r |
638 | CopyMem (BltMemDst, BltMemSrc, WidthInBytes);\r |
639 | }\r |
640 | \r |
641 | return EFI_SUCCESS;\r |
642 | }\r |
643 | \r |
644 | \r |
645 | /**\r |
646 | Performs a UEFI Graphics Output Protocol Blt Video to Video operation\r |
647 | \r |
648 | @param[in] SourceX X location within video\r |
649 | @param[in] SourceY Y location within video\r |
650 | @param[in] DestinationX X location within video\r |
651 | @param[in] DestinationY Y location within video\r |
652 | @param[in] Width Width (in pixels)\r |
653 | @param[in] Height Height\r |
654 | \r |
655 | @retval EFI_DEVICE_ERROR - A hardware error occured\r |
656 | @retval EFI_INVALID_PARAMETER - Invalid parameter passed in\r |
657 | @retval EFI_SUCCESS - The sizes were returned\r |
658 | \r |
659 | **/\r |
660 | EFI_STATUS\r |
661 | EFIAPI\r |
662 | BltLibVideoToVideo (\r |
663 | IN UINTN SourceX,\r |
664 | IN UINTN SourceY,\r |
665 | IN UINTN DestinationX,\r |
666 | IN UINTN DestinationY,\r |
667 | IN UINTN Width,\r |
668 | IN UINTN Height\r |
669 | )\r |
670 | {\r |
671 | VOID *BltMemSrc;\r |
672 | VOID *BltMemDst;\r |
673 | UINTN Offset;\r |
674 | UINTN WidthInBytes;\r |
675 | INTN LineStride;\r |
676 | \r |
677 | //\r |
678 | // Video to Video: Source is Video, destination is Video\r |
679 | //\r |
680 | if (SourceY + Height > mBltLibHeight) {\r |
681 | return EFI_INVALID_PARAMETER;\r |
682 | }\r |
683 | \r |
684 | if (SourceX + Width > mBltLibWidthInPixels) {\r |
685 | return EFI_INVALID_PARAMETER;\r |
686 | }\r |
687 | \r |
688 | if (DestinationY + Height > mBltLibHeight) {\r |
689 | return EFI_INVALID_PARAMETER;\r |
690 | }\r |
691 | \r |
692 | if (DestinationX + Width > mBltLibWidthInPixels) {\r |
693 | return EFI_INVALID_PARAMETER;\r |
694 | }\r |
695 | \r |
696 | if (Width == 0 || Height == 0) {\r |
697 | return EFI_INVALID_PARAMETER;\r |
698 | }\r |
699 | \r |
700 | WidthInBytes = Width * mBltLibBytesPerPixel;\r |
701 | \r |
702 | Offset = (SourceY * mBltLibWidthInPixels) + SourceX;\r |
703 | Offset = mBltLibBytesPerPixel * Offset;\r |
704 | BltMemSrc = (VOID *) (mBltLibFrameBuffer + Offset);\r |
705 | \r |
706 | Offset = (DestinationY * mBltLibWidthInPixels) + DestinationX;\r |
707 | Offset = mBltLibBytesPerPixel * Offset;\r |
708 | BltMemDst = (VOID *) (mBltLibFrameBuffer + Offset);\r |
709 | \r |
710 | LineStride = mBltLibWidthInBytes;\r |
711 | if ((UINTN) BltMemDst > (UINTN) BltMemSrc) {\r |
712 | LineStride = -LineStride;\r |
713 | }\r |
714 | \r |
715 | while (Height > 0) {\r |
716 | CopyMem (BltMemDst, BltMemSrc, WidthInBytes);\r |
717 | \r |
718 | BltMemSrc = (VOID*) ((UINT8*) BltMemSrc + LineStride);\r |
719 | BltMemDst = (VOID*) ((UINT8*) BltMemDst + LineStride);\r |
720 | Height--;\r |
721 | }\r |
722 | \r |
723 | return EFI_SUCCESS;\r |
724 | }\r |
725 | \r |
726 | \r |
727 | /**\r |
728 | Returns the sizes related to the video device\r |
729 | \r |
730 | @param[out] Width Width (in pixels)\r |
731 | @param[out] Height Height (in pixels)\r |
732 | \r |
733 | @retval EFI_INVALID_PARAMETER - Invalid parameter passed in\r |
734 | @retval EFI_SUCCESS - The sizes were returned\r |
735 | \r |
736 | **/\r |
737 | EFI_STATUS\r |
738 | EFIAPI\r |
739 | BltLibGetSizes (\r |
740 | OUT UINTN *Width, OPTIONAL\r |
741 | OUT UINTN *Height OPTIONAL\r |
742 | )\r |
743 | {\r |
744 | if (Width != NULL) {\r |
745 | *Width = mBltLibWidthInPixels;\r |
746 | }\r |
747 | if (Height != NULL) {\r |
748 | *Height = mBltLibHeight;\r |
749 | }\r |
750 | \r |
751 | return EFI_SUCCESS;\r |
752 | }\r |
753 | \r |