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