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