3 Copyright (c) 2011 - 2020, Arm Limited. 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
,
41 UINTN DestinationLine
;
46 VOID
*DestinationAddr
;
50 if ( DestinationY
<= SourceY
) {
51 // scrolling up (or horizontally but without overlap)
53 DestinationLine
= DestinationY
;
57 SourceLine
= SourceY
+ Height
;
58 DestinationLine
= DestinationY
+ Height
;
62 switch (BitsPerPixel
) {
63 case LcdBitsPerPixel_24
:
65 WidthInBytes
= Width
* 4;
67 for ( LineCount
= 0; LineCount
< Height
; LineCount
++ ) {
68 // Update the start addresses of source & destination using 32bit pointer arithmetic
69 SourceAddr
= (VOID
*)((UINT32
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourceX
);
70 DestinationAddr
= (VOID
*)((UINT32
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationX
);
72 // Copy the entire line Y from video ram to the temp buffer
73 CopyMem (DestinationAddr
, SourceAddr
, WidthInBytes
);
75 // Update the line numbers
77 DestinationLine
+= Step
;
82 case LcdBitsPerPixel_16_555
:
83 case LcdBitsPerPixel_16_565
:
84 case LcdBitsPerPixel_12_444
:
86 WidthInBytes
= Width
* 2;
88 for ( LineCount
= 0; LineCount
< Height
; LineCount
++ ) {
89 // Update the start addresses of source & destination using 16bit pointer arithmetic
90 SourceAddr
= (VOID
*)((UINT16
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourceX
);
91 DestinationAddr
= (VOID
*)((UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationX
);
93 // Copy the entire line Y from video ram to the temp buffer
94 CopyMem (DestinationAddr
, SourceAddr
, WidthInBytes
);
96 // Update the line numbers
98 DestinationLine
+= Step
;
103 case LcdBitsPerPixel_8
:
104 case LcdBitsPerPixel_4
:
105 case LcdBitsPerPixel_2
:
106 case LcdBitsPerPixel_1
:
108 // Can't handle this case
109 DEBUG ((DEBUG_ERROR
, "ArmVeGraphics_Blt: EfiBltVideoToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
110 Status
= EFI_INVALID_PARAMETER
;
121 VideoCopyHorizontalOverlap (
122 IN UINTN BitsPerPixel
,
123 IN
volatile VOID
*FrameBufferBase
,
124 UINT32 HorizontalResolution
,
127 IN UINTN DestinationX
,
128 IN UINTN DestinationY
,
135 UINT32
*PixelBuffer32bit
;
136 UINT32
*SourcePixel32bit
;
137 UINT32
*DestinationPixel32bit
;
139 UINT16
*PixelBuffer16bit
;
140 UINT16
*SourcePixel16bit
;
141 UINT16
*DestinationPixel16bit
;
144 UINT32 DestinationPixelY
;
148 Status
= EFI_SUCCESS
;
150 switch (BitsPerPixel
) {
151 case LcdBitsPerPixel_24
:
152 // Allocate a temporary buffer
154 PixelBuffer32bit
= (UINT32
*)AllocatePool ((Height
* Width
) * sizeof (UINT32
));
156 if (PixelBuffer32bit
== NULL
) {
157 Status
= EFI_OUT_OF_RESOURCES
;
161 SizeIn32Bits
= Width
* 4;
163 // Copy from the video ram (source region) to a temp buffer
164 for (SourcePixelY
= SourceY
, DestinationPixel32bit
= PixelBuffer32bit
;
165 SourcePixelY
< SourceY
+ Height
;
166 SourcePixelY
++, DestinationPixel32bit
+= Width
)
168 // Update the start address of line Y (source)
169 SourcePixel32bit
= (UINT32
*)FrameBufferBase
+ SourcePixelY
* HorizontalResolution
+ SourceX
;
171 // Copy the entire line Y from video ram to the temp buffer
172 CopyMem ((VOID
*)DestinationPixel32bit
, (CONST VOID
*)SourcePixel32bit
, SizeIn32Bits
);
175 // Copy from the temp buffer to the video ram (destination region)
176 for (DestinationPixelY
= DestinationY
, SourcePixel32bit
= PixelBuffer32bit
;
177 DestinationPixelY
< DestinationY
+ Height
;
178 DestinationPixelY
++, SourcePixel32bit
+= Width
)
180 // Update the start address of line Y (target)
181 DestinationPixel32bit
= (UINT32
*)FrameBufferBase
+ DestinationPixelY
* HorizontalResolution
+ DestinationX
;
183 // Copy the entire line Y from the temp buffer to video ram
184 CopyMem ((VOID
*)DestinationPixel32bit
, (CONST VOID
*)SourcePixel32bit
, SizeIn32Bits
);
187 // Free up the allocated memory
188 FreePool ((VOID
*)PixelBuffer32bit
);
192 case LcdBitsPerPixel_16_555
:
193 case LcdBitsPerPixel_16_565
:
194 case LcdBitsPerPixel_12_444
:
195 // Allocate a temporary buffer
196 PixelBuffer16bit
= (UINT16
*)AllocatePool ((Height
* Width
) * sizeof (UINT16
));
198 if (PixelBuffer16bit
== NULL
) {
199 Status
= EFI_OUT_OF_RESOURCES
;
203 // Access each pixel inside the source area of the Video Memory and copy it to the temp buffer
205 SizeIn16Bits
= Width
* 2;
207 for (SourcePixelY
= SourceY
, DestinationPixel16bit
= PixelBuffer16bit
;
208 SourcePixelY
< SourceY
+ Height
;
209 SourcePixelY
++, DestinationPixel16bit
+= Width
)
211 // Calculate the source address:
212 SourcePixel16bit
= (UINT16
*)FrameBufferBase
+ SourcePixelY
* HorizontalResolution
+ SourceX
;
214 // Copy the entire line Y from Video to the temp buffer
215 CopyMem ((VOID
*)DestinationPixel16bit
, (CONST VOID
*)SourcePixel16bit
, SizeIn16Bits
);
218 // Copy from the temp buffer into the destination area of the Video Memory
220 for (DestinationPixelY
= DestinationY
, SourcePixel16bit
= PixelBuffer16bit
;
221 DestinationPixelY
< DestinationY
+ Height
;
222 DestinationPixelY
++, SourcePixel16bit
+= Width
)
224 // Calculate the target address:
225 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ (DestinationPixelY
* HorizontalResolution
+ DestinationX
);
227 // Copy the entire line Y from the temp buffer to Video
228 CopyMem ((VOID
*)DestinationPixel16bit
, (CONST VOID
*)SourcePixel16bit
, SizeIn16Bits
);
231 // Free the allocated memory
232 FreePool ((VOID
*)PixelBuffer16bit
);
236 case LcdBitsPerPixel_8
:
237 case LcdBitsPerPixel_4
:
238 case LcdBitsPerPixel_2
:
239 case LcdBitsPerPixel_1
:
241 // Can't handle this case
242 DEBUG ((DEBUG_ERROR
, "ArmVeGraphics_Blt: EfiBltVideoToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
243 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 LcdBitsPerPixel_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
));
303 case LcdBitsPerPixel_16_555
:
304 // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
305 Pixel16bit
= (UINT16
)(
306 ((EfiSourcePixel
->Red
<< 7) & PixelInformation
->RedMask
)
307 | ((EfiSourcePixel
->Green
<< 2) & PixelInformation
->GreenMask
)
308 | ((EfiSourcePixel
->Blue
>> 3) & PixelInformation
->BlueMask
)
309 // | ( 0 & PixelInformation->ReservedMask )
312 // Copy the SourcePixel into every pixel inside the target rectangle
313 for (DestinationLine
= DestinationY
;
314 DestinationLine
< DestinationY
+ Height
;
317 for (DestinationPixelX
= DestinationX
;
318 DestinationPixelX
< DestinationX
+ Width
;
321 // Calculate the target address:
322 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
324 // Copy the pixel into the new target
325 *DestinationPixel16bit
= Pixel16bit
;
331 case LcdBitsPerPixel_16_565
:
332 // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
333 Pixel16bit
= (UINT16
)(
334 ((EfiSourcePixel
->Red
<< 8) & PixelInformation
->RedMask
)
335 | ((EfiSourcePixel
->Green
<< 3) & PixelInformation
->GreenMask
)
336 | ((EfiSourcePixel
->Blue
>> 3) & PixelInformation
->BlueMask
)
339 // Copy the SourcePixel into every pixel inside the target rectangle
340 for (DestinationLine
= DestinationY
;
341 DestinationLine
< DestinationY
+ Height
;
344 for (DestinationPixelX
= DestinationX
;
345 DestinationPixelX
< DestinationX
+ Width
;
348 // Calculate the target address:
349 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
351 // Copy the pixel into the new target
352 *DestinationPixel16bit
= Pixel16bit
;
358 case LcdBitsPerPixel_12_444
:
359 // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
360 Pixel16bit
= (UINT16
)(
361 ((EfiSourcePixel
->Red
>> 4) & PixelInformation
->RedMask
)
362 | ((EfiSourcePixel
->Green
) & PixelInformation
->GreenMask
)
363 | ((EfiSourcePixel
->Blue
<< 4) & PixelInformation
->BlueMask
)
366 // Copy the SourcePixel into every pixel inside the target rectangle
367 for (DestinationLine
= DestinationY
;
368 DestinationLine
< DestinationY
+ Height
;
371 for (DestinationPixelX
= DestinationX
;
372 DestinationPixelX
< DestinationX
+ Width
;
375 // Calculate the target address:
376 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
378 // Copy the pixel into the new target
379 *DestinationPixel16bit
= Pixel16bit
;
385 case LcdBitsPerPixel_8
:
386 case LcdBitsPerPixel_4
:
387 case LcdBitsPerPixel_2
:
388 case LcdBitsPerPixel_1
:
390 // Can't handle this case
391 DEBUG ((DEBUG_ERROR
, "LcdGraphicsBlt: EfiBltVideoFill: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
392 Status
= EFI_INVALID_PARAMETER
;
401 BltVideoToBltBuffer (
402 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
403 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer OPTIONAL
,
406 IN UINTN DestinationX
,
407 IN UINTN DestinationY
,
410 IN UINTN Delta OPTIONAL
// Number of BYTES in a row of the BltBuffer
414 UINT32 HorizontalResolution
;
415 LCD_BPP BitsPerPixel
;
416 EFI_PIXEL_BITMASK
*PixelInformation
;
417 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*EfiDestinationPixel
;
418 VOID
*FrameBufferBase
;
420 VOID
*DestinationAddr
;
421 UINT16
*SourcePixel16bit
;
425 UINT32 DestinationPixelX
;
426 UINT32 DestinationLine
;
427 UINT32 BltBufferHorizontalResolution
;
430 Status
= EFI_SUCCESS
;
431 PixelInformation
= &This
->Mode
->Info
->PixelInformation
;
432 HorizontalResolution
= This
->Mode
->Info
->HorizontalResolution
;
433 FrameBufferBase
= (UINTN
*)((UINTN
)(This
->Mode
->FrameBufferBase
));
435 if ((Delta
!= 0) && (Delta
!= Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
))) {
436 // Delta is not zero and it is different from the width.
437 // Divide it by the size of a pixel to find out the buffer's horizontal resolution.
438 BltBufferHorizontalResolution
= (UINT32
)(Delta
/ sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
440 BltBufferHorizontalResolution
= Width
;
443 LcdPlatformGetBpp (This
->Mode
->Mode
, &BitsPerPixel
);
445 switch (BitsPerPixel
) {
446 case LcdBitsPerPixel_24
:
447 WidthInBytes
= Width
* 4;
449 // Access each line inside the Video Memory
450 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
451 SourceLine
< SourceY
+ Height
;
452 SourceLine
++, DestinationLine
++)
454 // Calculate the source and target addresses using 32bit pointer arithmetic:
455 SourceAddr
= (VOID
*)((UINT32
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourceX
);
456 DestinationAddr
= (VOID
*)((UINT32
*)BltBuffer
+ DestinationLine
* BltBufferHorizontalResolution
+ DestinationX
);
458 // Copy the entire line
459 CopyMem (DestinationAddr
, SourceAddr
, WidthInBytes
);
464 case LcdBitsPerPixel_16_555
:
465 // Access each pixel inside the Video Memory
466 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
467 SourceLine
< SourceY
+ Height
;
468 SourceLine
++, DestinationLine
++)
470 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
471 SourcePixelX
< SourceX
+ Width
;
472 SourcePixelX
++, DestinationPixelX
++)
474 // Calculate the source and target addresses:
475 SourcePixel16bit
= (UINT16
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourcePixelX
;
476 EfiDestinationPixel
= BltBuffer
+ DestinationLine
* BltBufferHorizontalResolution
+ DestinationPixelX
;
478 // Snapshot the pixel from the video buffer once, to speed up the operation.
479 // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.
480 Pixel16bit
= *SourcePixel16bit
;
482 // Copy the pixel into the new target
483 EfiDestinationPixel
->Red
= (UINT8
)((Pixel16bit
& PixelInformation
->RedMask
) >> 7);
484 EfiDestinationPixel
->Green
= (UINT8
)((Pixel16bit
& PixelInformation
->GreenMask
) >> 2);
485 EfiDestinationPixel
->Blue
= (UINT8
)((Pixel16bit
& PixelInformation
->BlueMask
) << 3);
486 // EfiDestinationPixel->Reserved = (UINT8) 0;
492 case LcdBitsPerPixel_16_565
:
493 // Access each pixel inside the Video Memory
494 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
495 SourceLine
< SourceY
+ Height
;
496 SourceLine
++, DestinationLine
++)
498 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
499 SourcePixelX
< SourceX
+ Width
;
500 SourcePixelX
++, DestinationPixelX
++)
502 // Calculate the source and target addresses:
503 SourcePixel16bit
= (UINT16
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourcePixelX
;
504 EfiDestinationPixel
= BltBuffer
+ DestinationLine
* BltBufferHorizontalResolution
+ DestinationPixelX
;
506 // Snapshot the pixel from the video buffer once, to speed up the operation.
507 // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.
508 Pixel16bit
= *SourcePixel16bit
;
510 // Copy the pixel into the new target
511 // There is no info for the Reserved byte, so we set it to zero
512 EfiDestinationPixel
->Red
= (UINT8
)((Pixel16bit
& PixelInformation
->RedMask
) >> 8);
513 EfiDestinationPixel
->Green
= (UINT8
)((Pixel16bit
& PixelInformation
->GreenMask
) >> 3);
514 EfiDestinationPixel
->Blue
= (UINT8
)((Pixel16bit
& PixelInformation
->BlueMask
) << 3);
515 // EfiDestinationPixel->Reserved = (UINT8) 0;
521 case LcdBitsPerPixel_12_444
:
522 // Access each pixel inside the Video Memory
523 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
524 SourceLine
< SourceY
+ Height
;
525 SourceLine
++, DestinationLine
++)
527 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
528 SourcePixelX
< SourceX
+ Width
;
529 SourcePixelX
++, DestinationPixelX
++)
531 // Calculate the source and target addresses:
532 SourcePixel16bit
= (UINT16
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourcePixelX
;
533 EfiDestinationPixel
= BltBuffer
+ DestinationLine
* BltBufferHorizontalResolution
+ DestinationPixelX
;
535 // Snapshot the pixel from the video buffer once, to speed up the operation.
536 // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.
537 Pixel16bit
= *SourcePixel16bit
;
539 // Copy the pixel into the new target
540 EfiDestinationPixel
->Red
= (UINT8
)((Pixel16bit
& PixelInformation
->RedMask
) >> 4);
541 EfiDestinationPixel
->Green
= (UINT8
)((Pixel16bit
& PixelInformation
->GreenMask
));
542 EfiDestinationPixel
->Blue
= (UINT8
)((Pixel16bit
& PixelInformation
->BlueMask
) << 4);
543 // EfiDestinationPixel->Reserved = (UINT8) 0;
549 case LcdBitsPerPixel_8
:
550 case LcdBitsPerPixel_4
:
551 case LcdBitsPerPixel_2
:
552 case LcdBitsPerPixel_1
:
554 // Can't handle this case
555 DEBUG ((DEBUG_ERROR
, "LcdGraphicsBlt: EfiBltVideoToBltBuffer: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
556 Status
= EFI_INVALID_PARAMETER
;
566 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
567 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer OPTIONAL
,
570 IN UINTN DestinationX
,
571 IN UINTN DestinationY
,
574 IN UINTN Delta OPTIONAL
// Number of BYTES in a row of the BltBuffer
578 UINT32 HorizontalResolution
;
579 LCD_BPP BitsPerPixel
;
580 EFI_PIXEL_BITMASK
*PixelInformation
;
581 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*EfiSourcePixel
;
582 VOID
*FrameBufferBase
;
584 VOID
*DestinationAddr
;
585 UINT16
*DestinationPixel16bit
;
588 UINT32 DestinationPixelX
;
589 UINT32 DestinationLine
;
590 UINT32 BltBufferHorizontalResolution
;
593 Status
= EFI_SUCCESS
;
594 PixelInformation
= &This
->Mode
->Info
->PixelInformation
;
595 HorizontalResolution
= This
->Mode
->Info
->HorizontalResolution
;
596 FrameBufferBase
= (UINTN
*)((UINTN
)(This
->Mode
->FrameBufferBase
));
598 if ((Delta
!= 0) && (Delta
!= Width
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
))) {
599 // Delta is not zero and it is different from the width.
600 // Divide it by the size of a pixel to find out the buffer's horizontal resolution.
601 BltBufferHorizontalResolution
= (UINT32
)(Delta
/ sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
603 BltBufferHorizontalResolution
= Width
;
606 LcdPlatformGetBpp (This
->Mode
->Mode
, &BitsPerPixel
);
608 switch (BitsPerPixel
) {
609 case LcdBitsPerPixel_24
:
610 WidthInBytes
= Width
* 4;
612 // Access each pixel inside the BltBuffer Memory
613 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
614 SourceLine
< SourceY
+ Height
;
615 SourceLine
++, DestinationLine
++)
617 // Calculate the source and target addresses using 32bit pointer arithmetic:
618 SourceAddr
= (VOID
*)((UINT32
*)BltBuffer
+ SourceLine
* BltBufferHorizontalResolution
+ SourceX
);
619 DestinationAddr
= (VOID
*)((UINT32
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationX
);
621 // Copy the entire row Y
622 CopyMem (DestinationAddr
, SourceAddr
, WidthInBytes
);
627 case LcdBitsPerPixel_16_555
:
628 // Access each pixel inside the BltBuffer Memory
629 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
630 SourceLine
< SourceY
+ Height
;
631 SourceLine
++, DestinationLine
++)
633 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
634 SourcePixelX
< SourceX
+ Width
;
635 SourcePixelX
++, DestinationPixelX
++)
637 // Calculate the source and target addresses:
638 EfiSourcePixel
= BltBuffer
+ SourceLine
* BltBufferHorizontalResolution
+ SourcePixelX
;
639 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
641 // Copy the pixel into the new target
642 // Only the most significant bits will be copied across:
643 // To convert from 8 bits to 5 bits per pixel we throw away the 3 least significant bits
644 *DestinationPixel16bit
= (UINT16
)(
645 ((EfiSourcePixel
->Red
<< 7) & PixelInformation
->RedMask
)
646 | ((EfiSourcePixel
->Green
<< 2) & PixelInformation
->GreenMask
)
647 | ((EfiSourcePixel
->Blue
>> 3) & PixelInformation
->BlueMask
)
648 // | ( 0 & PixelInformation->ReservedMask )
655 case LcdBitsPerPixel_16_565
:
656 // Access each pixel inside the BltBuffer Memory
657 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
658 SourceLine
< SourceY
+ Height
;
659 SourceLine
++, DestinationLine
++)
661 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
662 SourcePixelX
< SourceX
+ Width
;
663 SourcePixelX
++, DestinationPixelX
++)
665 // Calculate the source and target addresses:
666 EfiSourcePixel
= BltBuffer
+ SourceLine
* BltBufferHorizontalResolution
+ SourcePixelX
;
667 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
669 // Copy the pixel into the new target
670 // Only the most significant bits will be copied across:
671 // To convert from 8 bits to 5 or 6 bits per pixel we throw away the 3 or 2 least significant bits
672 // There is no room for the Reserved byte so we ignore that completely
673 *DestinationPixel16bit
= (UINT16
)(
674 ((EfiSourcePixel
->Red
<< 8) & PixelInformation
->RedMask
)
675 | ((EfiSourcePixel
->Green
<< 3) & PixelInformation
->GreenMask
)
676 | ((EfiSourcePixel
->Blue
>> 3) & PixelInformation
->BlueMask
)
683 case LcdBitsPerPixel_12_444
:
684 // Access each pixel inside the BltBuffer Memory
685 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
686 SourceLine
< SourceY
+ Height
;
687 SourceLine
++, DestinationLine
++)
689 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
690 SourcePixelX
< SourceX
+ Width
;
691 SourcePixelX
++, DestinationPixelX
++)
693 // Calculate the source and target addresses:
694 EfiSourcePixel
= BltBuffer
+ SourceLine
* BltBufferHorizontalResolution
+ SourcePixelX
;
695 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
697 // Copy the pixel into the new target
698 // Only the most significant bits will be copied across:
699 // To convert from 8 bits to 5 bits per pixel we throw away the 3 least significant bits
700 *DestinationPixel16bit
= (UINT16
)(
701 ((EfiSourcePixel
->Red
<< 4) & PixelInformation
->RedMask
)
702 | ((EfiSourcePixel
->Green
) & PixelInformation
->GreenMask
)
703 | ((EfiSourcePixel
->Blue
>> 4) & PixelInformation
->BlueMask
)
704 // | ( 0 & PixelInformation->ReservedMask )
711 case LcdBitsPerPixel_8
:
712 case LcdBitsPerPixel_4
:
713 case LcdBitsPerPixel_2
:
714 case LcdBitsPerPixel_1
:
716 // Can't handle this case
717 DEBUG ((DEBUG_ERROR
, "LcdGraphicsBlt: EfiBltBufferToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
718 Status
= EFI_INVALID_PARAMETER
;
728 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
729 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer OPTIONAL
,
732 IN UINTN DestinationX
,
733 IN UINTN DestinationY
,
736 IN UINTN Delta OPTIONAL
// Number of BYTES in a row of the BltBuffer
740 UINT32 HorizontalResolution
;
741 LCD_BPP BitsPerPixel
;
742 VOID
*FrameBufferBase
;
744 HorizontalResolution
= This
->Mode
->Info
->HorizontalResolution
;
745 FrameBufferBase
= (UINTN
*)((UINTN
)(This
->Mode
->FrameBufferBase
));
748 // BltVideo to BltVideo:
750 // Source is the Video Memory,
751 // Destination is the Video Memory
753 LcdPlatformGetBpp (This
->Mode
->Mode
, &BitsPerPixel
);
754 FrameBufferBase
= (UINTN
*)((UINTN
)(This
->Mode
->FrameBufferBase
));
756 // The UEFI spec currently states:
757 // "There is no limitation on the overlapping of the source and destination rectangles"
758 // Therefore, we must be careful to avoid overwriting the source data
759 if ( SourceY
== DestinationY
) {
760 // Copying within the same height, e.g. horizontal shift
761 if ( SourceX
== DestinationX
) {
763 Status
= EFI_SUCCESS
;
764 } else if (((SourceX
> DestinationX
) ? (SourceX
- DestinationX
) : (DestinationX
- SourceX
)) < Width
) {
766 Status
= VideoCopyHorizontalOverlap (BitsPerPixel
, FrameBufferBase
, HorizontalResolution
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
);
769 Status
= VideoCopyNoHorizontalOverlap (BitsPerPixel
, FrameBufferBase
, HorizontalResolution
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
);
772 // Copying from different heights
773 Status
= VideoCopyNoHorizontalOverlap (BitsPerPixel
, FrameBufferBase
, HorizontalResolution
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
);
779 /***************************************
780 * GraphicsOutput Protocol function, mapping to
781 * EFI_GRAPHICS_OUTPUT_PROTOCOL.Blt
783 * PRESUMES: 1 pixel = 4 bytes (32bits)
784 * ***************************************/
788 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
789 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer OPTIONAL
,
790 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation
,
793 IN UINTN DestinationX
,
794 IN UINTN DestinationY
,
797 IN UINTN Delta OPTIONAL
// Number of BYTES in a row of the BltBuffer
801 UINT32 HorizontalResolution
;
802 UINT32 VerticalResolution
;
803 LCD_INSTANCE
*Instance
;
805 Instance
= LCD_INSTANCE_FROM_GOP_THIS (This
);
807 // Setup the hardware if not already done
808 if (!mDisplayInitialized
) {
809 Status
= InitializeDisplay (Instance
);
810 if (EFI_ERROR (Status
)) {
815 HorizontalResolution
= This
->Mode
->Info
->HorizontalResolution
;
816 VerticalResolution
= This
->Mode
->Info
->VerticalResolution
;
820 "LcdGraphicsBlt (BltOperation:%d,DestX:%d,DestY:%d,Width:%d,Height:%d) res(%d,%d)\n",
826 HorizontalResolution
,
830 // Check we have reasonable parameters
831 if ((Width
== 0) || (Height
== 0)) {
832 DEBUG ((DEBUG_ERROR
, "LcdGraphicsBlt: ERROR - Invalid dimension: Zero size area.\n"));
833 Status
= EFI_INVALID_PARAMETER
;
837 if ((BltOperation
== EfiBltVideoFill
) || (BltOperation
== EfiBltBufferToVideo
) || (BltOperation
== EfiBltVideoToBltBuffer
)) {
838 ASSERT (BltBuffer
!= NULL
);
841 /*if ((DestinationX >= HorizontalResolution) || (DestinationY >= VerticalResolution)) {
842 DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: ERROR - Invalid destination.\n" ));
843 Status = EFI_INVALID_PARAMETER;
847 // If we are reading data out of the video buffer, check that the source area is within the display limits
848 if ((BltOperation
== EfiBltVideoToBltBuffer
) || (BltOperation
== EfiBltVideoToVideo
)) {
849 if ((SourceY
+ Height
> VerticalResolution
) || (SourceX
+ Width
> HorizontalResolution
)) {
850 DEBUG ((DEBUG_INFO
, "LcdGraphicsBlt: ERROR - Invalid source resolution.\n"));
851 DEBUG ((DEBUG_INFO
, " - SourceY=%d + Height=%d > VerticalResolution=%d.\n", SourceY
, Height
, VerticalResolution
));
852 DEBUG ((DEBUG_INFO
, " - SourceX=%d + Width=%d > HorizontalResolution=%d.\n", SourceX
, Width
, HorizontalResolution
));
853 Status
= EFI_INVALID_PARAMETER
;
858 // If we are writing data into the video buffer, that the destination area is within the display limits
859 if ((BltOperation
== EfiBltVideoFill
) || (BltOperation
== EfiBltBufferToVideo
) || (BltOperation
== EfiBltVideoToVideo
)) {
860 if ((DestinationY
+ Height
> VerticalResolution
) || (DestinationX
+ Width
> HorizontalResolution
)) {
861 DEBUG ((DEBUG_INFO
, "LcdGraphicsBlt: ERROR - Invalid destination resolution.\n"));
862 DEBUG ((DEBUG_INFO
, " - DestinationY=%d + Height=%d > VerticalResolution=%d.\n", DestinationY
, Height
, VerticalResolution
));
863 DEBUG ((DEBUG_INFO
, " - DestinationX=%d + Width=%d > HorizontalResolution=%d.\n", DestinationX
, Width
, HorizontalResolution
));
864 Status
= EFI_INVALID_PARAMETER
;
870 // Perform the Block Transfer Operation
873 switch (BltOperation
) {
874 case EfiBltVideoFill
:
875 Status
= BltVideoFill (This
, BltBuffer
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
, Delta
);
878 case EfiBltVideoToBltBuffer
:
879 Status
= BltVideoToBltBuffer (This
, BltBuffer
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
, Delta
);
882 case EfiBltBufferToVideo
:
883 Status
= BltBufferToVideo (This
, BltBuffer
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
, Delta
);
886 case EfiBltVideoToVideo
:
887 Status
= BltVideoToVideo (This
, BltBuffer
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
, Delta
);
890 case EfiGraphicsOutputBltOperationMax
:
892 DEBUG ((DEBUG_ERROR
, "LcdGraphicsBlt: Invalid Operation\n"));
893 Status
= EFI_INVALID_PARAMETER
;