/** @file
  FrameBufferBltLib - Library to perform blt operations on a frame buffer.

  Copyright (c) 2007 - 2018, Intel Corporation. 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 <Uefi/UefiBaseType.h>
#include <Protocol/GraphicsOutput.h>

#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/FrameBufferBltLib.h>

struct FRAME_BUFFER_CONFIGURE {
  UINT32                          PixelsPerScanLine;
  UINT32                          BytesPerPixel;
  UINT32                          Width;
  UINT32                          Height;
  UINT8                           *FrameBuffer;
  EFI_GRAPHICS_PIXEL_FORMAT       PixelFormat;
  EFI_PIXEL_BITMASK               PixelMasks;
  INT8                            PixelShl[4]; // R-G-B-Rsvd
  INT8                            PixelShr[4]; // R-G-B-Rsvd
  UINT8                           LineBuffer[0];
};

CONST EFI_PIXEL_BITMASK mRgbPixelMasks = {
  0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000
};

CONST EFI_PIXEL_BITMASK mBgrPixelMasks = {
  0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000
};

/**
  Initialize the bit mask in frame buffer configure.

  @param BitMask       The bit mask of pixel.
  @param BytesPerPixel Size in bytes of pixel.
  @param PixelShl      Left shift array.
  @param PixelShr      Right shift array.
**/
VOID
FrameBufferBltLibConfigurePixelFormat (
  IN CONST EFI_PIXEL_BITMASK    *BitMask,
  OUT UINT32                    *BytesPerPixel,
  OUT INT8                      *PixelShl,
  OUT INT8                      *PixelShr
  )
{
  UINT8   Index;
  UINT32  *Masks;
  UINT32  MergedMasks;

  ASSERT (BytesPerPixel != NULL);

  MergedMasks = 0;
  Masks = (UINT32*) BitMask;
  for (Index = 0; Index < 3; Index++) {
    ASSERT ((MergedMasks & Masks[Index]) == 0);

    PixelShl[Index] = (INT8) HighBitSet32 (Masks[Index]) - 23 + (Index * 8);
    if (PixelShl[Index] < 0) {
      PixelShr[Index] = -PixelShl[Index];
      PixelShl[Index] = 0;
    } else {
      PixelShr[Index] = 0;
    }
    DEBUG ((DEBUG_INFO, "%d: shl:%d shr:%d mask:%x\n", Index,
            PixelShl[Index], PixelShr[Index], Masks[Index]));

    MergedMasks = (UINT32) (MergedMasks | Masks[Index]);
  }
  MergedMasks = (UINT32) (MergedMasks | Masks[3]);

  ASSERT (MergedMasks != 0);
  *BytesPerPixel = (UINT32) ((HighBitSet32 (MergedMasks) + 7) / 8);
  DEBUG ((DEBUG_INFO, "Bytes per pixel: %d\n", *BytesPerPixel));
}

