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