3 Copyright (c) 2011, 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/PcdLib.h>
16 #include <Library/DebugLib.h>
17 #include <Library/BaseMemoryLib.h>
18 #include <Library/DevicePathLib.h>
19 #include <Library/UefiBootServicesTableLib.h>
20 #include <Library/UefiRuntimeServicesTableLib.h>
21 #include <Library/MemoryAllocationLib.h>
23 #include <Guid/GlobalVariable.h>
25 #include <ArmPlatform.h>
26 #include "LcdGraphicsOutputDxe.h"
28 extern BOOLEAN mDisplayInitialized
;
31 // Function Definitions
36 VideoCopyNoHorizontalOverlap (
37 IN UINTN BitsPerPixel
,
38 IN
volatile VOID
*FrameBufferBase
,
39 IN UINT32 HorizontalResolution
,
42 IN UINTN DestinationX
,
43 IN UINTN DestinationY
,
48 EFI_STATUS Status
= EFI_SUCCESS
;
50 UINTN DestinationLine
;
55 VOID
*DestinationAddr
;
57 if( DestinationY
<= SourceY
) {
58 // scrolling up (or horizontally but without overlap)
60 DestinationLine
= DestinationY
;
64 SourceLine
= SourceY
+ Height
;
65 DestinationLine
= DestinationY
+ Height
;
69 switch (BitsPerPixel
) {
71 case LCD_BITS_PER_PIXEL_24
:
73 WidthInBytes
= Width
* 4;
75 for( LineCount
= 0; LineCount
< Height
; LineCount
++ ) {
76 // Update the start addresses of source & destination using 32bit pointer arithmetic
77 SourceAddr
= (VOID
*)((UINT32
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourceX
);
78 DestinationAddr
= (VOID
*)((UINT32
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationX
);
80 // Copy the entire line Y from video ram to the temp buffer
81 CopyMem( DestinationAddr
, SourceAddr
, WidthInBytes
);
83 // Update the line numbers
85 DestinationLine
+= Step
;
89 case LCD_BITS_PER_PIXEL_16_555
:
90 case LCD_BITS_PER_PIXEL_16_565
:
91 case LCD_BITS_PER_PIXEL_12_444
:
93 WidthInBytes
= Width
* 2;
95 for( LineCount
= 0; LineCount
< Height
; LineCount
++ ) {
96 // Update the start addresses of source & destination using 16bit pointer arithmetic
97 SourceAddr
= (VOID
*)((UINT16
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourceX
);
98 DestinationAddr
= (VOID
*)((UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationX
);
100 // Copy the entire line Y from video ram to the temp buffer
101 CopyMem( DestinationAddr
, SourceAddr
, WidthInBytes
);
103 // Update the line numbers
105 DestinationLine
+= Step
;
109 case LCD_BITS_PER_PIXEL_8
:
110 case LCD_BITS_PER_PIXEL_4
:
111 case LCD_BITS_PER_PIXEL_2
:
112 case LCD_BITS_PER_PIXEL_1
:
114 // Can't handle this case
115 DEBUG((DEBUG_ERROR
, "ArmVeGraphics_Blt: EfiBltVideoToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
116 Status
= EFI_INVALID_PARAMETER
;
128 VideoCopyHorizontalOverlap (
129 IN UINTN BitsPerPixel
,
130 IN
volatile VOID
*FrameBufferBase
,
131 UINT32 HorizontalResolution
,
134 IN UINTN DestinationX
,
135 IN UINTN DestinationY
,
140 EFI_STATUS Status
= EFI_SUCCESS
;
142 UINT32
*PixelBuffer32bit
;
143 UINT32
*SourcePixel32bit
;
144 UINT32
*DestinationPixel32bit
;
146 UINT16
*PixelBuffer16bit
;
147 UINT16
*SourcePixel16bit
;
148 UINT16
*DestinationPixel16bit
;
151 UINT32 DestinationPixelY
;
155 switch (BitsPerPixel
) {
157 case LCD_BITS_PER_PIXEL_24
:
158 // Allocate a temporary buffer
160 PixelBuffer32bit
= (UINT32
*) AllocatePool((Height
* Width
) * sizeof(UINT32
));
162 if (PixelBuffer32bit
== NULL
) {
163 Status
= EFI_OUT_OF_RESOURCES
;
167 SizeIn32Bits
= Width
* 4;
169 // Copy from the video ram (source region) to a temp buffer
170 for (SourcePixelY
= SourceY
, DestinationPixel32bit
= PixelBuffer32bit
;
171 SourcePixelY
< SourceY
+ Height
;
172 SourcePixelY
++, DestinationPixel32bit
+= Width
)
174 // Update the start address of line Y (source)
175 SourcePixel32bit
= (UINT32
*)FrameBufferBase
+ SourcePixelY
* HorizontalResolution
+ SourceX
;
177 // Copy the entire line Y from video ram to the temp buffer
178 CopyMem( (VOID
*)DestinationPixel32bit
, (CONST VOID
*)SourcePixel32bit
, SizeIn32Bits
);
181 // Copy from the temp buffer to the video ram (destination region)
182 for (DestinationPixelY
= DestinationY
, SourcePixel32bit
= PixelBuffer32bit
;
183 DestinationPixelY
< DestinationY
+ Height
;
184 DestinationPixelY
++, SourcePixel32bit
+= Width
)
186 // Update the start address of line Y (target)
187 DestinationPixel32bit
= (UINT32
*)FrameBufferBase
+ DestinationPixelY
* HorizontalResolution
+ DestinationX
;
189 // Copy the entire line Y from the temp buffer to video ram
190 CopyMem( (VOID
*)DestinationPixel32bit
, (CONST VOID
*)SourcePixel32bit
, SizeIn32Bits
);
193 // Free up the allocated memory
194 FreePool((VOID
*) PixelBuffer32bit
);
199 case LCD_BITS_PER_PIXEL_16_555
:
200 case LCD_BITS_PER_PIXEL_16_565
:
201 case LCD_BITS_PER_PIXEL_12_444
:
202 // Allocate a temporary buffer
203 PixelBuffer16bit
= (UINT16
*) AllocatePool((Height
* Width
) * sizeof(UINT16
));
205 if (PixelBuffer16bit
== NULL
) {
206 Status
= EFI_OUT_OF_RESOURCES
;
210 // Access each pixel inside the source area of the Video Memory and copy it to the temp buffer
212 SizeIn16Bits
= Width
* 2;
214 for (SourcePixelY
= SourceY
, DestinationPixel16bit
= PixelBuffer16bit
;
215 SourcePixelY
< SourceY
+ Height
;
216 SourcePixelY
++, DestinationPixel16bit
+= Width
)
218 // Calculate the source address:
219 SourcePixel16bit
= (UINT16
*)FrameBufferBase
+ SourcePixelY
* HorizontalResolution
+ SourceX
;
221 // Copy the entire line Y from Video to the temp buffer
222 CopyMem( (VOID
*)DestinationPixel16bit
, (CONST VOID
*)SourcePixel16bit
, SizeIn16Bits
);
225 // Copy from the temp buffer into the destination area of the Video Memory
227 for (DestinationPixelY
= DestinationY
, SourcePixel16bit
= PixelBuffer16bit
;
228 DestinationPixelY
< DestinationY
+ Height
;
229 DestinationPixelY
++, SourcePixel16bit
+= Width
)
231 // Calculate the target address:
232 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ (DestinationPixelY
* HorizontalResolution
+ DestinationX
);
234 // Copy the entire line Y from the temp buffer to Video
235 CopyMem( (VOID
*)DestinationPixel16bit
, (CONST VOID
*)SourcePixel16bit
, SizeIn16Bits
);
238 // Free the allocated memory
239 FreePool((VOID
*) PixelBuffer16bit
);
244 case LCD_BITS_PER_PIXEL_8
:
245 case LCD_BITS_PER_PIXEL_4
:
246 case LCD_BITS_PER_PIXEL_2
:
247 case LCD_BITS_PER_PIXEL_1
:
249 // Can't handle this case
250 DEBUG((DEBUG_ERROR
, "ArmVeGraphics_Blt: EfiBltVideoToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
251 Status
= EFI_INVALID_PARAMETER
;
264 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
265 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*EfiSourcePixel
, OPTIONAL
268 IN UINTN DestinationX
,
269 IN UINTN DestinationY
,
272 IN UINTN Delta OPTIONAL
// Number of BYTES in a row of the BltBuffer
275 EFI_PIXEL_BITMASK
* PixelInformation
;
277 UINT32 HorizontalResolution
;
278 LCD_BPP BitsPerPixel
;
279 VOID
*FrameBufferBase
;
280 VOID
*DestinationAddr
;
281 UINT16
*DestinationPixel16bit
;
283 UINT32 DestinationPixelX
;
284 UINT32 DestinationLine
;
287 Status
= EFI_SUCCESS
;
288 PixelInformation
= &This
->Mode
->Info
->PixelInformation
;
289 FrameBufferBase
= (UINTN
*)((UINTN
)(This
->Mode
->FrameBufferBase
));
290 HorizontalResolution
= This
->Mode
->Info
->HorizontalResolution
;
292 LcdPlatformGetBpp (This
->Mode
->Mode
,&BitsPerPixel
);
294 switch (BitsPerPixel
) {
295 case LCD_BITS_PER_PIXEL_24
:
296 WidthInBytes
= Width
* 4;
298 // Copy the SourcePixel into every pixel inside the target rectangle
299 for (DestinationLine
= DestinationY
;
300 DestinationLine
< DestinationY
+ Height
;
303 // Calculate the target address using 32bit pointer arithmetic:
304 DestinationAddr
= (VOID
*)((UINT32
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationX
);
306 // Fill the entire line
307 SetMemN( DestinationAddr
, WidthInBytes
, *((UINTN
*)EfiSourcePixel
));
311 case LCD_BITS_PER_PIXEL_16_555
:
312 // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
313 Pixel16bit
= (UINT16
) (
314 ( (EfiSourcePixel
->Red
<< 7) & PixelInformation
->RedMask
)
315 | ( (EfiSourcePixel
->Green
<< 2) & PixelInformation
->GreenMask
)
316 | ( (EfiSourcePixel
->Blue
>> 3) & PixelInformation
->BlueMask
)
317 // | ( 0 & PixelInformation->ReservedMask )
320 // Copy the SourcePixel into every pixel inside the target rectangle
321 for (DestinationLine
= DestinationY
;
322 DestinationLine
< DestinationY
+ Height
;
325 for (DestinationPixelX
= DestinationX
;
326 DestinationPixelX
< DestinationX
+ Width
;
329 // Calculate the target address:
330 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
332 // Copy the pixel into the new target
333 *DestinationPixel16bit
= Pixel16bit
;
338 case LCD_BITS_PER_PIXEL_16_565
:
339 // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
340 Pixel16bit
= (UINT16
) (
341 ( (EfiSourcePixel
->Red
<< 8) & PixelInformation
->RedMask
)
342 | ( (EfiSourcePixel
->Green
<< 3) & PixelInformation
->GreenMask
)
343 | ( (EfiSourcePixel
->Blue
>> 3) & PixelInformation
->BlueMask
)
346 // Copy the SourcePixel into every pixel inside the target rectangle
347 for (DestinationLine
= DestinationY
;
348 DestinationLine
< DestinationY
+ Height
;
351 for (DestinationPixelX
= DestinationX
;
352 DestinationPixelX
< DestinationX
+ Width
;
355 // Calculate the target address:
356 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
358 // Copy the pixel into the new target
359 *DestinationPixel16bit
= Pixel16bit
;
364 case LCD_BITS_PER_PIXEL_12_444
:
365 // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
366 Pixel16bit
= (UINT16
) (
367 ( (EfiSourcePixel
->Red
>> 4) & PixelInformation
->RedMask
)
368 | ( (EfiSourcePixel
->Green
) & PixelInformation
->GreenMask
)
369 | ( (EfiSourcePixel
->Blue
<< 4) & PixelInformation
->BlueMask
)
372 // Copy the SourcePixel into every pixel inside the target rectangle
373 for (DestinationLine
= DestinationY
;
374 DestinationLine
< DestinationY
+ Height
;
377 for (DestinationPixelX
= DestinationX
;
378 DestinationPixelX
< DestinationX
+ Width
;
381 // Calculate the target address:
382 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
384 // Copy the pixel into the new target
385 *DestinationPixel16bit
= Pixel16bit
;
390 case LCD_BITS_PER_PIXEL_8
:
391 case LCD_BITS_PER_PIXEL_4
:
392 case LCD_BITS_PER_PIXEL_2
:
393 case LCD_BITS_PER_PIXEL_1
:
395 // Can't handle this case
396 DEBUG((DEBUG_ERROR
, "LcdGraphicsBlt: EfiBltVideoFill: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
397 Status
= EFI_INVALID_PARAMETER
;
406 BltVideoToBltBuffer (
407 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
408 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
411 IN UINTN DestinationX
,
412 IN UINTN DestinationY
,
415 IN UINTN Delta OPTIONAL
// Number of BYTES in a row of the BltBuffer
419 UINT32 HorizontalResolution
;
420 LCD_BPP BitsPerPixel
;
421 EFI_PIXEL_BITMASK
*PixelInformation
;
422 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*EfiDestinationPixel
;
423 VOID
*FrameBufferBase
;
425 VOID
*DestinationAddr
;
426 UINT16
*SourcePixel16bit
;
430 UINT32 DestinationPixelX
;
431 UINT32 DestinationLine
;
432 UINT32 BltBufferHorizontalResolution
;
435 Status
= EFI_SUCCESS
;
436 PixelInformation
= &This
->Mode
->Info
->PixelInformation
;
437 HorizontalResolution
= This
->Mode
->Info
->HorizontalResolution
;
438 FrameBufferBase
= (UINTN
*)((UINTN
)(This
->Mode
->FrameBufferBase
));
440 if(( Delta
!= 0 ) && ( Delta
!= Width
* sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL
))) {
441 // Delta is not zero and it is different from the width.
442 // Divide it by the size of a pixel to find out the buffer's horizontal resolution.
443 BltBufferHorizontalResolution
= (UINT32
) (Delta
/ sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
445 BltBufferHorizontalResolution
= Width
;
448 LcdPlatformGetBpp (This
->Mode
->Mode
,&BitsPerPixel
);
450 switch (BitsPerPixel
) {
451 case LCD_BITS_PER_PIXEL_24
:
452 WidthInBytes
= Width
* 4;
454 // Access each line inside the Video Memory
455 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
456 SourceLine
< SourceY
+ Height
;
457 SourceLine
++, DestinationLine
++)
459 // Calculate the source and target addresses using 32bit pointer arithmetic:
460 SourceAddr
= (VOID
*)((UINT32
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourceX
);
461 DestinationAddr
= (VOID
*)((UINT32
*)BltBuffer
+ DestinationLine
* BltBufferHorizontalResolution
+ DestinationX
);
463 // Copy the entire line
464 CopyMem( DestinationAddr
, SourceAddr
, WidthInBytes
);
468 case LCD_BITS_PER_PIXEL_16_555
:
469 // Access each pixel inside the Video Memory
470 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
471 SourceLine
< SourceY
+ Height
;
472 SourceLine
++, DestinationLine
++)
474 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
475 SourcePixelX
< SourceX
+ Width
;
476 SourcePixelX
++, DestinationPixelX
++)
478 // Calculate the source and target addresses:
479 SourcePixel16bit
= (UINT16
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourcePixelX
;
480 EfiDestinationPixel
= BltBuffer
+ DestinationLine
* BltBufferHorizontalResolution
+ DestinationPixelX
;
482 // Snapshot the pixel from the video buffer once, to speed up the operation.
483 // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.
484 Pixel16bit
= *SourcePixel16bit
;
486 // Copy the pixel into the new target
487 EfiDestinationPixel
->Red
= (UINT8
) ( (Pixel16bit
& PixelInformation
->RedMask
) >> 7 );
488 EfiDestinationPixel
->Green
= (UINT8
) ( (Pixel16bit
& PixelInformation
->GreenMask
) >> 2);
489 EfiDestinationPixel
->Blue
= (UINT8
) ( (Pixel16bit
& PixelInformation
->BlueMask
) << 3 );
490 // EfiDestinationPixel->Reserved = (UINT8) 0;
495 case LCD_BITS_PER_PIXEL_16_565
:
496 // Access each pixel inside the Video Memory
497 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
498 SourceLine
< SourceY
+ Height
;
499 SourceLine
++, DestinationLine
++)
501 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
502 SourcePixelX
< SourceX
+ Width
;
503 SourcePixelX
++, DestinationPixelX
++)
505 // Calculate the source and target addresses:
506 SourcePixel16bit
= (UINT16
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourcePixelX
;
507 EfiDestinationPixel
= BltBuffer
+ DestinationLine
* BltBufferHorizontalResolution
+ DestinationPixelX
;
509 // Snapshot the pixel from the video buffer once, to speed up the operation.
510 // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.
511 Pixel16bit
= *SourcePixel16bit
;
513 // Copy the pixel into the new target
514 // There is no info for the Reserved byte, so we set it to zero
515 EfiDestinationPixel
->Red
= (UINT8
) ( (Pixel16bit
& PixelInformation
->RedMask
) >> 8 );
516 EfiDestinationPixel
->Green
= (UINT8
) ( (Pixel16bit
& PixelInformation
->GreenMask
) >> 3);
517 EfiDestinationPixel
->Blue
= (UINT8
) ( (Pixel16bit
& PixelInformation
->BlueMask
) << 3 );
518 // EfiDestinationPixel->Reserved = (UINT8) 0;
523 case LCD_BITS_PER_PIXEL_12_444
:
524 // Access each pixel inside the Video Memory
525 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
526 SourceLine
< SourceY
+ Height
;
527 SourceLine
++, DestinationLine
++)
529 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
530 SourcePixelX
< SourceX
+ Width
;
531 SourcePixelX
++, DestinationPixelX
++)
533 // Calculate the source and target addresses:
534 SourcePixel16bit
= (UINT16
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourcePixelX
;
535 EfiDestinationPixel
= BltBuffer
+ DestinationLine
* BltBufferHorizontalResolution
+ DestinationPixelX
;
537 // Snapshot the pixel from the video buffer once, to speed up the operation.
538 // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.
539 Pixel16bit
= *SourcePixel16bit
;
541 // Copy the pixel into the new target
542 EfiDestinationPixel
->Red
= (UINT8
) ( (Pixel16bit
& PixelInformation
->RedMask
) >> 4 );
543 EfiDestinationPixel
->Green
= (UINT8
) ( (Pixel16bit
& PixelInformation
->GreenMask
) );
544 EfiDestinationPixel
->Blue
= (UINT8
) ( (Pixel16bit
& PixelInformation
->BlueMask
) << 4 );
545 // EfiDestinationPixel->Reserved = (UINT8) 0;
550 case LCD_BITS_PER_PIXEL_8
:
551 case LCD_BITS_PER_PIXEL_4
:
552 case LCD_BITS_PER_PIXEL_2
:
553 case LCD_BITS_PER_PIXEL_1
:
555 // Can't handle this case
556 DEBUG((DEBUG_ERROR
, "LcdGraphicsBlt: EfiBltVideoToBltBuffer: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
557 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 LCD_BITS_PER_PIXEL_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
);
626 case LCD_BITS_PER_PIXEL_16_555
:
627 // Access each pixel inside the BltBuffer Memory
628 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
629 SourceLine
< SourceY
+ Height
;
630 SourceLine
++, DestinationLine
++) {
632 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
633 SourcePixelX
< SourceX
+ Width
;
634 SourcePixelX
++, DestinationPixelX
++)
636 // Calculate the source and target addresses:
637 EfiSourcePixel
= BltBuffer
+ SourceLine
* BltBufferHorizontalResolution
+ SourcePixelX
;
638 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
640 // Copy the pixel into the new target
641 // Only the most significant bits will be copied across:
642 // To convert from 8 bits to 5 bits per pixel we throw away the 3 least significant bits
643 *DestinationPixel16bit
= (UINT16
) (
644 ( (EfiSourcePixel
->Red
<< 7) & PixelInformation
->RedMask
)
645 | ( (EfiSourcePixel
->Green
<< 2) & PixelInformation
->GreenMask
)
646 | ( (EfiSourcePixel
->Blue
>> 3) & PixelInformation
->BlueMask
)
647 // | ( 0 & PixelInformation->ReservedMask )
653 case LCD_BITS_PER_PIXEL_16_565
:
654 // Access each pixel inside the BltBuffer Memory
655 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
656 SourceLine
< SourceY
+ Height
;
657 SourceLine
++, DestinationLine
++) {
659 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
660 SourcePixelX
< SourceX
+ Width
;
661 SourcePixelX
++, DestinationPixelX
++)
663 // Calculate the source and target addresses:
664 EfiSourcePixel
= BltBuffer
+ SourceLine
* BltBufferHorizontalResolution
+ SourcePixelX
;
665 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
667 // Copy the pixel into the new target
668 // Only the most significant bits will be copied across:
669 // To convert from 8 bits to 5 or 6 bits per pixel we throw away the 3 or 2 least significant bits
670 // There is no room for the Reserved byte so we ignore that completely
671 *DestinationPixel16bit
= (UINT16
) (
672 ( (EfiSourcePixel
->Red
<< 8) & PixelInformation
->RedMask
)
673 | ( (EfiSourcePixel
->Green
<< 3) & PixelInformation
->GreenMask
)
674 | ( (EfiSourcePixel
->Blue
>> 3) & PixelInformation
->BlueMask
)
680 case LCD_BITS_PER_PIXEL_12_444
:
681 // Access each pixel inside the BltBuffer Memory
682 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
683 SourceLine
< SourceY
+ Height
;
684 SourceLine
++, DestinationLine
++) {
686 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
687 SourcePixelX
< SourceX
+ Width
;
688 SourcePixelX
++, DestinationPixelX
++)
690 // Calculate the source and target addresses:
691 EfiSourcePixel
= BltBuffer
+ SourceLine
* BltBufferHorizontalResolution
+ SourcePixelX
;
692 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
694 // Copy the pixel into the new target
695 // Only the most significant bits will be copied across:
696 // To convert from 8 bits to 5 bits per pixel we throw away the 3 least significant bits
697 *DestinationPixel16bit
= (UINT16
) (
698 ( (EfiSourcePixel
->Red
<< 4) & PixelInformation
->RedMask
)
699 | ( (EfiSourcePixel
->Green
) & PixelInformation
->GreenMask
)
700 | ( (EfiSourcePixel
->Blue
>> 4) & PixelInformation
->BlueMask
)
701 // | ( 0 & PixelInformation->ReservedMask )
707 case LCD_BITS_PER_PIXEL_8
:
708 case LCD_BITS_PER_PIXEL_4
:
709 case LCD_BITS_PER_PIXEL_2
:
710 case LCD_BITS_PER_PIXEL_1
:
712 // Can't handle this case
713 DEBUG((DEBUG_ERROR
, "LcdGraphicsBlt: EfiBltBufferToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
714 Status
= EFI_INVALID_PARAMETER
;
723 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
724 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
727 IN UINTN DestinationX
,
728 IN UINTN DestinationY
,
731 IN UINTN Delta OPTIONAL
// Number of BYTES in a row of the BltBuffer
735 UINT32 HorizontalResolution
;
736 LCD_BPP BitsPerPixel
;
737 VOID
*FrameBufferBase
;
739 HorizontalResolution
= This
->Mode
->Info
->HorizontalResolution
;
740 FrameBufferBase
= (UINTN
*)((UINTN
)(This
->Mode
->FrameBufferBase
));
743 // BltVideo to BltVideo:
745 // Source is the Video Memory,
746 // Destination is the Video Memory
748 LcdPlatformGetBpp (This
->Mode
->Mode
,&BitsPerPixel
);
749 FrameBufferBase
= (UINTN
*)((UINTN
)(This
->Mode
->FrameBufferBase
));
751 // The UEFI spec currently states:
752 // "There is no limitation on the overlapping of the source and destination rectangles"
753 // Therefore, we must be careful to avoid overwriting the source data
754 if( SourceY
== DestinationY
) {
755 // Copying within the same height, e.g. horizontal shift
756 if( SourceX
== DestinationX
) {
758 Status
= EFI_SUCCESS
;
759 } else if( ((SourceX
>DestinationX
)?(SourceX
- DestinationX
):(DestinationX
- SourceX
)) < Width
) {
761 Status
= VideoCopyHorizontalOverlap (BitsPerPixel
, FrameBufferBase
, HorizontalResolution
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
);
764 Status
= VideoCopyNoHorizontalOverlap (BitsPerPixel
, FrameBufferBase
, HorizontalResolution
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
);
767 // Copying from different heights
768 Status
= VideoCopyNoHorizontalOverlap (BitsPerPixel
, FrameBufferBase
, HorizontalResolution
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
);
774 /***************************************
775 * GraphicsOutput Protocol function, mapping to
776 * EFI_GRAPHICS_OUTPUT_PROTOCOL.Blt
778 * PRESUMES: 1 pixel = 4 bytes (32bits)
779 * ***************************************/
783 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
784 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
785 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation
,
788 IN UINTN DestinationX
,
789 IN UINTN DestinationY
,
792 IN UINTN Delta OPTIONAL
// Number of BYTES in a row of the BltBuffer
796 UINT32 HorizontalResolution
;
797 UINT32 VerticalResolution
;
798 LCD_INSTANCE
* Instance
;
800 Instance
= LCD_INSTANCE_FROM_GOP_THIS(This
);
802 // Setup the hardware if not already done
803 if (!mDisplayInitialized
) {
804 Status
= InitializeDisplay (Instance
);
805 if (EFI_ERROR(Status
)) {
810 HorizontalResolution
= This
->Mode
->Info
->HorizontalResolution
;
811 VerticalResolution
= This
->Mode
->Info
->VerticalResolution
;
813 DEBUG((DEBUG_INFO
, "LcdGraphicsBlt (BltOperation:%d,DestX:%d,DestY:%d,Width:%d,Height:%d) res(%d,%d)\n",
814 BltOperation
,DestinationX
,DestinationY
,Width
,Height
,HorizontalResolution
,VerticalResolution
));
816 // Check we have reasonable parameters
817 if (Width
== 0 || Height
== 0) {
818 DEBUG((DEBUG_ERROR
, "LcdGraphicsBlt: ERROR - Invalid dimension: Zero size area.\n" ));
819 Status
= EFI_INVALID_PARAMETER
;
823 if ((BltOperation
== EfiBltVideoFill
) || (BltOperation
== EfiBltBufferToVideo
) || (BltOperation
== EfiBltVideoToBltBuffer
)) {
824 ASSERT( BltBuffer
!= NULL
);
827 /*if ((DestinationX >= HorizontalResolution) || (DestinationY >= VerticalResolution)) {
828 DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: ERROR - Invalid destination.\n" ));
829 Status = EFI_INVALID_PARAMETER;
833 // If we are reading data out of the video buffer, check that the source area is within the display limits
834 if ((BltOperation
== EfiBltVideoToBltBuffer
) || (BltOperation
== EfiBltVideoToVideo
)) {
835 if ((SourceY
+ Height
> VerticalResolution
) || (SourceX
+ Width
> HorizontalResolution
)) {
836 DEBUG((DEBUG_INFO
, "LcdGraphicsBlt: ERROR - Invalid source resolution.\n" ));
837 DEBUG((DEBUG_INFO
, " - SourceY=%d + Height=%d > VerticalResolution=%d.\n", SourceY
, Height
, VerticalResolution
));
838 DEBUG((DEBUG_INFO
, " - SourceX=%d + Width=%d > HorizontalResolution=%d.\n", SourceX
, Width
, HorizontalResolution
));
839 Status
= EFI_INVALID_PARAMETER
;
844 // If we are writing data into the video buffer, that the destination area is within the display limits
845 if ((BltOperation
== EfiBltVideoFill
) || (BltOperation
== EfiBltBufferToVideo
) || (BltOperation
== EfiBltVideoToVideo
)) {
846 if ((DestinationY
+ Height
> VerticalResolution
) || (DestinationX
+ Width
> HorizontalResolution
)) {
847 DEBUG((DEBUG_INFO
, "LcdGraphicsBlt: ERROR - Invalid destination resolution.\n" ));
848 DEBUG((DEBUG_INFO
, " - DestinationY=%d + Height=%d > VerticalResolution=%d.\n", DestinationY
, Height
, VerticalResolution
));
849 DEBUG((DEBUG_INFO
, " - DestinationX=%d + Width=%d > HorizontalResolution=%d.\n", DestinationX
, Width
, HorizontalResolution
));
850 Status
= EFI_INVALID_PARAMETER
;
856 // Perform the Block Transfer Operation
859 switch (BltOperation
) {
860 case EfiBltVideoFill
:
861 Status
= BltVideoFill (This
, BltBuffer
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
, Delta
);
864 case EfiBltVideoToBltBuffer
:
865 Status
= BltVideoToBltBuffer (This
, BltBuffer
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
, Delta
);
868 case EfiBltBufferToVideo
:
869 Status
= BltBufferToVideo (This
, BltBuffer
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
, Delta
);
872 case EfiBltVideoToVideo
:
873 Status
= BltVideoToVideo (This
, BltBuffer
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
, Delta
);
876 case EfiGraphicsOutputBltOperationMax
:
878 DEBUG((DEBUG_ERROR
, "LcdGraphicsBlt: Invalid Operation\n"));
879 Status
= EFI_INVALID_PARAMETER
;