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