3 Copyright (c) 2011-2013, ARM Ltd. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include <Library/BaseMemoryLib.h>
16 #include <Library/DevicePathLib.h>
17 #include <Library/UefiBootServicesTableLib.h>
18 #include <Library/UefiRuntimeServicesTableLib.h>
19 #include <Library/MemoryAllocationLib.h>
21 #include <Guid/GlobalVariable.h>
23 #include "LcdGraphicsOutputDxe.h"
25 extern BOOLEAN mDisplayInitialized
;
28 // Function Definitions
33 VideoCopyNoHorizontalOverlap (
34 IN UINTN BitsPerPixel
,
35 IN
volatile VOID
*FrameBufferBase
,
36 IN UINT32 HorizontalResolution
,
39 IN UINTN DestinationX
,
40 IN UINTN DestinationY
,
45 EFI_STATUS Status
= EFI_SUCCESS
;
47 UINTN DestinationLine
;
52 VOID
*DestinationAddr
;
54 if( DestinationY
<= SourceY
) {
55 // scrolling up (or horizontally but without overlap)
57 DestinationLine
= DestinationY
;
61 SourceLine
= SourceY
+ Height
;
62 DestinationLine
= DestinationY
+ Height
;
66 switch (BitsPerPixel
) {
68 case LCD_BITS_PER_PIXEL_24
:
70 WidthInBytes
= Width
* 4;
72 for( LineCount
= 0; LineCount
< Height
; LineCount
++ ) {
73 // Update the start addresses of source & destination using 32bit pointer arithmetic
74 SourceAddr
= (VOID
*)((UINT32
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourceX
);
75 DestinationAddr
= (VOID
*)((UINT32
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationX
);
77 // Copy the entire line Y from video ram to the temp buffer
78 CopyMem( DestinationAddr
, SourceAddr
, WidthInBytes
);
80 // Update the line numbers
82 DestinationLine
+= Step
;
86 case LCD_BITS_PER_PIXEL_16_555
:
87 case LCD_BITS_PER_PIXEL_16_565
:
88 case LCD_BITS_PER_PIXEL_12_444
:
90 WidthInBytes
= Width
* 2;
92 for( LineCount
= 0; LineCount
< Height
; LineCount
++ ) {
93 // Update the start addresses of source & destination using 16bit pointer arithmetic
94 SourceAddr
= (VOID
*)((UINT16
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourceX
);
95 DestinationAddr
= (VOID
*)((UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationX
);
97 // Copy the entire line Y from video ram to the temp buffer
98 CopyMem( DestinationAddr
, SourceAddr
, WidthInBytes
);
100 // Update the line numbers
102 DestinationLine
+= Step
;
106 case LCD_BITS_PER_PIXEL_8
:
107 case LCD_BITS_PER_PIXEL_4
:
108 case LCD_BITS_PER_PIXEL_2
:
109 case LCD_BITS_PER_PIXEL_1
:
111 // Can't handle this case
112 DEBUG((DEBUG_ERROR
, "ArmVeGraphics_Blt: EfiBltVideoToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
113 Status
= EFI_INVALID_PARAMETER
;
125 VideoCopyHorizontalOverlap (
126 IN UINTN BitsPerPixel
,
127 IN
volatile VOID
*FrameBufferBase
,
128 UINT32 HorizontalResolution
,
131 IN UINTN DestinationX
,
132 IN UINTN DestinationY
,
137 EFI_STATUS Status
= EFI_SUCCESS
;
139 UINT32
*PixelBuffer32bit
;
140 UINT32
*SourcePixel32bit
;
141 UINT32
*DestinationPixel32bit
;
143 UINT16
*PixelBuffer16bit
;
144 UINT16
*SourcePixel16bit
;
145 UINT16
*DestinationPixel16bit
;
148 UINT32 DestinationPixelY
;
152 switch (BitsPerPixel
) {
154 case LCD_BITS_PER_PIXEL_24
:
155 // Allocate a temporary buffer
157 PixelBuffer32bit
= (UINT32
*) AllocatePool((Height
* Width
) * sizeof(UINT32
));
159 if (PixelBuffer32bit
== NULL
) {
160 Status
= EFI_OUT_OF_RESOURCES
;
164 SizeIn32Bits
= Width
* 4;
166 // Copy from the video ram (source region) to a temp buffer
167 for (SourcePixelY
= SourceY
, DestinationPixel32bit
= PixelBuffer32bit
;
168 SourcePixelY
< SourceY
+ Height
;
169 SourcePixelY
++, DestinationPixel32bit
+= Width
)
171 // Update the start address of line Y (source)
172 SourcePixel32bit
= (UINT32
*)FrameBufferBase
+ SourcePixelY
* HorizontalResolution
+ SourceX
;
174 // Copy the entire line Y from video ram to the temp buffer
175 CopyMem( (VOID
*)DestinationPixel32bit
, (CONST VOID
*)SourcePixel32bit
, SizeIn32Bits
);
178 // Copy from the temp buffer to the video ram (destination region)
179 for (DestinationPixelY
= DestinationY
, SourcePixel32bit
= PixelBuffer32bit
;
180 DestinationPixelY
< DestinationY
+ Height
;
181 DestinationPixelY
++, SourcePixel32bit
+= Width
)
183 // Update the start address of line Y (target)
184 DestinationPixel32bit
= (UINT32
*)FrameBufferBase
+ DestinationPixelY
* HorizontalResolution
+ DestinationX
;
186 // Copy the entire line Y from the temp buffer to video ram
187 CopyMem( (VOID
*)DestinationPixel32bit
, (CONST VOID
*)SourcePixel32bit
, SizeIn32Bits
);
190 // Free up the allocated memory
191 FreePool((VOID
*) PixelBuffer32bit
);
196 case LCD_BITS_PER_PIXEL_16_555
:
197 case LCD_BITS_PER_PIXEL_16_565
:
198 case LCD_BITS_PER_PIXEL_12_444
:
199 // Allocate a temporary buffer
200 PixelBuffer16bit
= (UINT16
*) AllocatePool((Height
* Width
) * sizeof(UINT16
));
202 if (PixelBuffer16bit
== NULL
) {
203 Status
= EFI_OUT_OF_RESOURCES
;
207 // Access each pixel inside the source area of the Video Memory and copy it to the temp buffer
209 SizeIn16Bits
= Width
* 2;
211 for (SourcePixelY
= SourceY
, DestinationPixel16bit
= PixelBuffer16bit
;
212 SourcePixelY
< SourceY
+ Height
;
213 SourcePixelY
++, DestinationPixel16bit
+= Width
)
215 // Calculate the source address:
216 SourcePixel16bit
= (UINT16
*)FrameBufferBase
+ SourcePixelY
* HorizontalResolution
+ SourceX
;
218 // Copy the entire line Y from Video to the temp buffer
219 CopyMem( (VOID
*)DestinationPixel16bit
, (CONST VOID
*)SourcePixel16bit
, SizeIn16Bits
);
222 // Copy from the temp buffer into the destination area of the Video Memory
224 for (DestinationPixelY
= DestinationY
, SourcePixel16bit
= PixelBuffer16bit
;
225 DestinationPixelY
< DestinationY
+ Height
;
226 DestinationPixelY
++, SourcePixel16bit
+= Width
)
228 // Calculate the target address:
229 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ (DestinationPixelY
* HorizontalResolution
+ DestinationX
);
231 // Copy the entire line Y from the temp buffer to Video
232 CopyMem( (VOID
*)DestinationPixel16bit
, (CONST VOID
*)SourcePixel16bit
, SizeIn16Bits
);
235 // Free the allocated memory
236 FreePool((VOID
*) PixelBuffer16bit
);
241 case LCD_BITS_PER_PIXEL_8
:
242 case LCD_BITS_PER_PIXEL_4
:
243 case LCD_BITS_PER_PIXEL_2
:
244 case LCD_BITS_PER_PIXEL_1
:
246 // Can't handle this case
247 DEBUG((DEBUG_ERROR
, "ArmVeGraphics_Blt: EfiBltVideoToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
248 Status
= EFI_INVALID_PARAMETER
;
261 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
262 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*EfiSourcePixel
, OPTIONAL
265 IN UINTN DestinationX
,
266 IN UINTN DestinationY
,
269 IN UINTN Delta OPTIONAL
// Number of BYTES in a row of the BltBuffer
272 EFI_PIXEL_BITMASK
* PixelInformation
;
274 UINT32 HorizontalResolution
;
275 LCD_BPP BitsPerPixel
;
276 VOID
*FrameBufferBase
;
277 VOID
*DestinationAddr
;
278 UINT16
*DestinationPixel16bit
;
280 UINT32 DestinationPixelX
;
281 UINT32 DestinationLine
;
284 Status
= EFI_SUCCESS
;
285 PixelInformation
= &This
->Mode
->Info
->PixelInformation
;
286 FrameBufferBase
= (UINTN
*)((UINTN
)(This
->Mode
->FrameBufferBase
));
287 HorizontalResolution
= This
->Mode
->Info
->HorizontalResolution
;
289 LcdPlatformGetBpp (This
->Mode
->Mode
,&BitsPerPixel
);
291 switch (BitsPerPixel
) {
292 case LCD_BITS_PER_PIXEL_24
:
293 WidthInBytes
= Width
* 4;
295 // Copy the SourcePixel into every pixel inside the target rectangle
296 for (DestinationLine
= DestinationY
;
297 DestinationLine
< DestinationY
+ Height
;
300 // Calculate the target address using 32bit pointer arithmetic:
301 DestinationAddr
= (VOID
*)((UINT32
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationX
);
303 // Fill the entire line
304 SetMem32 (DestinationAddr
, WidthInBytes
, *((UINT32
*)EfiSourcePixel
));
308 case LCD_BITS_PER_PIXEL_16_555
:
309 // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
310 Pixel16bit
= (UINT16
) (
311 ( (EfiSourcePixel
->Red
<< 7) & PixelInformation
->RedMask
)
312 | ( (EfiSourcePixel
->Green
<< 2) & PixelInformation
->GreenMask
)
313 | ( (EfiSourcePixel
->Blue
>> 3) & PixelInformation
->BlueMask
)
314 // | ( 0 & PixelInformation->ReservedMask )
317 // Copy the SourcePixel into every pixel inside the target rectangle
318 for (DestinationLine
= DestinationY
;
319 DestinationLine
< DestinationY
+ Height
;
322 for (DestinationPixelX
= DestinationX
;
323 DestinationPixelX
< DestinationX
+ Width
;
326 // Calculate the target address:
327 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
329 // Copy the pixel into the new target
330 *DestinationPixel16bit
= Pixel16bit
;
335 case LCD_BITS_PER_PIXEL_16_565
:
336 // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
337 Pixel16bit
= (UINT16
) (
338 ( (EfiSourcePixel
->Red
<< 8) & PixelInformation
->RedMask
)
339 | ( (EfiSourcePixel
->Green
<< 3) & PixelInformation
->GreenMask
)
340 | ( (EfiSourcePixel
->Blue
>> 3) & PixelInformation
->BlueMask
)
343 // Copy the SourcePixel into every pixel inside the target rectangle
344 for (DestinationLine
= DestinationY
;
345 DestinationLine
< DestinationY
+ Height
;
348 for (DestinationPixelX
= DestinationX
;
349 DestinationPixelX
< DestinationX
+ Width
;
352 // Calculate the target address:
353 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
355 // Copy the pixel into the new target
356 *DestinationPixel16bit
= Pixel16bit
;
361 case LCD_BITS_PER_PIXEL_12_444
:
362 // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
363 Pixel16bit
= (UINT16
) (
364 ( (EfiSourcePixel
->Red
>> 4) & PixelInformation
->RedMask
)
365 | ( (EfiSourcePixel
->Green
) & PixelInformation
->GreenMask
)
366 | ( (EfiSourcePixel
->Blue
<< 4) & PixelInformation
->BlueMask
)
369 // Copy the SourcePixel into every pixel inside the target rectangle
370 for (DestinationLine
= DestinationY
;
371 DestinationLine
< DestinationY
+ Height
;
374 for (DestinationPixelX
= DestinationX
;
375 DestinationPixelX
< DestinationX
+ Width
;
378 // Calculate the target address:
379 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
381 // Copy the pixel into the new target
382 *DestinationPixel16bit
= Pixel16bit
;
387 case LCD_BITS_PER_PIXEL_8
:
388 case LCD_BITS_PER_PIXEL_4
:
389 case LCD_BITS_PER_PIXEL_2
:
390 case LCD_BITS_PER_PIXEL_1
:
392 // Can't handle this case
393 DEBUG((DEBUG_ERROR
, "LcdGraphicsBlt: EfiBltVideoFill: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
394 Status
= EFI_INVALID_PARAMETER
;
403 BltVideoToBltBuffer (
404 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
405 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
408 IN UINTN DestinationX
,
409 IN UINTN DestinationY
,
412 IN UINTN Delta OPTIONAL
// Number of BYTES in a row of the BltBuffer
416 UINT32 HorizontalResolution
;
417 LCD_BPP BitsPerPixel
;
418 EFI_PIXEL_BITMASK
*PixelInformation
;
419 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*EfiDestinationPixel
;
420 VOID
*FrameBufferBase
;
422 VOID
*DestinationAddr
;
423 UINT16
*SourcePixel16bit
;
427 UINT32 DestinationPixelX
;
428 UINT32 DestinationLine
;
429 UINT32 BltBufferHorizontalResolution
;
432 Status
= EFI_SUCCESS
;
433 PixelInformation
= &This
->Mode
->Info
->PixelInformation
;
434 HorizontalResolution
= This
->Mode
->Info
->HorizontalResolution
;
435 FrameBufferBase
= (UINTN
*)((UINTN
)(This
->Mode
->FrameBufferBase
));
437 if(( Delta
!= 0 ) && ( Delta
!= Width
* sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL
))) {
438 // Delta is not zero and it is different from the width.
439 // Divide it by the size of a pixel to find out the buffer's horizontal resolution.
440 BltBufferHorizontalResolution
= (UINT32
) (Delta
/ sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
442 BltBufferHorizontalResolution
= Width
;
445 LcdPlatformGetBpp (This
->Mode
->Mode
,&BitsPerPixel
);
447 switch (BitsPerPixel
) {
448 case LCD_BITS_PER_PIXEL_24
:
449 WidthInBytes
= Width
* 4;
451 // Access each line inside the Video Memory
452 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
453 SourceLine
< SourceY
+ Height
;
454 SourceLine
++, DestinationLine
++)
456 // Calculate the source and target addresses using 32bit pointer arithmetic:
457 SourceAddr
= (VOID
*)((UINT32
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourceX
);
458 DestinationAddr
= (VOID
*)((UINT32
*)BltBuffer
+ DestinationLine
* BltBufferHorizontalResolution
+ DestinationX
);
460 // Copy the entire line
461 CopyMem( DestinationAddr
, SourceAddr
, WidthInBytes
);
465 case LCD_BITS_PER_PIXEL_16_555
:
466 // Access each pixel inside the Video Memory
467 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
468 SourceLine
< SourceY
+ Height
;
469 SourceLine
++, DestinationLine
++)
471 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
472 SourcePixelX
< SourceX
+ Width
;
473 SourcePixelX
++, DestinationPixelX
++)
475 // Calculate the source and target addresses:
476 SourcePixel16bit
= (UINT16
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourcePixelX
;
477 EfiDestinationPixel
= BltBuffer
+ DestinationLine
* BltBufferHorizontalResolution
+ DestinationPixelX
;
479 // Snapshot the pixel from the video buffer once, to speed up the operation.
480 // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.
481 Pixel16bit
= *SourcePixel16bit
;
483 // Copy the pixel into the new target
484 EfiDestinationPixel
->Red
= (UINT8
) ( (Pixel16bit
& PixelInformation
->RedMask
) >> 7 );
485 EfiDestinationPixel
->Green
= (UINT8
) ( (Pixel16bit
& PixelInformation
->GreenMask
) >> 2);
486 EfiDestinationPixel
->Blue
= (UINT8
) ( (Pixel16bit
& PixelInformation
->BlueMask
) << 3 );
487 // EfiDestinationPixel->Reserved = (UINT8) 0;
492 case LCD_BITS_PER_PIXEL_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;
520 case LCD_BITS_PER_PIXEL_12_444
:
521 // Access each pixel inside the Video Memory
522 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
523 SourceLine
< SourceY
+ Height
;
524 SourceLine
++, DestinationLine
++)
526 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
527 SourcePixelX
< SourceX
+ Width
;
528 SourcePixelX
++, DestinationPixelX
++)
530 // Calculate the source and target addresses:
531 SourcePixel16bit
= (UINT16
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourcePixelX
;
532 EfiDestinationPixel
= BltBuffer
+ DestinationLine
* BltBufferHorizontalResolution
+ DestinationPixelX
;
534 // Snapshot the pixel from the video buffer once, to speed up the operation.
535 // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.
536 Pixel16bit
= *SourcePixel16bit
;
538 // Copy the pixel into the new target
539 EfiDestinationPixel
->Red
= (UINT8
) ( (Pixel16bit
& PixelInformation
->RedMask
) >> 4 );
540 EfiDestinationPixel
->Green
= (UINT8
) ( (Pixel16bit
& PixelInformation
->GreenMask
) );
541 EfiDestinationPixel
->Blue
= (UINT8
) ( (Pixel16bit
& PixelInformation
->BlueMask
) << 4 );
542 // EfiDestinationPixel->Reserved = (UINT8) 0;
547 case LCD_BITS_PER_PIXEL_8
:
548 case LCD_BITS_PER_PIXEL_4
:
549 case LCD_BITS_PER_PIXEL_2
:
550 case LCD_BITS_PER_PIXEL_1
:
552 // Can't handle this case
553 DEBUG((DEBUG_ERROR
, "LcdGraphicsBlt: EfiBltVideoToBltBuffer: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
554 Status
= EFI_INVALID_PARAMETER
;
563 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
564 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
567 IN UINTN DestinationX
,
568 IN UINTN DestinationY
,
571 IN UINTN Delta OPTIONAL
// Number of BYTES in a row of the BltBuffer
575 UINT32 HorizontalResolution
;
576 LCD_BPP BitsPerPixel
;
577 EFI_PIXEL_BITMASK
*PixelInformation
;
578 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*EfiSourcePixel
;
579 VOID
*FrameBufferBase
;
581 VOID
*DestinationAddr
;
582 UINT16
*DestinationPixel16bit
;
585 UINT32 DestinationPixelX
;
586 UINT32 DestinationLine
;
587 UINT32 BltBufferHorizontalResolution
;
590 Status
= EFI_SUCCESS
;
591 PixelInformation
= &This
->Mode
->Info
->PixelInformation
;
592 HorizontalResolution
= This
->Mode
->Info
->HorizontalResolution
;
593 FrameBufferBase
= (UINTN
*)((UINTN
)(This
->Mode
->FrameBufferBase
));
595 if(( Delta
!= 0 ) && ( Delta
!= Width
* sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL
))) {
596 // Delta is not zero and it is different from the width.
597 // Divide it by the size of a pixel to find out the buffer's horizontal resolution.
598 BltBufferHorizontalResolution
= (UINT32
) (Delta
/ sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
600 BltBufferHorizontalResolution
= Width
;
603 LcdPlatformGetBpp (This
->Mode
->Mode
,&BitsPerPixel
);
605 switch (BitsPerPixel
) {
606 case LCD_BITS_PER_PIXEL_24
:
607 WidthInBytes
= Width
* 4;
609 // Access each pixel inside the BltBuffer Memory
610 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
611 SourceLine
< SourceY
+ Height
;
612 SourceLine
++, DestinationLine
++)
614 // Calculate the source and target addresses using 32bit pointer arithmetic:
615 SourceAddr
= (VOID
*)((UINT32
*)BltBuffer
+ SourceLine
* BltBufferHorizontalResolution
+ SourceX
);
616 DestinationAddr
= (VOID
*)((UINT32
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationX
);
618 // Copy the entire row Y
619 CopyMem( DestinationAddr
, SourceAddr
, WidthInBytes
);
623 case LCD_BITS_PER_PIXEL_16_555
:
624 // Access each pixel inside the BltBuffer Memory
625 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
626 SourceLine
< SourceY
+ Height
;
627 SourceLine
++, DestinationLine
++) {
629 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
630 SourcePixelX
< SourceX
+ Width
;
631 SourcePixelX
++, DestinationPixelX
++)
633 // Calculate the source and target addresses:
634 EfiSourcePixel
= BltBuffer
+ SourceLine
* BltBufferHorizontalResolution
+ SourcePixelX
;
635 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
637 // Copy the pixel into the new target
638 // Only the most significant bits will be copied across:
639 // To convert from 8 bits to 5 bits per pixel we throw away the 3 least significant bits
640 *DestinationPixel16bit
= (UINT16
) (
641 ( (EfiSourcePixel
->Red
<< 7) & PixelInformation
->RedMask
)
642 | ( (EfiSourcePixel
->Green
<< 2) & PixelInformation
->GreenMask
)
643 | ( (EfiSourcePixel
->Blue
>> 3) & PixelInformation
->BlueMask
)
644 // | ( 0 & PixelInformation->ReservedMask )
650 case LCD_BITS_PER_PIXEL_16_565
:
651 // Access each pixel inside the BltBuffer Memory
652 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
653 SourceLine
< SourceY
+ Height
;
654 SourceLine
++, DestinationLine
++) {
656 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
657 SourcePixelX
< SourceX
+ Width
;
658 SourcePixelX
++, DestinationPixelX
++)
660 // Calculate the source and target addresses:
661 EfiSourcePixel
= BltBuffer
+ SourceLine
* BltBufferHorizontalResolution
+ SourcePixelX
;
662 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
664 // Copy the pixel into the new target
665 // Only the most significant bits will be copied across:
666 // To convert from 8 bits to 5 or 6 bits per pixel we throw away the 3 or 2 least significant bits
667 // There is no room for the Reserved byte so we ignore that completely
668 *DestinationPixel16bit
= (UINT16
) (
669 ( (EfiSourcePixel
->Red
<< 8) & PixelInformation
->RedMask
)
670 | ( (EfiSourcePixel
->Green
<< 3) & PixelInformation
->GreenMask
)
671 | ( (EfiSourcePixel
->Blue
>> 3) & PixelInformation
->BlueMask
)
677 case LCD_BITS_PER_PIXEL_12_444
:
678 // Access each pixel inside the BltBuffer Memory
679 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
680 SourceLine
< SourceY
+ Height
;
681 SourceLine
++, DestinationLine
++) {
683 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
684 SourcePixelX
< SourceX
+ Width
;
685 SourcePixelX
++, DestinationPixelX
++)
687 // Calculate the source and target addresses:
688 EfiSourcePixel
= BltBuffer
+ SourceLine
* BltBufferHorizontalResolution
+ SourcePixelX
;
689 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
691 // Copy the pixel into the new target
692 // Only the most significant bits will be copied across:
693 // To convert from 8 bits to 5 bits per pixel we throw away the 3 least significant bits
694 *DestinationPixel16bit
= (UINT16
) (
695 ( (EfiSourcePixel
->Red
<< 4) & PixelInformation
->RedMask
)
696 | ( (EfiSourcePixel
->Green
) & PixelInformation
->GreenMask
)
697 | ( (EfiSourcePixel
->Blue
>> 4) & PixelInformation
->BlueMask
)
698 // | ( 0 & PixelInformation->ReservedMask )
704 case LCD_BITS_PER_PIXEL_8
:
705 case LCD_BITS_PER_PIXEL_4
:
706 case LCD_BITS_PER_PIXEL_2
:
707 case LCD_BITS_PER_PIXEL_1
:
709 // Can't handle this case
710 DEBUG((DEBUG_ERROR
, "LcdGraphicsBlt: EfiBltBufferToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
711 Status
= EFI_INVALID_PARAMETER
;
720 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
721 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
724 IN UINTN DestinationX
,
725 IN UINTN DestinationY
,
728 IN UINTN Delta OPTIONAL
// Number of BYTES in a row of the BltBuffer
732 UINT32 HorizontalResolution
;
733 LCD_BPP BitsPerPixel
;
734 VOID
*FrameBufferBase
;
736 HorizontalResolution
= This
->Mode
->Info
->HorizontalResolution
;
737 FrameBufferBase
= (UINTN
*)((UINTN
)(This
->Mode
->FrameBufferBase
));
740 // BltVideo to BltVideo:
742 // Source is the Video Memory,
743 // Destination is the Video Memory
745 LcdPlatformGetBpp (This
->Mode
->Mode
,&BitsPerPixel
);
746 FrameBufferBase
= (UINTN
*)((UINTN
)(This
->Mode
->FrameBufferBase
));
748 // The UEFI spec currently states:
749 // "There is no limitation on the overlapping of the source and destination rectangles"
750 // Therefore, we must be careful to avoid overwriting the source data
751 if( SourceY
== DestinationY
) {
752 // Copying within the same height, e.g. horizontal shift
753 if( SourceX
== DestinationX
) {
755 Status
= EFI_SUCCESS
;
756 } else if( ((SourceX
>DestinationX
)?(SourceX
- DestinationX
):(DestinationX
- SourceX
)) < Width
) {
758 Status
= VideoCopyHorizontalOverlap (BitsPerPixel
, FrameBufferBase
, HorizontalResolution
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
);
761 Status
= VideoCopyNoHorizontalOverlap (BitsPerPixel
, FrameBufferBase
, HorizontalResolution
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
);
764 // Copying from different heights
765 Status
= VideoCopyNoHorizontalOverlap (BitsPerPixel
, FrameBufferBase
, HorizontalResolution
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
);
771 /***************************************
772 * GraphicsOutput Protocol function, mapping to
773 * EFI_GRAPHICS_OUTPUT_PROTOCOL.Blt
775 * PRESUMES: 1 pixel = 4 bytes (32bits)
776 * ***************************************/
780 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
781 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
782 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation
,
785 IN UINTN DestinationX
,
786 IN UINTN DestinationY
,
789 IN UINTN Delta OPTIONAL
// Number of BYTES in a row of the BltBuffer
793 UINT32 HorizontalResolution
;
794 UINT32 VerticalResolution
;
795 LCD_INSTANCE
* Instance
;
797 Instance
= LCD_INSTANCE_FROM_GOP_THIS(This
);
799 // Setup the hardware if not already done
800 if (!mDisplayInitialized
) {
801 Status
= InitializeDisplay (Instance
);
802 if (EFI_ERROR(Status
)) {
807 HorizontalResolution
= This
->Mode
->Info
->HorizontalResolution
;
808 VerticalResolution
= This
->Mode
->Info
->VerticalResolution
;
810 DEBUG((DEBUG_INFO
, "LcdGraphicsBlt (BltOperation:%d,DestX:%d,DestY:%d,Width:%d,Height:%d) res(%d,%d)\n",
811 BltOperation
,DestinationX
,DestinationY
,Width
,Height
,HorizontalResolution
,VerticalResolution
));
813 // Check we have reasonable parameters
814 if (Width
== 0 || Height
== 0) {
815 DEBUG((DEBUG_ERROR
, "LcdGraphicsBlt: ERROR - Invalid dimension: Zero size area.\n" ));
816 Status
= EFI_INVALID_PARAMETER
;
820 if ((BltOperation
== EfiBltVideoFill
) || (BltOperation
== EfiBltBufferToVideo
) || (BltOperation
== EfiBltVideoToBltBuffer
)) {
821 ASSERT( BltBuffer
!= NULL
);
824 /*if ((DestinationX >= HorizontalResolution) || (DestinationY >= VerticalResolution)) {
825 DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: ERROR - Invalid destination.\n" ));
826 Status = EFI_INVALID_PARAMETER;
830 // If we are reading data out of the video buffer, check that the source area is within the display limits
831 if ((BltOperation
== EfiBltVideoToBltBuffer
) || (BltOperation
== EfiBltVideoToVideo
)) {
832 if ((SourceY
+ Height
> VerticalResolution
) || (SourceX
+ Width
> HorizontalResolution
)) {
833 DEBUG((DEBUG_INFO
, "LcdGraphicsBlt: ERROR - Invalid source resolution.\n" ));
834 DEBUG((DEBUG_INFO
, " - SourceY=%d + Height=%d > VerticalResolution=%d.\n", SourceY
, Height
, VerticalResolution
));
835 DEBUG((DEBUG_INFO
, " - SourceX=%d + Width=%d > HorizontalResolution=%d.\n", SourceX
, Width
, HorizontalResolution
));
836 Status
= EFI_INVALID_PARAMETER
;
841 // If we are writing data into the video buffer, that the destination area is within the display limits
842 if ((BltOperation
== EfiBltVideoFill
) || (BltOperation
== EfiBltBufferToVideo
) || (BltOperation
== EfiBltVideoToVideo
)) {
843 if ((DestinationY
+ Height
> VerticalResolution
) || (DestinationX
+ Width
> HorizontalResolution
)) {
844 DEBUG((DEBUG_INFO
, "LcdGraphicsBlt: ERROR - Invalid destination resolution.\n" ));
845 DEBUG((DEBUG_INFO
, " - DestinationY=%d + Height=%d > VerticalResolution=%d.\n", DestinationY
, Height
, VerticalResolution
));
846 DEBUG((DEBUG_INFO
, " - DestinationX=%d + Width=%d > HorizontalResolution=%d.\n", DestinationX
, Width
, HorizontalResolution
));
847 Status
= EFI_INVALID_PARAMETER
;
853 // Perform the Block Transfer Operation
856 switch (BltOperation
) {
857 case EfiBltVideoFill
:
858 Status
= BltVideoFill (This
, BltBuffer
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
, Delta
);
861 case EfiBltVideoToBltBuffer
:
862 Status
= BltVideoToBltBuffer (This
, BltBuffer
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
, Delta
);
865 case EfiBltBufferToVideo
:
866 Status
= BltBufferToVideo (This
, BltBuffer
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
, Delta
);
869 case EfiBltVideoToVideo
:
870 Status
= BltVideoToVideo (This
, BltBuffer
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
, Delta
);
873 case EfiGraphicsOutputBltOperationMax
:
875 DEBUG((DEBUG_ERROR
, "LcdGraphicsBlt: Invalid Operation\n"));
876 Status
= EFI_INVALID_PARAMETER
;