/** @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;
  }

  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;
  }

  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;

  UINT16 *PixelBuffer16bit;
  UINT16 *SourcePixel16bit;
  UINT16 *DestinationPixel16bit;

  UINT32          SourcePixelY;
  UINT32          DestinationPixelY;
  UINTN           SizeIn16Bits;

  // 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);


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;
  VOID                *FrameBufferBase;
  UINT16              *DestinationPixel16bit;
  UINT16              Pixel16bit;
  UINT32              DestinationPixelX;
  UINT32              DestinationLine;

  Status           = EFI_SUCCESS;
  PixelInformation = &This->Mode->Info->PixelInformation;
  FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
  HorizontalResolution = This->Mode->Info->HorizontalResolution;

  // 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;
    }
  }


  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;
  EFI_PIXEL_BITMASK  *PixelInformation;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *EfiDestinationPixel;
  VOID               *FrameBufferBase;
  UINT16             *SourcePixel16bit;
  UINT16             Pixel16bit;
  UINT32             SourcePixelX;
  UINT32             SourceLine;
  UINT32             DestinationPixelX;
  UINT32             DestinationLine;
  UINT32             BltBufferHorizontalResolution;

  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;
  }

  // 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     ) >>  8 );
      EfiDestinationPixel->Green    = (UINT8) ( (Pixel16bit & PixelInformation->GreenMask   ) >>  3 );
      EfiDestinationPixel->Blue     = (UINT8) ( (Pixel16bit & PixelInformation->BlueMask    ) <<  3 );
    }
  }

  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;
  EFI_PIXEL_BITMASK  *PixelInformation;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *EfiSourcePixel;
  VOID               *FrameBufferBase;
  UINT16             *DestinationPixel16bit;
  UINT32             SourcePixelX;
  UINT32             SourceLine;
  UINT32             DestinationPixelX;
  UINT32             DestinationLine;
  UINT32             BltBufferHorizontalResolution;

  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;
  }

  // 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      <<  8) & PixelInformation->RedMask      )
            | ( (EfiSourcePixel->Green    <<  3) & PixelInformation->GreenMask    )
            | ( (EfiSourcePixel->Blue     >>  3) & PixelInformation->BlueMask     )
            );
      }
    }

  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;
  UINTN              BitsPerPixel;
  VOID               *FrameBufferBase;

  BitsPerPixel = 16;

  HorizontalResolution = This->Mode->Info->HorizontalResolution;
  FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));

  //
  // BltVideo to BltVideo:
  //
  //  Source is the Video Memory,
  //  Destination is the Video Memory

  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;
}

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;
  LCD_INSTANCE  *Instance;

  Instance = LCD_INSTANCE_FROM_GOP_THIS(This);

  if (!mDisplayInitialized) {
    InitializeDisplay (Instance);
  }

  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;
}

  return Status;
}
