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