/**
  Create the configuration for a video frame buffer.

  The configuration is returned in the caller provided buffer.

  @param[in] FrameBuffer       Pointer to the start of the frame buffer.
  @param[in] FrameBufferInfo   Describes the frame buffer characteristics.
  @param[in,out] Configure     The created configuration information.
  @param[in,out] ConfigureSize Size of the configuration information.

  @retval RETURN_SUCCESS            The configuration was successful created.
  @retval RETURN_BUFFER_TOO_SMALL   The Configure is to too small. The required
                                    size is returned in ConfigureSize.
  @retval RETURN_UNSUPPORTED        The requested mode is not supported by
                                    this implementaion.

**/
RETURN_STATUS
EFIAPI
FrameBufferBltConfigure (
  IN     VOID                                  *FrameBuffer,
  IN     EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *FrameBufferInfo,
  IN OUT FRAME_BUFFER_CONFIGURE                *Configure,
  IN OUT UINTN                                 *ConfigureSize
  )
{
  CONST EFI_PIXEL_BITMASK                      *BitMask;
  UINT32                                       BytesPerPixel;
  INT8                                         PixelShl[4];
  INT8                                         PixelShr[4];

  if (ConfigureSize == NULL) {
    return RETURN_INVALID_PARAMETER;
  }

  switch (FrameBufferInfo->PixelFormat) {
  case PixelRedGreenBlueReserved8BitPerColor:
    BitMask = &mRgbPixelMasks;
    break;

  case PixelBlueGreenRedReserved8BitPerColor:
    BitMask = &mBgrPixelMasks;
    break;

  case PixelBitMask:
    BitMask = &FrameBufferInfo->PixelInformation;
    break;

  case PixelBltOnly:
    ASSERT (FrameBufferInfo->PixelFormat != PixelBltOnly);
    return RETURN_UNSUPPORTED;

  default:
    ASSERT (FALSE);
    return RETURN_INVALID_PARAMETER;
  }

  if (FrameBufferInfo->PixelsPerScanLine < FrameBufferInfo->HorizontalResolution) {
    return RETURN_UNSUPPORTED;
  }

  FrameBufferBltLibConfigurePixelFormat (BitMask, &BytesPerPixel, PixelShl, PixelShr);

  if (*ConfigureSize < sizeof (FRAME_BUFFER_CONFIGURE)
                     + FrameBufferInfo->HorizontalResolution * BytesPerPixel) {
    *ConfigureSize = sizeof (FRAME_BUFFER_CONFIGURE)
                   + FrameBufferInfo->HorizontalResolution * BytesPerPixel;
    return RETURN_BUFFER_TOO_SMALL;
  }

  if (Configure == NULL) {
    return RETURN_INVALID_PARAMETER;
  }

  CopyMem (&Configure->PixelMasks, BitMask,  sizeof (*BitMask));
  CopyMem (Configure->PixelShl,    PixelShl, sizeof (PixelShl));
  CopyMem (Configure->PixelShr,    PixelShr, sizeof (PixelShr));
  Configure->BytesPerPixel     = BytesPerPixel;
  Configure->PixelFormat       = FrameBufferInfo->PixelFormat;
  Configure->FrameBuffer       = (UINT8*) FrameBuffer;
  Configure->Width             = FrameBufferInfo->HorizontalResolution;
  Configure->Height            = FrameBufferInfo->VerticalResolution;
  Configure->PixelsPerScanLine = FrameBufferInfo->PixelsPerScanLine;

  return RETURN_SUCCESS;
}

