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