]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.c
MdeModulePkg: Add missing sourceX for Blt
[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
043944c5 4 Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
b1ca3860
RN
6\r
7**/\r
8\r
9#include <Uefi/UefiBaseType.h>\r
10#include <Protocol/GraphicsOutput.h>\r
11\r
12#include <Library/BaseLib.h>\r
13#include <Library/BaseMemoryLib.h>\r
14#include <Library/DebugLib.h>\r
15#include <Library/FrameBufferBltLib.h>\r
16\r
17struct FRAME_BUFFER_CONFIGURE {\r
5ae07233 18 UINT32 PixelsPerScanLine;\r
043944c5 19 UINT32 BytesPerPixel;\r
5ae07233 20 UINT32 Width;\r
043944c5 21 UINT32 Height;\r
b1ca3860
RN
22 UINT8 *FrameBuffer;\r
23 EFI_GRAPHICS_PIXEL_FORMAT PixelFormat;\r
24 EFI_PIXEL_BITMASK PixelMasks;\r
5af29d0d
RN
25 INT8 PixelShl[4]; // R-G-B-Rsvd\r
26 INT8 PixelShr[4]; // R-G-B-Rsvd\r
1d71d0c7 27 UINT8 LineBuffer[0];\r
b1ca3860
RN
28};\r
29\r
30CONST EFI_PIXEL_BITMASK mRgbPixelMasks = {\r
31 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000\r
32};\r
33\r
34CONST EFI_PIXEL_BITMASK mBgrPixelMasks = {\r
35 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000\r
36};\r
37\r
38/**\r
39 Initialize the bit mask in frame buffer configure.\r
40\r
5af29d0d
RN
41 @param BitMask The bit mask of pixel.\r
42 @param BytesPerPixel Size in bytes of pixel.\r
43 @param PixelShl Left shift array.\r
44 @param PixelShr Right shift array.\r
b1ca3860
RN
45**/\r
46VOID\r
5af29d0d
RN
47FrameBufferBltLibConfigurePixelFormat (\r
48 IN CONST EFI_PIXEL_BITMASK *BitMask,\r
043944c5 49 OUT UINT32 *BytesPerPixel,\r
5af29d0d
RN
50 OUT INT8 *PixelShl,\r
51 OUT INT8 *PixelShr\r
b1ca3860
RN
52 )\r
53{\r
5af29d0d 54 UINT8 Index;\r
b1ca3860
RN
55 UINT32 *Masks;\r
56 UINT32 MergedMasks;\r
57\r
5af29d0d
RN
58 ASSERT (BytesPerPixel != NULL);\r
59\r
b1ca3860
RN
60 MergedMasks = 0;\r
61 Masks = (UINT32*) BitMask;\r
5af29d0d
RN
62 for (Index = 0; Index < 3; Index++) {\r
63 ASSERT ((MergedMasks & Masks[Index]) == 0);\r
64\r
65 PixelShl[Index] = (INT8) HighBitSet32 (Masks[Index]) - 23 + (Index * 8);\r
66 if (PixelShl[Index] < 0) {\r
67 PixelShr[Index] = -PixelShl[Index];\r
68 PixelShl[Index] = 0;\r
b1ca3860 69 } else {\r
5af29d0d 70 PixelShr[Index] = 0;\r
b1ca3860 71 }\r
5af29d0d
RN
72 DEBUG ((DEBUG_INFO, "%d: shl:%d shr:%d mask:%x\n", Index,\r
73 PixelShl[Index], PixelShr[Index], Masks[Index]));\r
74\r
75 MergedMasks = (UINT32) (MergedMasks | Masks[Index]);\r
b1ca3860
RN
76 }\r
77 MergedMasks = (UINT32) (MergedMasks | Masks[3]);\r
78\r
79 ASSERT (MergedMasks != 0);\r
043944c5 80 *BytesPerPixel = (UINT32) ((HighBitSet32 (MergedMasks) + 7) / 8);\r
5af29d0d 81 DEBUG ((DEBUG_INFO, "Bytes per pixel: %d\n", *BytesPerPixel));\r
b1ca3860
RN
82}\r
83\r
84/**\r
85 Create the configuration for a video frame buffer.\r
86\r
87 The configuration is returned in the caller provided buffer.\r
88\r
89 @param[in] FrameBuffer Pointer to the start of the frame buffer.\r
90 @param[in] FrameBufferInfo Describes the frame buffer characteristics.\r
91 @param[in,out] Configure The created configuration information.\r
92 @param[in,out] ConfigureSize Size of the configuration information.\r
93\r
94 @retval RETURN_SUCCESS The configuration was successful created.\r
95 @retval RETURN_BUFFER_TOO_SMALL The Configure is to too small. The required\r
96 size is returned in ConfigureSize.\r
97 @retval RETURN_UNSUPPORTED The requested mode is not supported by\r
98 this implementaion.\r
99\r
100**/\r
101RETURN_STATUS\r
102EFIAPI\r
103FrameBufferBltConfigure (\r
104 IN VOID *FrameBuffer,\r
105 IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo,\r
106 IN OUT FRAME_BUFFER_CONFIGURE *Configure,\r
107 IN OUT UINTN *ConfigureSize\r
108 )\r
109{\r
5af29d0d 110 CONST EFI_PIXEL_BITMASK *BitMask;\r
043944c5 111 UINT32 BytesPerPixel;\r
5af29d0d
RN
112 INT8 PixelShl[4];\r
113 INT8 PixelShr[4];\r
114\r
b1ca3860
RN
115 if (ConfigureSize == NULL) {\r
116 return RETURN_INVALID_PARAMETER;\r
117 }\r
118\r
b1ca3860
RN
119 switch (FrameBufferInfo->PixelFormat) {\r
120 case PixelRedGreenBlueReserved8BitPerColor:\r
5af29d0d 121 BitMask = &mRgbPixelMasks;\r
b1ca3860
RN
122 break;\r
123\r
124 case PixelBlueGreenRedReserved8BitPerColor:\r
5af29d0d 125 BitMask = &mBgrPixelMasks;\r
b1ca3860
RN
126 break;\r
127\r
128 case PixelBitMask:\r
5af29d0d 129 BitMask = &FrameBufferInfo->PixelInformation;\r
b1ca3860
RN
130 break;\r
131\r
132 case PixelBltOnly:\r
133 ASSERT (FrameBufferInfo->PixelFormat != PixelBltOnly);\r
134 return RETURN_UNSUPPORTED;\r
135\r
136 default:\r
137 ASSERT (FALSE);\r
138 return RETURN_INVALID_PARAMETER;\r
139 }\r
140\r
5ae07233
RN
141 if (FrameBufferInfo->PixelsPerScanLine < FrameBufferInfo->HorizontalResolution) {\r
142 return RETURN_UNSUPPORTED;\r
143 }\r
144\r
5af29d0d
RN
145 FrameBufferBltLibConfigurePixelFormat (BitMask, &BytesPerPixel, PixelShl, PixelShr);\r
146\r
1d71d0c7
RN
147 if (*ConfigureSize < sizeof (FRAME_BUFFER_CONFIGURE)\r
148 + FrameBufferInfo->HorizontalResolution * BytesPerPixel) {\r
149 *ConfigureSize = sizeof (FRAME_BUFFER_CONFIGURE)\r
150 + FrameBufferInfo->HorizontalResolution * BytesPerPixel;\r
151 return RETURN_BUFFER_TOO_SMALL;\r
152 }\r
153\r
154 if (Configure == NULL) {\r
155 return RETURN_INVALID_PARAMETER;\r
156 }\r
157\r
5af29d0d
RN
158 CopyMem (&Configure->PixelMasks, BitMask, sizeof (*BitMask));\r
159 CopyMem (Configure->PixelShl, PixelShl, sizeof (PixelShl));\r
160 CopyMem (Configure->PixelShr, PixelShr, sizeof (PixelShr));\r
5ae07233
RN
161 Configure->BytesPerPixel = BytesPerPixel;\r
162 Configure->PixelFormat = FrameBufferInfo->PixelFormat;\r
163 Configure->FrameBuffer = (UINT8*) FrameBuffer;\r
164 Configure->Width = FrameBufferInfo->HorizontalResolution;\r
165 Configure->Height = FrameBufferInfo->VerticalResolution;\r
166 Configure->PixelsPerScanLine = FrameBufferInfo->PixelsPerScanLine;\r
b1ca3860 167\r
b1ca3860
RN
168 return RETURN_SUCCESS;\r
169}\r
170\r
171/**\r
172 Performs a UEFI Graphics Output Protocol Blt Video Fill.\r
173\r
174 @param[in] Configure Pointer to a configuration which was successfully\r
175 created by FrameBufferBltConfigure ().\r
176 @param[in] Color Color to fill the region with.\r
177 @param[in] DestinationX X location to start fill operation.\r
178 @param[in] DestinationY Y location to start fill operation.\r
179 @param[in] Width Width (in pixels) to fill.\r
180 @param[in] Height Height to fill.\r
181\r
182 @retval RETURN_INVALID_PARAMETER Invalid parameter was passed in.\r
183 @retval RETURN_SUCCESS The video was filled successfully.\r
184\r
185**/\r
186EFI_STATUS\r
187FrameBufferBltLibVideoFill (\r
188 IN FRAME_BUFFER_CONFIGURE *Configure,\r
189 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Color,\r
190 IN UINTN DestinationX,\r
191 IN UINTN DestinationY,\r
192 IN UINTN Width,\r
193 IN UINTN Height\r
194 )\r
195{\r
196 UINTN IndexX;\r
197 UINTN IndexY;\r
198 UINT8 *Destination;\r
199 UINT8 Uint8;\r
200 UINT32 Uint32;\r
201 UINT64 WideFill;\r
202 BOOLEAN UseWideFill;\r
203 BOOLEAN LineBufferReady;\r
204 UINTN Offset;\r
205 UINTN WidthInBytes;\r
206 UINTN SizeInBytes;\r
207\r
208 //\r
209 // BltBuffer to Video: Source is BltBuffer, destination is Video\r
210 //\r
211 if (DestinationY + Height > Configure->Height) {\r
212 DEBUG ((EFI_D_VERBOSE, "VideoFill: Past screen (Y)\n"));\r
213 return RETURN_INVALID_PARAMETER;\r
214 }\r
215\r
5ae07233 216 if (DestinationX + Width > Configure->Width) {\r
b1ca3860
RN
217 DEBUG ((EFI_D_VERBOSE, "VideoFill: Past screen (X)\n"));\r
218 return RETURN_INVALID_PARAMETER;\r
219 }\r
220\r
221 if (Width == 0 || Height == 0) {\r
222 DEBUG ((EFI_D_VERBOSE, "VideoFill: Width or Height is 0\n"));\r
223 return RETURN_INVALID_PARAMETER;\r
224 }\r
225\r
226 WidthInBytes = Width * Configure->BytesPerPixel;\r
227\r
228 Uint32 = *(UINT32*) Color;\r
229 WideFill =\r
230 (UINT32) (\r
231 (((Uint32 << Configure->PixelShl[0]) >> Configure->PixelShr[0]) &\r
232 Configure->PixelMasks.RedMask) |\r
233 (((Uint32 << Configure->PixelShl[1]) >> Configure->PixelShr[1]) &\r
234 Configure->PixelMasks.GreenMask) |\r
235 (((Uint32 << Configure->PixelShl[2]) >> Configure->PixelShr[2]) &\r
236 Configure->PixelMasks.BlueMask)\r
237 );\r
238 DEBUG ((EFI_D_VERBOSE, "VideoFill: color=0x%x, wide-fill=0x%x\n",\r
239 Uint32, WideFill));\r
240\r
241 //\r
242 // If the size of the pixel data evenly divides the sizeof\r
243 // WideFill, then a wide fill operation can be used\r
244 //\r
245 UseWideFill = TRUE;\r
246 if ((sizeof (WideFill) % Configure->BytesPerPixel) == 0) {\r
247 for (IndexX = Configure->BytesPerPixel; IndexX < sizeof (WideFill); IndexX++) {\r
248 ((UINT8*) &WideFill)[IndexX] = ((UINT8*) &WideFill)[IndexX % Configure->BytesPerPixel];\r
249 }\r
250 } else {\r
251 //\r
252 // If all the bytes in the pixel are the same value, then use\r
253 // a wide fill operation.\r
254 //\r
255 for (\r
256 IndexX = 1, Uint8 = ((UINT8*) &WideFill)[0];\r
257 IndexX < Configure->BytesPerPixel;\r
258 IndexX++) {\r
259 if (Uint8 != ((UINT8*) &WideFill)[IndexX]) {\r
260 UseWideFill = FALSE;\r
261 break;\r
262 }\r
263 }\r
264 if (UseWideFill) {\r
265 SetMem (&WideFill, sizeof (WideFill), Uint8);\r
266 }\r
267 }\r
268\r
5ae07233 269 if (UseWideFill && (DestinationX == 0) && (Width == Configure->PixelsPerScanLine)) {\r
b1ca3860 270 DEBUG ((EFI_D_VERBOSE, "VideoFill (wide, one-shot)\n"));\r
5ae07233 271 Offset = DestinationY * Configure->PixelsPerScanLine;\r
b1ca3860
RN
272 Offset = Configure->BytesPerPixel * Offset;\r
273 Destination = Configure->FrameBuffer + Offset;\r
274 SizeInBytes = WidthInBytes * Height;\r
275 if (SizeInBytes >= 8) {\r
276 SetMem32 (Destination, SizeInBytes & ~3, (UINT32) WideFill);\r
0e58b55a 277 Destination += SizeInBytes & ~3;\r
b1ca3860
RN
278 SizeInBytes &= 3;\r
279 }\r
280 if (SizeInBytes > 0) {\r
281 SetMem (Destination, SizeInBytes, (UINT8) (UINTN) WideFill);\r
282 }\r
283 } else {\r
284 LineBufferReady = FALSE;\r
285 for (IndexY = DestinationY; IndexY < (Height + DestinationY); IndexY++) {\r
5ae07233 286 Offset = (IndexY * Configure->PixelsPerScanLine) + DestinationX;\r
b1ca3860
RN
287 Offset = Configure->BytesPerPixel * Offset;\r
288 Destination = Configure->FrameBuffer + Offset;\r
289\r
290 if (UseWideFill && (((UINTN) Destination & 7) == 0)) {\r
291 DEBUG ((EFI_D_VERBOSE, "VideoFill (wide)\n"));\r
292 SizeInBytes = WidthInBytes;\r
293 if (SizeInBytes >= 8) {\r
294 SetMem64 (Destination, SizeInBytes & ~7, WideFill);\r
0e58b55a 295 Destination += SizeInBytes & ~7;\r
b1ca3860
RN
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
5ae07233 371 if (SourceX + Width > Configure->Width) {\r
b1ca3860
RN
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
5ae07233 397 Offset = (SrcY * Configure->PixelsPerScanLine) + SourceX;\r
b1ca3860
RN
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
5ae07233 479 if (DestinationX + Width > Configure->Width) {\r
b1ca3860
RN
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
5ae07233 502 Offset = (DstY * Configure->PixelsPerScanLine) + DestinationX;\r
b1ca3860
RN
503 Offset = Configure->BytesPerPixel * Offset;\r
504 Destination = Configure->FrameBuffer + Offset;\r
505\r
506 if (Configure->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) {\r
96301aad 507 Source = (UINT8 *) BltBuffer + (SrcY * Delta) + SourceX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
b1ca3860
RN
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
5ae07233 575 if (SourceX + Width > Configure->Width) {\r
b1ca3860
RN
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
5ae07233 583 if (DestinationX + Width > Configure->Width) {\r
b1ca3860
RN
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
5ae07233 593 Offset = (SourceY * Configure->PixelsPerScanLine) + SourceX;\r
b1ca3860
RN
594 Offset = Configure->BytesPerPixel * Offset;\r
595 Source = Configure->FrameBuffer + Offset;\r
596\r
5ae07233 597 Offset = (DestinationY * Configure->PixelsPerScanLine) + DestinationX;\r
b1ca3860
RN
598 Offset = Configure->BytesPerPixel * Offset;\r
599 Destination = Configure->FrameBuffer + Offset;\r
600\r
5ae07233 601 LineStride = Configure->BytesPerPixel * Configure->PixelsPerScanLine;\r
b1ca3860
RN
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