/** @file

 Copyright (c) 2011 - 2020, Arm Limited. All rights reserved.<BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent

 **/

#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;
  UINTN       SourceLine;
  UINTN       DestinationLine;
  UINTN       WidthInBytes;
  UINTN       LineCount;
  INTN        Step;
  VOID        *SourceAddr;
  VOID        *DestinationAddr;

  Status = EFI_SUCCESS;

  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 LcdBitsPerPixel_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 LcdBitsPerPixel_16_555:
    case LcdBitsPerPixel_16_565:
    case LcdBitsPerPixel_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 LcdBitsPerPixel_8:
    case LcdBitsPerPixel_4:
    case LcdBitsPerPixel_2:
    case LcdBitsPerPixel_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;

  UINT32  *PixelBuffer32bit;
  UINT32  *SourcePixel32bit;
  UINT32  *DestinationPixel32bit;

  UINT16  *PixelBuffer16bit;
  UINT16  *SourcePixel16bit;
  UINT16  *DestinationPixel16bit;

  UINTN  SourcePixelY;
  UINTN  DestinationPixelY;
  UINTN  SizeIn32Bits;
  UINTN  SizeIn16Bits;

  Status = EFI_SUCCESS;

  switch (BitsPerPixel) {
    case LcdBitsPerPixel_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 LcdBitsPerPixel_16_555:
    case LcdBitsPerPixel_16_565:
    case LcdBitsPerPixel_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 LcdBitsPerPixel_8:
    case LcdBitsPerPixel_4:
    case LcdBitsPerPixel_2:
    case LcdBitsPerPixel_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;
  UINTN              DestinationPixelX;
  UINTN              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 LcdBitsPerPixel_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
        SetMem32 (DestinationAddr, WidthInBytes, *((UINT32 *)EfiSourcePixel));
      }

      break;

    case LcdBitsPerPixel_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 LcdBitsPerPixel_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 LcdBitsPerPixel_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 LcdBitsPerPixel_8:
    case LcdBitsPerPixel_4:
    case LcdBitsPerPixel_2:
    case LcdBitsPerPixel_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;
  UINTN                          SourcePixelX;
  UINTN                          SourceLine;
  UINTN                          DestinationPixelX;
  UINTN                          DestinationLine;
  UINTN                          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 LcdBitsPerPixel_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 LcdBitsPerPixel_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 LcdBitsPerPixel_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 LcdBitsPerPixel_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 LcdBitsPerPixel_8:
    case LcdBitsPerPixel_4:
    case LcdBitsPerPixel_2:
    case LcdBitsPerPixel_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;
  UINTN                          SourcePixelX;
  UINTN                          SourceLine;
  UINTN                          DestinationPixelX;
  UINTN                          DestinationLine;
  UINTN                          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 LcdBitsPerPixel_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 LcdBitsPerPixel_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 LcdBitsPerPixel_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 LcdBitsPerPixel_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 LcdBitsPerPixel_8:
    case LcdBitsPerPixel_4:
    case LcdBitsPerPixel_2:
    case LcdBitsPerPixel_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;

  // 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;
}
