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