/**
  Performs a UEFI Graphics Output Protocol Blt Video Fill.

  @param[in]  Configure     Pointer to a configuration which was successfully
                            created by FrameBufferBltConfigure ().
  @param[in]  Color         Color to fill the region with.
  @param[in]  DestinationX  X location to start fill operation.
  @param[in]  DestinationY  Y location to start fill operation.
  @param[in]  Width         Width (in pixels) to fill.
  @param[in]  Height        Height to fill.

  @retval  RETURN_INVALID_PARAMETER Invalid parameter was passed in.
  @retval  RETURN_SUCCESS           The video was filled successfully.

**/
EFI_STATUS
FrameBufferBltLibVideoFill (
  IN  FRAME_BUFFER_CONFIGURE        *Configure,
  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Color,
  IN  UINTN                         DestinationX,
  IN  UINTN                         DestinationY,
  IN  UINTN                         Width,
  IN  UINTN                         Height
  )
{
  UINTN                             IndexX;
  UINTN                             IndexY;
  UINT8                             *Destination;
  UINT8                             Uint8;
  UINT32                            Uint32;
  UINT64                            WideFill;
  BOOLEAN                           UseWideFill;
  BOOLEAN                           LineBufferReady;
  UINTN                             Offset;
  UINTN                             WidthInBytes;
  UINTN                             SizeInBytes;

  //
  // BltBuffer to Video: Source is BltBuffer, destination is Video
  //
  if (DestinationY + Height > Configure->Height) {
    DEBUG ((EFI_D_VERBOSE, "VideoFill: Past screen (Y)\n"));
    return RETURN_INVALID_PARAMETER;
  }

  if (DestinationX + Width > Configure->Width) {
    DEBUG ((EFI_D_VERBOSE, "VideoFill: Past screen (X)\n"));
    return RETURN_INVALID_PARAMETER;
  }

  if (Width == 0 || Height == 0) {
    DEBUG ((EFI_D_VERBOSE, "VideoFill: Width or Height is 0\n"));
    return RETURN_INVALID_PARAMETER;
  }

  WidthInBytes = Width * Configure->BytesPerPixel;

  Uint32 = *(UINT32*) Color;
  WideFill =
    (UINT32) (
    (((Uint32 << Configure->PixelShl[0]) >> Configure->PixelShr[0]) &
     Configure->PixelMasks.RedMask) |
     (((Uint32 << Configure->PixelShl[1]) >> Configure->PixelShr[1]) &
      Configure->PixelMasks.GreenMask) |
      (((Uint32 << Configure->PixelShl[2]) >> Configure->PixelShr[2]) &
       Configure->PixelMasks.BlueMask)
      );
  DEBUG ((EFI_D_VERBOSE, "VideoFill: color=0x%x, wide-fill=0x%x\n",
          Uint32, WideFill));

  //
  // If the size of the pixel data evenly divides the sizeof
  // WideFill, then a wide fill operation can be used
  //
  UseWideFill = TRUE;
  if ((sizeof (WideFill) % Configure->BytesPerPixel) == 0) {
    for (IndexX = Configure->BytesPerPixel; IndexX < sizeof (WideFill); IndexX++) {
      ((UINT8*) &WideFill)[IndexX] = ((UINT8*) &WideFill)[IndexX % Configure->BytesPerPixel];
    }
  } else {
    //
    // If all the bytes in the pixel are the same value, then use
    // a wide fill operation.
    //
    for (
      IndexX = 1, Uint8 = ((UINT8*) &WideFill)[0];
      IndexX < Configure->BytesPerPixel;
      IndexX++) {
      if (Uint8 != ((UINT8*) &WideFill)[IndexX]) {
        UseWideFill = FALSE;
        break;
      }
    }
    if (UseWideFill) {
      SetMem (&WideFill, sizeof (WideFill), Uint8);
    }
  }

  if (UseWideFill && (DestinationX == 0) && (Width == Configure->PixelsPerScanLine)) {
    DEBUG ((EFI_D_VERBOSE, "VideoFill (wide, one-shot)\n"));
    Offset = DestinationY * Configure->PixelsPerScanLine;
    Offset = Configure->BytesPerPixel * Offset;
    Destination = Configure->FrameBuffer + Offset;
    SizeInBytes = WidthInBytes * Height;
    if (SizeInBytes >= 8) {
      SetMem32 (Destination, SizeInBytes & ~3, (UINT32) WideFill);
      Destination += SizeInBytes & ~3;
      SizeInBytes &= 3;
    }
    if (SizeInBytes > 0) {
      SetMem (Destination, SizeInBytes, (UINT8) (UINTN) WideFill);
    }
  } else {
    LineBufferReady = FALSE;
    for (IndexY = DestinationY; IndexY < (Height + DestinationY); IndexY++) {
      Offset = (IndexY * Configure->PixelsPerScanLine) + DestinationX;
      Offset = Configure->BytesPerPixel * Offset;
      Destination = Configure->FrameBuffer + Offset;

      if (UseWideFill && (((UINTN) Destination & 7) == 0)) {
        DEBUG ((EFI_D_VERBOSE, "VideoFill (wide)\n"));
        SizeInBytes = WidthInBytes;
        if (SizeInBytes >= 8) {
          SetMem64 (Destination, SizeInBytes & ~7, WideFill);
          Destination += SizeInBytes & ~7;
          SizeInBytes &= 7;
        }
        if (SizeInBytes > 0) {
          CopyMem (Destination, &WideFill, SizeInBytes);
        }
      } else {
        DEBUG ((EFI_D_VERBOSE, "VideoFill (not wide)\n"));
        if (!LineBufferReady) {
          CopyMem (Configure->LineBuffer, &WideFill, Configure->BytesPerPixel);
          for (IndexX = 1; IndexX < Width; ) {
            CopyMem (
              (Configure->LineBuffer + (IndexX * Configure->BytesPerPixel)),
              Configure->LineBuffer,
              MIN (IndexX, Width - IndexX) * Configure->BytesPerPixel
            );
            IndexX += MIN (IndexX, Width - IndexX);
          }
          LineBufferReady = TRUE;
        }
        CopyMem (Destination, Configure->LineBuffer, WidthInBytes);
      }
    }
  }

  return RETURN_SUCCESS;
}

