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