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
) {
64 case LcdBitsPerPixel_24
:
66 WidthInBytes
= Width
* 4;
68 for( LineCount
= 0; LineCount
< Height
; LineCount
++ ) {
69 // Update the start addresses of source & destination using 32bit pointer arithmetic
70 SourceAddr
= (VOID
*)((UINT32
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourceX
);
71 DestinationAddr
= (VOID
*)((UINT32
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationX
);
73 // Copy the entire line Y from video ram to the temp buffer
74 CopyMem( DestinationAddr
, SourceAddr
, WidthInBytes
);
76 // Update the line numbers
78 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
;
102 case LcdBitsPerPixel_8
:
103 case LcdBitsPerPixel_4
:
104 case LcdBitsPerPixel_2
:
105 case LcdBitsPerPixel_1
:
107 // Can't handle this case
108 DEBUG((DEBUG_ERROR
, "ArmVeGraphics_Blt: EfiBltVideoToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
109 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
) {
152 case LcdBitsPerPixel_24
:
153 // Allocate a temporary buffer
155 PixelBuffer32bit
= (UINT32
*) AllocatePool((Height
* Width
) * sizeof(UINT32
));
157 if (PixelBuffer32bit
== NULL
) {
158 Status
= EFI_OUT_OF_RESOURCES
;
162 SizeIn32Bits
= Width
* 4;
164 // Copy from the video ram (source region) to a temp buffer
165 for (SourcePixelY
= SourceY
, DestinationPixel32bit
= PixelBuffer32bit
;
166 SourcePixelY
< SourceY
+ Height
;
167 SourcePixelY
++, DestinationPixel32bit
+= Width
)
169 // Update the start address of line Y (source)
170 SourcePixel32bit
= (UINT32
*)FrameBufferBase
+ SourcePixelY
* HorizontalResolution
+ SourceX
;
172 // Copy the entire line Y from video ram to the temp buffer
173 CopyMem( (VOID
*)DestinationPixel32bit
, (CONST VOID
*)SourcePixel32bit
, SizeIn32Bits
);
176 // Copy from the temp buffer to the video ram (destination region)
177 for (DestinationPixelY
= DestinationY
, SourcePixel32bit
= PixelBuffer32bit
;
178 DestinationPixelY
< DestinationY
+ Height
;
179 DestinationPixelY
++, SourcePixel32bit
+= Width
)
181 // Update the start address of line Y (target)
182 DestinationPixel32bit
= (UINT32
*)FrameBufferBase
+ DestinationPixelY
* HorizontalResolution
+ DestinationX
;
184 // Copy the entire line Y from the temp buffer to video ram
185 CopyMem( (VOID
*)DestinationPixel32bit
, (CONST VOID
*)SourcePixel32bit
, SizeIn32Bits
);
188 // Free up the allocated memory
189 FreePool((VOID
*) PixelBuffer32bit
);
194 case LcdBitsPerPixel_16_555
:
195 case LcdBitsPerPixel_16_565
:
196 case LcdBitsPerPixel_12_444
:
197 // Allocate a temporary buffer
198 PixelBuffer16bit
= (UINT16
*) AllocatePool((Height
* Width
) * sizeof(UINT16
));
200 if (PixelBuffer16bit
== NULL
) {
201 Status
= EFI_OUT_OF_RESOURCES
;
205 // Access each pixel inside the source area of the Video Memory and copy it to the temp buffer
207 SizeIn16Bits
= Width
* 2;
209 for (SourcePixelY
= SourceY
, DestinationPixel16bit
= PixelBuffer16bit
;
210 SourcePixelY
< SourceY
+ Height
;
211 SourcePixelY
++, DestinationPixel16bit
+= Width
)
213 // Calculate the source address:
214 SourcePixel16bit
= (UINT16
*)FrameBufferBase
+ SourcePixelY
* HorizontalResolution
+ SourceX
;
216 // Copy the entire line Y from Video to the temp buffer
217 CopyMem( (VOID
*)DestinationPixel16bit
, (CONST VOID
*)SourcePixel16bit
, SizeIn16Bits
);
220 // Copy from the temp buffer into the destination area of the Video Memory
222 for (DestinationPixelY
= DestinationY
, SourcePixel16bit
= PixelBuffer16bit
;
223 DestinationPixelY
< DestinationY
+ Height
;
224 DestinationPixelY
++, SourcePixel16bit
+= Width
)
226 // Calculate the target address:
227 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ (DestinationPixelY
* HorizontalResolution
+ DestinationX
);
229 // Copy the entire line Y from the temp buffer to Video
230 CopyMem( (VOID
*)DestinationPixel16bit
, (CONST VOID
*)SourcePixel16bit
, SizeIn16Bits
);
233 // Free the allocated memory
234 FreePool((VOID
*) PixelBuffer16bit
);
239 case LcdBitsPerPixel_8
:
240 case LcdBitsPerPixel_4
:
241 case LcdBitsPerPixel_2
:
242 case LcdBitsPerPixel_1
:
244 // Can't handle this case
245 DEBUG((DEBUG_ERROR
, "ArmVeGraphics_Blt: EfiBltVideoToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
246 Status
= EFI_INVALID_PARAMETER
;
259 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
260 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*EfiSourcePixel
, OPTIONAL
263 IN UINTN DestinationX
,
264 IN UINTN DestinationY
,
267 IN UINTN Delta OPTIONAL
// Number of BYTES in a row of the BltBuffer
270 EFI_PIXEL_BITMASK
* PixelInformation
;
272 UINT32 HorizontalResolution
;
273 LCD_BPP BitsPerPixel
;
274 VOID
*FrameBufferBase
;
275 VOID
*DestinationAddr
;
276 UINT16
*DestinationPixel16bit
;
278 UINT32 DestinationPixelX
;
279 UINT32 DestinationLine
;
282 Status
= EFI_SUCCESS
;
283 PixelInformation
= &This
->Mode
->Info
->PixelInformation
;
284 FrameBufferBase
= (UINTN
*)((UINTN
)(This
->Mode
->FrameBufferBase
));
285 HorizontalResolution
= This
->Mode
->Info
->HorizontalResolution
;
287 LcdPlatformGetBpp (This
->Mode
->Mode
,&BitsPerPixel
);
289 switch (BitsPerPixel
) {
290 case LcdBitsPerPixel_24
:
291 WidthInBytes
= Width
* 4;
293 // Copy the SourcePixel into every pixel inside the target rectangle
294 for (DestinationLine
= DestinationY
;
295 DestinationLine
< DestinationY
+ Height
;
298 // Calculate the target address using 32bit pointer arithmetic:
299 DestinationAddr
= (VOID
*)((UINT32
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationX
);
301 // Fill the entire line
302 SetMem32 (DestinationAddr
, WidthInBytes
, *((UINT32
*)EfiSourcePixel
));
306 case LcdBitsPerPixel_16_555
:
307 // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
308 Pixel16bit
= (UINT16
) (
309 ( (EfiSourcePixel
->Red
<< 7) & PixelInformation
->RedMask
)
310 | ( (EfiSourcePixel
->Green
<< 2) & PixelInformation
->GreenMask
)
311 | ( (EfiSourcePixel
->Blue
>> 3) & PixelInformation
->BlueMask
)
312 // | ( 0 & PixelInformation->ReservedMask )
315 // Copy the SourcePixel into every pixel inside the target rectangle
316 for (DestinationLine
= DestinationY
;
317 DestinationLine
< DestinationY
+ Height
;
320 for (DestinationPixelX
= DestinationX
;
321 DestinationPixelX
< DestinationX
+ Width
;
324 // Calculate the target address:
325 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
327 // Copy the pixel into the new target
328 *DestinationPixel16bit
= Pixel16bit
;
333 case LcdBitsPerPixel_16_565
:
334 // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
335 Pixel16bit
= (UINT16
) (
336 ( (EfiSourcePixel
->Red
<< 8) & PixelInformation
->RedMask
)
337 | ( (EfiSourcePixel
->Green
<< 3) & PixelInformation
->GreenMask
)
338 | ( (EfiSourcePixel
->Blue
>> 3) & PixelInformation
->BlueMask
)
341 // Copy the SourcePixel into every pixel inside the target rectangle
342 for (DestinationLine
= DestinationY
;
343 DestinationLine
< DestinationY
+ Height
;
346 for (DestinationPixelX
= DestinationX
;
347 DestinationPixelX
< DestinationX
+ Width
;
350 // Calculate the target address:
351 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
353 // Copy the pixel into the new target
354 *DestinationPixel16bit
= Pixel16bit
;
359 case LcdBitsPerPixel_12_444
:
360 // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
361 Pixel16bit
= (UINT16
) (
362 ( (EfiSourcePixel
->Red
>> 4) & PixelInformation
->RedMask
)
363 | ( (EfiSourcePixel
->Green
) & PixelInformation
->GreenMask
)
364 | ( (EfiSourcePixel
->Blue
<< 4) & PixelInformation
->BlueMask
)
367 // Copy the SourcePixel into every pixel inside the target rectangle
368 for (DestinationLine
= DestinationY
;
369 DestinationLine
< DestinationY
+ Height
;
372 for (DestinationPixelX
= DestinationX
;
373 DestinationPixelX
< DestinationX
+ Width
;
376 // Calculate the target address:
377 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
379 // Copy the pixel into the new target
380 *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
);
463 case LcdBitsPerPixel_16_555
:
464 // Access each pixel inside the Video Memory
465 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
466 SourceLine
< SourceY
+ Height
;
467 SourceLine
++, DestinationLine
++)
469 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
470 SourcePixelX
< SourceX
+ Width
;
471 SourcePixelX
++, DestinationPixelX
++)
473 // Calculate the source and target addresses:
474 SourcePixel16bit
= (UINT16
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourcePixelX
;
475 EfiDestinationPixel
= BltBuffer
+ DestinationLine
* BltBufferHorizontalResolution
+ DestinationPixelX
;
477 // Snapshot the pixel from the video buffer once, to speed up the operation.
478 // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.
479 Pixel16bit
= *SourcePixel16bit
;
481 // Copy the pixel into the new target
482 EfiDestinationPixel
->Red
= (UINT8
) ( (Pixel16bit
& PixelInformation
->RedMask
) >> 7 );
483 EfiDestinationPixel
->Green
= (UINT8
) ( (Pixel16bit
& PixelInformation
->GreenMask
) >> 2);
484 EfiDestinationPixel
->Blue
= (UINT8
) ( (Pixel16bit
& PixelInformation
->BlueMask
) << 3 );
485 // EfiDestinationPixel->Reserved = (UINT8) 0;
490 case LcdBitsPerPixel_16_565
:
491 // Access each pixel inside the Video Memory
492 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
493 SourceLine
< SourceY
+ Height
;
494 SourceLine
++, DestinationLine
++)
496 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
497 SourcePixelX
< SourceX
+ Width
;
498 SourcePixelX
++, DestinationPixelX
++)
500 // Calculate the source and target addresses:
501 SourcePixel16bit
= (UINT16
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourcePixelX
;
502 EfiDestinationPixel
= BltBuffer
+ DestinationLine
* BltBufferHorizontalResolution
+ DestinationPixelX
;
504 // Snapshot the pixel from the video buffer once, to speed up the operation.
505 // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.
506 Pixel16bit
= *SourcePixel16bit
;
508 // Copy the pixel into the new target
509 // There is no info for the Reserved byte, so we set it to zero
510 EfiDestinationPixel
->Red
= (UINT8
) ( (Pixel16bit
& PixelInformation
->RedMask
) >> 8 );
511 EfiDestinationPixel
->Green
= (UINT8
) ( (Pixel16bit
& PixelInformation
->GreenMask
) >> 3);
512 EfiDestinationPixel
->Blue
= (UINT8
) ( (Pixel16bit
& PixelInformation
->BlueMask
) << 3 );
513 // EfiDestinationPixel->Reserved = (UINT8) 0;
518 case LcdBitsPerPixel_12_444
:
519 // Access each pixel inside the Video Memory
520 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
521 SourceLine
< SourceY
+ Height
;
522 SourceLine
++, DestinationLine
++)
524 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
525 SourcePixelX
< SourceX
+ Width
;
526 SourcePixelX
++, DestinationPixelX
++)
528 // Calculate the source and target addresses:
529 SourcePixel16bit
= (UINT16
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourcePixelX
;
530 EfiDestinationPixel
= BltBuffer
+ DestinationLine
* BltBufferHorizontalResolution
+ DestinationPixelX
;
532 // Snapshot the pixel from the video buffer once, to speed up the operation.
533 // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.
534 Pixel16bit
= *SourcePixel16bit
;
536 // Copy the pixel into the new target
537 EfiDestinationPixel
->Red
= (UINT8
) ( (Pixel16bit
& PixelInformation
->RedMask
) >> 4 );
538 EfiDestinationPixel
->Green
= (UINT8
) ( (Pixel16bit
& PixelInformation
->GreenMask
) );
539 EfiDestinationPixel
->Blue
= (UINT8
) ( (Pixel16bit
& PixelInformation
->BlueMask
) << 4 );
540 // EfiDestinationPixel->Reserved = (UINT8) 0;
545 case LcdBitsPerPixel_8
:
546 case LcdBitsPerPixel_4
:
547 case LcdBitsPerPixel_2
:
548 case LcdBitsPerPixel_1
:
550 // Can't handle this case
551 DEBUG((DEBUG_ERROR
, "LcdGraphicsBlt: EfiBltVideoToBltBuffer: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
552 Status
= EFI_INVALID_PARAMETER
;
561 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
562 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
565 IN UINTN DestinationX
,
566 IN UINTN DestinationY
,
569 IN UINTN Delta OPTIONAL
// Number of BYTES in a row of the BltBuffer
573 UINT32 HorizontalResolution
;
574 LCD_BPP BitsPerPixel
;
575 EFI_PIXEL_BITMASK
*PixelInformation
;
576 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*EfiSourcePixel
;
577 VOID
*FrameBufferBase
;
579 VOID
*DestinationAddr
;
580 UINT16
*DestinationPixel16bit
;
583 UINT32 DestinationPixelX
;
584 UINT32 DestinationLine
;
585 UINT32 BltBufferHorizontalResolution
;
588 Status
= EFI_SUCCESS
;
589 PixelInformation
= &This
->Mode
->Info
->PixelInformation
;
590 HorizontalResolution
= This
->Mode
->Info
->HorizontalResolution
;
591 FrameBufferBase
= (UINTN
*)((UINTN
)(This
->Mode
->FrameBufferBase
));
593 if(( Delta
!= 0 ) && ( Delta
!= Width
* sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL
))) {
594 // Delta is not zero and it is different from the width.
595 // Divide it by the size of a pixel to find out the buffer's horizontal resolution.
596 BltBufferHorizontalResolution
= (UINT32
) (Delta
/ sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
598 BltBufferHorizontalResolution
= Width
;
601 LcdPlatformGetBpp (This
->Mode
->Mode
,&BitsPerPixel
);
603 switch (BitsPerPixel
) {
604 case LcdBitsPerPixel_24
:
605 WidthInBytes
= Width
* 4;
607 // Access each pixel inside the BltBuffer Memory
608 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
609 SourceLine
< SourceY
+ Height
;
610 SourceLine
++, DestinationLine
++)
612 // Calculate the source and target addresses using 32bit pointer arithmetic:
613 SourceAddr
= (VOID
*)((UINT32
*)BltBuffer
+ SourceLine
* BltBufferHorizontalResolution
+ SourceX
);
614 DestinationAddr
= (VOID
*)((UINT32
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationX
);
616 // Copy the entire row Y
617 CopyMem( DestinationAddr
, SourceAddr
, WidthInBytes
);
621 case LcdBitsPerPixel_16_555
:
622 // Access each pixel inside the BltBuffer Memory
623 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
624 SourceLine
< SourceY
+ Height
;
625 SourceLine
++, DestinationLine
++) {
627 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
628 SourcePixelX
< SourceX
+ Width
;
629 SourcePixelX
++, DestinationPixelX
++)
631 // Calculate the source and target addresses:
632 EfiSourcePixel
= BltBuffer
+ SourceLine
* BltBufferHorizontalResolution
+ SourcePixelX
;
633 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
635 // Copy the pixel into the new target
636 // Only the most significant bits will be copied across:
637 // To convert from 8 bits to 5 bits per pixel we throw away the 3 least significant bits
638 *DestinationPixel16bit
= (UINT16
) (
639 ( (EfiSourcePixel
->Red
<< 7) & PixelInformation
->RedMask
)
640 | ( (EfiSourcePixel
->Green
<< 2) & PixelInformation
->GreenMask
)
641 | ( (EfiSourcePixel
->Blue
>> 3) & PixelInformation
->BlueMask
)
642 // | ( 0 & PixelInformation->ReservedMask )
648 case LcdBitsPerPixel_16_565
:
649 // Access each pixel inside the BltBuffer Memory
650 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
651 SourceLine
< SourceY
+ Height
;
652 SourceLine
++, DestinationLine
++) {
654 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
655 SourcePixelX
< SourceX
+ Width
;
656 SourcePixelX
++, DestinationPixelX
++)
658 // Calculate the source and target addresses:
659 EfiSourcePixel
= BltBuffer
+ SourceLine
* BltBufferHorizontalResolution
+ SourcePixelX
;
660 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
662 // Copy the pixel into the new target
663 // Only the most significant bits will be copied across:
664 // To convert from 8 bits to 5 or 6 bits per pixel we throw away the 3 or 2 least significant bits
665 // There is no room for the Reserved byte so we ignore that completely
666 *DestinationPixel16bit
= (UINT16
) (
667 ( (EfiSourcePixel
->Red
<< 8) & PixelInformation
->RedMask
)
668 | ( (EfiSourcePixel
->Green
<< 3) & PixelInformation
->GreenMask
)
669 | ( (EfiSourcePixel
->Blue
>> 3) & PixelInformation
->BlueMask
)
675 case LcdBitsPerPixel_12_444
:
676 // Access each pixel inside the BltBuffer Memory
677 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
678 SourceLine
< SourceY
+ Height
;
679 SourceLine
++, DestinationLine
++) {
681 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
682 SourcePixelX
< SourceX
+ Width
;
683 SourcePixelX
++, DestinationPixelX
++)
685 // Calculate the source and target addresses:
686 EfiSourcePixel
= BltBuffer
+ SourceLine
* BltBufferHorizontalResolution
+ SourcePixelX
;
687 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
689 // Copy the pixel into the new target
690 // Only the most significant bits will be copied across:
691 // To convert from 8 bits to 5 bits per pixel we throw away the 3 least significant bits
692 *DestinationPixel16bit
= (UINT16
) (
693 ( (EfiSourcePixel
->Red
<< 4) & PixelInformation
->RedMask
)
694 | ( (EfiSourcePixel
->Green
) & PixelInformation
->GreenMask
)
695 | ( (EfiSourcePixel
->Blue
>> 4) & PixelInformation
->BlueMask
)
696 // | ( 0 & PixelInformation->ReservedMask )
702 case LcdBitsPerPixel_8
:
703 case LcdBitsPerPixel_4
:
704 case LcdBitsPerPixel_2
:
705 case LcdBitsPerPixel_1
:
707 // Can't handle this case
708 DEBUG((DEBUG_ERROR
, "LcdGraphicsBlt: EfiBltBufferToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
709 Status
= EFI_INVALID_PARAMETER
;
718 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
719 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
722 IN UINTN DestinationX
,
723 IN UINTN DestinationY
,
726 IN UINTN Delta OPTIONAL
// Number of BYTES in a row of the BltBuffer
730 UINT32 HorizontalResolution
;
731 LCD_BPP BitsPerPixel
;
732 VOID
*FrameBufferBase
;
734 HorizontalResolution
= This
->Mode
->Info
->HorizontalResolution
;
735 FrameBufferBase
= (UINTN
*)((UINTN
)(This
->Mode
->FrameBufferBase
));
738 // BltVideo to BltVideo:
740 // Source is the Video Memory,
741 // Destination is the Video Memory
743 LcdPlatformGetBpp (This
->Mode
->Mode
,&BitsPerPixel
);
744 FrameBufferBase
= (UINTN
*)((UINTN
)(This
->Mode
->FrameBufferBase
));
746 // The UEFI spec currently states:
747 // "There is no limitation on the overlapping of the source and destination rectangles"
748 // Therefore, we must be careful to avoid overwriting the source data
749 if( SourceY
== DestinationY
) {
750 // Copying within the same height, e.g. horizontal shift
751 if( SourceX
== DestinationX
) {
753 Status
= EFI_SUCCESS
;
754 } else if( ((SourceX
>DestinationX
)?(SourceX
- DestinationX
):(DestinationX
- SourceX
)) < Width
) {
756 Status
= VideoCopyHorizontalOverlap (BitsPerPixel
, FrameBufferBase
, HorizontalResolution
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
);
759 Status
= VideoCopyNoHorizontalOverlap (BitsPerPixel
, FrameBufferBase
, HorizontalResolution
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
);
762 // Copying from different heights
763 Status
= VideoCopyNoHorizontalOverlap (BitsPerPixel
, FrameBufferBase
, HorizontalResolution
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
);
769 /***************************************
770 * GraphicsOutput Protocol function, mapping to
771 * EFI_GRAPHICS_OUTPUT_PROTOCOL.Blt
773 * PRESUMES: 1 pixel = 4 bytes (32bits)
774 * ***************************************/
778 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
779 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
780 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation
,
783 IN UINTN DestinationX
,
784 IN UINTN DestinationY
,
787 IN UINTN Delta OPTIONAL
// Number of BYTES in a row of the BltBuffer
791 UINT32 HorizontalResolution
;
792 UINT32 VerticalResolution
;
793 LCD_INSTANCE
* Instance
;
795 Instance
= LCD_INSTANCE_FROM_GOP_THIS(This
);
797 // Setup the hardware if not already done
798 if (!mDisplayInitialized
) {
799 Status
= InitializeDisplay (Instance
);
800 if (EFI_ERROR(Status
)) {
805 HorizontalResolution
= This
->Mode
->Info
->HorizontalResolution
;
806 VerticalResolution
= This
->Mode
->Info
->VerticalResolution
;
808 DEBUG((DEBUG_INFO
, "LcdGraphicsBlt (BltOperation:%d,DestX:%d,DestY:%d,Width:%d,Height:%d) res(%d,%d)\n",
809 BltOperation
,DestinationX
,DestinationY
,Width
,Height
,HorizontalResolution
,VerticalResolution
));
811 // Check we have reasonable parameters
812 if (Width
== 0 || Height
== 0) {
813 DEBUG((DEBUG_ERROR
, "LcdGraphicsBlt: ERROR - Invalid dimension: Zero size area.\n" ));
814 Status
= EFI_INVALID_PARAMETER
;
818 if ((BltOperation
== EfiBltVideoFill
) || (BltOperation
== EfiBltBufferToVideo
) || (BltOperation
== EfiBltVideoToBltBuffer
)) {
819 ASSERT( BltBuffer
!= NULL
);
822 /*if ((DestinationX >= HorizontalResolution) || (DestinationY >= VerticalResolution)) {
823 DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: ERROR - Invalid destination.\n" ));
824 Status = EFI_INVALID_PARAMETER;
828 // If we are reading data out of the video buffer, check that the source area is within the display limits
829 if ((BltOperation
== EfiBltVideoToBltBuffer
) || (BltOperation
== EfiBltVideoToVideo
)) {
830 if ((SourceY
+ Height
> VerticalResolution
) || (SourceX
+ Width
> HorizontalResolution
)) {
831 DEBUG((DEBUG_INFO
, "LcdGraphicsBlt: ERROR - Invalid source resolution.\n" ));
832 DEBUG((DEBUG_INFO
, " - SourceY=%d + Height=%d > VerticalResolution=%d.\n", SourceY
, Height
, VerticalResolution
));
833 DEBUG((DEBUG_INFO
, " - SourceX=%d + Width=%d > HorizontalResolution=%d.\n", SourceX
, Width
, HorizontalResolution
));
834 Status
= EFI_INVALID_PARAMETER
;
839 // If we are writing data into the video buffer, that the destination area is within the display limits
840 if ((BltOperation
== EfiBltVideoFill
) || (BltOperation
== EfiBltBufferToVideo
) || (BltOperation
== EfiBltVideoToVideo
)) {
841 if ((DestinationY
+ Height
> VerticalResolution
) || (DestinationX
+ Width
> HorizontalResolution
)) {
842 DEBUG((DEBUG_INFO
, "LcdGraphicsBlt: ERROR - Invalid destination resolution.\n" ));
843 DEBUG((DEBUG_INFO
, " - DestinationY=%d + Height=%d > VerticalResolution=%d.\n", DestinationY
, Height
, VerticalResolution
));
844 DEBUG((DEBUG_INFO
, " - DestinationX=%d + Width=%d > HorizontalResolution=%d.\n", DestinationX
, Width
, HorizontalResolution
));
845 Status
= EFI_INVALID_PARAMETER
;
851 // Perform the Block Transfer Operation
854 switch (BltOperation
) {
855 case EfiBltVideoFill
:
856 Status
= BltVideoFill (This
, BltBuffer
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
, Delta
);
859 case EfiBltVideoToBltBuffer
:
860 Status
= BltVideoToBltBuffer (This
, BltBuffer
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
, Delta
);
863 case EfiBltBufferToVideo
:
864 Status
= BltBufferToVideo (This
, BltBuffer
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
, Delta
);
867 case EfiBltVideoToVideo
:
868 Status
= BltVideoToVideo (This
, BltBuffer
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
, Delta
);
871 case EfiGraphicsOutputBltOperationMax
:
873 DEBUG((DEBUG_ERROR
, "LcdGraphicsBlt: Invalid Operation\n"));
874 Status
= EFI_INVALID_PARAMETER
;