1 /** @file 2 FrameBufferBltLib - Library to perform blt operations on a frame buffer. 3 4 Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR> 5 This program and the accompanying materials 6 are licensed and made available under the terms and conditions of the BSD License 7 which accompanies this distribution. The full text of the license may be found at 8 http://opensource.org/licenses/bsd-license.php 9 10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 13 **/ 14 15 #include "PiDxe.h" 16 #include <Library/BaseLib.h> 17 #include <Library/BaseMemoryLib.h> 18 #include <Library/BltLib.h> 19 #include <Library/DebugLib.h> 20 21 #if 0 22 #define VDEBUG DEBUG 23 #else 24 #define VDEBUG(x) 25 #endif 26 27 #define MAX_LINE_BUFFER_SIZE (SIZE_4KB * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)) 28 29 UINTN mBltLibColorDepth; 30 UINTN mBltLibWidthInBytes; 31 UINTN mBltLibBytesPerPixel; 32 UINTN mBltLibWidthInPixels; 33 UINTN mBltLibHeight; 34 UINT8 mBltLibLineBuffer[MAX_LINE_BUFFER_SIZE]; 35 UINT8 *mBltLibFrameBuffer; 36 EFI_GRAPHICS_PIXEL_FORMAT mPixelFormat; 37 EFI_PIXEL_BITMASK mPixelBitMasks; 38 INTN mPixelShl[4]; // R-G-B-Rsvd 39 INTN mPixelShr[4]; // R-G-B-Rsvd 40 41 42 VOID 43 ConfigurePixelBitMaskFormat ( 44 IN EFI_PIXEL_BITMASK *BitMask 45 ) 46 { 47 UINTN Loop; 48 UINT32 *Masks; 49 UINT32 MergedMasks; 50 51 MergedMasks = 0; 52 Masks = (UINT32*) BitMask; 53 for (Loop = 0; Loop < 3; Loop++) { 54 ASSERT ((Loop == 3) || (Masks[Loop] != 0)); 55 ASSERT ((MergedMasks & Masks[Loop]) == 0); 56 mPixelShl[Loop] = HighBitSet32 (Masks[Loop]) - 23 + (Loop * 8); 57 if (mPixelShl[Loop] < 0) { 58 mPixelShr[Loop] = -mPixelShl[Loop]; 59 mPixelShl[Loop] = 0; 60 } else { 61 mPixelShr[Loop] = 0; 62 } 63 MergedMasks = (UINT32) (MergedMasks | Masks[Loop]); 64 DEBUG ((EFI_D_INFO, "%d: shl:%d shr:%d mask:%x\n", Loop, mPixelShl[Loop], mPixelShr[Loop], Masks[Loop])); 65 } 66 MergedMasks = (UINT32) (MergedMasks | Masks[3]); 67 68 ASSERT (MergedMasks != 0); 69 mBltLibBytesPerPixel = (UINTN) ((HighBitSet32 (MergedMasks) + 7) / 8); 70 71 DEBUG ((EFI_D_INFO, "Bytes per pixel: %d\n", mBltLibBytesPerPixel)); 72 73 CopyMem (&mPixelBitMasks, BitMask, sizeof (*BitMask)); 74 } 75 76 77 /** 78 Configure the FrameBufferLib instance 79 80 @param[in] FrameBuffer Pointer to the start of the frame buffer 81 @param[in] FrameBufferInfo Describes the frame buffer characteristics 82 83 @retval EFI_INVALID_PARAMETER - Invalid parameter 84 @retval EFI_UNSUPPORTED - The BltLib does not support this configuration 85 @retval EFI_SUCCESS - Blt operation success 86 87 **/ 88 EFI_STATUS 89 EFIAPI 90 BltLibConfigure ( 91 IN VOID *FrameBuffer, 92 IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo 93 ) 94 { 95 STATIC EFI_PIXEL_BITMASK RgbPixelMasks = 96 { 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 }; 97 STATIC EFI_PIXEL_BITMASK BgrPixelMasks = 98 { 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }; 99 100 switch (FrameBufferInfo->PixelFormat) { 101 case PixelRedGreenBlueReserved8BitPerColor: 102 ConfigurePixelBitMaskFormat (&RgbPixelMasks); 103 break; 104 case PixelBlueGreenRedReserved8BitPerColor: 105 ConfigurePixelBitMaskFormat (&BgrPixelMasks); 106 break; 107 case PixelBitMask: 108 ConfigurePixelBitMaskFormat (&(FrameBufferInfo->PixelInformation)); 109 break; 110 case PixelBltOnly: 111 ASSERT (FrameBufferInfo->PixelFormat != PixelBltOnly); 112 return EFI_UNSUPPORTED; 113 default: 114 ASSERT (FALSE); 115 return EFI_INVALID_PARAMETER; 116 } 117 mPixelFormat = FrameBufferInfo->PixelFormat; 118 119 mBltLibFrameBuffer = (UINT8*) FrameBuffer; 120 mBltLibWidthInPixels = (UINTN) FrameBufferInfo->HorizontalResolution; 121 mBltLibHeight = (UINTN) FrameBufferInfo->VerticalResolution; 122 mBltLibWidthInBytes = mBltLibWidthInPixels * mBltLibBytesPerPixel; 123 124 ASSERT (mBltLibWidthInBytes < sizeof (mBltLibLineBuffer)); 125 126 return EFI_SUCCESS; 127 } 128 129 130 /** 131 Performs a UEFI Graphics Output Protocol Blt operation. 132 133 @param[in,out] BltBuffer - The data to transfer to screen 134 @param[in] BltOperation - The operation to perform 135 @param[in] SourceX - The X coordinate of the source for BltOperation 136 @param[in] SourceY - The Y coordinate of the source for BltOperation 137 @param[in] DestinationX - The X coordinate of the destination for BltOperation 138 @param[in] DestinationY - The Y coordinate of the destination for BltOperation 139 @param[in] Width - The width of a rectangle in the blt rectangle in pixels 140 @param[in] Height - The height of a rectangle in the blt rectangle in pixels 141 @param[in] Delta - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation. 142 If a Delta of 0 is used, the entire BltBuffer will be operated on. 143 If a subrectangle of the BltBuffer is used, then Delta represents 144 the number of bytes in a row of the BltBuffer. 145 146 @retval EFI_DEVICE_ERROR - A hardware error occured 147 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in 148 @retval EFI_SUCCESS - Blt operation success 149 150 **/ 151 EFI_STATUS 152 EFIAPI 153 BltLibGopBlt ( 154 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL 155 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, 156 IN UINTN SourceX, 157 IN UINTN SourceY, 158 IN UINTN DestinationX, 159 IN UINTN DestinationY, 160 IN UINTN Width, 161 IN UINTN Height, 162 IN UINTN Delta 163 ) 164 { 165 switch (BltOperation) { 166 case EfiBltVideoToBltBuffer: 167 return BltLibVideoToBltBufferEx ( 168 BltBuffer, 169 SourceX, 170 SourceY, 171 DestinationX, 172 DestinationY, 173 Width, 174 Height, 175 Delta 176 ); 177 178 case EfiBltVideoToVideo: 179 return BltLibVideoToVideo ( 180 SourceX, 181 SourceY, 182 DestinationX, 183 DestinationY, 184 Width, 185 Height 186 ); 187 188 case EfiBltVideoFill: 189 return BltLibVideoFill ( 190 BltBuffer, 191 DestinationX, 192 DestinationY, 193 Width, 194 Height 195 ); 196 197 case EfiBltBufferToVideo: 198 return BltLibBufferToVideoEx ( 199 BltBuffer, 200 SourceX, 201 SourceY, 202 DestinationX, 203 DestinationY, 204 Width, 205 Height, 206 Delta 207 ); 208 default: 209 return EFI_INVALID_PARAMETER; 210 } 211 } 212 213 214 /** 215 Performs a UEFI Graphics Output Protocol Blt Video Fill. 216 217 @param[in] Color Color to fill the region with 218 @param[in] DestinationX X location to start fill operation 219 @param[in] DestinationY Y location to start fill operation 220 @param[in] Width Width (in pixels) to fill 221 @param[in] Height Height to fill 222 223 @retval EFI_DEVICE_ERROR - A hardware error occured 224 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in 225 @retval EFI_SUCCESS - The sizes were returned 226 227 **/ 228 EFI_STATUS 229 EFIAPI 230 BltLibVideoFill ( 231 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Color, 232 IN UINTN DestinationX, 233 IN UINTN DestinationY, 234 IN UINTN Width, 235 IN UINTN Height 236 ) 237 { 238 UINTN DstY; 239 VOID *BltMemDst; 240 UINTN X; 241 UINT8 Uint8; 242 UINT32 Uint32; 243 UINT64 WideFill; 244 BOOLEAN UseWideFill; 245 BOOLEAN LineBufferReady; 246 UINTN Offset; 247 UINTN WidthInBytes; 248 UINTN SizeInBytes; 249 250 // 251 // BltBuffer to Video: Source is BltBuffer, destination is Video 252 // 253 if (DestinationY + Height > mBltLibHeight) { 254 DEBUG ((EFI_D_INFO, "VideoFill: Past screen (Y)\n")); 255 return EFI_INVALID_PARAMETER; 256 } 257 258 if (DestinationX + Width > mBltLibWidthInPixels) { 259 DEBUG ((EFI_D_INFO, "VideoFill: Past screen (X)\n")); 260 return EFI_INVALID_PARAMETER; 261 } 262 263 if (Width == 0 || Height == 0) { 264 DEBUG ((EFI_D_INFO, "VideoFill: Width or Height is 0\n")); 265 return EFI_INVALID_PARAMETER; 266 } 267 268 WidthInBytes = Width * mBltLibBytesPerPixel; 269 270 Uint32 = *(UINT32*) Color; 271 WideFill = 272 (UINT32) ( 273 (((Uint32 << mPixelShl[0]) >> mPixelShr[0]) & mPixelBitMasks.RedMask) | 274 (((Uint32 << mPixelShl[1]) >> mPixelShr[1]) & mPixelBitMasks.GreenMask) | 275 (((Uint32 << mPixelShl[2]) >> mPixelShr[2]) & mPixelBitMasks.BlueMask) 276 ); 277 VDEBUG ((EFI_D_INFO, "VideoFill: color=0x%x, wide-fill=0x%x\n", Uint32, WideFill)); 278 279 // 280 // If the size of the pixel data evenly divides the sizeof 281 // WideFill, then a wide fill operation can be used 282 // 283 UseWideFill = TRUE; 284 if ((sizeof (WideFill) % mBltLibBytesPerPixel) == 0) { 285 for (X = mBltLibBytesPerPixel; X < sizeof (WideFill); X++) { 286 ((UINT8*)&WideFill)[X] = ((UINT8*)&WideFill)[X % mBltLibBytesPerPixel]; 287 } 288 } else { 289 // 290 // If all the bytes in the pixel are the same value, then use 291 // a wide fill operation. 292 // 293 for ( 294 X = 1, Uint8 = ((UINT8*)&WideFill)[0]; 295 X < mBltLibBytesPerPixel; 296 X++) { 297 if (Uint8 != ((UINT8*)&WideFill)[X]) { 298 UseWideFill = FALSE; 299 break; 300 } 301 } 302 if (UseWideFill) { 303 SetMem ((VOID*) &WideFill, sizeof (WideFill), Uint8); 304 } 305 } 306 307 if (UseWideFill && (DestinationX == 0) && (Width == mBltLibWidthInPixels)) { 308 VDEBUG ((EFI_D_INFO, "VideoFill (wide, one-shot)\n")); 309 Offset = DestinationY * mBltLibWidthInPixels; 310 Offset = mBltLibBytesPerPixel * Offset; 311 BltMemDst = (VOID*) (mBltLibFrameBuffer + Offset); 312 SizeInBytes = WidthInBytes * Height; 313 if (SizeInBytes >= 8) { 314 SetMem32 (BltMemDst, SizeInBytes & ~3, (UINT32) WideFill); 315 SizeInBytes = SizeInBytes & 3; 316 } 317 if (SizeInBytes > 0) { 318 SetMem (BltMemDst, SizeInBytes, (UINT8)(UINTN) WideFill); 319 } 320 } else { 321 LineBufferReady = FALSE; 322 for (DstY = DestinationY; DstY < (Height + DestinationY); DstY++) { 323 Offset = (DstY * mBltLibWidthInPixels) + DestinationX; 324 Offset = mBltLibBytesPerPixel * Offset; 325 BltMemDst = (VOID*) (mBltLibFrameBuffer + Offset); 326 327 if (UseWideFill && (((UINTN) BltMemDst & 7) == 0)) { 328 VDEBUG ((EFI_D_INFO, "VideoFill (wide)\n")); 329 SizeInBytes = WidthInBytes; 330 if (SizeInBytes >= 8) { 331 SetMem64 (BltMemDst, SizeInBytes & ~7, WideFill); 332 SizeInBytes = SizeInBytes & 7; 333 } 334 if (SizeInBytes > 0) { 335 CopyMem (BltMemDst, (VOID*) &WideFill, SizeInBytes); 336 } 337 } else { 338 VDEBUG ((EFI_D_INFO, "VideoFill (not wide)\n")); 339 if (!LineBufferReady) { 340 CopyMem (mBltLibLineBuffer, &WideFill, mBltLibBytesPerPixel); 341 for (X = 1; X < Width; ) { 342 CopyMem( 343 (mBltLibLineBuffer + (X * mBltLibBytesPerPixel)), 344 mBltLibLineBuffer, 345 MIN (X, Width - X) * mBltLibBytesPerPixel 346 ); 347 X = X + MIN (X, Width - X); 348 } 349 LineBufferReady = TRUE; 350 } 351 CopyMem (BltMemDst, mBltLibLineBuffer, WidthInBytes); 352 } 353 } 354 } 355 356 return EFI_SUCCESS; 357 } 358 359 360 /** 361 Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation. 362 363 @param[out] BltBuffer Output buffer for pixel color data 364 @param[in] SourceX X location within video 365 @param[in] SourceY Y location within video 366 @param[in] Width Width (in pixels) 367 @param[in] Height Height 368 369 @retval EFI_DEVICE_ERROR - A hardware error occured 370 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in 371 @retval EFI_SUCCESS - The sizes were returned 372 373 **/ 374 EFI_STATUS 375 EFIAPI 376 BltLibVideoToBltBuffer ( 377 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, 378 IN UINTN SourceX, 379 IN UINTN SourceY, 380 IN UINTN Width, 381 IN UINTN Height 382 ) 383 { 384 return BltLibVideoToBltBufferEx ( 385 BltBuffer, 386 SourceX, 387 SourceY, 388 0, 389 0, 390 Width, 391 Height, 392 0 393 ); 394 } 395 396 397 /** 398 Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation 399 with extended parameters. 400 401 @param[out] BltBuffer Output buffer for pixel color data 402 @param[in] SourceX X location within video 403 @param[in] SourceY Y location within video 404 @param[in] DestinationX X location within BltBuffer 405 @param[in] DestinationY Y location within BltBuffer 406 @param[in] Width Width (in pixels) 407 @param[in] Height Height 408 @param[in] Delta Number of bytes in a row of BltBuffer 409 410 @retval EFI_DEVICE_ERROR - A hardware error occured 411 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in 412 @retval EFI_SUCCESS - The sizes were returned 413 414 **/ 415 EFI_STATUS 416 EFIAPI 417 BltLibVideoToBltBufferEx ( 418 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, 419 IN UINTN SourceX, 420 IN UINTN SourceY, 421 IN UINTN DestinationX, 422 IN UINTN DestinationY, 423 IN UINTN Width, 424 IN UINTN Height, 425 IN UINTN Delta 426 ) 427 { 428 UINTN DstY; 429 UINTN SrcY; 430 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; 431 VOID *BltMemSrc; 432 VOID *BltMemDst; 433 UINTN X; 434 UINT32 Uint32; 435 UINTN Offset; 436 UINTN WidthInBytes; 437 438 // 439 // Video to BltBuffer: Source is Video, destination is BltBuffer 440 // 441 if (SourceY + Height > mBltLibHeight) { 442 return EFI_INVALID_PARAMETER; 443 } 444 445 if (SourceX + Width > mBltLibWidthInPixels) { 446 return EFI_INVALID_PARAMETER; 447 } 448 449 if (Width == 0 || Height == 0) { 450 return EFI_INVALID_PARAMETER; 451 } 452 453 // 454 // If Delta is zero, then the entire BltBuffer is being used, so Delta 455 // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size, 456 // the number of bytes in each row can be computed. 457 // 458 if (Delta == 0) { 459 Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL); 460 } 461 462 WidthInBytes = Width * mBltLibBytesPerPixel; 463 464 // 465 // Video to BltBuffer: Source is Video, destination is BltBuffer 466 // 467 for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY); SrcY++, DstY++) { 468 469 Offset = (SrcY * mBltLibWidthInPixels) + SourceX; 470 Offset = mBltLibBytesPerPixel * Offset; 471 BltMemSrc = (VOID *) (mBltLibFrameBuffer + Offset); 472 473 if (mPixelFormat == PixelBlueGreenRedReserved8BitPerColor) { 474 BltMemDst = 475 (VOID *) ( 476 (UINT8 *) BltBuffer + 477 (DstY * Delta) + 478 (DestinationX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)) 479 ); 480 } else { 481 BltMemDst = (VOID *) mBltLibLineBuffer; 482 } 483 484 CopyMem (BltMemDst, BltMemSrc, WidthInBytes); 485 486 if (mPixelFormat != PixelBlueGreenRedReserved8BitPerColor) { 487 for (X = 0; X < Width; X++) { 488 Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer + (DstY * Delta) + (DestinationX + X) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); 489 Uint32 = *(UINT32*) (mBltLibLineBuffer + (X * mBltLibBytesPerPixel)); 490 *(UINT32*) Blt = 491 (UINT32) ( 492 (((Uint32 & mPixelBitMasks.RedMask) >> mPixelShl[0]) << mPixelShr[0]) | 493 (((Uint32 & mPixelBitMasks.GreenMask) >> mPixelShl[1]) << mPixelShr[1]) | 494 (((Uint32 & mPixelBitMasks.BlueMask) >> mPixelShl[2]) << mPixelShr[2]) 495 ); 496 } 497 } 498 } 499 500 return EFI_SUCCESS; 501 } 502 503 504 /** 505 Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation. 506 507 @param[in] BltBuffer Output buffer for pixel color data 508 @param[in] DestinationX X location within video 509 @param[in] DestinationY Y location within video 510 @param[in] Width Width (in pixels) 511 @param[in] Height Height 512 513 @retval EFI_DEVICE_ERROR - A hardware error occured 514 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in 515 @retval EFI_SUCCESS - The sizes were returned 516 517 **/ 518 EFI_STATUS 519 EFIAPI 520 BltLibBufferToVideo ( 521 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, 522 IN UINTN DestinationX, 523 IN UINTN DestinationY, 524 IN UINTN Width, 525 IN UINTN Height 526 ) 527 { 528 return BltLibBufferToVideoEx ( 529 BltBuffer, 530 0, 531 0, 532 DestinationX, 533 DestinationY, 534 Width, 535 Height, 536 0 537 ); 538 } 539 540 541 /** 542 Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation 543 with extended parameters. 544 545 @param[in] BltBuffer Output buffer for pixel color data 546 @param[in] SourceX X location within BltBuffer 547 @param[in] SourceY Y location within BltBuffer 548 @param[in] DestinationX X location within video 549 @param[in] DestinationY Y location within video 550 @param[in] Width Width (in pixels) 551 @param[in] Height Height 552 @param[in] Delta Number of bytes in a row of BltBuffer 553 554 @retval EFI_DEVICE_ERROR - A hardware error occured 555 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in 556 @retval EFI_SUCCESS - The sizes were returned 557 558 **/ 559 EFI_STATUS 560 EFIAPI 561 BltLibBufferToVideoEx ( 562 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, 563 IN UINTN SourceX, 564 IN UINTN SourceY, 565 IN UINTN DestinationX, 566 IN UINTN DestinationY, 567 IN UINTN Width, 568 IN UINTN Height, 569 IN UINTN Delta 570 ) 571 { 572 UINTN DstY; 573 UINTN SrcY; 574 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; 575 VOID *BltMemSrc; 576 VOID *BltMemDst; 577 UINTN X; 578 UINT32 Uint32; 579 UINTN Offset; 580 UINTN WidthInBytes; 581 582 // 583 // BltBuffer to Video: Source is BltBuffer, destination is Video 584 // 585 if (DestinationY + Height > mBltLibHeight) { 586 return EFI_INVALID_PARAMETER; 587 } 588 589 if (DestinationX + Width > mBltLibWidthInPixels) { 590 return EFI_INVALID_PARAMETER; 591 } 592 593 if (Width == 0 || Height == 0) { 594 return EFI_INVALID_PARAMETER; 595 } 596 597 // 598 // If Delta is zero, then the entire BltBuffer is being used, so Delta 599 // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size, 600 // the number of bytes in each row can be computed. 601 // 602 if (Delta == 0) { 603 Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL); 604 } 605 606 WidthInBytes = Width * mBltLibBytesPerPixel; 607 608 for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) { 609 610 Offset = (DstY * mBltLibWidthInPixels) + DestinationX; 611 Offset = mBltLibBytesPerPixel * Offset; 612 BltMemDst = (VOID*) (mBltLibFrameBuffer + Offset); 613 614 if (mPixelFormat == PixelBlueGreenRedReserved8BitPerColor) { 615 BltMemSrc = (VOID *) ((UINT8 *) BltBuffer + (SrcY * Delta)); 616 } else { 617 for (X = 0; X < Width; X++) { 618 Blt = 619 (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ( 620 (UINT8 *) BltBuffer + 621 (SrcY * Delta) + 622 ((SourceX + X) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)) 623 ); 624 Uint32 = *(UINT32*) Blt; 625 *(UINT32*) (mBltLibLineBuffer + (X * mBltLibBytesPerPixel)) = 626 (UINT32) ( 627 (((Uint32 << mPixelShl[0]) >> mPixelShr[0]) & mPixelBitMasks.RedMask) | 628 (((Uint32 << mPixelShl[1]) >> mPixelShr[1]) & mPixelBitMasks.GreenMask) | 629 (((Uint32 << mPixelShl[2]) >> mPixelShr[2]) & mPixelBitMasks.BlueMask) 630 ); 631 } 632 BltMemSrc = (VOID *) mBltLibLineBuffer; 633 } 634 635 CopyMem (BltMemDst, BltMemSrc, WidthInBytes); 636 } 637 638 return EFI_SUCCESS; 639 } 640 641 642 /** 643 Performs a UEFI Graphics Output Protocol Blt Video to Video operation 644 645 @param[in] SourceX X location within video 646 @param[in] SourceY Y location within video 647 @param[in] DestinationX X location within video 648 @param[in] DestinationY Y location within video 649 @param[in] Width Width (in pixels) 650 @param[in] Height Height 651 652 @retval EFI_DEVICE_ERROR - A hardware error occured 653 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in 654 @retval EFI_SUCCESS - The sizes were returned 655 656 **/ 657 EFI_STATUS 658 EFIAPI 659 BltLibVideoToVideo ( 660 IN UINTN SourceX, 661 IN UINTN SourceY, 662 IN UINTN DestinationX, 663 IN UINTN DestinationY, 664 IN UINTN Width, 665 IN UINTN Height 666 ) 667 { 668 VOID *BltMemSrc; 669 VOID *BltMemDst; 670 UINTN Offset; 671 UINTN WidthInBytes; 672 INTN LineStride; 673 674 // 675 // Video to Video: Source is Video, destination is Video 676 // 677 if (SourceY + Height > mBltLibHeight) { 678 return EFI_INVALID_PARAMETER; 679 } 680 681 if (SourceX + Width > mBltLibWidthInPixels) { 682 return EFI_INVALID_PARAMETER; 683 } 684 685 if (DestinationY + Height > mBltLibHeight) { 686 return EFI_INVALID_PARAMETER; 687 } 688 689 if (DestinationX + Width > mBltLibWidthInPixels) { 690 return EFI_INVALID_PARAMETER; 691 } 692 693 if (Width == 0 || Height == 0) { 694 return EFI_INVALID_PARAMETER; 695 } 696 697 WidthInBytes = Width * mBltLibBytesPerPixel; 698 699 Offset = (SourceY * mBltLibWidthInPixels) + SourceX; 700 Offset = mBltLibBytesPerPixel * Offset; 701 BltMemSrc = (VOID *) (mBltLibFrameBuffer + Offset); 702 703 Offset = (DestinationY * mBltLibWidthInPixels) + DestinationX; 704 Offset = mBltLibBytesPerPixel * Offset; 705 BltMemDst = (VOID *) (mBltLibFrameBuffer + Offset); 706 707 LineStride = mBltLibWidthInBytes; 708 if ((UINTN) BltMemDst > (UINTN) BltMemSrc) { 709 LineStride = -LineStride; 710 } 711 712 while (Height > 0) { 713 CopyMem (BltMemDst, BltMemSrc, WidthInBytes); 714 715 BltMemSrc = (VOID*) ((UINT8*) BltMemSrc + LineStride); 716 BltMemDst = (VOID*) ((UINT8*) BltMemDst + LineStride); 717 Height--; 718 } 719 720 return EFI_SUCCESS; 721 } 722 723 724 /** 725 Returns the sizes related to the video device 726 727 @param[out] Width Width (in pixels) 728 @param[out] Height Height (in pixels) 729 730 @retval EFI_INVALID_PARAMETER - Invalid parameter passed in 731 @retval EFI_SUCCESS - The sizes were returned 732 733 **/ 734 EFI_STATUS 735 EFIAPI 736 BltLibGetSizes ( 737 OUT UINTN *Width, OPTIONAL 738 OUT UINTN *Height OPTIONAL 739 ) 740 { 741 if (Width != NULL) { 742 *Width = mBltLibWidthInPixels; 743 } 744 if (Height != NULL) { 745 *Height = mBltLibHeight; 746 } 747 748 return EFI_SUCCESS; 749 } 750 751