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