]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputBlt.c
ARM Packages: Fixed line endings
[mirror_edk2.git] / ArmPlatformPkg / Drivers / LcdGraphicsOutputDxe / LcdGraphicsOutputBlt.c
1 /** @file
2
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
8
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.
11
12 **/
13
14 #include <PiDxe.h>
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>
20
21 #include <Guid/GlobalVariable.h>
22
23 #include "LcdGraphicsOutputDxe.h"
24
25 extern BOOLEAN mDisplayInitialized;
26
27 //
28 // Function Definitions
29 //
30
31 STATIC
32 EFI_STATUS
33 VideoCopyNoHorizontalOverlap (
34 IN UINTN BitsPerPixel,
35 IN volatile VOID *FrameBufferBase,
36 IN UINT32 HorizontalResolution,
37 IN UINTN SourceX,
38 IN UINTN SourceY,
39 IN UINTN DestinationX,
40 IN UINTN DestinationY,
41 IN UINTN Width,
42 IN UINTN Height
43 )
44 {
45 EFI_STATUS Status = EFI_SUCCESS;
46 UINTN SourceLine;
47 UINTN DestinationLine;
48 UINTN WidthInBytes;
49 UINTN LineCount;
50 INTN Step;
51 VOID *SourceAddr;
52 VOID *DestinationAddr;
53
54 if( DestinationY <= SourceY ) {
55 // scrolling up (or horizontally but without overlap)
56 SourceLine = SourceY;
57 DestinationLine = DestinationY;
58 Step = 1;
59 } else {
60 // scrolling down
61 SourceLine = SourceY + Height;
62 DestinationLine = DestinationY + Height;
63 Step = -1;
64 }
65
66 switch (BitsPerPixel) {
67
68 case LCD_BITS_PER_PIXEL_24:
69
70 WidthInBytes = Width * 4;
71
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);
76
77 // Copy the entire line Y from video ram to the temp buffer
78 CopyMem( DestinationAddr, SourceAddr, WidthInBytes);
79
80 // Update the line numbers
81 SourceLine += Step;
82 DestinationLine += Step;
83 }
84 break;
85
86 case LCD_BITS_PER_PIXEL_16_555:
87 case LCD_BITS_PER_PIXEL_16_565:
88 case LCD_BITS_PER_PIXEL_12_444:
89
90 WidthInBytes = Width * 2;
91
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);
96
97 // Copy the entire line Y from video ram to the temp buffer
98 CopyMem( DestinationAddr, SourceAddr, WidthInBytes);
99
100 // Update the line numbers
101 SourceLine += Step;
102 DestinationLine += Step;
103 }
104 break;
105
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:
110 default:
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;
114 goto EXIT;
115 // break;
116
117 }
118
119 EXIT:
120 return Status;
121 }
122
123 STATIC
124 EFI_STATUS
125 VideoCopyHorizontalOverlap (
126 IN UINTN BitsPerPixel,
127 IN volatile VOID *FrameBufferBase,
128 UINT32 HorizontalResolution,
129 IN UINTN SourceX,
130 IN UINTN SourceY,
131 IN UINTN DestinationX,
132 IN UINTN DestinationY,
133 IN UINTN Width,
134 IN UINTN Height
135 )
136 {
137 EFI_STATUS Status = EFI_SUCCESS;
138
139 UINT32 *PixelBuffer32bit;
140 UINT32 *SourcePixel32bit;
141 UINT32 *DestinationPixel32bit;
142
143 UINT16 *PixelBuffer16bit;
144 UINT16 *SourcePixel16bit;
145 UINT16 *DestinationPixel16bit;
146
147 UINT32 SourcePixelY;
148 UINT32 DestinationPixelY;
149 UINTN SizeIn32Bits;
150 UINTN SizeIn16Bits;
151
152 switch (BitsPerPixel) {
153
154 case LCD_BITS_PER_PIXEL_24:
155 // Allocate a temporary buffer
156
157 PixelBuffer32bit = (UINT32 *) AllocatePool((Height * Width) * sizeof(UINT32));
158
159 if (PixelBuffer32bit == NULL) {
160 Status = EFI_OUT_OF_RESOURCES;
161 goto EXIT;
162 }
163
164 SizeIn32Bits = Width * 4;
165
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)
170 {
171 // Update the start address of line Y (source)
172 SourcePixel32bit = (UINT32 *)FrameBufferBase + SourcePixelY * HorizontalResolution + SourceX;
173
174 // Copy the entire line Y from video ram to the temp buffer
175 CopyMem( (VOID *)DestinationPixel32bit, (CONST VOID *)SourcePixel32bit, SizeIn32Bits);
176 }
177
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)
182 {
183 // Update the start address of line Y (target)
184 DestinationPixel32bit = (UINT32 *)FrameBufferBase + DestinationPixelY * HorizontalResolution + DestinationX;
185
186 // Copy the entire line Y from the temp buffer to video ram
187 CopyMem( (VOID *)DestinationPixel32bit, (CONST VOID *)SourcePixel32bit, SizeIn32Bits);
188 }
189
190 // Free up the allocated memory
191 FreePool((VOID *) PixelBuffer32bit);
192
193 break;
194
195
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));
201
202 if (PixelBuffer16bit == NULL) {
203 Status = EFI_OUT_OF_RESOURCES;
204 goto EXIT;
205 }
206
207 // Access each pixel inside the source area of the Video Memory and copy it to the temp buffer
208
209 SizeIn16Bits = Width * 2;
210
211 for (SourcePixelY = SourceY, DestinationPixel16bit = PixelBuffer16bit;
212 SourcePixelY < SourceY + Height;
213 SourcePixelY++, DestinationPixel16bit += Width)
214 {
215 // Calculate the source address:
216 SourcePixel16bit = (UINT16 *)FrameBufferBase + SourcePixelY * HorizontalResolution + SourceX;
217
218 // Copy the entire line Y from Video to the temp buffer
219 CopyMem( (VOID *)DestinationPixel16bit, (CONST VOID *)SourcePixel16bit, SizeIn16Bits);
220 }
221
222 // Copy from the temp buffer into the destination area of the Video Memory
223
224 for (DestinationPixelY = DestinationY, SourcePixel16bit = PixelBuffer16bit;
225 DestinationPixelY < DestinationY + Height;
226 DestinationPixelY++, SourcePixel16bit += Width)
227 {
228 // Calculate the target address:
229 DestinationPixel16bit = (UINT16 *)FrameBufferBase + (DestinationPixelY * HorizontalResolution + DestinationX);
230
231 // Copy the entire line Y from the temp buffer to Video
232 CopyMem( (VOID *)DestinationPixel16bit, (CONST VOID *)SourcePixel16bit, SizeIn16Bits);
233 }
234
235 // Free the allocated memory
236 FreePool((VOID *) PixelBuffer16bit);
237
238 break;
239
240
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:
245 default:
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;
249 goto EXIT;
250 // break;
251
252 }
253
254 EXIT:
255 return Status;
256 }
257
258 STATIC
259 EFI_STATUS
260 BltVideoFill (
261 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
262 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *EfiSourcePixel, OPTIONAL
263 IN UINTN SourceX,
264 IN UINTN SourceY,
265 IN UINTN DestinationX,
266 IN UINTN DestinationY,
267 IN UINTN Width,
268 IN UINTN Height,
269 IN UINTN Delta OPTIONAL // Number of BYTES in a row of the BltBuffer
270 )
271 {
272 EFI_PIXEL_BITMASK* PixelInformation;
273 EFI_STATUS Status;
274 UINT32 HorizontalResolution;
275 LCD_BPP BitsPerPixel;
276 VOID *FrameBufferBase;
277 VOID *DestinationAddr;
278 UINT16 *DestinationPixel16bit;
279 UINT16 Pixel16bit;
280 UINT32 DestinationPixelX;
281 UINT32 DestinationLine;
282 UINTN WidthInBytes;
283
284 Status = EFI_SUCCESS;
285 PixelInformation = &This->Mode->Info->PixelInformation;
286 FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
287 HorizontalResolution = This->Mode->Info->HorizontalResolution;
288
289 LcdPlatformGetBpp (This->Mode->Mode,&BitsPerPixel);
290
291 switch (BitsPerPixel) {
292 case LCD_BITS_PER_PIXEL_24:
293 WidthInBytes = Width * 4;
294
295 // Copy the SourcePixel into every pixel inside the target rectangle
296 for (DestinationLine = DestinationY;
297 DestinationLine < DestinationY + Height;
298 DestinationLine++)
299 {
300 // Calculate the target address using 32bit pointer arithmetic:
301 DestinationAddr = (VOID *)((UINT32 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationX);
302
303 // Fill the entire line
304 SetMemN( DestinationAddr, WidthInBytes, *((UINTN *)EfiSourcePixel));
305 }
306 break;
307
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 )
315 );
316
317 // Copy the SourcePixel into every pixel inside the target rectangle
318 for (DestinationLine = DestinationY;
319 DestinationLine < DestinationY + Height;
320 DestinationLine++)
321 {
322 for (DestinationPixelX = DestinationX;
323 DestinationPixelX < DestinationX + Width;
324 DestinationPixelX++)
325 {
326 // Calculate the target address:
327 DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX;
328
329 // Copy the pixel into the new target
330 *DestinationPixel16bit = Pixel16bit;
331 }
332 }
333 break;
334
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 )
341 );
342
343 // Copy the SourcePixel into every pixel inside the target rectangle
344 for (DestinationLine = DestinationY;
345 DestinationLine < DestinationY + Height;
346 DestinationLine++)
347 {
348 for (DestinationPixelX = DestinationX;
349 DestinationPixelX < DestinationX + Width;
350 DestinationPixelX++)
351 {
352 // Calculate the target address:
353 DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX;
354
355 // Copy the pixel into the new target
356 *DestinationPixel16bit = Pixel16bit;
357 }
358 }
359 break;
360
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 )
367 );
368
369 // Copy the SourcePixel into every pixel inside the target rectangle
370 for (DestinationLine = DestinationY;
371 DestinationLine < DestinationY + Height;
372 DestinationLine++)
373 {
374 for (DestinationPixelX = DestinationX;
375 DestinationPixelX < DestinationX + Width;
376 DestinationPixelX++)
377 {
378 // Calculate the target address:
379 DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX;
380
381 // Copy the pixel into the new target
382 *DestinationPixel16bit = Pixel16bit;
383 }
384 }
385 break;
386
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:
391 default:
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;
395 break;
396 }
397
398 return Status;
399 }
400
401 STATIC
402 EFI_STATUS
403 BltVideoToBltBuffer (
404 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
405 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
406 IN UINTN SourceX,
407 IN UINTN SourceY,
408 IN UINTN DestinationX,
409 IN UINTN DestinationY,
410 IN UINTN Width,
411 IN UINTN Height,
412 IN UINTN Delta OPTIONAL // Number of BYTES in a row of the BltBuffer
413 )
414 {
415 EFI_STATUS Status;
416 UINT32 HorizontalResolution;
417 LCD_BPP BitsPerPixel;
418 EFI_PIXEL_BITMASK *PixelInformation;
419 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *EfiDestinationPixel;
420 VOID *FrameBufferBase;
421 VOID *SourceAddr;
422 VOID *DestinationAddr;
423 UINT16 *SourcePixel16bit;
424 UINT16 Pixel16bit;
425 UINT32 SourcePixelX;
426 UINT32 SourceLine;
427 UINT32 DestinationPixelX;
428 UINT32 DestinationLine;
429 UINT32 BltBufferHorizontalResolution;
430 UINTN WidthInBytes;
431
432 Status = EFI_SUCCESS;
433 PixelInformation = &This->Mode->Info->PixelInformation;
434 HorizontalResolution = This->Mode->Info->HorizontalResolution;
435 FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
436
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));
441 } else {
442 BltBufferHorizontalResolution = Width;
443 }
444
445 LcdPlatformGetBpp (This->Mode->Mode,&BitsPerPixel);
446
447 switch (BitsPerPixel) {
448 case LCD_BITS_PER_PIXEL_24:
449 WidthInBytes = Width * 4;
450
451 // Access each line inside the Video Memory
452 for (SourceLine = SourceY, DestinationLine = DestinationY;
453 SourceLine < SourceY + Height;
454 SourceLine++, DestinationLine++)
455 {
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);
459
460 // Copy the entire line
461 CopyMem( DestinationAddr, SourceAddr, WidthInBytes);
462 }
463 break;
464
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++)
470 {
471 for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;
472 SourcePixelX < SourceX + Width;
473 SourcePixelX++, DestinationPixelX++)
474 {
475 // Calculate the source and target addresses:
476 SourcePixel16bit = (UINT16 *)FrameBufferBase + SourceLine * HorizontalResolution + SourcePixelX;
477 EfiDestinationPixel = BltBuffer + DestinationLine * BltBufferHorizontalResolution + DestinationPixelX;
478
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;
482
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;
488 }
489 }
490 break;
491
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++)
497 {
498 for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;
499 SourcePixelX < SourceX + Width;
500 SourcePixelX++, DestinationPixelX++)
501 {
502 // Calculate the source and target addresses:
503 SourcePixel16bit = (UINT16 *)FrameBufferBase + SourceLine * HorizontalResolution + SourcePixelX;
504 EfiDestinationPixel = BltBuffer + DestinationLine * BltBufferHorizontalResolution + DestinationPixelX;
505
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;
509
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;
516 }
517 }
518 break;
519
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++)
525 {
526 for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;
527 SourcePixelX < SourceX + Width;
528 SourcePixelX++, DestinationPixelX++)
529 {
530 // Calculate the source and target addresses:
531 SourcePixel16bit = (UINT16 *)FrameBufferBase + SourceLine * HorizontalResolution + SourcePixelX;
532 EfiDestinationPixel = BltBuffer + DestinationLine * BltBufferHorizontalResolution + DestinationPixelX;
533
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;
537
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;
543 }
544 }
545 break;
546
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:
551 default:
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;
555 break;
556 }
557 return Status;
558 }
559
560 STATIC
561 EFI_STATUS
562 BltBufferToVideo (
563 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
564 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
565 IN UINTN SourceX,
566 IN UINTN SourceY,
567 IN UINTN DestinationX,
568 IN UINTN DestinationY,
569 IN UINTN Width,
570 IN UINTN Height,
571 IN UINTN Delta OPTIONAL // Number of BYTES in a row of the BltBuffer
572 )
573 {
574 EFI_STATUS Status;
575 UINT32 HorizontalResolution;
576 LCD_BPP BitsPerPixel;
577 EFI_PIXEL_BITMASK *PixelInformation;
578 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *EfiSourcePixel;
579 VOID *FrameBufferBase;
580 VOID *SourceAddr;
581 VOID *DestinationAddr;
582 UINT16 *DestinationPixel16bit;
583 UINT32 SourcePixelX;
584 UINT32 SourceLine;
585 UINT32 DestinationPixelX;
586 UINT32 DestinationLine;
587 UINT32 BltBufferHorizontalResolution;
588 UINTN WidthInBytes;
589
590 Status = EFI_SUCCESS;
591 PixelInformation = &This->Mode->Info->PixelInformation;
592 HorizontalResolution = This->Mode->Info->HorizontalResolution;
593 FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
594
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));
599 } else {
600 BltBufferHorizontalResolution = Width;
601 }
602
603 LcdPlatformGetBpp (This->Mode->Mode,&BitsPerPixel);
604
605 switch (BitsPerPixel) {
606 case LCD_BITS_PER_PIXEL_24:
607 WidthInBytes = Width * 4;
608
609 // Access each pixel inside the BltBuffer Memory
610 for (SourceLine = SourceY, DestinationLine = DestinationY;
611 SourceLine < SourceY + Height;
612 SourceLine++, DestinationLine++)
613 {
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);
617
618 // Copy the entire row Y
619 CopyMem( DestinationAddr, SourceAddr, WidthInBytes);
620 }
621 break;
622
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++) {
628
629 for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;
630 SourcePixelX < SourceX + Width;
631 SourcePixelX++, DestinationPixelX++)
632 {
633 // Calculate the source and target addresses:
634 EfiSourcePixel = BltBuffer + SourceLine * BltBufferHorizontalResolution + SourcePixelX;
635 DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX;
636
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 )
645 );
646 }
647 }
648 break;
649
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++) {
655
656 for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;
657 SourcePixelX < SourceX + Width;
658 SourcePixelX++, DestinationPixelX++)
659 {
660 // Calculate the source and target addresses:
661 EfiSourcePixel = BltBuffer + SourceLine * BltBufferHorizontalResolution + SourcePixelX;
662 DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX;
663
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 )
672 );
673 }
674 }
675 break;
676
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++) {
682
683 for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;
684 SourcePixelX < SourceX + Width;
685 SourcePixelX++, DestinationPixelX++)
686 {
687 // Calculate the source and target addresses:
688 EfiSourcePixel = BltBuffer + SourceLine * BltBufferHorizontalResolution + SourcePixelX;
689 DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX;
690
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 )
699 );
700 }
701 }
702 break;
703
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:
708 default:
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;
712 break;
713 }
714 return Status;
715 }
716
717 STATIC
718 EFI_STATUS
719 BltVideoToVideo (
720 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
721 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
722 IN UINTN SourceX,
723 IN UINTN SourceY,
724 IN UINTN DestinationX,
725 IN UINTN DestinationY,
726 IN UINTN Width,
727 IN UINTN Height,
728 IN UINTN Delta OPTIONAL // Number of BYTES in a row of the BltBuffer
729 )
730 {
731 EFI_STATUS Status;
732 UINT32 HorizontalResolution;
733 LCD_BPP BitsPerPixel;
734 VOID *FrameBufferBase;
735
736 HorizontalResolution = This->Mode->Info->HorizontalResolution;
737 FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
738
739 //
740 // BltVideo to BltVideo:
741 //
742 // Source is the Video Memory,
743 // Destination is the Video Memory
744
745 LcdPlatformGetBpp (This->Mode->Mode,&BitsPerPixel);
746 FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
747
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 ) {
754 // Nothing to do
755 Status = EFI_SUCCESS;
756 } else if( ((SourceX>DestinationX)?(SourceX - DestinationX):(DestinationX - SourceX)) < Width ) {
757 // There is overlap
758 Status = VideoCopyHorizontalOverlap (BitsPerPixel, FrameBufferBase, HorizontalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height );
759 } else {
760 // No overlap
761 Status = VideoCopyNoHorizontalOverlap (BitsPerPixel, FrameBufferBase, HorizontalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height );
762 }
763 } else {
764 // Copying from different heights
765 Status = VideoCopyNoHorizontalOverlap (BitsPerPixel, FrameBufferBase, HorizontalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height );
766 }
767
768 return Status;
769 }
770
771 /***************************************
772 * GraphicsOutput Protocol function, mapping to
773 * EFI_GRAPHICS_OUTPUT_PROTOCOL.Blt
774 *
775 * PRESUMES: 1 pixel = 4 bytes (32bits)
776 * ***************************************/
777 EFI_STATUS
778 EFIAPI
779 LcdGraphicsBlt (
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,
783 IN UINTN SourceX,
784 IN UINTN SourceY,
785 IN UINTN DestinationX,
786 IN UINTN DestinationY,
787 IN UINTN Width,
788 IN UINTN Height,
789 IN UINTN Delta OPTIONAL // Number of BYTES in a row of the BltBuffer
790 )
791 {
792 EFI_STATUS Status;
793 UINT32 HorizontalResolution;
794 UINT32 VerticalResolution;
795 LCD_INSTANCE* Instance;
796
797 Instance = LCD_INSTANCE_FROM_GOP_THIS(This);
798
799 // Setup the hardware if not already done
800 if (!mDisplayInitialized) {
801 Status = InitializeDisplay (Instance);
802 if (EFI_ERROR(Status)) {
803 goto EXIT;
804 }
805 }
806
807 HorizontalResolution = This->Mode->Info->HorizontalResolution;
808 VerticalResolution = This->Mode->Info->VerticalResolution;
809
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));
812
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;
817 goto EXIT;
818 }
819
820 if ((BltOperation == EfiBltVideoFill) || (BltOperation == EfiBltBufferToVideo) || (BltOperation == EfiBltVideoToBltBuffer)) {
821 ASSERT( BltBuffer != NULL);
822 }
823
824 /*if ((DestinationX >= HorizontalResolution) || (DestinationY >= VerticalResolution)) {
825 DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: ERROR - Invalid destination.\n" ));
826 Status = EFI_INVALID_PARAMETER;
827 goto EXIT;
828 }*/
829
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;
837 goto EXIT;
838 }
839 }
840
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;
848 goto EXIT;
849 }
850 }
851
852 //
853 // Perform the Block Transfer Operation
854 //
855
856 switch (BltOperation) {
857 case EfiBltVideoFill:
858 Status = BltVideoFill (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);
859 break;
860
861 case EfiBltVideoToBltBuffer:
862 Status = BltVideoToBltBuffer (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);
863 break;
864
865 case EfiBltBufferToVideo:
866 Status = BltBufferToVideo (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);
867 break;
868
869 case EfiBltVideoToVideo:
870 Status = BltVideoToVideo (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);
871 break;
872
873 case EfiGraphicsOutputBltOperationMax:
874 default:
875 DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: Invalid Operation\n"));
876 Status = EFI_INVALID_PARAMETER;
877 break;
878 }
879
880 EXIT:
881 return Status;
882 }