]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputBlt.c
ARM Packages: Fixed line endings
[mirror_edk2.git] / ArmPlatformPkg / Drivers / LcdGraphicsOutputDxe / LcdGraphicsOutputBlt.c
index 3c267df4dad4294806b4a419b9f4e18747c3b070..e998a195ff6e72c4a64f7676864544e5d9f533ac 100644 (file)
-/** @file
-
- Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>
- This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD License
- which accompanies this distribution.  The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
-
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
- **/
-
-#include <PiDxe.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
-#include <Library/MemoryAllocationLib.h>
-
-#include <Guid/GlobalVariable.h>
-
-#include "LcdGraphicsOutputDxe.h"
-
-extern BOOLEAN mDisplayInitialized;
-
-//
-// Function Definitions
-//
-
-STATIC
-EFI_STATUS
-VideoCopyNoHorizontalOverlap (
-  IN UINTN          BitsPerPixel,
-  IN volatile VOID  *FrameBufferBase,
-  IN UINT32         HorizontalResolution,
-  IN UINTN          SourceX,
-  IN UINTN          SourceY,
-  IN UINTN          DestinationX,
-  IN UINTN          DestinationY,
-  IN UINTN          Width,
-  IN UINTN          Height
-)
-{
-  EFI_STATUS    Status = EFI_SUCCESS;
-  UINTN         SourceLine;
-  UINTN         DestinationLine;
-  UINTN         WidthInBytes;
-  UINTN         LineCount;
-  INTN          Step;
-  VOID          *SourceAddr;
-  VOID          *DestinationAddr;
-
-  if( DestinationY <= SourceY ) {
-    // scrolling up (or horizontally but without overlap)
-    SourceLine       = SourceY;
-    DestinationLine  = DestinationY;
-    Step             = 1;
-  } else {
-    // scrolling down
-    SourceLine       = SourceY + Height;
-    DestinationLine  = DestinationY + Height;
-    Step             = -1;
-  }
-
-  switch (BitsPerPixel) {
-
-  case LCD_BITS_PER_PIXEL_24:
-
-    WidthInBytes = Width * 4;
-
-    for( LineCount = 0; LineCount < Height; LineCount++ ) {
-      // Update the start addresses of source & destination using 32bit pointer arithmetic
-      SourceAddr      = (VOID *)((UINT32 *)FrameBufferBase + SourceLine      * HorizontalResolution + SourceX     );
-      DestinationAddr = (VOID *)((UINT32 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationX);
-
-      // Copy the entire line Y from video ram to the temp buffer
-      CopyMem( DestinationAddr, SourceAddr, WidthInBytes);
-
-      // Update the line numbers
-      SourceLine      += Step;
-      DestinationLine += Step;
-    }
-    break;
-
-  case LCD_BITS_PER_PIXEL_16_555:
-  case LCD_BITS_PER_PIXEL_16_565:
-  case LCD_BITS_PER_PIXEL_12_444:
-
-    WidthInBytes = Width * 2;
-
-    for( LineCount = 0; LineCount < Height; LineCount++ ) {
-      // Update the start addresses of source & destination using 16bit pointer arithmetic
-      SourceAddr      = (VOID *)((UINT16 *)FrameBufferBase + SourceLine      * HorizontalResolution + SourceX     );
-      DestinationAddr = (VOID *)((UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationX);
-
-      // Copy the entire line Y from video ram to the temp buffer
-      CopyMem( DestinationAddr, SourceAddr, WidthInBytes);
-
-      // Update the line numbers
-      SourceLine      += Step;
-      DestinationLine += Step;
-    }
-    break;
-
-  case LCD_BITS_PER_PIXEL_8:
-  case LCD_BITS_PER_PIXEL_4:
-  case LCD_BITS_PER_PIXEL_2:
-  case LCD_BITS_PER_PIXEL_1:
-  default:
-    // Can't handle this case
-    DEBUG((DEBUG_ERROR, "ArmVeGraphics_Blt: EfiBltVideoToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel));
-    Status = EFI_INVALID_PARAMETER;
-    goto EXIT;
-    // break;
-
-  }
-
-  EXIT:
-  return Status;
-}
-
-STATIC
-EFI_STATUS
-VideoCopyHorizontalOverlap (
-  IN UINTN          BitsPerPixel,
-  IN volatile VOID  *FrameBufferBase,
-  UINT32            HorizontalResolution,
-  IN UINTN          SourceX,
-  IN UINTN          SourceY,
-  IN UINTN          DestinationX,
-  IN UINTN          DestinationY,
-  IN UINTN          Width,
-  IN UINTN          Height
-)
-{
-  EFI_STATUS      Status = EFI_SUCCESS;
-
-  UINT32 *PixelBuffer32bit;
-  UINT32 *SourcePixel32bit;
-  UINT32 *DestinationPixel32bit;
-
-  UINT16 *PixelBuffer16bit;
-  UINT16 *SourcePixel16bit;
-  UINT16 *DestinationPixel16bit;
-
-  UINT32          SourcePixelY;
-  UINT32          DestinationPixelY;
-  UINTN           SizeIn32Bits;
-  UINTN           SizeIn16Bits;
-
-  switch (BitsPerPixel) {
-
-  case LCD_BITS_PER_PIXEL_24:
-    // Allocate a temporary buffer
-
-    PixelBuffer32bit = (UINT32 *) AllocatePool((Height * Width) * sizeof(UINT32));
-
-    if (PixelBuffer32bit == NULL) {
-      Status = EFI_OUT_OF_RESOURCES;
-      goto EXIT;
-    }
-
-    SizeIn32Bits = Width * 4;
-
-    // Copy from the video ram (source region) to a temp buffer
-    for (SourcePixelY = SourceY, DestinationPixel32bit = PixelBuffer32bit;
-         SourcePixelY < SourceY + Height;
-         SourcePixelY++, DestinationPixel32bit += Width)
-    {
-      // Update the start address of line Y (source)
-      SourcePixel32bit = (UINT32 *)FrameBufferBase + SourcePixelY * HorizontalResolution + SourceX;
-
-      // Copy the entire line Y from video ram to the temp buffer
-      CopyMem( (VOID *)DestinationPixel32bit, (CONST VOID *)SourcePixel32bit, SizeIn32Bits);
-    }
-
-    // Copy from the temp buffer to the video ram (destination region)
-    for (DestinationPixelY = DestinationY, SourcePixel32bit = PixelBuffer32bit;
-         DestinationPixelY < DestinationY + Height;
-         DestinationPixelY++, SourcePixel32bit += Width)
-    {
-      // Update the start address of line Y (target)
-      DestinationPixel32bit = (UINT32 *)FrameBufferBase + DestinationPixelY * HorizontalResolution + DestinationX;
-
-      // Copy the entire line Y from the temp buffer to video ram
-      CopyMem( (VOID *)DestinationPixel32bit, (CONST VOID *)SourcePixel32bit, SizeIn32Bits);
-    }
-
-    // Free up the allocated memory
-    FreePool((VOID *) PixelBuffer32bit);
-
-    break;
-
-
-  case LCD_BITS_PER_PIXEL_16_555:
-  case LCD_BITS_PER_PIXEL_16_565:
-  case LCD_BITS_PER_PIXEL_12_444:
-    // Allocate a temporary buffer
-    PixelBuffer16bit = (UINT16 *) AllocatePool((Height * Width) * sizeof(UINT16));
-
-    if (PixelBuffer16bit == NULL) {
-      Status = EFI_OUT_OF_RESOURCES;
-      goto EXIT;
-    }
-
-    // Access each pixel inside the source area of the Video Memory and copy it to the temp buffer
-
-    SizeIn16Bits = Width * 2;
-
-    for (SourcePixelY = SourceY, DestinationPixel16bit = PixelBuffer16bit;
-         SourcePixelY < SourceY + Height;
-         SourcePixelY++, DestinationPixel16bit += Width)
-    {
-      // Calculate the source address:
-      SourcePixel16bit = (UINT16 *)FrameBufferBase + SourcePixelY * HorizontalResolution + SourceX;
-
-      // Copy the entire line Y from Video to the temp buffer
-      CopyMem( (VOID *)DestinationPixel16bit, (CONST VOID *)SourcePixel16bit, SizeIn16Bits);
-    }
-
-    // Copy from the temp buffer into the destination area of the Video Memory
-
-    for (DestinationPixelY = DestinationY, SourcePixel16bit = PixelBuffer16bit;
-         DestinationPixelY < DestinationY + Height;
-         DestinationPixelY++, SourcePixel16bit += Width)
-    {
-      // Calculate the target address:
-      DestinationPixel16bit = (UINT16 *)FrameBufferBase + (DestinationPixelY * HorizontalResolution + DestinationX);
-
-      // Copy the entire line Y from the temp buffer to Video
-      CopyMem( (VOID *)DestinationPixel16bit, (CONST VOID *)SourcePixel16bit, SizeIn16Bits);
-    }
-
-    // Free the allocated memory
-    FreePool((VOID *) PixelBuffer16bit);
-
-    break;
-
-
-  case LCD_BITS_PER_PIXEL_8:
-  case LCD_BITS_PER_PIXEL_4:
-  case LCD_BITS_PER_PIXEL_2:
-  case LCD_BITS_PER_PIXEL_1:
-  default:
-    // Can't handle this case
-    DEBUG((DEBUG_ERROR, "ArmVeGraphics_Blt: EfiBltVideoToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel));
-    Status = EFI_INVALID_PARAMETER;
-    goto EXIT;
-    // break;
-
-  }
-
-EXIT:
-  return Status;
-}
-
-STATIC
-EFI_STATUS
-BltVideoFill (
-  IN EFI_GRAPHICS_OUTPUT_PROTOCOL        *This,
-  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *EfiSourcePixel,     OPTIONAL
-  IN UINTN                               SourceX,
-  IN UINTN                               SourceY,
-  IN UINTN                               DestinationX,
-  IN UINTN                               DestinationY,
-  IN UINTN                               Width,
-  IN UINTN                               Height,
-  IN UINTN                               Delta           OPTIONAL   // Number of BYTES in a row of the BltBuffer
-  )
-{
-  EFI_PIXEL_BITMASK*  PixelInformation;
-  EFI_STATUS         Status;
-  UINT32             HorizontalResolution;
-  LCD_BPP            BitsPerPixel;
-  VOID            *FrameBufferBase;
-  VOID            *DestinationAddr;
-  UINT16          *DestinationPixel16bit;
-  UINT16          Pixel16bit;
-  UINT32          DestinationPixelX;
-  UINT32          DestinationLine;
-  UINTN           WidthInBytes;
-
-  Status           = EFI_SUCCESS;
-  PixelInformation = &This->Mode->Info->PixelInformation;
-  FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
-  HorizontalResolution = This->Mode->Info->HorizontalResolution;
-
-  LcdPlatformGetBpp (This->Mode->Mode,&BitsPerPixel);
-
-  switch (BitsPerPixel) {
-  case LCD_BITS_PER_PIXEL_24:
-    WidthInBytes = Width * 4;
-
-    // Copy the SourcePixel into every pixel inside the target rectangle
-    for (DestinationLine = DestinationY;
-         DestinationLine < DestinationY + Height;
-         DestinationLine++)
-    {
-      // Calculate the target address using 32bit pointer arithmetic:
-      DestinationAddr = (VOID *)((UINT32 *)FrameBufferBase + DestinationLine * HorizontalResolution  + DestinationX);
-
-      // Fill the entire line
-      SetMemN( DestinationAddr, WidthInBytes, *((UINTN *)EfiSourcePixel));
-    }
-    break;
-
-  case LCD_BITS_PER_PIXEL_16_555:
-    // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
-    Pixel16bit = (UINT16) (
-        ( (EfiSourcePixel->Red      <<  7) & PixelInformation->RedMask      )
-      | ( (EfiSourcePixel->Green    <<  2) & PixelInformation->GreenMask    )
-      | ( (EfiSourcePixel->Blue     >>  3) & PixelInformation->BlueMask     )
-//      | ( 0                           & PixelInformation->ReservedMask )
-     );
-
-    // Copy the SourcePixel into every pixel inside the target rectangle
-    for (DestinationLine = DestinationY;
-         DestinationLine < DestinationY + Height;
-         DestinationLine++)
-    {
-      for (DestinationPixelX = DestinationX;
-           DestinationPixelX < DestinationX + Width;
-           DestinationPixelX++)
-      {
-        // Calculate the target address:
-        DestinationPixel16bit =  (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX;
-
-        // Copy the pixel into the new target
-        *DestinationPixel16bit = Pixel16bit;
-      }
-    }
-    break;
-
-  case LCD_BITS_PER_PIXEL_16_565:
-    // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
-    Pixel16bit = (UINT16) (
-        ( (EfiSourcePixel->Red      <<  8) & PixelInformation->RedMask      )
-      | ( (EfiSourcePixel->Green    <<  3) & PixelInformation->GreenMask    )
-      | ( (EfiSourcePixel->Blue     >>  3) & PixelInformation->BlueMask     )
-     );
-
-    // Copy the SourcePixel into every pixel inside the target rectangle
-    for (DestinationLine = DestinationY;
-         DestinationLine < DestinationY + Height;
-         DestinationLine++)
-    {
-      for (DestinationPixelX = DestinationX;
-           DestinationPixelX < DestinationX + Width;
-           DestinationPixelX++)
-      {
-        // Calculate the target address:
-        DestinationPixel16bit =  (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution  + DestinationPixelX;
-
-        // Copy the pixel into the new target
-        *DestinationPixel16bit = Pixel16bit;
-      }
-    }
-    break;
-
-  case LCD_BITS_PER_PIXEL_12_444:
-    // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
-    Pixel16bit = (UINT16) (
-        ( (EfiSourcePixel->Red      >> 4) & PixelInformation->RedMask      )
-      | ( (EfiSourcePixel->Green        ) & PixelInformation->GreenMask    )
-      | ( (EfiSourcePixel->Blue     << 4) & PixelInformation->BlueMask     )
-     );
-
-    // Copy the SourcePixel into every pixel inside the target rectangle
-    for (DestinationLine = DestinationY;
-         DestinationLine < DestinationY + Height;
-         DestinationLine++)
-    {
-      for (DestinationPixelX = DestinationX;
-           DestinationPixelX < DestinationX + Width;
-           DestinationPixelX++)
-      {
-        // Calculate the target address:
-        DestinationPixel16bit =  (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution  + DestinationPixelX;
-
-        // Copy the pixel into the new target
-        *DestinationPixel16bit = Pixel16bit;
-      }
-    }
-    break;
-
-  case LCD_BITS_PER_PIXEL_8:
-  case LCD_BITS_PER_PIXEL_4:
-  case LCD_BITS_PER_PIXEL_2:
-  case LCD_BITS_PER_PIXEL_1:
-  default:
-    // Can't handle this case
-    DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: EfiBltVideoFill: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel));
-    Status = EFI_INVALID_PARAMETER;
-    break;
-  }
-
-  return Status;
-}
-
-STATIC
-EFI_STATUS
-BltVideoToBltBuffer (
-  IN EFI_GRAPHICS_OUTPUT_PROTOCOL        *This,
-  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *BltBuffer,     OPTIONAL
-  IN UINTN                               SourceX,
-  IN UINTN                               SourceY,
-  IN UINTN                               DestinationX,
-  IN UINTN                               DestinationY,
-  IN UINTN                               Width,
-  IN UINTN                               Height,
-  IN UINTN                               Delta           OPTIONAL   // Number of BYTES in a row of the BltBuffer
-  )
-{
-  EFI_STATUS         Status;
-  UINT32             HorizontalResolution;
-  LCD_BPP            BitsPerPixel;
-  EFI_PIXEL_BITMASK  *PixelInformation;
-  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *EfiDestinationPixel;
-  VOID   *FrameBufferBase;
-  VOID            *SourceAddr;
-  VOID            *DestinationAddr;
-  UINT16 *SourcePixel16bit;
-  UINT16          Pixel16bit;
-  UINT32          SourcePixelX;
-  UINT32          SourceLine;
-  UINT32          DestinationPixelX;
-  UINT32          DestinationLine;
-  UINT32          BltBufferHorizontalResolution;
-  UINTN           WidthInBytes;
-
-  Status = EFI_SUCCESS;
-  PixelInformation = &This->Mode->Info->PixelInformation;
-  HorizontalResolution = This->Mode->Info->HorizontalResolution;
-  FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
-
-  if(( Delta != 0 ) && ( Delta != Width * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {
-    // Delta is not zero and it is different from the width.
-    // Divide it by the size of a pixel to find out the buffer's horizontal resolution.
-    BltBufferHorizontalResolution = (UINT32) (Delta / sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
-  } else {
-    BltBufferHorizontalResolution = Width;
-  }
-
-  LcdPlatformGetBpp (This->Mode->Mode,&BitsPerPixel);
-
-  switch (BitsPerPixel) {
-  case LCD_BITS_PER_PIXEL_24:
-    WidthInBytes = Width * 4;
-
-    // Access each line inside the Video Memory
-    for (SourceLine = SourceY, DestinationLine = DestinationY;
-         SourceLine < SourceY + Height;
-         SourceLine++, DestinationLine++)
-    {
-      // Calculate the source and target addresses using 32bit pointer arithmetic:
-      SourceAddr      = (VOID *)((UINT32 *)FrameBufferBase + SourceLine      * HorizontalResolution          + SourceX     );
-      DestinationAddr = (VOID *)((UINT32 *)BltBuffer       + DestinationLine * BltBufferHorizontalResolution + DestinationX);
-
-      // Copy the entire line
-      CopyMem( DestinationAddr, SourceAddr, WidthInBytes);
-    }
-    break;
-
-  case LCD_BITS_PER_PIXEL_16_555:
-    // Access each pixel inside the Video Memory
-    for (SourceLine = SourceY, DestinationLine = DestinationY;
-         SourceLine < SourceY + Height;
-         SourceLine++, DestinationLine++)
-    {
-      for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;
-           SourcePixelX < SourceX + Width;
-           SourcePixelX++, DestinationPixelX++)
-      {
-        // Calculate the source and target addresses:
-        SourcePixel16bit = (UINT16 *)FrameBufferBase + SourceLine * HorizontalResolution + SourcePixelX;
-        EfiDestinationPixel = BltBuffer + DestinationLine * BltBufferHorizontalResolution + DestinationPixelX;
-
-        // Snapshot the pixel from the video buffer once, to speed up the operation.
-        // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.
-        Pixel16bit = *SourcePixel16bit;
-
-        // Copy the pixel into the new target
-        EfiDestinationPixel->Red      = (UINT8) ( (Pixel16bit & PixelInformation->RedMask     ) >>  7 );
-        EfiDestinationPixel->Green    = (UINT8) ( (Pixel16bit & PixelInformation->GreenMask   ) >>  2);
-        EfiDestinationPixel->Blue     = (UINT8) ( (Pixel16bit & PixelInformation->BlueMask    ) <<  3 );
-        // EfiDestinationPixel->Reserved = (UINT8) 0;
-      }
-    }
-    break;
-
-  case LCD_BITS_PER_PIXEL_16_565:
-    // Access each pixel inside the Video Memory
-    for (SourceLine = SourceY, DestinationLine = DestinationY;
-         SourceLine < SourceY + Height;
-         SourceLine++, DestinationLine++)
-    {
-      for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;
-           SourcePixelX < SourceX + Width;
-           SourcePixelX++, DestinationPixelX++)
-      {
-        // Calculate the source and target addresses:
-        SourcePixel16bit = (UINT16 *)FrameBufferBase + SourceLine * HorizontalResolution + SourcePixelX;
-        EfiDestinationPixel = BltBuffer + DestinationLine * BltBufferHorizontalResolution + DestinationPixelX;
-
-        // Snapshot the pixel from the video buffer once, to speed up the operation.
-        // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.
-        Pixel16bit = *SourcePixel16bit;
-
-        // Copy the pixel into the new target
-        // There is no info for the Reserved byte, so we set it to zero
-        EfiDestinationPixel->Red      = (UINT8) ( (Pixel16bit & PixelInformation->RedMask     ) >> 8 );
-        EfiDestinationPixel->Green    = (UINT8) ( (Pixel16bit & PixelInformation->GreenMask   ) >> 3);
-        EfiDestinationPixel->Blue     = (UINT8) ( (Pixel16bit & PixelInformation->BlueMask    ) << 3 );
-        // EfiDestinationPixel->Reserved = (UINT8) 0;
-      }
-    }
-    break;
-
-  case LCD_BITS_PER_PIXEL_12_444:
-    // Access each pixel inside the Video Memory
-    for (SourceLine = SourceY, DestinationLine = DestinationY;
-         SourceLine < SourceY + Height;
-         SourceLine++, DestinationLine++)
-    {
-      for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;
-           SourcePixelX < SourceX + Width;
-           SourcePixelX++, DestinationPixelX++)
-      {
-        // Calculate the source and target addresses:
-        SourcePixel16bit = (UINT16 *)FrameBufferBase + SourceLine * HorizontalResolution + SourcePixelX;
-        EfiDestinationPixel = BltBuffer + DestinationLine * BltBufferHorizontalResolution + DestinationPixelX;
-
-        // Snapshot the pixel from the video buffer once, to speed up the operation.
-        // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.
-        Pixel16bit = *SourcePixel16bit;
-
-        // Copy the pixel into the new target
-        EfiDestinationPixel->Red      = (UINT8) ( (Pixel16bit & PixelInformation->RedMask     ) >> 4 );
-        EfiDestinationPixel->Green    = (UINT8) ( (Pixel16bit & PixelInformation->GreenMask   )     );
-        EfiDestinationPixel->Blue     = (UINT8) ( (Pixel16bit & PixelInformation->BlueMask    ) << 4 );
-        // EfiDestinationPixel->Reserved = (UINT8) 0;
-      }
-    }
-    break;
-
-  case LCD_BITS_PER_PIXEL_8:
-  case LCD_BITS_PER_PIXEL_4:
-  case LCD_BITS_PER_PIXEL_2:
-  case LCD_BITS_PER_PIXEL_1:
-  default:
-    // Can't handle this case
-    DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: EfiBltVideoToBltBuffer: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel));
-    Status = EFI_INVALID_PARAMETER;
-    break;
-  }
-  return Status;
-}
-
-STATIC
-EFI_STATUS
-BltBufferToVideo (
-  IN EFI_GRAPHICS_OUTPUT_PROTOCOL        *This,
-  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *BltBuffer,     OPTIONAL
-  IN UINTN                               SourceX,
-  IN UINTN                               SourceY,
-  IN UINTN                               DestinationX,
-  IN UINTN                               DestinationY,
-  IN UINTN                               Width,
-  IN UINTN                               Height,
-  IN UINTN                               Delta           OPTIONAL   // Number of BYTES in a row of the BltBuffer
-  )
-{
-  EFI_STATUS         Status;
-  UINT32             HorizontalResolution;
-  LCD_BPP            BitsPerPixel;
-  EFI_PIXEL_BITMASK  *PixelInformation;
-  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *EfiSourcePixel;
-  VOID   *FrameBufferBase;
-  VOID            *SourceAddr;
-  VOID            *DestinationAddr;
-  UINT16 *DestinationPixel16bit;
-  UINT32          SourcePixelX;
-  UINT32          SourceLine;
-  UINT32          DestinationPixelX;
-  UINT32          DestinationLine;
-  UINT32          BltBufferHorizontalResolution;
-  UINTN           WidthInBytes;
-
-  Status = EFI_SUCCESS;
-  PixelInformation = &This->Mode->Info->PixelInformation;
-  HorizontalResolution = This->Mode->Info->HorizontalResolution;
-  FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
-
-  if(( Delta != 0 ) && ( Delta != Width * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {
-    // Delta is not zero and it is different from the width.
-    // Divide it by the size of a pixel to find out the buffer's horizontal resolution.
-    BltBufferHorizontalResolution = (UINT32) (Delta / sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
-  } else {
-    BltBufferHorizontalResolution = Width;
-  }
-
-  LcdPlatformGetBpp (This->Mode->Mode,&BitsPerPixel);
-
-  switch (BitsPerPixel) {
-  case LCD_BITS_PER_PIXEL_24:
-    WidthInBytes = Width * 4;
-
-    // Access each pixel inside the BltBuffer Memory
-    for (SourceLine = SourceY, DestinationLine = DestinationY;
-       SourceLine < SourceY + Height;
-       SourceLine++, DestinationLine++)
-    {
-      // Calculate the source and target addresses using 32bit pointer arithmetic:
-      SourceAddr      = (VOID *)((UINT32 *)BltBuffer       + SourceLine      * BltBufferHorizontalResolution + SourceX     );
-      DestinationAddr = (VOID *)((UINT32 *)FrameBufferBase + DestinationLine * HorizontalResolution          + DestinationX);
-
-      // Copy the entire row Y
-      CopyMem( DestinationAddr, SourceAddr, WidthInBytes);
-    }
-    break;
-
-  case LCD_BITS_PER_PIXEL_16_555:
-    // Access each pixel inside the BltBuffer Memory
-    for (SourceLine = SourceY, DestinationLine = DestinationY;
-       SourceLine < SourceY + Height;
-       SourceLine++, DestinationLine++) {
-
-      for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;
-           SourcePixelX < SourceX + Width;
-           SourcePixelX++, DestinationPixelX++)
-      {
-        // Calculate the source and target addresses:
-        EfiSourcePixel  = BltBuffer + SourceLine * BltBufferHorizontalResolution + SourcePixelX;
-        DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX;
-
-        // Copy the pixel into the new target
-        // Only the most significant bits will be copied across:
-        // To convert from 8 bits to 5 bits per pixel we throw away the 3 least significant bits
-        *DestinationPixel16bit = (UINT16) (
-              ( (EfiSourcePixel->Red      <<  7) & PixelInformation->RedMask      )
-            | ( (EfiSourcePixel->Green    <<  2) & PixelInformation->GreenMask    )
-            | ( (EfiSourcePixel->Blue     >>  3) & PixelInformation->BlueMask     )
-      //            | ( 0                                & PixelInformation->ReservedMask )
-            );
-      }
-    }
-    break;
-
-  case LCD_BITS_PER_PIXEL_16_565:
-    // Access each pixel inside the BltBuffer Memory
-    for (SourceLine = SourceY, DestinationLine = DestinationY;
-         SourceLine < SourceY + Height;
-         SourceLine++, DestinationLine++) {
-
-      for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;
-           SourcePixelX < SourceX + Width;
-           SourcePixelX++, DestinationPixelX++)
-      {
-        // Calculate the source and target addresses:
-        EfiSourcePixel = BltBuffer + SourceLine * BltBufferHorizontalResolution + SourcePixelX;
-        DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX;
-
-        // Copy the pixel into the new target
-        // Only the most significant bits will be copied across:
-        // To convert from 8 bits to 5 or 6 bits per pixel we throw away the 3 or 2  least significant bits
-        // There is no room for the Reserved byte so we ignore that completely
-        *DestinationPixel16bit = (UINT16) (
-              ( (EfiSourcePixel->Red      <<  8) & PixelInformation->RedMask      )
-            | ( (EfiSourcePixel->Green    <<  3) & PixelInformation->GreenMask    )
-            | ( (EfiSourcePixel->Blue     >>  3) & PixelInformation->BlueMask     )
-           );
-      }
-    }
-    break;
-
-  case LCD_BITS_PER_PIXEL_12_444:
-    // Access each pixel inside the BltBuffer Memory
-    for (SourceLine = SourceY, DestinationLine = DestinationY;
-         SourceLine < SourceY + Height;
-         SourceLine++, DestinationLine++) {
-
-      for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;
-           SourcePixelX < SourceX + Width;
-           SourcePixelX++, DestinationPixelX++)
-      {
-        // Calculate the source and target addresses:
-        EfiSourcePixel = BltBuffer + SourceLine * BltBufferHorizontalResolution + SourcePixelX;
-        DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX;
-
-        // Copy the pixel into the new target
-        // Only the most significant bits will be copied across:
-        // To convert from 8 bits to 5 bits per pixel we throw away the 3 least significant bits
-        *DestinationPixel16bit = (UINT16) (
-              ( (EfiSourcePixel->Red      << 4) & PixelInformation->RedMask      )
-            | ( (EfiSourcePixel->Green        ) & PixelInformation->GreenMask    )
-            | ( (EfiSourcePixel->Blue     >> 4) & PixelInformation->BlueMask     )
-  //            | ( 0                               & PixelInformation->ReservedMask )
-           );
-      }
-    }
-    break;
-
-  case LCD_BITS_PER_PIXEL_8:
-  case LCD_BITS_PER_PIXEL_4:
-  case LCD_BITS_PER_PIXEL_2:
-  case LCD_BITS_PER_PIXEL_1:
-  default:
-    // Can't handle this case
-    DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: EfiBltBufferToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel));
-    Status = EFI_INVALID_PARAMETER;
-    break;
-  }
-  return Status;
-}
-
-STATIC
-EFI_STATUS
-BltVideoToVideo (
-  IN EFI_GRAPHICS_OUTPUT_PROTOCOL        *This,
-  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *BltBuffer,     OPTIONAL
-  IN UINTN                               SourceX,
-  IN UINTN                               SourceY,
-  IN UINTN                               DestinationX,
-  IN UINTN                               DestinationY,
-  IN UINTN                               Width,
-  IN UINTN                               Height,
-  IN UINTN                               Delta           OPTIONAL   // Number of BYTES in a row of the BltBuffer
-  )
-{
-  EFI_STATUS         Status;
-  UINT32             HorizontalResolution;
-  LCD_BPP            BitsPerPixel;
-  VOID   *FrameBufferBase;
-
-  HorizontalResolution = This->Mode->Info->HorizontalResolution;
-  FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
-
-  //
-  // BltVideo to BltVideo:
-  //
-  //  Source is the Video Memory,
-  //  Destination is the Video Memory
-
-  LcdPlatformGetBpp (This->Mode->Mode,&BitsPerPixel);
-  FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
-
-  // The UEFI spec currently states:
-  // "There is no limitation on the overlapping of the source and destination rectangles"
-  // Therefore, we must be careful to avoid overwriting the source data
-  if( SourceY == DestinationY ) {
-    // Copying within the same height, e.g. horizontal shift
-    if( SourceX == DestinationX ) {
-      // Nothing to do
-      Status = EFI_SUCCESS;
-    } else if( ((SourceX>DestinationX)?(SourceX - DestinationX):(DestinationX - SourceX)) < Width ) {
-      // There is overlap
-      Status = VideoCopyHorizontalOverlap (BitsPerPixel, FrameBufferBase, HorizontalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height );
-    } else {
-      // No overlap
-      Status = VideoCopyNoHorizontalOverlap (BitsPerPixel, FrameBufferBase, HorizontalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height );
-    }
-  } else {
-    // Copying from different heights
-    Status = VideoCopyNoHorizontalOverlap (BitsPerPixel, FrameBufferBase, HorizontalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height );
-  }
-
-  return Status;
-}
-
-/***************************************
- * GraphicsOutput Protocol function, mapping to
- * EFI_GRAPHICS_OUTPUT_PROTOCOL.Blt
- *
- * PRESUMES: 1 pixel = 4 bytes (32bits)
- *  ***************************************/
-EFI_STATUS
-EFIAPI
-LcdGraphicsBlt (
-  IN EFI_GRAPHICS_OUTPUT_PROTOCOL        *This,
-       IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *BltBuffer,     OPTIONAL
-       IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION   BltOperation,
-       IN UINTN                               SourceX,
-       IN UINTN                               SourceY,
-       IN UINTN                               DestinationX,
-       IN UINTN                               DestinationY,
-       IN UINTN                               Width,
-       IN UINTN                               Height,
-       IN UINTN                               Delta           OPTIONAL   // Number of BYTES in a row of the BltBuffer
-  )
-{
-       EFI_STATUS         Status;
-       UINT32             HorizontalResolution;
-  UINT32             VerticalResolution;
-       LCD_INSTANCE*      Instance;
-
-  Instance = LCD_INSTANCE_FROM_GOP_THIS(This);
-
-  // Setup the hardware if not already done
-  if (!mDisplayInitialized) {
-    Status = InitializeDisplay (Instance);
-    if (EFI_ERROR(Status)) {
-      goto EXIT;
-    }
-  }
-
-  HorizontalResolution = This->Mode->Info->HorizontalResolution;
-  VerticalResolution   = This->Mode->Info->VerticalResolution;
-
-  DEBUG((DEBUG_INFO, "LcdGraphicsBlt (BltOperation:%d,DestX:%d,DestY:%d,Width:%d,Height:%d) res(%d,%d)\n",
-      BltOperation,DestinationX,DestinationY,Width,Height,HorizontalResolution,VerticalResolution));
-
-  // Check we have reasonable parameters
-       if (Width == 0 || Height == 0) {
-    DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: ERROR - Invalid dimension: Zero size area.\n" ));
-               Status = EFI_INVALID_PARAMETER;
-               goto EXIT;
-       }
-
-       if ((BltOperation == EfiBltVideoFill) || (BltOperation == EfiBltBufferToVideo) || (BltOperation == EfiBltVideoToBltBuffer)) {
-         ASSERT( BltBuffer != NULL);
-       }
-
-       /*if ((DestinationX >= HorizontalResolution) || (DestinationY >= VerticalResolution)) {
-         DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: ERROR - Invalid destination.\n" ));
-         Status = EFI_INVALID_PARAMETER;
-         goto EXIT;
-       }*/
-
-       // If we are reading data out of the video buffer, check that the source area is within the display limits
-       if ((BltOperation == EfiBltVideoToBltBuffer) || (BltOperation == EfiBltVideoToVideo)) {
-    if ((SourceY + Height > VerticalResolution) || (SourceX + Width > HorizontalResolution)) {
-      DEBUG((DEBUG_INFO, "LcdGraphicsBlt: ERROR - Invalid source resolution.\n" ));
-      DEBUG((DEBUG_INFO, "                      - SourceY=%d + Height=%d > VerticalResolution=%d.\n", SourceY, Height, VerticalResolution ));
-      DEBUG((DEBUG_INFO, "                      - SourceX=%d + Width=%d > HorizontalResolution=%d.\n", SourceX, Width, HorizontalResolution ));
-      Status = EFI_INVALID_PARAMETER;
-      goto EXIT;
-    }
-       }
-
-       // If we are writing data into the video buffer, that the destination area is within the display limits
-       if ((BltOperation == EfiBltVideoFill) || (BltOperation == EfiBltBufferToVideo) || (BltOperation == EfiBltVideoToVideo)) {
-    if ((DestinationY + Height > VerticalResolution) || (DestinationX + Width > HorizontalResolution)) {
-      DEBUG((DEBUG_INFO, "LcdGraphicsBlt: ERROR - Invalid destination resolution.\n" ));
-      DEBUG((DEBUG_INFO, "                      - DestinationY=%d + Height=%d > VerticalResolution=%d.\n", DestinationY, Height, VerticalResolution ));
-      DEBUG((DEBUG_INFO, "                      - DestinationX=%d + Width=%d > HorizontalResolution=%d.\n", DestinationX, Width, HorizontalResolution ));
-      Status = EFI_INVALID_PARAMETER;
-      goto EXIT;
-    }
-       }
-
-  //
-  // Perform the Block Transfer Operation
-  //
-
-       switch (BltOperation) {
-       case EfiBltVideoFill:
-         Status = BltVideoFill (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);
-               break;
-
-       case EfiBltVideoToBltBuffer:
-         Status = BltVideoToBltBuffer (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);
-    break;
-
-  case EfiBltBufferToVideo:
-    Status = BltBufferToVideo (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);
-               break;
-
-       case EfiBltVideoToVideo:
-         Status = BltVideoToVideo (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);
-               break;
-
-       case EfiGraphicsOutputBltOperationMax:
-       default:
-               DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: Invalid Operation\n"));
-               Status = EFI_INVALID_PARAMETER;
-               break;
-       }
-
-EXIT:
-       return Status;
-}
+/** @file\r
+\r
+ Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution.  The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ **/\r
+\r
+#include <PiDxe.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+\r
+#include <Guid/GlobalVariable.h>\r
+\r
+#include "LcdGraphicsOutputDxe.h"\r
+\r
+extern BOOLEAN mDisplayInitialized;\r
+\r
+//\r
+// Function Definitions\r
+//\r
+\r
+STATIC\r
+EFI_STATUS\r
+VideoCopyNoHorizontalOverlap (\r
+  IN UINTN          BitsPerPixel,\r
+  IN volatile VOID  *FrameBufferBase,\r
+  IN UINT32         HorizontalResolution,\r
+  IN UINTN          SourceX,\r
+  IN UINTN          SourceY,\r
+  IN UINTN          DestinationX,\r
+  IN UINTN          DestinationY,\r
+  IN UINTN          Width,\r
+  IN UINTN          Height\r
+)\r
+{\r
+  EFI_STATUS    Status = EFI_SUCCESS;\r
+  UINTN         SourceLine;\r
+  UINTN         DestinationLine;\r
+  UINTN         WidthInBytes;\r
+  UINTN         LineCount;\r
+  INTN          Step;\r
+  VOID          *SourceAddr;\r
+  VOID          *DestinationAddr;\r
+\r
+  if( DestinationY <= SourceY ) {\r
+    // scrolling up (or horizontally but without overlap)\r
+    SourceLine       = SourceY;\r
+    DestinationLine  = DestinationY;\r
+    Step             = 1;\r
+  } else {\r
+    // scrolling down\r
+    SourceLine       = SourceY + Height;\r
+    DestinationLine  = DestinationY + Height;\r
+    Step             = -1;\r
+  }\r
+\r
+  switch (BitsPerPixel) {\r
+\r
+  case LCD_BITS_PER_PIXEL_24:\r
+\r
+    WidthInBytes = Width * 4;\r
+\r
+    for( LineCount = 0; LineCount < Height; LineCount++ ) {\r
+      // Update the start addresses of source & destination using 32bit pointer arithmetic\r
+      SourceAddr      = (VOID *)((UINT32 *)FrameBufferBase + SourceLine      * HorizontalResolution + SourceX     );\r
+      DestinationAddr = (VOID *)((UINT32 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationX);\r
+\r
+      // Copy the entire line Y from video ram to the temp buffer\r
+      CopyMem( DestinationAddr, SourceAddr, WidthInBytes);\r
+\r
+      // Update the line numbers\r
+      SourceLine      += Step;\r
+      DestinationLine += Step;\r
+    }\r
+    break;\r
+\r
+  case LCD_BITS_PER_PIXEL_16_555:\r
+  case LCD_BITS_PER_PIXEL_16_565:\r
+  case LCD_BITS_PER_PIXEL_12_444:\r
+\r
+    WidthInBytes = Width * 2;\r
+\r
+    for( LineCount = 0; LineCount < Height; LineCount++ ) {\r
+      // Update the start addresses of source & destination using 16bit pointer arithmetic\r
+      SourceAddr      = (VOID *)((UINT16 *)FrameBufferBase + SourceLine      * HorizontalResolution + SourceX     );\r
+      DestinationAddr = (VOID *)((UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationX);\r
+\r
+      // Copy the entire line Y from video ram to the temp buffer\r
+      CopyMem( DestinationAddr, SourceAddr, WidthInBytes);\r
+\r
+      // Update the line numbers\r
+      SourceLine      += Step;\r
+      DestinationLine += Step;\r
+    }\r
+    break;\r
+\r
+  case LCD_BITS_PER_PIXEL_8:\r
+  case LCD_BITS_PER_PIXEL_4:\r
+  case LCD_BITS_PER_PIXEL_2:\r
+  case LCD_BITS_PER_PIXEL_1:\r
+  default:\r
+    // Can't handle this case\r
+    DEBUG((DEBUG_ERROR, "ArmVeGraphics_Blt: EfiBltVideoToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel));\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto EXIT;\r
+    // break;\r
+\r
+  }\r
+\r
+  EXIT:\r
+  return Status;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+VideoCopyHorizontalOverlap (\r
+  IN UINTN          BitsPerPixel,\r
+  IN volatile VOID  *FrameBufferBase,\r
+  UINT32            HorizontalResolution,\r
+  IN UINTN          SourceX,\r
+  IN UINTN          SourceY,\r
+  IN UINTN          DestinationX,\r
+  IN UINTN          DestinationY,\r
+  IN UINTN          Width,\r
+  IN UINTN          Height\r
+)\r
+{\r
+  EFI_STATUS      Status = EFI_SUCCESS;\r
+\r
+  UINT32 *PixelBuffer32bit;\r
+  UINT32 *SourcePixel32bit;\r
+  UINT32 *DestinationPixel32bit;\r
+\r
+  UINT16 *PixelBuffer16bit;\r
+  UINT16 *SourcePixel16bit;\r
+  UINT16 *DestinationPixel16bit;\r
+\r
+  UINT32          SourcePixelY;\r
+  UINT32          DestinationPixelY;\r
+  UINTN           SizeIn32Bits;\r
+  UINTN           SizeIn16Bits;\r
+\r
+  switch (BitsPerPixel) {\r
+\r
+  case LCD_BITS_PER_PIXEL_24:\r
+    // Allocate a temporary buffer\r
+\r
+    PixelBuffer32bit = (UINT32 *) AllocatePool((Height * Width) * sizeof(UINT32));\r
+\r
+    if (PixelBuffer32bit == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto EXIT;\r
+    }\r
+\r
+    SizeIn32Bits = Width * 4;\r
+\r
+    // Copy from the video ram (source region) to a temp buffer\r
+    for (SourcePixelY = SourceY, DestinationPixel32bit = PixelBuffer32bit;\r
+         SourcePixelY < SourceY + Height;\r
+         SourcePixelY++, DestinationPixel32bit += Width)\r
+    {\r
+      // Update the start address of line Y (source)\r
+      SourcePixel32bit = (UINT32 *)FrameBufferBase + SourcePixelY * HorizontalResolution + SourceX;\r
+\r
+      // Copy the entire line Y from video ram to the temp buffer\r
+      CopyMem( (VOID *)DestinationPixel32bit, (CONST VOID *)SourcePixel32bit, SizeIn32Bits);\r
+    }\r
+\r
+    // Copy from the temp buffer to the video ram (destination region)\r
+    for (DestinationPixelY = DestinationY, SourcePixel32bit = PixelBuffer32bit;\r
+         DestinationPixelY < DestinationY + Height;\r
+         DestinationPixelY++, SourcePixel32bit += Width)\r
+    {\r
+      // Update the start address of line Y (target)\r
+      DestinationPixel32bit = (UINT32 *)FrameBufferBase + DestinationPixelY * HorizontalResolution + DestinationX;\r
+\r
+      // Copy the entire line Y from the temp buffer to video ram\r
+      CopyMem( (VOID *)DestinationPixel32bit, (CONST VOID *)SourcePixel32bit, SizeIn32Bits);\r
+    }\r
+\r
+    // Free up the allocated memory\r
+    FreePool((VOID *) PixelBuffer32bit);\r
+\r
+    break;\r
+\r
+\r
+  case LCD_BITS_PER_PIXEL_16_555:\r
+  case LCD_BITS_PER_PIXEL_16_565:\r
+  case LCD_BITS_PER_PIXEL_12_444:\r
+    // Allocate a temporary buffer\r
+    PixelBuffer16bit = (UINT16 *) AllocatePool((Height * Width) * sizeof(UINT16));\r
+\r
+    if (PixelBuffer16bit == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto EXIT;\r
+    }\r
+\r
+    // Access each pixel inside the source area of the Video Memory and copy it to the temp buffer\r
+\r
+    SizeIn16Bits = Width * 2;\r
+\r
+    for (SourcePixelY = SourceY, DestinationPixel16bit = PixelBuffer16bit;\r
+         SourcePixelY < SourceY + Height;\r
+         SourcePixelY++, DestinationPixel16bit += Width)\r
+    {\r
+      // Calculate the source address:\r
+      SourcePixel16bit = (UINT16 *)FrameBufferBase + SourcePixelY * HorizontalResolution + SourceX;\r
+\r
+      // Copy the entire line Y from Video to the temp buffer\r
+      CopyMem( (VOID *)DestinationPixel16bit, (CONST VOID *)SourcePixel16bit, SizeIn16Bits);\r
+    }\r
+\r
+    // Copy from the temp buffer into the destination area of the Video Memory\r
+\r
+    for (DestinationPixelY = DestinationY, SourcePixel16bit = PixelBuffer16bit;\r
+         DestinationPixelY < DestinationY + Height;\r
+         DestinationPixelY++, SourcePixel16bit += Width)\r
+    {\r
+      // Calculate the target address:\r
+      DestinationPixel16bit = (UINT16 *)FrameBufferBase + (DestinationPixelY * HorizontalResolution + DestinationX);\r
+\r
+      // Copy the entire line Y from the temp buffer to Video\r
+      CopyMem( (VOID *)DestinationPixel16bit, (CONST VOID *)SourcePixel16bit, SizeIn16Bits);\r
+    }\r
+\r
+    // Free the allocated memory\r
+    FreePool((VOID *) PixelBuffer16bit);\r
+\r
+    break;\r
+\r
+\r
+  case LCD_BITS_PER_PIXEL_8:\r
+  case LCD_BITS_PER_PIXEL_4:\r
+  case LCD_BITS_PER_PIXEL_2:\r
+  case LCD_BITS_PER_PIXEL_1:\r
+  default:\r
+    // Can't handle this case\r
+    DEBUG((DEBUG_ERROR, "ArmVeGraphics_Blt: EfiBltVideoToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel));\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto EXIT;\r
+    // break;\r
+\r
+  }\r
+\r
+EXIT:\r
+  return Status;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+BltVideoFill (\r
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL        *This,\r
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *EfiSourcePixel,     OPTIONAL\r
+  IN UINTN                               SourceX,\r
+  IN UINTN                               SourceY,\r
+  IN UINTN                               DestinationX,\r
+  IN UINTN                               DestinationY,\r
+  IN UINTN                               Width,\r
+  IN UINTN                               Height,\r
+  IN UINTN                               Delta           OPTIONAL   // Number of BYTES in a row of the BltBuffer\r
+  )\r
+{\r
+  EFI_PIXEL_BITMASK*  PixelInformation;\r
+  EFI_STATUS         Status;\r
+  UINT32             HorizontalResolution;\r
+  LCD_BPP            BitsPerPixel;\r
+  VOID            *FrameBufferBase;\r
+  VOID            *DestinationAddr;\r
+  UINT16          *DestinationPixel16bit;\r
+  UINT16          Pixel16bit;\r
+  UINT32          DestinationPixelX;\r
+  UINT32          DestinationLine;\r
+  UINTN           WidthInBytes;\r
+\r
+  Status           = EFI_SUCCESS;\r
+  PixelInformation = &This->Mode->Info->PixelInformation;\r
+  FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));\r
+  HorizontalResolution = This->Mode->Info->HorizontalResolution;\r
+\r
+  LcdPlatformGetBpp (This->Mode->Mode,&BitsPerPixel);\r
+\r
+  switch (BitsPerPixel) {\r
+  case LCD_BITS_PER_PIXEL_24:\r
+    WidthInBytes = Width * 4;\r
+\r
+    // Copy the SourcePixel into every pixel inside the target rectangle\r
+    for (DestinationLine = DestinationY;\r
+         DestinationLine < DestinationY + Height;\r
+         DestinationLine++)\r
+    {\r
+      // Calculate the target address using 32bit pointer arithmetic:\r
+      DestinationAddr = (VOID *)((UINT32 *)FrameBufferBase + DestinationLine * HorizontalResolution  + DestinationX);\r
+\r
+      // Fill the entire line\r
+      SetMemN( DestinationAddr, WidthInBytes, *((UINTN *)EfiSourcePixel));\r
+    }\r
+    break;\r
+\r
+  case LCD_BITS_PER_PIXEL_16_555:\r
+    // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel\r
+    Pixel16bit = (UINT16) (\r
+        ( (EfiSourcePixel->Red      <<  7) & PixelInformation->RedMask      )\r
+      | ( (EfiSourcePixel->Green    <<  2) & PixelInformation->GreenMask    )\r
+      | ( (EfiSourcePixel->Blue     >>  3) & PixelInformation->BlueMask     )\r
+//      | ( 0                           & PixelInformation->ReservedMask )\r
+     );\r
+\r
+    // Copy the SourcePixel into every pixel inside the target rectangle\r
+    for (DestinationLine = DestinationY;\r
+         DestinationLine < DestinationY + Height;\r
+         DestinationLine++)\r
+    {\r
+      for (DestinationPixelX = DestinationX;\r
+           DestinationPixelX < DestinationX + Width;\r
+           DestinationPixelX++)\r
+      {\r
+        // Calculate the target address:\r
+        DestinationPixel16bit =  (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX;\r
+\r
+        // Copy the pixel into the new target\r
+        *DestinationPixel16bit = Pixel16bit;\r
+      }\r
+    }\r
+    break;\r
+\r
+  case LCD_BITS_PER_PIXEL_16_565:\r
+    // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel\r
+    Pixel16bit = (UINT16) (\r
+        ( (EfiSourcePixel->Red      <<  8) & PixelInformation->RedMask      )\r
+      | ( (EfiSourcePixel->Green    <<  3) & PixelInformation->GreenMask    )\r
+      | ( (EfiSourcePixel->Blue     >>  3) & PixelInformation->BlueMask     )\r
+     );\r
+\r
+    // Copy the SourcePixel into every pixel inside the target rectangle\r
+    for (DestinationLine = DestinationY;\r
+         DestinationLine < DestinationY + Height;\r
+         DestinationLine++)\r
+    {\r
+      for (DestinationPixelX = DestinationX;\r
+           DestinationPixelX < DestinationX + Width;\r
+           DestinationPixelX++)\r
+      {\r
+        // Calculate the target address:\r
+        DestinationPixel16bit =  (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution  + DestinationPixelX;\r
+\r
+        // Copy the pixel into the new target\r
+        *DestinationPixel16bit = Pixel16bit;\r
+      }\r
+    }\r
+    break;\r
+\r
+  case LCD_BITS_PER_PIXEL_12_444:\r
+    // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel\r
+    Pixel16bit = (UINT16) (\r
+        ( (EfiSourcePixel->Red      >> 4) & PixelInformation->RedMask      )\r
+      | ( (EfiSourcePixel->Green        ) & PixelInformation->GreenMask    )\r
+      | ( (EfiSourcePixel->Blue     << 4) & PixelInformation->BlueMask     )\r
+     );\r
+\r
+    // Copy the SourcePixel into every pixel inside the target rectangle\r
+    for (DestinationLine = DestinationY;\r
+         DestinationLine < DestinationY + Height;\r
+         DestinationLine++)\r
+    {\r
+      for (DestinationPixelX = DestinationX;\r
+           DestinationPixelX < DestinationX + Width;\r
+           DestinationPixelX++)\r
+      {\r
+        // Calculate the target address:\r
+        DestinationPixel16bit =  (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution  + DestinationPixelX;\r
+\r
+        // Copy the pixel into the new target\r
+        *DestinationPixel16bit = Pixel16bit;\r
+      }\r
+    }\r
+    break;\r
+\r
+  case LCD_BITS_PER_PIXEL_8:\r
+  case LCD_BITS_PER_PIXEL_4:\r
+  case LCD_BITS_PER_PIXEL_2:\r
+  case LCD_BITS_PER_PIXEL_1:\r
+  default:\r
+    // Can't handle this case\r
+    DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: EfiBltVideoFill: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel));\r
+    Status = EFI_INVALID_PARAMETER;\r
+    break;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+BltVideoToBltBuffer (\r
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL        *This,\r
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *BltBuffer,     OPTIONAL\r
+  IN UINTN                               SourceX,\r
+  IN UINTN                               SourceY,\r
+  IN UINTN                               DestinationX,\r
+  IN UINTN                               DestinationY,\r
+  IN UINTN                               Width,\r
+  IN UINTN                               Height,\r
+  IN UINTN                               Delta           OPTIONAL   // Number of BYTES in a row of the BltBuffer\r
+  )\r
+{\r
+  EFI_STATUS         Status;\r
+  UINT32             HorizontalResolution;\r
+  LCD_BPP            BitsPerPixel;\r
+  EFI_PIXEL_BITMASK  *PixelInformation;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *EfiDestinationPixel;\r
+  VOID   *FrameBufferBase;\r
+  VOID            *SourceAddr;\r
+  VOID            *DestinationAddr;\r
+  UINT16 *SourcePixel16bit;\r
+  UINT16          Pixel16bit;\r
+  UINT32          SourcePixelX;\r
+  UINT32          SourceLine;\r
+  UINT32          DestinationPixelX;\r
+  UINT32          DestinationLine;\r
+  UINT32          BltBufferHorizontalResolution;\r
+  UINTN           WidthInBytes;\r
+\r
+  Status = EFI_SUCCESS;\r
+  PixelInformation = &This->Mode->Info->PixelInformation;\r
+  HorizontalResolution = This->Mode->Info->HorizontalResolution;\r
+  FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));\r
+\r
+  if(( Delta != 0 ) && ( Delta != Width * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {\r
+    // Delta is not zero and it is different from the width.\r
+    // Divide it by the size of a pixel to find out the buffer's horizontal resolution.\r
+    BltBufferHorizontalResolution = (UINT32) (Delta / sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+  } else {\r
+    BltBufferHorizontalResolution = Width;\r
+  }\r
+\r
+  LcdPlatformGetBpp (This->Mode->Mode,&BitsPerPixel);\r
+\r
+  switch (BitsPerPixel) {\r
+  case LCD_BITS_PER_PIXEL_24:\r
+    WidthInBytes = Width * 4;\r
+\r
+    // Access each line inside the Video Memory\r
+    for (SourceLine = SourceY, DestinationLine = DestinationY;\r
+         SourceLine < SourceY + Height;\r
+         SourceLine++, DestinationLine++)\r
+    {\r
+      // Calculate the source and target addresses using 32bit pointer arithmetic:\r
+      SourceAddr      = (VOID *)((UINT32 *)FrameBufferBase + SourceLine      * HorizontalResolution          + SourceX     );\r
+      DestinationAddr = (VOID *)((UINT32 *)BltBuffer       + DestinationLine * BltBufferHorizontalResolution + DestinationX);\r
+\r
+      // Copy the entire line\r
+      CopyMem( DestinationAddr, SourceAddr, WidthInBytes);\r
+    }\r
+    break;\r
+\r
+  case LCD_BITS_PER_PIXEL_16_555:\r
+    // Access each pixel inside the Video Memory\r
+    for (SourceLine = SourceY, DestinationLine = DestinationY;\r
+         SourceLine < SourceY + Height;\r
+         SourceLine++, DestinationLine++)\r
+    {\r
+      for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;\r
+           SourcePixelX < SourceX + Width;\r
+           SourcePixelX++, DestinationPixelX++)\r
+      {\r
+        // Calculate the source and target addresses:\r
+        SourcePixel16bit = (UINT16 *)FrameBufferBase + SourceLine * HorizontalResolution + SourcePixelX;\r
+        EfiDestinationPixel = BltBuffer + DestinationLine * BltBufferHorizontalResolution + DestinationPixelX;\r
+\r
+        // Snapshot the pixel from the video buffer once, to speed up the operation.\r
+        // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.\r
+        Pixel16bit = *SourcePixel16bit;\r
+\r
+        // Copy the pixel into the new target\r
+        EfiDestinationPixel->Red      = (UINT8) ( (Pixel16bit & PixelInformation->RedMask     ) >>  7 );\r
+        EfiDestinationPixel->Green    = (UINT8) ( (Pixel16bit & PixelInformation->GreenMask   ) >>  2);\r
+        EfiDestinationPixel->Blue     = (UINT8) ( (Pixel16bit & PixelInformation->BlueMask    ) <<  3 );\r
+        // EfiDestinationPixel->Reserved = (UINT8) 0;\r
+      }\r
+    }\r
+    break;\r
+\r
+  case LCD_BITS_PER_PIXEL_16_565:\r
+    // Access each pixel inside the Video Memory\r
+    for (SourceLine = SourceY, DestinationLine = DestinationY;\r
+         SourceLine < SourceY + Height;\r
+         SourceLine++, DestinationLine++)\r
+    {\r
+      for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;\r
+           SourcePixelX < SourceX + Width;\r
+           SourcePixelX++, DestinationPixelX++)\r
+      {\r
+        // Calculate the source and target addresses:\r
+        SourcePixel16bit = (UINT16 *)FrameBufferBase + SourceLine * HorizontalResolution + SourcePixelX;\r
+        EfiDestinationPixel = BltBuffer + DestinationLine * BltBufferHorizontalResolution + DestinationPixelX;\r
+\r
+        // Snapshot the pixel from the video buffer once, to speed up the operation.\r
+        // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.\r
+        Pixel16bit = *SourcePixel16bit;\r
+\r
+        // Copy the pixel into the new target\r
+        // There is no info for the Reserved byte, so we set it to zero\r
+        EfiDestinationPixel->Red      = (UINT8) ( (Pixel16bit & PixelInformation->RedMask     ) >> 8 );\r
+        EfiDestinationPixel->Green    = (UINT8) ( (Pixel16bit & PixelInformation->GreenMask   ) >> 3);\r
+        EfiDestinationPixel->Blue     = (UINT8) ( (Pixel16bit & PixelInformation->BlueMask    ) << 3 );\r
+        // EfiDestinationPixel->Reserved = (UINT8) 0;\r
+      }\r
+    }\r
+    break;\r
+\r
+  case LCD_BITS_PER_PIXEL_12_444:\r
+    // Access each pixel inside the Video Memory\r
+    for (SourceLine = SourceY, DestinationLine = DestinationY;\r
+         SourceLine < SourceY + Height;\r
+         SourceLine++, DestinationLine++)\r
+    {\r
+      for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;\r
+           SourcePixelX < SourceX + Width;\r
+           SourcePixelX++, DestinationPixelX++)\r
+      {\r
+        // Calculate the source and target addresses:\r
+        SourcePixel16bit = (UINT16 *)FrameBufferBase + SourceLine * HorizontalResolution + SourcePixelX;\r
+        EfiDestinationPixel = BltBuffer + DestinationLine * BltBufferHorizontalResolution + DestinationPixelX;\r
+\r
+        // Snapshot the pixel from the video buffer once, to speed up the operation.\r
+        // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.\r
+        Pixel16bit = *SourcePixel16bit;\r
+\r
+        // Copy the pixel into the new target\r
+        EfiDestinationPixel->Red      = (UINT8) ( (Pixel16bit & PixelInformation->RedMask     ) >> 4 );\r
+        EfiDestinationPixel->Green    = (UINT8) ( (Pixel16bit & PixelInformation->GreenMask   )     );\r
+        EfiDestinationPixel->Blue     = (UINT8) ( (Pixel16bit & PixelInformation->BlueMask    ) << 4 );\r
+        // EfiDestinationPixel->Reserved = (UINT8) 0;\r
+      }\r
+    }\r
+    break;\r
+\r
+  case LCD_BITS_PER_PIXEL_8:\r
+  case LCD_BITS_PER_PIXEL_4:\r
+  case LCD_BITS_PER_PIXEL_2:\r
+  case LCD_BITS_PER_PIXEL_1:\r
+  default:\r
+    // Can't handle this case\r
+    DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: EfiBltVideoToBltBuffer: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel));\r
+    Status = EFI_INVALID_PARAMETER;\r
+    break;\r
+  }\r
+  return Status;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+BltBufferToVideo (\r
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL        *This,\r
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *BltBuffer,     OPTIONAL\r
+  IN UINTN                               SourceX,\r
+  IN UINTN                               SourceY,\r
+  IN UINTN                               DestinationX,\r
+  IN UINTN                               DestinationY,\r
+  IN UINTN                               Width,\r
+  IN UINTN                               Height,\r
+  IN UINTN                               Delta           OPTIONAL   // Number of BYTES in a row of the BltBuffer\r
+  )\r
+{\r
+  EFI_STATUS         Status;\r
+  UINT32             HorizontalResolution;\r
+  LCD_BPP            BitsPerPixel;\r
+  EFI_PIXEL_BITMASK  *PixelInformation;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *EfiSourcePixel;\r
+  VOID   *FrameBufferBase;\r
+  VOID            *SourceAddr;\r
+  VOID            *DestinationAddr;\r
+  UINT16 *DestinationPixel16bit;\r
+  UINT32          SourcePixelX;\r
+  UINT32          SourceLine;\r
+  UINT32          DestinationPixelX;\r
+  UINT32          DestinationLine;\r
+  UINT32          BltBufferHorizontalResolution;\r
+  UINTN           WidthInBytes;\r
+\r
+  Status = EFI_SUCCESS;\r
+  PixelInformation = &This->Mode->Info->PixelInformation;\r
+  HorizontalResolution = This->Mode->Info->HorizontalResolution;\r
+  FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));\r
+\r
+  if(( Delta != 0 ) && ( Delta != Width * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {\r
+    // Delta is not zero and it is different from the width.\r
+    // Divide it by the size of a pixel to find out the buffer's horizontal resolution.\r
+    BltBufferHorizontalResolution = (UINT32) (Delta / sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+  } else {\r
+    BltBufferHorizontalResolution = Width;\r
+  }\r
+\r
+  LcdPlatformGetBpp (This->Mode->Mode,&BitsPerPixel);\r
+\r
+  switch (BitsPerPixel) {\r
+  case LCD_BITS_PER_PIXEL_24:\r
+    WidthInBytes = Width * 4;\r
+\r
+    // Access each pixel inside the BltBuffer Memory\r
+    for (SourceLine = SourceY, DestinationLine = DestinationY;\r
+       SourceLine < SourceY + Height;\r
+       SourceLine++, DestinationLine++)\r
+    {\r
+      // Calculate the source and target addresses using 32bit pointer arithmetic:\r
+      SourceAddr      = (VOID *)((UINT32 *)BltBuffer       + SourceLine      * BltBufferHorizontalResolution + SourceX     );\r
+      DestinationAddr = (VOID *)((UINT32 *)FrameBufferBase + DestinationLine * HorizontalResolution          + DestinationX);\r
+\r
+      // Copy the entire row Y\r
+      CopyMem( DestinationAddr, SourceAddr, WidthInBytes);\r
+    }\r
+    break;\r
+\r
+  case LCD_BITS_PER_PIXEL_16_555:\r
+    // Access each pixel inside the BltBuffer Memory\r
+    for (SourceLine = SourceY, DestinationLine = DestinationY;\r
+       SourceLine < SourceY + Height;\r
+       SourceLine++, DestinationLine++) {\r
+\r
+      for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;\r
+           SourcePixelX < SourceX + Width;\r
+           SourcePixelX++, DestinationPixelX++)\r
+      {\r
+        // Calculate the source and target addresses:\r
+        EfiSourcePixel  = BltBuffer + SourceLine * BltBufferHorizontalResolution + SourcePixelX;\r
+        DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX;\r
+\r
+        // Copy the pixel into the new target\r
+        // Only the most significant bits will be copied across:\r
+        // To convert from 8 bits to 5 bits per pixel we throw away the 3 least significant bits\r
+        *DestinationPixel16bit = (UINT16) (\r
+              ( (EfiSourcePixel->Red      <<  7) & PixelInformation->RedMask      )\r
+            | ( (EfiSourcePixel->Green    <<  2) & PixelInformation->GreenMask    )\r
+            | ( (EfiSourcePixel->Blue     >>  3) & PixelInformation->BlueMask     )\r
+      //            | ( 0                                & PixelInformation->ReservedMask )\r
+            );\r
+      }\r
+    }\r
+    break;\r
+\r
+  case LCD_BITS_PER_PIXEL_16_565:\r
+    // Access each pixel inside the BltBuffer Memory\r
+    for (SourceLine = SourceY, DestinationLine = DestinationY;\r
+         SourceLine < SourceY + Height;\r
+         SourceLine++, DestinationLine++) {\r
+\r
+      for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;\r
+           SourcePixelX < SourceX + Width;\r
+           SourcePixelX++, DestinationPixelX++)\r
+      {\r
+        // Calculate the source and target addresses:\r
+        EfiSourcePixel = BltBuffer + SourceLine * BltBufferHorizontalResolution + SourcePixelX;\r
+        DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX;\r
+\r
+        // Copy the pixel into the new target\r
+        // Only the most significant bits will be copied across:\r
+        // To convert from 8 bits to 5 or 6 bits per pixel we throw away the 3 or 2  least significant bits\r
+        // There is no room for the Reserved byte so we ignore that completely\r
+        *DestinationPixel16bit = (UINT16) (\r
+              ( (EfiSourcePixel->Red      <<  8) & PixelInformation->RedMask      )\r
+            | ( (EfiSourcePixel->Green    <<  3) & PixelInformation->GreenMask    )\r
+            | ( (EfiSourcePixel->Blue     >>  3) & PixelInformation->BlueMask     )\r
+           );\r
+      }\r
+    }\r
+    break;\r
+\r
+  case LCD_BITS_PER_PIXEL_12_444:\r
+    // Access each pixel inside the BltBuffer Memory\r
+    for (SourceLine = SourceY, DestinationLine = DestinationY;\r
+         SourceLine < SourceY + Height;\r
+         SourceLine++, DestinationLine++) {\r
+\r
+      for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;\r
+           SourcePixelX < SourceX + Width;\r
+           SourcePixelX++, DestinationPixelX++)\r
+      {\r
+        // Calculate the source and target addresses:\r
+        EfiSourcePixel = BltBuffer + SourceLine * BltBufferHorizontalResolution + SourcePixelX;\r
+        DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX;\r
+\r
+        // Copy the pixel into the new target\r
+        // Only the most significant bits will be copied across:\r
+        // To convert from 8 bits to 5 bits per pixel we throw away the 3 least significant bits\r
+        *DestinationPixel16bit = (UINT16) (\r
+              ( (EfiSourcePixel->Red      << 4) & PixelInformation->RedMask      )\r
+            | ( (EfiSourcePixel->Green        ) & PixelInformation->GreenMask    )\r
+            | ( (EfiSourcePixel->Blue     >> 4) & PixelInformation->BlueMask     )\r
+  //            | ( 0                               & PixelInformation->ReservedMask )\r
+           );\r
+      }\r
+    }\r
+    break;\r
+\r
+  case LCD_BITS_PER_PIXEL_8:\r
+  case LCD_BITS_PER_PIXEL_4:\r
+  case LCD_BITS_PER_PIXEL_2:\r
+  case LCD_BITS_PER_PIXEL_1:\r
+  default:\r
+    // Can't handle this case\r
+    DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: EfiBltBufferToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel));\r
+    Status = EFI_INVALID_PARAMETER;\r
+    break;\r
+  }\r
+  return Status;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+BltVideoToVideo (\r
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL        *This,\r
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *BltBuffer,     OPTIONAL\r
+  IN UINTN                               SourceX,\r
+  IN UINTN                               SourceY,\r
+  IN UINTN                               DestinationX,\r
+  IN UINTN                               DestinationY,\r
+  IN UINTN                               Width,\r
+  IN UINTN                               Height,\r
+  IN UINTN                               Delta           OPTIONAL   // Number of BYTES in a row of the BltBuffer\r
+  )\r
+{\r
+  EFI_STATUS         Status;\r
+  UINT32             HorizontalResolution;\r
+  LCD_BPP            BitsPerPixel;\r
+  VOID   *FrameBufferBase;\r
+\r
+  HorizontalResolution = This->Mode->Info->HorizontalResolution;\r
+  FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));\r
+\r
+  //\r
+  // BltVideo to BltVideo:\r
+  //\r
+  //  Source is the Video Memory,\r
+  //  Destination is the Video Memory\r
+\r
+  LcdPlatformGetBpp (This->Mode->Mode,&BitsPerPixel);\r
+  FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));\r
+\r
+  // The UEFI spec currently states:\r
+  // "There is no limitation on the overlapping of the source and destination rectangles"\r
+  // Therefore, we must be careful to avoid overwriting the source data\r
+  if( SourceY == DestinationY ) {\r
+    // Copying within the same height, e.g. horizontal shift\r
+    if( SourceX == DestinationX ) {\r
+      // Nothing to do\r
+      Status = EFI_SUCCESS;\r
+    } else if( ((SourceX>DestinationX)?(SourceX - DestinationX):(DestinationX - SourceX)) < Width ) {\r
+      // There is overlap\r
+      Status = VideoCopyHorizontalOverlap (BitsPerPixel, FrameBufferBase, HorizontalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height );\r
+    } else {\r
+      // No overlap\r
+      Status = VideoCopyNoHorizontalOverlap (BitsPerPixel, FrameBufferBase, HorizontalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height );\r
+    }\r
+  } else {\r
+    // Copying from different heights\r
+    Status = VideoCopyNoHorizontalOverlap (BitsPerPixel, FrameBufferBase, HorizontalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/***************************************\r
+ * GraphicsOutput Protocol function, mapping to\r
+ * EFI_GRAPHICS_OUTPUT_PROTOCOL.Blt\r
+ *\r
+ * PRESUMES: 1 pixel = 4 bytes (32bits)\r
+ *  ***************************************/\r
+EFI_STATUS\r
+EFIAPI\r
+LcdGraphicsBlt (\r
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL        *This,\r
+       IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *BltBuffer,     OPTIONAL\r
+       IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION   BltOperation,\r
+       IN UINTN                               SourceX,\r
+       IN UINTN                               SourceY,\r
+       IN UINTN                               DestinationX,\r
+       IN UINTN                               DestinationY,\r
+       IN UINTN                               Width,\r
+       IN UINTN                               Height,\r
+       IN UINTN                               Delta           OPTIONAL   // Number of BYTES in a row of the BltBuffer\r
+  )\r
+{\r
+       EFI_STATUS         Status;\r
+       UINT32             HorizontalResolution;\r
+  UINT32             VerticalResolution;\r
+       LCD_INSTANCE*      Instance;\r
+\r
+  Instance = LCD_INSTANCE_FROM_GOP_THIS(This);\r
+\r
+  // Setup the hardware if not already done\r
+  if (!mDisplayInitialized) {\r
+    Status = InitializeDisplay (Instance);\r
+    if (EFI_ERROR(Status)) {\r
+      goto EXIT;\r
+    }\r
+  }\r
+\r
+  HorizontalResolution = This->Mode->Info->HorizontalResolution;\r
+  VerticalResolution   = This->Mode->Info->VerticalResolution;\r
+\r
+  DEBUG((DEBUG_INFO, "LcdGraphicsBlt (BltOperation:%d,DestX:%d,DestY:%d,Width:%d,Height:%d) res(%d,%d)\n",\r
+      BltOperation,DestinationX,DestinationY,Width,Height,HorizontalResolution,VerticalResolution));\r
+\r
+  // Check we have reasonable parameters\r
+       if (Width == 0 || Height == 0) {\r
+    DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: ERROR - Invalid dimension: Zero size area.\n" ));\r
+               Status = EFI_INVALID_PARAMETER;\r
+               goto EXIT;\r
+       }\r
+\r
+       if ((BltOperation == EfiBltVideoFill) || (BltOperation == EfiBltBufferToVideo) || (BltOperation == EfiBltVideoToBltBuffer)) {\r
+         ASSERT( BltBuffer != NULL);\r
+       }\r
+\r
+       /*if ((DestinationX >= HorizontalResolution) || (DestinationY >= VerticalResolution)) {\r
+         DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: ERROR - Invalid destination.\n" ));\r
+         Status = EFI_INVALID_PARAMETER;\r
+         goto EXIT;\r
+       }*/\r
+\r
+       // If we are reading data out of the video buffer, check that the source area is within the display limits\r
+       if ((BltOperation == EfiBltVideoToBltBuffer) || (BltOperation == EfiBltVideoToVideo)) {\r
+    if ((SourceY + Height > VerticalResolution) || (SourceX + Width > HorizontalResolution)) {\r
+      DEBUG((DEBUG_INFO, "LcdGraphicsBlt: ERROR - Invalid source resolution.\n" ));\r
+      DEBUG((DEBUG_INFO, "                      - SourceY=%d + Height=%d > VerticalResolution=%d.\n", SourceY, Height, VerticalResolution ));\r
+      DEBUG((DEBUG_INFO, "                      - SourceX=%d + Width=%d > HorizontalResolution=%d.\n", SourceX, Width, HorizontalResolution ));\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto EXIT;\r
+    }\r
+       }\r
+\r
+       // If we are writing data into the video buffer, that the destination area is within the display limits\r
+       if ((BltOperation == EfiBltVideoFill) || (BltOperation == EfiBltBufferToVideo) || (BltOperation == EfiBltVideoToVideo)) {\r
+    if ((DestinationY + Height > VerticalResolution) || (DestinationX + Width > HorizontalResolution)) {\r
+      DEBUG((DEBUG_INFO, "LcdGraphicsBlt: ERROR - Invalid destination resolution.\n" ));\r
+      DEBUG((DEBUG_INFO, "                      - DestinationY=%d + Height=%d > VerticalResolution=%d.\n", DestinationY, Height, VerticalResolution ));\r
+      DEBUG((DEBUG_INFO, "                      - DestinationX=%d + Width=%d > HorizontalResolution=%d.\n", DestinationX, Width, HorizontalResolution ));\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto EXIT;\r
+    }\r
+       }\r
+\r
+  //\r
+  // Perform the Block Transfer Operation\r
+  //\r
+\r
+       switch (BltOperation) {\r
+       case EfiBltVideoFill:\r
+         Status = BltVideoFill (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);\r
+               break;\r
+\r
+       case EfiBltVideoToBltBuffer:\r
+         Status = BltVideoToBltBuffer (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);\r
+    break;\r
+\r
+  case EfiBltBufferToVideo:\r
+    Status = BltBufferToVideo (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);\r
+               break;\r
+\r
+       case EfiBltVideoToVideo:\r
+         Status = BltVideoToVideo (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);\r
+               break;\r
+\r
+       case EfiGraphicsOutputBltOperationMax:\r
+       default:\r
+               DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: Invalid Operation\n"));\r
+               Status = EFI_INVALID_PARAMETER;\r
+               break;\r
+       }\r
+\r
+EXIT:\r
+       return Status;\r
+}\r