3 Copyright (c) 2011-2013, ARM Ltd. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include <Library/BaseMemoryLib.h>
10 #include <Library/DevicePathLib.h>
11 #include <Library/UefiBootServicesTableLib.h>
12 #include <Library/UefiRuntimeServicesTableLib.h>
13 #include <Library/MemoryAllocationLib.h>
15 #include <Guid/GlobalVariable.h>
17 #include "LcdGraphicsOutputDxe.h"
19 extern BOOLEAN mDisplayInitialized
;
22 // Function Definitions
27 VideoCopyNoHorizontalOverlap (
28 IN UINTN BitsPerPixel
,
29 IN
volatile VOID
*FrameBufferBase
,
30 IN UINT32 HorizontalResolution
,
33 IN UINTN DestinationX
,
34 IN UINTN DestinationY
,
39 EFI_STATUS Status
= EFI_SUCCESS
;
41 UINTN DestinationLine
;
46 VOID
*DestinationAddr
;
48 if( DestinationY
<= SourceY
) {
49 // scrolling up (or horizontally but without overlap)
51 DestinationLine
= DestinationY
;
55 SourceLine
= SourceY
+ Height
;
56 DestinationLine
= DestinationY
+ Height
;
60 switch (BitsPerPixel
) {
62 case LCD_BITS_PER_PIXEL_24
:
64 WidthInBytes
= Width
* 4;
66 for( LineCount
= 0; LineCount
< Height
; LineCount
++ ) {
67 // Update the start addresses of source & destination using 32bit pointer arithmetic
68 SourceAddr
= (VOID
*)((UINT32
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourceX
);
69 DestinationAddr
= (VOID
*)((UINT32
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationX
);
71 // Copy the entire line Y from video ram to the temp buffer
72 CopyMem( DestinationAddr
, SourceAddr
, WidthInBytes
);
74 // Update the line numbers
76 DestinationLine
+= Step
;
80 case LCD_BITS_PER_PIXEL_16_555
:
81 case LCD_BITS_PER_PIXEL_16_565
:
82 case LCD_BITS_PER_PIXEL_12_444
:
84 WidthInBytes
= Width
* 2;
86 for( LineCount
= 0; LineCount
< Height
; LineCount
++ ) {
87 // Update the start addresses of source & destination using 16bit pointer arithmetic
88 SourceAddr
= (VOID
*)((UINT16
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourceX
);
89 DestinationAddr
= (VOID
*)((UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationX
);
91 // Copy the entire line Y from video ram to the temp buffer
92 CopyMem( DestinationAddr
, SourceAddr
, WidthInBytes
);
94 // Update the line numbers
96 DestinationLine
+= Step
;
100 case LCD_BITS_PER_PIXEL_8
:
101 case LCD_BITS_PER_PIXEL_4
:
102 case LCD_BITS_PER_PIXEL_2
:
103 case LCD_BITS_PER_PIXEL_1
:
105 // Can't handle this case
106 DEBUG((DEBUG_ERROR
, "ArmVeGraphics_Blt: EfiBltVideoToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
107 Status
= EFI_INVALID_PARAMETER
;
119 VideoCopyHorizontalOverlap (
120 IN UINTN BitsPerPixel
,
121 IN
volatile VOID
*FrameBufferBase
,
122 UINT32 HorizontalResolution
,
125 IN UINTN DestinationX
,
126 IN UINTN DestinationY
,
131 EFI_STATUS Status
= EFI_SUCCESS
;
133 UINT32
*PixelBuffer32bit
;
134 UINT32
*SourcePixel32bit
;
135 UINT32
*DestinationPixel32bit
;
137 UINT16
*PixelBuffer16bit
;
138 UINT16
*SourcePixel16bit
;
139 UINT16
*DestinationPixel16bit
;
142 UINT32 DestinationPixelY
;
146 switch (BitsPerPixel
) {
148 case LCD_BITS_PER_PIXEL_24
:
149 // Allocate a temporary buffer
151 PixelBuffer32bit
= (UINT32
*) AllocatePool((Height
* Width
) * sizeof(UINT32
));
153 if (PixelBuffer32bit
== NULL
) {
154 Status
= EFI_OUT_OF_RESOURCES
;
158 SizeIn32Bits
= Width
* 4;
160 // Copy from the video ram (source region) to a temp buffer
161 for (SourcePixelY
= SourceY
, DestinationPixel32bit
= PixelBuffer32bit
;
162 SourcePixelY
< SourceY
+ Height
;
163 SourcePixelY
++, DestinationPixel32bit
+= Width
)
165 // Update the start address of line Y (source)
166 SourcePixel32bit
= (UINT32
*)FrameBufferBase
+ SourcePixelY
* HorizontalResolution
+ SourceX
;
168 // Copy the entire line Y from video ram to the temp buffer
169 CopyMem( (VOID
*)DestinationPixel32bit
, (CONST VOID
*)SourcePixel32bit
, SizeIn32Bits
);
172 // Copy from the temp buffer to the video ram (destination region)
173 for (DestinationPixelY
= DestinationY
, SourcePixel32bit
= PixelBuffer32bit
;
174 DestinationPixelY
< DestinationY
+ Height
;
175 DestinationPixelY
++, SourcePixel32bit
+= Width
)
177 // Update the start address of line Y (target)
178 DestinationPixel32bit
= (UINT32
*)FrameBufferBase
+ DestinationPixelY
* HorizontalResolution
+ DestinationX
;
180 // Copy the entire line Y from the temp buffer to video ram
181 CopyMem( (VOID
*)DestinationPixel32bit
, (CONST VOID
*)SourcePixel32bit
, SizeIn32Bits
);
184 // Free up the allocated memory
185 FreePool((VOID
*) PixelBuffer32bit
);
190 case LCD_BITS_PER_PIXEL_16_555
:
191 case LCD_BITS_PER_PIXEL_16_565
:
192 case LCD_BITS_PER_PIXEL_12_444
:
193 // Allocate a temporary buffer
194 PixelBuffer16bit
= (UINT16
*) AllocatePool((Height
* Width
) * sizeof(UINT16
));
196 if (PixelBuffer16bit
== NULL
) {
197 Status
= EFI_OUT_OF_RESOURCES
;
201 // Access each pixel inside the source area of the Video Memory and copy it to the temp buffer
203 SizeIn16Bits
= Width
* 2;
205 for (SourcePixelY
= SourceY
, DestinationPixel16bit
= PixelBuffer16bit
;
206 SourcePixelY
< SourceY
+ Height
;
207 SourcePixelY
++, DestinationPixel16bit
+= Width
)
209 // Calculate the source address:
210 SourcePixel16bit
= (UINT16
*)FrameBufferBase
+ SourcePixelY
* HorizontalResolution
+ SourceX
;
212 // Copy the entire line Y from Video to the temp buffer
213 CopyMem( (VOID
*)DestinationPixel16bit
, (CONST VOID
*)SourcePixel16bit
, SizeIn16Bits
);
216 // Copy from the temp buffer into the destination area of the Video Memory
218 for (DestinationPixelY
= DestinationY
, SourcePixel16bit
= PixelBuffer16bit
;
219 DestinationPixelY
< DestinationY
+ Height
;
220 DestinationPixelY
++, SourcePixel16bit
+= Width
)
222 // Calculate the target address:
223 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ (DestinationPixelY
* HorizontalResolution
+ DestinationX
);
225 // Copy the entire line Y from the temp buffer to Video
226 CopyMem( (VOID
*)DestinationPixel16bit
, (CONST VOID
*)SourcePixel16bit
, SizeIn16Bits
);
229 // Free the allocated memory
230 FreePool((VOID
*) PixelBuffer16bit
);
235 case LCD_BITS_PER_PIXEL_8
:
236 case LCD_BITS_PER_PIXEL_4
:
237 case LCD_BITS_PER_PIXEL_2
:
238 case LCD_BITS_PER_PIXEL_1
:
240 // Can't handle this case
241 DEBUG((DEBUG_ERROR
, "ArmVeGraphics_Blt: EfiBltVideoToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
242 Status
= EFI_INVALID_PARAMETER
;
255 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
256 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*EfiSourcePixel
, OPTIONAL
259 IN UINTN DestinationX
,
260 IN UINTN DestinationY
,
263 IN UINTN Delta OPTIONAL
// Number of BYTES in a row of the BltBuffer
266 EFI_PIXEL_BITMASK
* PixelInformation
;
268 UINT32 HorizontalResolution
;
269 LCD_BPP BitsPerPixel
;
270 VOID
*FrameBufferBase
;
271 VOID
*DestinationAddr
;
272 UINT16
*DestinationPixel16bit
;
274 UINT32 DestinationPixelX
;
275 UINT32 DestinationLine
;
278 Status
= EFI_SUCCESS
;
279 PixelInformation
= &This
->Mode
->Info
->PixelInformation
;
280 FrameBufferBase
= (UINTN
*)((UINTN
)(This
->Mode
->FrameBufferBase
));
281 HorizontalResolution
= This
->Mode
->Info
->HorizontalResolution
;
283 LcdPlatformGetBpp (This
->Mode
->Mode
,&BitsPerPixel
);
285 switch (BitsPerPixel
) {
286 case LCD_BITS_PER_PIXEL_24
:
287 WidthInBytes
= Width
* 4;
289 // Copy the SourcePixel into every pixel inside the target rectangle
290 for (DestinationLine
= DestinationY
;
291 DestinationLine
< DestinationY
+ Height
;
294 // Calculate the target address using 32bit pointer arithmetic:
295 DestinationAddr
= (VOID
*)((UINT32
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationX
);
297 // Fill the entire line
298 SetMem32 (DestinationAddr
, WidthInBytes
, *((UINT32
*)EfiSourcePixel
));
302 case LCD_BITS_PER_PIXEL_16_555
:
303 // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
304 Pixel16bit
= (UINT16
) (
305 ( (EfiSourcePixel
->Red
<< 7) & PixelInformation
->RedMask
)
306 | ( (EfiSourcePixel
->Green
<< 2) & PixelInformation
->GreenMask
)
307 | ( (EfiSourcePixel
->Blue
>> 3) & PixelInformation
->BlueMask
)
308 // | ( 0 & PixelInformation->ReservedMask )
311 // Copy the SourcePixel into every pixel inside the target rectangle
312 for (DestinationLine
= DestinationY
;
313 DestinationLine
< DestinationY
+ Height
;
316 for (DestinationPixelX
= DestinationX
;
317 DestinationPixelX
< DestinationX
+ Width
;
320 // Calculate the target address:
321 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
323 // Copy the pixel into the new target
324 *DestinationPixel16bit
= Pixel16bit
;
329 case LCD_BITS_PER_PIXEL_16_565
:
330 // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
331 Pixel16bit
= (UINT16
) (
332 ( (EfiSourcePixel
->Red
<< 8) & PixelInformation
->RedMask
)
333 | ( (EfiSourcePixel
->Green
<< 3) & PixelInformation
->GreenMask
)
334 | ( (EfiSourcePixel
->Blue
>> 3) & PixelInformation
->BlueMask
)
337 // Copy the SourcePixel into every pixel inside the target rectangle
338 for (DestinationLine
= DestinationY
;
339 DestinationLine
< DestinationY
+ Height
;
342 for (DestinationPixelX
= DestinationX
;
343 DestinationPixelX
< DestinationX
+ Width
;
346 // Calculate the target address:
347 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
349 // Copy the pixel into the new target
350 *DestinationPixel16bit
= Pixel16bit
;
355 case LCD_BITS_PER_PIXEL_12_444
:
356 // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
357 Pixel16bit
= (UINT16
) (
358 ( (EfiSourcePixel
->Red
>> 4) & PixelInformation
->RedMask
)
359 | ( (EfiSourcePixel
->Green
) & PixelInformation
->GreenMask
)
360 | ( (EfiSourcePixel
->Blue
<< 4) & PixelInformation
->BlueMask
)
363 // Copy the SourcePixel into every pixel inside the target rectangle
364 for (DestinationLine
= DestinationY
;
365 DestinationLine
< DestinationY
+ Height
;
368 for (DestinationPixelX
= DestinationX
;
369 DestinationPixelX
< DestinationX
+ Width
;
372 // Calculate the target address:
373 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
375 // Copy the pixel into the new target
376 *DestinationPixel16bit
= Pixel16bit
;
381 case LCD_BITS_PER_PIXEL_8
:
382 case LCD_BITS_PER_PIXEL_4
:
383 case LCD_BITS_PER_PIXEL_2
:
384 case LCD_BITS_PER_PIXEL_1
:
386 // Can't handle this case
387 DEBUG((DEBUG_ERROR
, "LcdGraphicsBlt: EfiBltVideoFill: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
388 Status
= EFI_INVALID_PARAMETER
;
397 BltVideoToBltBuffer (
398 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
399 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
402 IN UINTN DestinationX
,
403 IN UINTN DestinationY
,
406 IN UINTN Delta OPTIONAL
// Number of BYTES in a row of the BltBuffer
410 UINT32 HorizontalResolution
;
411 LCD_BPP BitsPerPixel
;
412 EFI_PIXEL_BITMASK
*PixelInformation
;
413 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*EfiDestinationPixel
;
414 VOID
*FrameBufferBase
;
416 VOID
*DestinationAddr
;
417 UINT16
*SourcePixel16bit
;
421 UINT32 DestinationPixelX
;
422 UINT32 DestinationLine
;
423 UINT32 BltBufferHorizontalResolution
;
426 Status
= EFI_SUCCESS
;
427 PixelInformation
= &This
->Mode
->Info
->PixelInformation
;
428 HorizontalResolution
= This
->Mode
->Info
->HorizontalResolution
;
429 FrameBufferBase
= (UINTN
*)((UINTN
)(This
->Mode
->FrameBufferBase
));
431 if(( Delta
!= 0 ) && ( Delta
!= Width
* sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL
))) {
432 // Delta is not zero and it is different from the width.
433 // Divide it by the size of a pixel to find out the buffer's horizontal resolution.
434 BltBufferHorizontalResolution
= (UINT32
) (Delta
/ sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
436 BltBufferHorizontalResolution
= Width
;
439 LcdPlatformGetBpp (This
->Mode
->Mode
,&BitsPerPixel
);
441 switch (BitsPerPixel
) {
442 case LCD_BITS_PER_PIXEL_24
:
443 WidthInBytes
= Width
* 4;
445 // Access each line inside the Video Memory
446 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
447 SourceLine
< SourceY
+ Height
;
448 SourceLine
++, DestinationLine
++)
450 // Calculate the source and target addresses using 32bit pointer arithmetic:
451 SourceAddr
= (VOID
*)((UINT32
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourceX
);
452 DestinationAddr
= (VOID
*)((UINT32
*)BltBuffer
+ DestinationLine
* BltBufferHorizontalResolution
+ DestinationX
);
454 // Copy the entire line
455 CopyMem( DestinationAddr
, SourceAddr
, WidthInBytes
);
459 case LCD_BITS_PER_PIXEL_16_555
:
460 // Access each pixel inside the Video Memory
461 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
462 SourceLine
< SourceY
+ Height
;
463 SourceLine
++, DestinationLine
++)
465 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
466 SourcePixelX
< SourceX
+ Width
;
467 SourcePixelX
++, DestinationPixelX
++)
469 // Calculate the source and target addresses:
470 SourcePixel16bit
= (UINT16
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourcePixelX
;
471 EfiDestinationPixel
= BltBuffer
+ DestinationLine
* BltBufferHorizontalResolution
+ DestinationPixelX
;
473 // Snapshot the pixel from the video buffer once, to speed up the operation.
474 // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.
475 Pixel16bit
= *SourcePixel16bit
;
477 // Copy the pixel into the new target
478 EfiDestinationPixel
->Red
= (UINT8
) ( (Pixel16bit
& PixelInformation
->RedMask
) >> 7 );
479 EfiDestinationPixel
->Green
= (UINT8
) ( (Pixel16bit
& PixelInformation
->GreenMask
) >> 2);
480 EfiDestinationPixel
->Blue
= (UINT8
) ( (Pixel16bit
& PixelInformation
->BlueMask
) << 3 );
481 // EfiDestinationPixel->Reserved = (UINT8) 0;
486 case LCD_BITS_PER_PIXEL_16_565
:
487 // Access each pixel inside the Video Memory
488 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
489 SourceLine
< SourceY
+ Height
;
490 SourceLine
++, DestinationLine
++)
492 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
493 SourcePixelX
< SourceX
+ Width
;
494 SourcePixelX
++, DestinationPixelX
++)
496 // Calculate the source and target addresses:
497 SourcePixel16bit
= (UINT16
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourcePixelX
;
498 EfiDestinationPixel
= BltBuffer
+ DestinationLine
* BltBufferHorizontalResolution
+ DestinationPixelX
;
500 // Snapshot the pixel from the video buffer once, to speed up the operation.
501 // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.
502 Pixel16bit
= *SourcePixel16bit
;
504 // Copy the pixel into the new target
505 // There is no info for the Reserved byte, so we set it to zero
506 EfiDestinationPixel
->Red
= (UINT8
) ( (Pixel16bit
& PixelInformation
->RedMask
) >> 8 );
507 EfiDestinationPixel
->Green
= (UINT8
) ( (Pixel16bit
& PixelInformation
->GreenMask
) >> 3);
508 EfiDestinationPixel
->Blue
= (UINT8
) ( (Pixel16bit
& PixelInformation
->BlueMask
) << 3 );
509 // EfiDestinationPixel->Reserved = (UINT8) 0;
514 case LCD_BITS_PER_PIXEL_12_444
:
515 // Access each pixel inside the Video Memory
516 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
517 SourceLine
< SourceY
+ Height
;
518 SourceLine
++, DestinationLine
++)
520 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
521 SourcePixelX
< SourceX
+ Width
;
522 SourcePixelX
++, DestinationPixelX
++)
524 // Calculate the source and target addresses:
525 SourcePixel16bit
= (UINT16
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourcePixelX
;
526 EfiDestinationPixel
= BltBuffer
+ DestinationLine
* BltBufferHorizontalResolution
+ DestinationPixelX
;
528 // Snapshot the pixel from the video buffer once, to speed up the operation.
529 // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.
530 Pixel16bit
= *SourcePixel16bit
;
532 // Copy the pixel into the new target
533 EfiDestinationPixel
->Red
= (UINT8
) ( (Pixel16bit
& PixelInformation
->RedMask
) >> 4 );
534 EfiDestinationPixel
->Green
= (UINT8
) ( (Pixel16bit
& PixelInformation
->GreenMask
) );
535 EfiDestinationPixel
->Blue
= (UINT8
) ( (Pixel16bit
& PixelInformation
->BlueMask
) << 4 );
536 // EfiDestinationPixel->Reserved = (UINT8) 0;
541 case LCD_BITS_PER_PIXEL_8
:
542 case LCD_BITS_PER_PIXEL_4
:
543 case LCD_BITS_PER_PIXEL_2
:
544 case LCD_BITS_PER_PIXEL_1
:
546 // Can't handle this case
547 DEBUG((DEBUG_ERROR
, "LcdGraphicsBlt: EfiBltVideoToBltBuffer: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
548 Status
= EFI_INVALID_PARAMETER
;
557 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
558 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
561 IN UINTN DestinationX
,
562 IN UINTN DestinationY
,
565 IN UINTN Delta OPTIONAL
// Number of BYTES in a row of the BltBuffer
569 UINT32 HorizontalResolution
;
570 LCD_BPP BitsPerPixel
;
571 EFI_PIXEL_BITMASK
*PixelInformation
;
572 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*EfiSourcePixel
;
573 VOID
*FrameBufferBase
;
575 VOID
*DestinationAddr
;
576 UINT16
*DestinationPixel16bit
;
579 UINT32 DestinationPixelX
;
580 UINT32 DestinationLine
;
581 UINT32 BltBufferHorizontalResolution
;
584 Status
= EFI_SUCCESS
;
585 PixelInformation
= &This
->Mode
->Info
->PixelInformation
;
586 HorizontalResolution
= This
->Mode
->Info
->HorizontalResolution
;
587 FrameBufferBase
= (UINTN
*)((UINTN
)(This
->Mode
->FrameBufferBase
));
589 if(( Delta
!= 0 ) && ( Delta
!= Width
* sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL
))) {
590 // Delta is not zero and it is different from the width.
591 // Divide it by the size of a pixel to find out the buffer's horizontal resolution.
592 BltBufferHorizontalResolution
= (UINT32
) (Delta
/ sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
594 BltBufferHorizontalResolution
= Width
;
597 LcdPlatformGetBpp (This
->Mode
->Mode
,&BitsPerPixel
);
599 switch (BitsPerPixel
) {
600 case LCD_BITS_PER_PIXEL_24
:
601 WidthInBytes
= Width
* 4;
603 // Access each pixel inside the BltBuffer Memory
604 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
605 SourceLine
< SourceY
+ Height
;
606 SourceLine
++, DestinationLine
++)
608 // Calculate the source and target addresses using 32bit pointer arithmetic:
609 SourceAddr
= (VOID
*)((UINT32
*)BltBuffer
+ SourceLine
* BltBufferHorizontalResolution
+ SourceX
);
610 DestinationAddr
= (VOID
*)((UINT32
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationX
);
612 // Copy the entire row Y
613 CopyMem( DestinationAddr
, SourceAddr
, WidthInBytes
);
617 case LCD_BITS_PER_PIXEL_16_555
:
618 // Access each pixel inside the BltBuffer Memory
619 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
620 SourceLine
< SourceY
+ Height
;
621 SourceLine
++, DestinationLine
++) {
623 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
624 SourcePixelX
< SourceX
+ Width
;
625 SourcePixelX
++, DestinationPixelX
++)
627 // Calculate the source and target addresses:
628 EfiSourcePixel
= BltBuffer
+ SourceLine
* BltBufferHorizontalResolution
+ SourcePixelX
;
629 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
631 // Copy the pixel into the new target
632 // Only the most significant bits will be copied across:
633 // To convert from 8 bits to 5 bits per pixel we throw away the 3 least significant bits
634 *DestinationPixel16bit
= (UINT16
) (
635 ( (EfiSourcePixel
->Red
<< 7) & PixelInformation
->RedMask
)
636 | ( (EfiSourcePixel
->Green
<< 2) & PixelInformation
->GreenMask
)
637 | ( (EfiSourcePixel
->Blue
>> 3) & PixelInformation
->BlueMask
)
638 // | ( 0 & PixelInformation->ReservedMask )
644 case LCD_BITS_PER_PIXEL_16_565
:
645 // Access each pixel inside the BltBuffer Memory
646 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
647 SourceLine
< SourceY
+ Height
;
648 SourceLine
++, DestinationLine
++) {
650 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
651 SourcePixelX
< SourceX
+ Width
;
652 SourcePixelX
++, DestinationPixelX
++)
654 // Calculate the source and target addresses:
655 EfiSourcePixel
= BltBuffer
+ SourceLine
* BltBufferHorizontalResolution
+ SourcePixelX
;
656 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
658 // Copy the pixel into the new target
659 // Only the most significant bits will be copied across:
660 // To convert from 8 bits to 5 or 6 bits per pixel we throw away the 3 or 2 least significant bits
661 // There is no room for the Reserved byte so we ignore that completely
662 *DestinationPixel16bit
= (UINT16
) (
663 ( (EfiSourcePixel
->Red
<< 8) & PixelInformation
->RedMask
)
664 | ( (EfiSourcePixel
->Green
<< 3) & PixelInformation
->GreenMask
)
665 | ( (EfiSourcePixel
->Blue
>> 3) & PixelInformation
->BlueMask
)
671 case LCD_BITS_PER_PIXEL_12_444
:
672 // Access each pixel inside the BltBuffer Memory
673 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
674 SourceLine
< SourceY
+ Height
;
675 SourceLine
++, DestinationLine
++) {
677 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
678 SourcePixelX
< SourceX
+ Width
;
679 SourcePixelX
++, DestinationPixelX
++)
681 // Calculate the source and target addresses:
682 EfiSourcePixel
= BltBuffer
+ SourceLine
* BltBufferHorizontalResolution
+ SourcePixelX
;
683 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
685 // Copy the pixel into the new target
686 // Only the most significant bits will be copied across:
687 // To convert from 8 bits to 5 bits per pixel we throw away the 3 least significant bits
688 *DestinationPixel16bit
= (UINT16
) (
689 ( (EfiSourcePixel
->Red
<< 4) & PixelInformation
->RedMask
)
690 | ( (EfiSourcePixel
->Green
) & PixelInformation
->GreenMask
)
691 | ( (EfiSourcePixel
->Blue
>> 4) & PixelInformation
->BlueMask
)
692 // | ( 0 & PixelInformation->ReservedMask )
698 case LCD_BITS_PER_PIXEL_8
:
699 case LCD_BITS_PER_PIXEL_4
:
700 case LCD_BITS_PER_PIXEL_2
:
701 case LCD_BITS_PER_PIXEL_1
:
703 // Can't handle this case
704 DEBUG((DEBUG_ERROR
, "LcdGraphicsBlt: EfiBltBufferToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
705 Status
= EFI_INVALID_PARAMETER
;
714 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
715 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
718 IN UINTN DestinationX
,
719 IN UINTN DestinationY
,
722 IN UINTN Delta OPTIONAL
// Number of BYTES in a row of the BltBuffer
726 UINT32 HorizontalResolution
;
727 LCD_BPP BitsPerPixel
;
728 VOID
*FrameBufferBase
;
730 HorizontalResolution
= This
->Mode
->Info
->HorizontalResolution
;
731 FrameBufferBase
= (UINTN
*)((UINTN
)(This
->Mode
->FrameBufferBase
));
734 // BltVideo to BltVideo:
736 // Source is the Video Memory,
737 // Destination is the Video Memory
739 LcdPlatformGetBpp (This
->Mode
->Mode
,&BitsPerPixel
);
740 FrameBufferBase
= (UINTN
*)((UINTN
)(This
->Mode
->FrameBufferBase
));
742 // The UEFI spec currently states:
743 // "There is no limitation on the overlapping of the source and destination rectangles"
744 // Therefore, we must be careful to avoid overwriting the source data
745 if( SourceY
== DestinationY
) {
746 // Copying within the same height, e.g. horizontal shift
747 if( SourceX
== DestinationX
) {
749 Status
= EFI_SUCCESS
;
750 } else if( ((SourceX
>DestinationX
)?(SourceX
- DestinationX
):(DestinationX
- SourceX
)) < Width
) {
752 Status
= VideoCopyHorizontalOverlap (BitsPerPixel
, FrameBufferBase
, HorizontalResolution
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
);
755 Status
= VideoCopyNoHorizontalOverlap (BitsPerPixel
, FrameBufferBase
, HorizontalResolution
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
);
758 // Copying from different heights
759 Status
= VideoCopyNoHorizontalOverlap (BitsPerPixel
, FrameBufferBase
, HorizontalResolution
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
);
765 /***************************************
766 * GraphicsOutput Protocol function, mapping to
767 * EFI_GRAPHICS_OUTPUT_PROTOCOL.Blt
769 * PRESUMES: 1 pixel = 4 bytes (32bits)
770 * ***************************************/
774 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
775 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
776 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation
,
779 IN UINTN DestinationX
,
780 IN UINTN DestinationY
,
783 IN UINTN Delta OPTIONAL
// Number of BYTES in a row of the BltBuffer
787 UINT32 HorizontalResolution
;
788 UINT32 VerticalResolution
;
789 LCD_INSTANCE
* Instance
;
791 Instance
= LCD_INSTANCE_FROM_GOP_THIS(This
);
793 // Setup the hardware if not already done
794 if (!mDisplayInitialized
) {
795 Status
= InitializeDisplay (Instance
);
796 if (EFI_ERROR(Status
)) {
801 HorizontalResolution
= This
->Mode
->Info
->HorizontalResolution
;
802 VerticalResolution
= This
->Mode
->Info
->VerticalResolution
;
804 DEBUG((DEBUG_INFO
, "LcdGraphicsBlt (BltOperation:%d,DestX:%d,DestY:%d,Width:%d,Height:%d) res(%d,%d)\n",
805 BltOperation
,DestinationX
,DestinationY
,Width
,Height
,HorizontalResolution
,VerticalResolution
));
807 // Check we have reasonable parameters
808 if (Width
== 0 || Height
== 0) {
809 DEBUG((DEBUG_ERROR
, "LcdGraphicsBlt: ERROR - Invalid dimension: Zero size area.\n" ));
810 Status
= EFI_INVALID_PARAMETER
;
814 if ((BltOperation
== EfiBltVideoFill
) || (BltOperation
== EfiBltBufferToVideo
) || (BltOperation
== EfiBltVideoToBltBuffer
)) {
815 ASSERT( BltBuffer
!= NULL
);
818 /*if ((DestinationX >= HorizontalResolution) || (DestinationY >= VerticalResolution)) {
819 DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: ERROR - Invalid destination.\n" ));
820 Status = EFI_INVALID_PARAMETER;
824 // If we are reading data out of the video buffer, check that the source area is within the display limits
825 if ((BltOperation
== EfiBltVideoToBltBuffer
) || (BltOperation
== EfiBltVideoToVideo
)) {
826 if ((SourceY
+ Height
> VerticalResolution
) || (SourceX
+ Width
> HorizontalResolution
)) {
827 DEBUG((DEBUG_INFO
, "LcdGraphicsBlt: ERROR - Invalid source resolution.\n" ));
828 DEBUG((DEBUG_INFO
, " - SourceY=%d + Height=%d > VerticalResolution=%d.\n", SourceY
, Height
, VerticalResolution
));
829 DEBUG((DEBUG_INFO
, " - SourceX=%d + Width=%d > HorizontalResolution=%d.\n", SourceX
, Width
, HorizontalResolution
));
830 Status
= EFI_INVALID_PARAMETER
;
835 // If we are writing data into the video buffer, that the destination area is within the display limits
836 if ((BltOperation
== EfiBltVideoFill
) || (BltOperation
== EfiBltBufferToVideo
) || (BltOperation
== EfiBltVideoToVideo
)) {
837 if ((DestinationY
+ Height
> VerticalResolution
) || (DestinationX
+ Width
> HorizontalResolution
)) {
838 DEBUG((DEBUG_INFO
, "LcdGraphicsBlt: ERROR - Invalid destination resolution.\n" ));
839 DEBUG((DEBUG_INFO
, " - DestinationY=%d + Height=%d > VerticalResolution=%d.\n", DestinationY
, Height
, VerticalResolution
));
840 DEBUG((DEBUG_INFO
, " - DestinationX=%d + Width=%d > HorizontalResolution=%d.\n", DestinationX
, Width
, HorizontalResolution
));
841 Status
= EFI_INVALID_PARAMETER
;
847 // Perform the Block Transfer Operation
850 switch (BltOperation
) {
851 case EfiBltVideoFill
:
852 Status
= BltVideoFill (This
, BltBuffer
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
, Delta
);
855 case EfiBltVideoToBltBuffer
:
856 Status
= BltVideoToBltBuffer (This
, BltBuffer
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
, Delta
);
859 case EfiBltBufferToVideo
:
860 Status
= BltBufferToVideo (This
, BltBuffer
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
, Delta
);
863 case EfiBltVideoToVideo
:
864 Status
= BltVideoToVideo (This
, BltBuffer
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
, Delta
);
867 case EfiGraphicsOutputBltOperationMax
:
869 DEBUG((DEBUG_ERROR
, "LcdGraphicsBlt: Invalid Operation\n"));
870 Status
= EFI_INVALID_PARAMETER
;