/**
  Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation
  with extended parameters.

  @param[in]  Configure     Pointer to a configuration which was successfully
                            created by FrameBufferBltConfigure ().
  @param[out] BltBuffer     Output buffer for pixel color data.
  @param[in]  SourceX       X location within video.
  @param[in]  SourceY       Y location within video.
  @param[in]  DestinationX  X location within BltBuffer.
  @param[in]  DestinationY  Y location within BltBuffer.
  @param[in]  Width         Width (in pixels).
  @param[in]  Height        Height.
  @param[in]  Delta         Number of bytes in a row of BltBuffer.

  @retval RETURN_INVALID_PARAMETER Invalid parameter were passed in.
  @retval RETURN_SUCCESS           The Blt operation was performed successfully.
**/
RETURN_STATUS
FrameBufferBltLibVideoToBltBuffer (
  IN     FRAME_BUFFER_CONFIGURE          *Configure,
     OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *BltBuffer,
  IN     UINTN                           SourceX,
  IN     UINTN                           SourceY,
  IN     UINTN                           DestinationX,
  IN     UINTN                           DestinationY,
  IN     UINTN                           Width,
  IN     UINTN                           Height,
  IN     UINTN                           Delta
  )
{
  UINTN                                  DstY;
  UINTN                                  SrcY;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL          *Blt;
  UINT8                                  *Source;
  UINT8                                  *Destination;
  UINTN                                  IndexX;
  UINT32                                 Uint32;
  UINTN                                  Offset;
  UINTN                                  WidthInBytes;

  //
  // Video to BltBuffer: Source is Video, destination is BltBuffer
  //
  if (SourceY + Height > Configure->Height) {
    return RETURN_INVALID_PARAMETER;
  }

  if (SourceX + Width > Configure->Width) {
    return RETURN_INVALID_PARAMETER;
  }

  if (Width == 0 || Height == 0) {
    return RETURN_INVALID_PARAMETER;
  }

  //
  // If Delta is zero, then the entire BltBuffer is being used, so Delta is
  // the number of bytes in each row of BltBuffer. Since BltBuffer is Width
  // pixels size, the number of bytes in each row can be computed.
  //
  if (Delta == 0) {
    Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
  }

  WidthInBytes = Width * Configure->BytesPerPixel;

  //
  // Video to BltBuffer: Source is Video, destination is BltBuffer
  //
  for (SrcY = SourceY, DstY = DestinationY;
       DstY < (Height + DestinationY);
       SrcY++, DstY++) {

    Offset = (SrcY * Configure->PixelsPerScanLine) + SourceX;
    Offset = Configure->BytesPerPixel * Offset;
    Source = Configure->FrameBuffer + Offset;

    if (Configure->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
      Destination = (UINT8 *) BltBuffer + (DstY * Delta) + (DestinationX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
    } else {
      Destination = Configure->LineBuffer;
    }

    CopyMem (Destination, Source, WidthInBytes);

    if (Configure->PixelFormat != PixelBlueGreenRedReserved8BitPerColor) {
      for (IndexX = 0; IndexX < Width; IndexX++) {
        Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)
          ((UINT8 *) BltBuffer + (DstY * Delta) +
          (DestinationX + IndexX) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
        Uint32 = *(UINT32*) (Configure->LineBuffer + (IndexX * Configure->BytesPerPixel));
        *(UINT32*) Blt =
          (UINT32) (
          (((Uint32 & Configure->PixelMasks.RedMask) >>
            Configure->PixelShl[0]) << Configure->PixelShr[0]) |
            (((Uint32 & Configure->PixelMasks.GreenMask) >>
              Configure->PixelShl[1]) << Configure->PixelShr[1]) |
              (((Uint32 & Configure->PixelMasks.BlueMask) >>
                Configure->PixelShl[2]) << Configure->PixelShr[2])
            );
      }
    }
  }

  return RETURN_SUCCESS;
}

/**
  Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation
  with extended parameters.

  @param[in]  Configure     Pointer to a configuration which was successfully
                            created by FrameBufferBltConfigure ().
  @param[in]  BltBuffer     Output buffer for pixel color data.
  @param[in]  SourceX       X location within BltBuffer.
  @param[in]  SourceY       Y location within BltBuffer.
  @param[in]  DestinationX  X location within video.
  @param[in]  DestinationY  Y location within video.
  @param[in]  Width         Width (in pixels).
  @param[in]  Height        Height.
  @param[in]  Delta         Number of bytes in a row of BltBuffer.

  @retval RETURN_INVALID_PARAMETER Invalid parameter were passed in.
  @retval RETURN_SUCCESS           The Blt operation was performed successfully.
**/
RETURN_STATUS
FrameBufferBltLibBufferToVideo (
  IN  FRAME_BUFFER_CONFIGURE                *Configure,
  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer,
  IN  UINTN                                 SourceX,
  IN  UINTN                                 SourceY,
  IN  UINTN                                 DestinationX,
  IN  UINTN                                 DestinationY,
  IN  UINTN                                 Width,
  IN  UINTN                                 Height,
  IN  UINTN                                 Delta
  )
{
  UINTN                                    DstY;
  UINTN                                    SrcY;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL            *Blt;
  UINT8                                    *Source;
  UINT8                                    *Destination;
  UINTN                                    IndexX;
  UINT32                                   Uint32;
  UINTN                                    Offset;
  UINTN                                    WidthInBytes;

  //
  // BltBuffer to Video: Source is BltBuffer, destination is Video
  //
  if (DestinationY + Height > Configure->Height) {
    return RETURN_INVALID_PARAMETER;
  }

  if (DestinationX + Width > Configure->Width) {
    return RETURN_INVALID_PARAMETER;
  }

  if (Width == 0 || Height == 0) {
    return RETURN_INVALID_PARAMETER;
  }

  //
  // If Delta is zero, then the entire BltBuffer is being used, so Delta is
  // the number of bytes in each row of BltBuffer. Since BltBuffer is Width
  // pixels size, the number of bytes in each row can be computed.
  //
  if (Delta == 0) {
    Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
  }

  WidthInBytes = Width * Configure->BytesPerPixel;

  for (SrcY = SourceY, DstY = DestinationY;
       SrcY < (Height + SourceY);
       SrcY++, DstY++) {

    Offset = (DstY * Configure->PixelsPerScanLine) + DestinationX;
    Offset = Configure->BytesPerPixel * Offset;
    Destination = Configure->FrameBuffer + Offset;

    if (Configure->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
      Source = (UINT8 *) BltBuffer + (SrcY * Delta);
    } else {
      for (IndexX = 0; IndexX < Width; IndexX++) {
        Blt =
          (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) (
              (UINT8 *) BltBuffer +
              (SrcY * Delta) +
              ((SourceX + IndexX) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))
            );
        Uint32 = *(UINT32*) Blt;
        *(UINT32*) (Configure->LineBuffer + (IndexX * Configure->BytesPerPixel)) =
          (UINT32) (
              (((Uint32 << Configure->PixelShl[0]) >> Configure->PixelShr[0]) &
               Configure->PixelMasks.RedMask) |
              (((Uint32 << Configure->PixelShl[1]) >> Configure->PixelShr[1]) &
               Configure->PixelMasks.GreenMask) |
              (((Uint32 << Configure->PixelShl[2]) >> Configure->PixelShr[2]) &
               Configure->PixelMasks.BlueMask)
            );
      }
      Source = Configure->LineBuffer;
    }

    CopyMem (Destination, Source, WidthInBytes);
  }

  return RETURN_SUCCESS;
}

