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