]> git.proxmox.com Git - mirror_edk2.git/blame - OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.c
OptionRomPkg: Add FrameBufferBltLib implementation of BltLib
[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
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
89EFI_STATUS\r
90EFIAPI\r
91BltLibConfigure (\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
152EFI_STATUS\r
153EFIAPI\r
154BltLibGopBlt (\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
229EFI_STATUS\r
230EFIAPI\r
231BltLibVideoFill (\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
377EFI_STATUS\r
378EFIAPI\r
379BltLibVideoToBltBuffer (\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
418EFI_STATUS\r
419EFIAPI\r
420BltLibVideoToBltBufferEx (\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
521EFI_STATUS\r
522EFIAPI\r
523BltLibBufferToVideo (\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
562EFI_STATUS\r
563EFIAPI\r
564BltLibBufferToVideoEx (\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
660EFI_STATUS\r
661EFIAPI\r
662BltLibVideoToVideo (\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
737EFI_STATUS\r
738EFIAPI\r
739BltLibGetSizes (\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