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