/**
  Performs a UEFI Graphics Output Protocol Blt Video to Video operation

  @param[in]  Configure     Pointer to a configuration which was successfully
                            created by FrameBufferBltConfigure ().
  @param[in]  SourceX       X location within video.
  @param[in]  SourceY       Y location within video.
  @param[in]  DestinationX  X location within video.
  @param[in]  DestinationY  Y location within video.
  @param[in]  Width         Width (in pixels).
  @param[in]  Height        Height.

  @retval RETURN_INVALID_PARAMETER Invalid parameter were passed in.
  @retval RETURN_SUCCESS           The Blt operation was performed successfully.
**/
RETURN_STATUS
FrameBufferBltLibVideoToVideo (
  IN  FRAME_BUFFER_CONFIGURE                *Configure,
  IN  UINTN                                 SourceX,
  IN  UINTN                                 SourceY,
  IN  UINTN                                 DestinationX,
  IN  UINTN                                 DestinationY,
  IN  UINTN                                 Width,
  IN  UINTN                                 Height
  )
{
  UINT8                                     *Source;
  UINT8                                     *Destination;
  UINTN                                     Offset;
  UINTN                                     WidthInBytes;
  INTN                                      LineStride;

  //
  // Video to Video: Source is Video, destination is Video
  //
  if (SourceY + Height > Configure->Height) {
    return RETURN_INVALID_PARAMETER;
  }

  if (SourceX + Width > Configure->Width) {
    return RETURN_INVALID_PARAMETER;
  }

  if (DestinationY + Height > Configure->Height) {
    return RETURN_INVALID_PARAMETER;
  }

  if (DestinationX + Width > Configure->Width) {
    return RETURN_INVALID_PARAMETER;
  }

  if (Width == 0 || Height == 0) {
    return RETURN_INVALID_PARAMETER;
  }

  WidthInBytes = Width * Configure->BytesPerPixel;

  Offset = (SourceY * Configure->PixelsPerScanLine) + SourceX;
  Offset = Configure->BytesPerPixel * Offset;
  Source = Configure->FrameBuffer + Offset;

  Offset = (DestinationY * Configure->PixelsPerScanLine) + DestinationX;
  Offset = Configure->BytesPerPixel * Offset;
  Destination = Configure->FrameBuffer + Offset;

  LineStride = Configure->BytesPerPixel * Configure->PixelsPerScanLine;
  if (Destination > Source) {
    //
    // Copy from last line to avoid source is corrupted by copying
    //
    Source += Height * LineStride;
    Destination += Height * LineStride;
    LineStride = -LineStride;
  }

  while (Height-- > 0) {
    CopyMem (Destination, Source, WidthInBytes);

    Source += LineStride;
    Destination += LineStride;
  }

  return RETURN_SUCCESS;
}

