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 "LcdGraphicsOutputDxe.h"
27 extern BOOLEAN mDisplayInitialized
;
30 // Function Definitions
35 VideoCopyNoHorizontalOverlap (
36 IN UINTN BitsPerPixel
,
37 IN
volatile VOID
*FrameBufferBase
,
38 IN UINT32 HorizontalResolution
,
41 IN UINTN DestinationX
,
42 IN UINTN DestinationY
,
47 EFI_STATUS Status
= EFI_SUCCESS
;
49 UINTN DestinationLine
;
54 VOID
*DestinationAddr
;
56 if( DestinationY
<= SourceY
) {
57 // scrolling up (or horizontally but without overlap)
59 DestinationLine
= DestinationY
;
63 SourceLine
= SourceY
+ Height
;
64 DestinationLine
= DestinationY
+ Height
;
68 switch (BitsPerPixel
) {
70 case LCD_BITS_PER_PIXEL_24
:
72 WidthInBytes
= Width
* 4;
74 for( LineCount
= 0; LineCount
< Height
; LineCount
++ ) {
75 // Update the start addresses of source & destination using 32bit pointer arithmetic
76 SourceAddr
= (VOID
*)((UINT32
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourceX
);
77 DestinationAddr
= (VOID
*)((UINT32
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationX
);
79 // Copy the entire line Y from video ram to the temp buffer
80 CopyMem( DestinationAddr
, SourceAddr
, WidthInBytes
);
82 // Update the line numbers
84 DestinationLine
+= Step
;
88 case LCD_BITS_PER_PIXEL_16_555
:
89 case LCD_BITS_PER_PIXEL_16_565
:
90 case LCD_BITS_PER_PIXEL_12_444
:
92 WidthInBytes
= Width
* 2;
94 for( LineCount
= 0; LineCount
< Height
; LineCount
++ ) {
95 // Update the start addresses of source & destination using 16bit pointer arithmetic
96 SourceAddr
= (VOID
*)((UINT16
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourceX
);
97 DestinationAddr
= (VOID
*)((UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationX
);
99 // Copy the entire line Y from video ram to the temp buffer
100 CopyMem( DestinationAddr
, SourceAddr
, WidthInBytes
);
102 // Update the line numbers
104 DestinationLine
+= Step
;
108 case LCD_BITS_PER_PIXEL_8
:
109 case LCD_BITS_PER_PIXEL_4
:
110 case LCD_BITS_PER_PIXEL_2
:
111 case LCD_BITS_PER_PIXEL_1
:
113 // Can't handle this case
114 DEBUG((DEBUG_ERROR
, "ArmVeGraphics_Blt: EfiBltVideoToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
115 Status
= EFI_INVALID_PARAMETER
;
127 VideoCopyHorizontalOverlap (
128 IN UINTN BitsPerPixel
,
129 IN
volatile VOID
*FrameBufferBase
,
130 UINT32 HorizontalResolution
,
133 IN UINTN DestinationX
,
134 IN UINTN DestinationY
,
139 EFI_STATUS Status
= EFI_SUCCESS
;
141 UINT32
*PixelBuffer32bit
;
142 UINT32
*SourcePixel32bit
;
143 UINT32
*DestinationPixel32bit
;
145 UINT16
*PixelBuffer16bit
;
146 UINT16
*SourcePixel16bit
;
147 UINT16
*DestinationPixel16bit
;
150 UINT32 DestinationPixelY
;
154 switch (BitsPerPixel
) {
156 case LCD_BITS_PER_PIXEL_24
:
157 // Allocate a temporary buffer
159 PixelBuffer32bit
= (UINT32
*) AllocatePool((Height
* Width
) * sizeof(UINT32
));
161 if (PixelBuffer32bit
== NULL
) {
162 Status
= EFI_OUT_OF_RESOURCES
;
166 SizeIn32Bits
= Width
* 4;
168 // Copy from the video ram (source region) to a temp buffer
169 for (SourcePixelY
= SourceY
, DestinationPixel32bit
= PixelBuffer32bit
;
170 SourcePixelY
< SourceY
+ Height
;
171 SourcePixelY
++, DestinationPixel32bit
+= Width
)
173 // Update the start address of line Y (source)
174 SourcePixel32bit
= (UINT32
*)FrameBufferBase
+ SourcePixelY
* HorizontalResolution
+ SourceX
;
176 // Copy the entire line Y from video ram to the temp buffer
177 CopyMem( (VOID
*)DestinationPixel32bit
, (CONST VOID
*)SourcePixel32bit
, SizeIn32Bits
);
180 // Copy from the temp buffer to the video ram (destination region)
181 for (DestinationPixelY
= DestinationY
, SourcePixel32bit
= PixelBuffer32bit
;
182 DestinationPixelY
< DestinationY
+ Height
;
183 DestinationPixelY
++, SourcePixel32bit
+= Width
)
185 // Update the start address of line Y (target)
186 DestinationPixel32bit
= (UINT32
*)FrameBufferBase
+ DestinationPixelY
* HorizontalResolution
+ DestinationX
;
188 // Copy the entire line Y from the temp buffer to video ram
189 CopyMem( (VOID
*)DestinationPixel32bit
, (CONST VOID
*)SourcePixel32bit
, SizeIn32Bits
);
192 // Free up the allocated memory
193 FreePool((VOID
*) PixelBuffer32bit
);
198 case LCD_BITS_PER_PIXEL_16_555
:
199 case LCD_BITS_PER_PIXEL_16_565
:
200 case LCD_BITS_PER_PIXEL_12_444
:
201 // Allocate a temporary buffer
202 PixelBuffer16bit
= (UINT16
*) AllocatePool((Height
* Width
) * sizeof(UINT16
));
204 if (PixelBuffer16bit
== NULL
) {
205 Status
= EFI_OUT_OF_RESOURCES
;
209 // Access each pixel inside the source area of the Video Memory and copy it to the temp buffer
211 SizeIn16Bits
= Width
* 2;
213 for (SourcePixelY
= SourceY
, DestinationPixel16bit
= PixelBuffer16bit
;
214 SourcePixelY
< SourceY
+ Height
;
215 SourcePixelY
++, DestinationPixel16bit
+= Width
)
217 // Calculate the source address:
218 SourcePixel16bit
= (UINT16
*)FrameBufferBase
+ SourcePixelY
* HorizontalResolution
+ SourceX
;
220 // Copy the entire line Y from Video to the temp buffer
221 CopyMem( (VOID
*)DestinationPixel16bit
, (CONST VOID
*)SourcePixel16bit
, SizeIn16Bits
);
224 // Copy from the temp buffer into the destination area of the Video Memory
226 for (DestinationPixelY
= DestinationY
, SourcePixel16bit
= PixelBuffer16bit
;
227 DestinationPixelY
< DestinationY
+ Height
;
228 DestinationPixelY
++, SourcePixel16bit
+= Width
)
230 // Calculate the target address:
231 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ (DestinationPixelY
* HorizontalResolution
+ DestinationX
);
233 // Copy the entire line Y from the temp buffer to Video
234 CopyMem( (VOID
*)DestinationPixel16bit
, (CONST VOID
*)SourcePixel16bit
, SizeIn16Bits
);
237 // Free the allocated memory
238 FreePool((VOID
*) PixelBuffer16bit
);
243 case LCD_BITS_PER_PIXEL_8
:
244 case LCD_BITS_PER_PIXEL_4
:
245 case LCD_BITS_PER_PIXEL_2
:
246 case LCD_BITS_PER_PIXEL_1
:
248 // Can't handle this case
249 DEBUG((DEBUG_ERROR
, "ArmVeGraphics_Blt: EfiBltVideoToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
250 Status
= EFI_INVALID_PARAMETER
;
263 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
264 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*EfiSourcePixel
, OPTIONAL
267 IN UINTN DestinationX
,
268 IN UINTN DestinationY
,
271 IN UINTN Delta OPTIONAL
// Number of BYTES in a row of the BltBuffer
274 EFI_PIXEL_BITMASK
* PixelInformation
;
276 UINT32 HorizontalResolution
;
277 LCD_BPP BitsPerPixel
;
278 VOID
*FrameBufferBase
;
279 VOID
*DestinationAddr
;
280 UINT16
*DestinationPixel16bit
;
282 UINT32 DestinationPixelX
;
283 UINT32 DestinationLine
;
286 Status
= EFI_SUCCESS
;
287 PixelInformation
= &This
->Mode
->Info
->PixelInformation
;
288 FrameBufferBase
= (UINTN
*)((UINTN
)(This
->Mode
->FrameBufferBase
));
289 HorizontalResolution
= This
->Mode
->Info
->HorizontalResolution
;
291 LcdPlatformGetBpp (This
->Mode
->Mode
,&BitsPerPixel
);
293 switch (BitsPerPixel
) {
294 case LCD_BITS_PER_PIXEL_24
:
295 WidthInBytes
= Width
* 4;
297 // Copy the SourcePixel into every pixel inside the target rectangle
298 for (DestinationLine
= DestinationY
;
299 DestinationLine
< DestinationY
+ Height
;
302 // Calculate the target address using 32bit pointer arithmetic:
303 DestinationAddr
= (VOID
*)((UINT32
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationX
);
305 // Fill the entire line
306 SetMemN( DestinationAddr
, WidthInBytes
, *((UINTN
*)EfiSourcePixel
));
310 case LCD_BITS_PER_PIXEL_16_555
:
311 // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
312 Pixel16bit
= (UINT16
) (
313 ( (EfiSourcePixel
->Red
<< 7) & PixelInformation
->RedMask
)
314 | ( (EfiSourcePixel
->Green
<< 2) & PixelInformation
->GreenMask
)
315 | ( (EfiSourcePixel
->Blue
>> 3) & PixelInformation
->BlueMask
)
316 // | ( 0 & PixelInformation->ReservedMask )
319 // Copy the SourcePixel into every pixel inside the target rectangle
320 for (DestinationLine
= DestinationY
;
321 DestinationLine
< DestinationY
+ Height
;
324 for (DestinationPixelX
= DestinationX
;
325 DestinationPixelX
< DestinationX
+ Width
;
328 // Calculate the target address:
329 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
331 // Copy the pixel into the new target
332 *DestinationPixel16bit
= Pixel16bit
;
337 case LCD_BITS_PER_PIXEL_16_565
:
338 // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
339 Pixel16bit
= (UINT16
) (
340 ( (EfiSourcePixel
->Red
<< 8) & PixelInformation
->RedMask
)
341 | ( (EfiSourcePixel
->Green
<< 3) & PixelInformation
->GreenMask
)
342 | ( (EfiSourcePixel
->Blue
>> 3) & PixelInformation
->BlueMask
)
345 // Copy the SourcePixel into every pixel inside the target rectangle
346 for (DestinationLine
= DestinationY
;
347 DestinationLine
< DestinationY
+ Height
;
350 for (DestinationPixelX
= DestinationX
;
351 DestinationPixelX
< DestinationX
+ Width
;
354 // Calculate the target address:
355 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
357 // Copy the pixel into the new target
358 *DestinationPixel16bit
= Pixel16bit
;
363 case LCD_BITS_PER_PIXEL_12_444
:
364 // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
365 Pixel16bit
= (UINT16
) (
366 ( (EfiSourcePixel
->Red
>> 4) & PixelInformation
->RedMask
)
367 | ( (EfiSourcePixel
->Green
) & PixelInformation
->GreenMask
)
368 | ( (EfiSourcePixel
->Blue
<< 4) & PixelInformation
->BlueMask
)
371 // Copy the SourcePixel into every pixel inside the target rectangle
372 for (DestinationLine
= DestinationY
;
373 DestinationLine
< DestinationY
+ Height
;
376 for (DestinationPixelX
= DestinationX
;
377 DestinationPixelX
< DestinationX
+ Width
;
380 // Calculate the target address:
381 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
383 // Copy the pixel into the new target
384 *DestinationPixel16bit
= Pixel16bit
;
389 case LCD_BITS_PER_PIXEL_8
:
390 case LCD_BITS_PER_PIXEL_4
:
391 case LCD_BITS_PER_PIXEL_2
:
392 case LCD_BITS_PER_PIXEL_1
:
394 // Can't handle this case
395 DEBUG((DEBUG_ERROR
, "LcdGraphicsBlt: EfiBltVideoFill: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
396 Status
= EFI_INVALID_PARAMETER
;
405 BltVideoToBltBuffer (
406 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
407 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
410 IN UINTN DestinationX
,
411 IN UINTN DestinationY
,
414 IN UINTN Delta OPTIONAL
// Number of BYTES in a row of the BltBuffer
418 UINT32 HorizontalResolution
;
419 LCD_BPP BitsPerPixel
;
420 EFI_PIXEL_BITMASK
*PixelInformation
;
421 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*EfiDestinationPixel
;
422 VOID
*FrameBufferBase
;
424 VOID
*DestinationAddr
;
425 UINT16
*SourcePixel16bit
;
429 UINT32 DestinationPixelX
;
430 UINT32 DestinationLine
;
431 UINT32 BltBufferHorizontalResolution
;
434 Status
= EFI_SUCCESS
;
435 PixelInformation
= &This
->Mode
->Info
->PixelInformation
;
436 HorizontalResolution
= This
->Mode
->Info
->HorizontalResolution
;
437 FrameBufferBase
= (UINTN
*)((UINTN
)(This
->Mode
->FrameBufferBase
));
439 if(( Delta
!= 0 ) && ( Delta
!= Width
* sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL
))) {
440 // Delta is not zero and it is different from the width.
441 // Divide it by the size of a pixel to find out the buffer's horizontal resolution.
442 BltBufferHorizontalResolution
= (UINT32
) (Delta
/ sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
444 BltBufferHorizontalResolution
= Width
;
447 LcdPlatformGetBpp (This
->Mode
->Mode
,&BitsPerPixel
);
449 switch (BitsPerPixel
) {
450 case LCD_BITS_PER_PIXEL_24
:
451 WidthInBytes
= Width
* 4;
453 // Access each line inside the Video Memory
454 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
455 SourceLine
< SourceY
+ Height
;
456 SourceLine
++, DestinationLine
++)
458 // Calculate the source and target addresses using 32bit pointer arithmetic:
459 SourceAddr
= (VOID
*)((UINT32
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourceX
);
460 DestinationAddr
= (VOID
*)((UINT32
*)BltBuffer
+ DestinationLine
* BltBufferHorizontalResolution
+ DestinationX
);
462 // Copy the entire line
463 CopyMem( DestinationAddr
, SourceAddr
, WidthInBytes
);
467 case LCD_BITS_PER_PIXEL_16_555
:
468 // Access each pixel inside the Video Memory
469 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
470 SourceLine
< SourceY
+ Height
;
471 SourceLine
++, DestinationLine
++)
473 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
474 SourcePixelX
< SourceX
+ Width
;
475 SourcePixelX
++, DestinationPixelX
++)
477 // Calculate the source and target addresses:
478 SourcePixel16bit
= (UINT16
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourcePixelX
;
479 EfiDestinationPixel
= BltBuffer
+ DestinationLine
* BltBufferHorizontalResolution
+ DestinationPixelX
;
481 // Snapshot the pixel from the video buffer once, to speed up the operation.
482 // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.
483 Pixel16bit
= *SourcePixel16bit
;
485 // Copy the pixel into the new target
486 EfiDestinationPixel
->Red
= (UINT8
) ( (Pixel16bit
& PixelInformation
->RedMask
) >> 7 );
487 EfiDestinationPixel
->Green
= (UINT8
) ( (Pixel16bit
& PixelInformation
->GreenMask
) >> 2);
488 EfiDestinationPixel
->Blue
= (UINT8
) ( (Pixel16bit
& PixelInformation
->BlueMask
) << 3 );
489 // EfiDestinationPixel->Reserved = (UINT8) 0;
494 case LCD_BITS_PER_PIXEL_16_565
:
495 // Access each pixel inside the Video Memory
496 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
497 SourceLine
< SourceY
+ Height
;
498 SourceLine
++, DestinationLine
++)
500 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
501 SourcePixelX
< SourceX
+ Width
;
502 SourcePixelX
++, DestinationPixelX
++)
504 // Calculate the source and target addresses:
505 SourcePixel16bit
= (UINT16
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourcePixelX
;
506 EfiDestinationPixel
= BltBuffer
+ DestinationLine
* BltBufferHorizontalResolution
+ DestinationPixelX
;
508 // Snapshot the pixel from the video buffer once, to speed up the operation.
509 // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.
510 Pixel16bit
= *SourcePixel16bit
;
512 // Copy the pixel into the new target
513 // There is no info for the Reserved byte, so we set it to zero
514 EfiDestinationPixel
->Red
= (UINT8
) ( (Pixel16bit
& PixelInformation
->RedMask
) >> 8 );
515 EfiDestinationPixel
->Green
= (UINT8
) ( (Pixel16bit
& PixelInformation
->GreenMask
) >> 3);
516 EfiDestinationPixel
->Blue
= (UINT8
) ( (Pixel16bit
& PixelInformation
->BlueMask
) << 3 );
517 // EfiDestinationPixel->Reserved = (UINT8) 0;
522 case LCD_BITS_PER_PIXEL_12_444
:
523 // Access each pixel inside the Video Memory
524 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
525 SourceLine
< SourceY
+ Height
;
526 SourceLine
++, DestinationLine
++)
528 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
529 SourcePixelX
< SourceX
+ Width
;
530 SourcePixelX
++, DestinationPixelX
++)
532 // Calculate the source and target addresses:
533 SourcePixel16bit
= (UINT16
*)FrameBufferBase
+ SourceLine
* HorizontalResolution
+ SourcePixelX
;
534 EfiDestinationPixel
= BltBuffer
+ DestinationLine
* BltBufferHorizontalResolution
+ DestinationPixelX
;
536 // Snapshot the pixel from the video buffer once, to speed up the operation.
537 // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.
538 Pixel16bit
= *SourcePixel16bit
;
540 // Copy the pixel into the new target
541 EfiDestinationPixel
->Red
= (UINT8
) ( (Pixel16bit
& PixelInformation
->RedMask
) >> 4 );
542 EfiDestinationPixel
->Green
= (UINT8
) ( (Pixel16bit
& PixelInformation
->GreenMask
) );
543 EfiDestinationPixel
->Blue
= (UINT8
) ( (Pixel16bit
& PixelInformation
->BlueMask
) << 4 );
544 // EfiDestinationPixel->Reserved = (UINT8) 0;
549 case LCD_BITS_PER_PIXEL_8
:
550 case LCD_BITS_PER_PIXEL_4
:
551 case LCD_BITS_PER_PIXEL_2
:
552 case LCD_BITS_PER_PIXEL_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
;
565 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
566 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
569 IN UINTN DestinationX
,
570 IN UINTN DestinationY
,
573 IN UINTN Delta OPTIONAL
// Number of BYTES in a row of the BltBuffer
577 UINT32 HorizontalResolution
;
578 LCD_BPP BitsPerPixel
;
579 EFI_PIXEL_BITMASK
*PixelInformation
;
580 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*EfiSourcePixel
;
581 VOID
*FrameBufferBase
;
583 VOID
*DestinationAddr
;
584 UINT16
*DestinationPixel16bit
;
587 UINT32 DestinationPixelX
;
588 UINT32 DestinationLine
;
589 UINT32 BltBufferHorizontalResolution
;
592 Status
= EFI_SUCCESS
;
593 PixelInformation
= &This
->Mode
->Info
->PixelInformation
;
594 HorizontalResolution
= This
->Mode
->Info
->HorizontalResolution
;
595 FrameBufferBase
= (UINTN
*)((UINTN
)(This
->Mode
->FrameBufferBase
));
597 if(( Delta
!= 0 ) && ( Delta
!= Width
* sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL
))) {
598 // Delta is not zero and it is different from the width.
599 // Divide it by the size of a pixel to find out the buffer's horizontal resolution.
600 BltBufferHorizontalResolution
= (UINT32
) (Delta
/ sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
602 BltBufferHorizontalResolution
= Width
;
605 LcdPlatformGetBpp (This
->Mode
->Mode
,&BitsPerPixel
);
607 switch (BitsPerPixel
) {
608 case LCD_BITS_PER_PIXEL_24
:
609 WidthInBytes
= Width
* 4;
611 // Access each pixel inside the BltBuffer Memory
612 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
613 SourceLine
< SourceY
+ Height
;
614 SourceLine
++, DestinationLine
++)
616 // Calculate the source and target addresses using 32bit pointer arithmetic:
617 SourceAddr
= (VOID
*)((UINT32
*)BltBuffer
+ SourceLine
* BltBufferHorizontalResolution
+ SourceX
);
618 DestinationAddr
= (VOID
*)((UINT32
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationX
);
620 // Copy the entire row Y
621 CopyMem( DestinationAddr
, SourceAddr
, WidthInBytes
);
625 case LCD_BITS_PER_PIXEL_16_555
:
626 // Access each pixel inside the BltBuffer Memory
627 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
628 SourceLine
< SourceY
+ Height
;
629 SourceLine
++, DestinationLine
++) {
631 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
632 SourcePixelX
< SourceX
+ Width
;
633 SourcePixelX
++, DestinationPixelX
++)
635 // Calculate the source and target addresses:
636 EfiSourcePixel
= BltBuffer
+ SourceLine
* BltBufferHorizontalResolution
+ SourcePixelX
;
637 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
639 // Copy the pixel into the new target
640 // Only the most significant bits will be copied across:
641 // To convert from 8 bits to 5 bits per pixel we throw away the 3 least significant bits
642 *DestinationPixel16bit
= (UINT16
) (
643 ( (EfiSourcePixel
->Red
<< 7) & PixelInformation
->RedMask
)
644 | ( (EfiSourcePixel
->Green
<< 2) & PixelInformation
->GreenMask
)
645 | ( (EfiSourcePixel
->Blue
>> 3) & PixelInformation
->BlueMask
)
646 // | ( 0 & PixelInformation->ReservedMask )
652 case LCD_BITS_PER_PIXEL_16_565
:
653 // Access each pixel inside the BltBuffer Memory
654 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
655 SourceLine
< SourceY
+ Height
;
656 SourceLine
++, DestinationLine
++) {
658 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
659 SourcePixelX
< SourceX
+ Width
;
660 SourcePixelX
++, DestinationPixelX
++)
662 // Calculate the source and target addresses:
663 EfiSourcePixel
= BltBuffer
+ SourceLine
* BltBufferHorizontalResolution
+ SourcePixelX
;
664 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
666 // Copy the pixel into the new target
667 // Only the most significant bits will be copied across:
668 // To convert from 8 bits to 5 or 6 bits per pixel we throw away the 3 or 2 least significant bits
669 // There is no room for the Reserved byte so we ignore that completely
670 *DestinationPixel16bit
= (UINT16
) (
671 ( (EfiSourcePixel
->Red
<< 8) & PixelInformation
->RedMask
)
672 | ( (EfiSourcePixel
->Green
<< 3) & PixelInformation
->GreenMask
)
673 | ( (EfiSourcePixel
->Blue
>> 3) & PixelInformation
->BlueMask
)
679 case LCD_BITS_PER_PIXEL_12_444
:
680 // Access each pixel inside the BltBuffer Memory
681 for (SourceLine
= SourceY
, DestinationLine
= DestinationY
;
682 SourceLine
< SourceY
+ Height
;
683 SourceLine
++, DestinationLine
++) {
685 for (SourcePixelX
= SourceX
, DestinationPixelX
= DestinationX
;
686 SourcePixelX
< SourceX
+ Width
;
687 SourcePixelX
++, DestinationPixelX
++)
689 // Calculate the source and target addresses:
690 EfiSourcePixel
= BltBuffer
+ SourceLine
* BltBufferHorizontalResolution
+ SourcePixelX
;
691 DestinationPixel16bit
= (UINT16
*)FrameBufferBase
+ DestinationLine
* HorizontalResolution
+ DestinationPixelX
;
693 // Copy the pixel into the new target
694 // Only the most significant bits will be copied across:
695 // To convert from 8 bits to 5 bits per pixel we throw away the 3 least significant bits
696 *DestinationPixel16bit
= (UINT16
) (
697 ( (EfiSourcePixel
->Red
<< 4) & PixelInformation
->RedMask
)
698 | ( (EfiSourcePixel
->Green
) & PixelInformation
->GreenMask
)
699 | ( (EfiSourcePixel
->Blue
>> 4) & PixelInformation
->BlueMask
)
700 // | ( 0 & PixelInformation->ReservedMask )
706 case LCD_BITS_PER_PIXEL_8
:
707 case LCD_BITS_PER_PIXEL_4
:
708 case LCD_BITS_PER_PIXEL_2
:
709 case LCD_BITS_PER_PIXEL_1
:
711 // Can't handle this case
712 DEBUG((DEBUG_ERROR
, "LcdGraphicsBlt: EfiBltBufferToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel
));
713 Status
= EFI_INVALID_PARAMETER
;
722 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
723 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
726 IN UINTN DestinationX
,
727 IN UINTN DestinationY
,
730 IN UINTN Delta OPTIONAL
// Number of BYTES in a row of the BltBuffer
734 UINT32 HorizontalResolution
;
735 LCD_BPP BitsPerPixel
;
736 VOID
*FrameBufferBase
;
738 HorizontalResolution
= This
->Mode
->Info
->HorizontalResolution
;
739 FrameBufferBase
= (UINTN
*)((UINTN
)(This
->Mode
->FrameBufferBase
));
742 // BltVideo to BltVideo:
744 // Source is the Video Memory,
745 // Destination is the Video Memory
747 LcdPlatformGetBpp (This
->Mode
->Mode
,&BitsPerPixel
);
748 FrameBufferBase
= (UINTN
*)((UINTN
)(This
->Mode
->FrameBufferBase
));
750 // The UEFI spec currently states:
751 // "There is no limitation on the overlapping of the source and destination rectangles"
752 // Therefore, we must be careful to avoid overwriting the source data
753 if( SourceY
== DestinationY
) {
754 // Copying within the same height, e.g. horizontal shift
755 if( SourceX
== DestinationX
) {
757 Status
= EFI_SUCCESS
;
758 } else if( ((SourceX
>DestinationX
)?(SourceX
- DestinationX
):(DestinationX
- SourceX
)) < Width
) {
760 Status
= VideoCopyHorizontalOverlap (BitsPerPixel
, FrameBufferBase
, HorizontalResolution
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
);
763 Status
= VideoCopyNoHorizontalOverlap (BitsPerPixel
, FrameBufferBase
, HorizontalResolution
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
);
766 // Copying from different heights
767 Status
= VideoCopyNoHorizontalOverlap (BitsPerPixel
, FrameBufferBase
, HorizontalResolution
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
);
773 /***************************************
774 * GraphicsOutput Protocol function, mapping to
775 * EFI_GRAPHICS_OUTPUT_PROTOCOL.Blt
777 * PRESUMES: 1 pixel = 4 bytes (32bits)
778 * ***************************************/
782 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
783 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
784 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation
,
787 IN UINTN DestinationX
,
788 IN UINTN DestinationY
,
791 IN UINTN Delta OPTIONAL
// Number of BYTES in a row of the BltBuffer
795 UINT32 HorizontalResolution
;
796 UINT32 VerticalResolution
;
797 LCD_INSTANCE
* Instance
;
799 Instance
= LCD_INSTANCE_FROM_GOP_THIS(This
);
801 // Setup the hardware if not already done
802 if (!mDisplayInitialized
) {
803 Status
= InitializeDisplay (Instance
);
804 if (EFI_ERROR(Status
)) {
809 HorizontalResolution
= This
->Mode
->Info
->HorizontalResolution
;
810 VerticalResolution
= This
->Mode
->Info
->VerticalResolution
;
812 DEBUG((DEBUG_INFO
, "LcdGraphicsBlt (BltOperation:%d,DestX:%d,DestY:%d,Width:%d,Height:%d) res(%d,%d)\n",
813 BltOperation
,DestinationX
,DestinationY
,Width
,Height
,HorizontalResolution
,VerticalResolution
));
815 // Check we have reasonable parameters
816 if (Width
== 0 || Height
== 0) {
817 DEBUG((DEBUG_ERROR
, "LcdGraphicsBlt: ERROR - Invalid dimension: Zero size area.\n" ));
818 Status
= EFI_INVALID_PARAMETER
;
822 if ((BltOperation
== EfiBltVideoFill
) || (BltOperation
== EfiBltBufferToVideo
) || (BltOperation
== EfiBltVideoToBltBuffer
)) {
823 ASSERT( BltBuffer
!= NULL
);
826 /*if ((DestinationX >= HorizontalResolution) || (DestinationY >= VerticalResolution)) {
827 DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: ERROR - Invalid destination.\n" ));
828 Status = EFI_INVALID_PARAMETER;
832 // If we are reading data out of the video buffer, check that the source area is within the display limits
833 if ((BltOperation
== EfiBltVideoToBltBuffer
) || (BltOperation
== EfiBltVideoToVideo
)) {
834 if ((SourceY
+ Height
> VerticalResolution
) || (SourceX
+ Width
> HorizontalResolution
)) {
835 DEBUG((DEBUG_INFO
, "LcdGraphicsBlt: ERROR - Invalid source resolution.\n" ));
836 DEBUG((DEBUG_INFO
, " - SourceY=%d + Height=%d > VerticalResolution=%d.\n", SourceY
, Height
, VerticalResolution
));
837 DEBUG((DEBUG_INFO
, " - SourceX=%d + Width=%d > HorizontalResolution=%d.\n", SourceX
, Width
, HorizontalResolution
));
838 Status
= EFI_INVALID_PARAMETER
;
843 // If we are writing data into the video buffer, that the destination area is within the display limits
844 if ((BltOperation
== EfiBltVideoFill
) || (BltOperation
== EfiBltBufferToVideo
) || (BltOperation
== EfiBltVideoToVideo
)) {
845 if ((DestinationY
+ Height
> VerticalResolution
) || (DestinationX
+ Width
> HorizontalResolution
)) {
846 DEBUG((DEBUG_INFO
, "LcdGraphicsBlt: ERROR - Invalid destination resolution.\n" ));
847 DEBUG((DEBUG_INFO
, " - DestinationY=%d + Height=%d > VerticalResolution=%d.\n", DestinationY
, Height
, VerticalResolution
));
848 DEBUG((DEBUG_INFO
, " - DestinationX=%d + Width=%d > HorizontalResolution=%d.\n", DestinationX
, Width
, HorizontalResolution
));
849 Status
= EFI_INVALID_PARAMETER
;
855 // Perform the Block Transfer Operation
858 switch (BltOperation
) {
859 case EfiBltVideoFill
:
860 Status
= BltVideoFill (This
, BltBuffer
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
, Delta
);
863 case EfiBltVideoToBltBuffer
:
864 Status
= BltVideoToBltBuffer (This
, BltBuffer
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
, Delta
);
867 case EfiBltBufferToVideo
:
868 Status
= BltBufferToVideo (This
, BltBuffer
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
, Delta
);
871 case EfiBltVideoToVideo
:
872 Status
= BltVideoToVideo (This
, BltBuffer
, SourceX
, SourceY
, DestinationX
, DestinationY
, Width
, Height
, Delta
);
875 case EfiGraphicsOutputBltOperationMax
:
877 DEBUG((DEBUG_ERROR
, "LcdGraphicsBlt: Invalid Operation\n"));
878 Status
= EFI_INVALID_PARAMETER
;