/**
  Performs a UEFI Graphics Output Protocol Blt operation.

  @param[in]     Configure    Pointer to a configuration which was successfully
                              created by FrameBufferBltConfigure ().
  @param[in,out] BltBuffer    The data to transfer to screen.
  @param[in]     BltOperation The operation to perform.
  @param[in]     SourceX      The X coordinate of the source for BltOperation.
  @param[in]     SourceY      The Y coordinate of the source for BltOperation.
  @param[in]     DestinationX The X coordinate of the destination for
                              BltOperation.
  @param[in]     DestinationY The Y coordinate of the destination for
                              BltOperation.
  @param[in]     Width        The width of a rectangle in the blt rectangle
                              in pixels.
  @param[in]     Height       The height of a rectangle in the blt rectangle
                              in pixels.
  @param[in]     Delta        Not used for EfiBltVideoFill and
                              EfiBltVideoToVideo operation. If a Delta of 0
                              is used, the entire BltBuffer will be operated
                              on. If a subrectangle of the BltBuffer is
                              used, then Delta represents the number of
                              bytes in a row of the BltBuffer.

  @retval RETURN_INVALID_PARAMETER Invalid parameter were passed in.
  @retval RETURN_SUCCESS           The Blt operation was performed successfully.
**/
RETURN_STATUS
EFIAPI
FrameBufferBlt (
  IN     FRAME_BUFFER_CONFIGURE                *Configure,
  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
  )
{
  if (Configure == NULL) {
    return RETURN_INVALID_PARAMETER;
  }

  switch (BltOperation) {
  case EfiBltVideoToBltBuffer:
    return FrameBufferBltLibVideoToBltBuffer (
             Configure,
             BltBuffer,
             SourceX,
             SourceY,
             DestinationX,
             DestinationY,
             Width,
             Height,
             Delta
             );

  case EfiBltVideoToVideo:
    return FrameBufferBltLibVideoToVideo (
             Configure,
             SourceX,
             SourceY,
             DestinationX,
             DestinationY,
             Width,
             Height
             );

  case EfiBltVideoFill:
    return FrameBufferBltLibVideoFill (
             Configure,
             BltBuffer,
             DestinationX,
             DestinationY,
             Width,
             Height
             );

  case EfiBltBufferToVideo:
    return FrameBufferBltLibBufferToVideo (
             Configure,
             BltBuffer,
             SourceX,
             SourceY,
             DestinationX,
             DestinationY,
             Width,
             Height,
             Delta
             );

  default:
    return RETURN_INVALID_PARAMETER;
  }
}
