On 06/30/16 07:09, Ruiyu Ni wrote:
> This library provides interfaces to perform UEFI Graphics
> Output Protocol Video BLT operations.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ruiyu Ni <[email protected]>
> Cc: Feng Tian <[email protected]>
> Cc: Justen Jordan <[email protected]>
> Cc: Laszlo Ersek <[email protected]>
> ---
>  MdeModulePkg/Include/Library/FrameBufferBltLib.h   |  94 +++
>  .../Library/FrameBufferBltLib/FrameBufferBltLib.c  | 704 
> +++++++++++++++++++++
>  .../FrameBufferBltLib/FrameBufferBltLib.inf        |  34 +
>  MdeModulePkg/MdeModulePkg.dec                      |   4 +
>  MdeModulePkg/MdeModulePkg.dsc                      |   1 +
>  5 files changed, 837 insertions(+)
>  create mode 100644 MdeModulePkg/Include/Library/FrameBufferBltLib.h
>  create mode 100644 MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.c
>  create mode 100644 
> MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf

In
<http://thread.gmane.org/gmane.comp.bios.edk2.devel/13809/focus=13835> I
made some comments; from them, the following seem to affect this patch:

(1) use FRAMEBUFFER_CONFIGURE* rather than VOID*
(3) FrameBufferBltLib.inf should get a new FILE_GUID
(6) the git history should remain bisectable

All of these have been addressed in this patch, so:

Acked-by: Laszlo Ersek <[email protected]>

(for this patch).

Jordan requests that this patch be split in two: lib class header and
lib instance (implementation). I agree that's a good idea: when you do
it, please add my Acked-by to both of the resultant patches.

Jordan also requests that you re-add the OvmfPkg patch. In the message
linked above, I commented on that patch as well -- please consider those
comments. I would like to see your new version of that patch before
giving my R-b for it.

Thanks!
Laszlo

> diff --git a/MdeModulePkg/Include/Library/FrameBufferBltLib.h 
> b/MdeModulePkg/Include/Library/FrameBufferBltLib.h
> new file mode 100644
> index 0000000..c92eb94
> --- /dev/null
> +++ b/MdeModulePkg/Include/Library/FrameBufferBltLib.h
> @@ -0,0 +1,94 @@
> +/** @file
> +  Library for performing UEFI GOP Blt operations on a framebuffer
> +
> +  Copyright (c) 2009 - 2016, 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.
> +
> +**/
> +
> +#ifndef __FRAMEBUFFER_BLT_LIB__
> +#define __FRAMEBUFFER_BLT_LIB__
> +
> +#include <Protocol/GraphicsOutput.h>
> +
> +//
> +// Opaque structure for the frame buffer configure.
> +//
> +typedef struct FRAME_BUFFER_CONFIGURE FRAME_BUFFER_CONFIGURE;
> +
> +/**
> +  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
> +  );
> +
> +/**
> +  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
> +  );
> +
> +#endif
> diff --git a/MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.c 
> b/MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.c
> new file mode 100644
> index 0000000..c9bb206
> --- /dev/null
> +++ b/MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.c
> @@ -0,0 +1,704 @@
> +/** @file
> +  FrameBufferBltLib - Library to perform blt operations on a frame buffer.
> +
> +  Copyright (c) 2007 - 2016, 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 {
> +  UINTN                           ColorDepth;
> +  UINTN                           WidthInBytes;
> +  UINTN                           BytesPerPixel;
> +  UINTN                           WidthInPixels;
> +  UINTN                           Height;
> +  UINT8                           LineBuffer[SIZE_4KB * sizeof 
> (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)];
> +  UINT8                           *FrameBuffer;
> +  EFI_GRAPHICS_PIXEL_FORMAT       PixelFormat;
> +  EFI_PIXEL_BITMASK               PixelMasks;
> +  INTN                            PixelShl[4]; // R-G-B-Rsvd
> +  INTN                            PixelShr[4]; // R-G-B-Rsvd
> +};
> +
> +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 Configure  The frame buffer configure.
> +  @param BitMask    The bit mask of pixel.
> +**/
> +VOID
> +ConfigurePixelBitMaskFormat (
> +  IN FRAME_BUFFER_CONFIGURE     *Configure,
> +  IN CONST EFI_PIXEL_BITMASK    *BitMask
> +  )
> +{
> +  UINTN   Loop;
> +  UINT32  *Masks;
> +  UINT32  MergedMasks;
> +
> +  MergedMasks = 0;
> +  Masks = (UINT32*) BitMask;
> +  for (Loop = 0; Loop < 3; Loop++) {
> +    ASSERT ((Loop == 3) || (Masks[Loop] != 0));
> +    ASSERT ((MergedMasks & Masks[Loop]) == 0);
> +    Configure->PixelShl[Loop] = HighBitSet32 (Masks[Loop]) - 23 + (Loop * 8);
> +    if (Configure->PixelShl[Loop] < 0) {
> +      Configure->PixelShr[Loop] = -Configure->PixelShl[Loop];
> +      Configure->PixelShl[Loop] = 0;
> +    } else {
> +      Configure->PixelShr[Loop] = 0;
> +    }
> +    MergedMasks = (UINT32) (MergedMasks | Masks[Loop]);
> +    DEBUG ((EFI_D_VERBOSE, "%d: shl:%d shr:%d mask:%x\n", Loop,
> +            Configure->PixelShl[Loop], Configure->PixelShr[Loop], 
> Masks[Loop]));
> +  }
> +  MergedMasks = (UINT32) (MergedMasks | Masks[3]);
> +
> +  ASSERT (MergedMasks != 0);
> +  Configure->BytesPerPixel = (UINTN) ((HighBitSet32 (MergedMasks) + 7) / 8);
> +
> +  DEBUG ((EFI_D_VERBOSE, "Bytes per pixel: %d\n", Configure->BytesPerPixel));
> +
> +  CopyMem (&Configure->PixelMasks, BitMask, sizeof (*BitMask));
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  if (ConfigureSize == NULL) {
> +    return RETURN_INVALID_PARAMETER;
> +  }
> +
> +  if (*ConfigureSize < sizeof (FRAME_BUFFER_CONFIGURE)) {
> +    *ConfigureSize = sizeof (FRAME_BUFFER_CONFIGURE);
> +    return RETURN_BUFFER_TOO_SMALL;
> +  }
> +
> +  if (Configure == NULL) {
> +    return RETURN_INVALID_PARAMETER;
> +  }
> +
> +  switch (FrameBufferInfo->PixelFormat) {
> +  case PixelRedGreenBlueReserved8BitPerColor:
> +    ConfigurePixelBitMaskFormat (Configure, &mRgbPixelMasks);
> +    break;
> +
> +  case PixelBlueGreenRedReserved8BitPerColor:
> +    ConfigurePixelBitMaskFormat (Configure, &mBgrPixelMasks);
> +    break;
> +
> +  case PixelBitMask:
> +    ConfigurePixelBitMaskFormat (Configure, 
> &(FrameBufferInfo->PixelInformation));
> +    break;
> +
> +  case PixelBltOnly:
> +    ASSERT (FrameBufferInfo->PixelFormat != PixelBltOnly);
> +    return RETURN_UNSUPPORTED;
> +
> +  default:
> +    ASSERT (FALSE);
> +    return RETURN_INVALID_PARAMETER;
> +  }
> +
> +  Configure->PixelFormat   = FrameBufferInfo->PixelFormat;
> +  Configure->FrameBuffer   = (UINT8*) FrameBuffer;
> +  Configure->WidthInPixels = (UINTN) FrameBufferInfo->HorizontalResolution;
> +  Configure->Height        = (UINTN) FrameBufferInfo->VerticalResolution;
> +  Configure->WidthInBytes  = Configure->WidthInPixels * 
> Configure->BytesPerPixel;
> +
> +  ASSERT (Configure->WidthInBytes < sizeof (Configure->LineBuffer));
> +
> +  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->WidthInPixels) {
> +    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->WidthInPixels)) {
> +    DEBUG ((EFI_D_VERBOSE, "VideoFill (wide, one-shot)\n"));
> +    Offset = DestinationY * Configure->WidthInPixels;
> +    Offset = Configure->BytesPerPixel * Offset;
> +    Destination = Configure->FrameBuffer + Offset;
> +    SizeInBytes = WidthInBytes * Height;
> +    if (SizeInBytes >= 8) {
> +      SetMem32 (Destination, SizeInBytes & ~3, (UINT32) WideFill);
> +      SizeInBytes &= 3;
> +    }
> +    if (SizeInBytes > 0) {
> +      SetMem (Destination, SizeInBytes, (UINT8) (UINTN) WideFill);
> +    }
> +  } else {
> +    LineBufferReady = FALSE;
> +    for (IndexY = DestinationY; IndexY < (Height + DestinationY); IndexY++) {
> +      Offset = (IndexY * Configure->WidthInPixels) + 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);
> +          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->WidthInPixels) {
> +    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->WidthInPixels) + 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->WidthInPixels) {
> +    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->WidthInPixels) + 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->WidthInPixels) {
> +    return RETURN_INVALID_PARAMETER;
> +  }
> +
> +  if (DestinationY + Height > Configure->Height) {
> +    return RETURN_INVALID_PARAMETER;
> +  }
> +
> +  if (DestinationX + Width > Configure->WidthInPixels) {
> +    return RETURN_INVALID_PARAMETER;
> +  }
> +
> +  if (Width == 0 || Height == 0) {
> +    return RETURN_INVALID_PARAMETER;
> +  }
> +
> +  WidthInBytes = Width * Configure->BytesPerPixel;
> +
> +  Offset = (SourceY * Configure->WidthInPixels) + SourceX;
> +  Offset = Configure->BytesPerPixel * Offset;
> +  Source = Configure->FrameBuffer + Offset;
> +
> +  Offset = (DestinationY * Configure->WidthInPixels) + DestinationX;
> +  Offset = Configure->BytesPerPixel * Offset;
> +  Destination = Configure->FrameBuffer + Offset;
> +
> +  LineStride = Configure->WidthInBytes;
> +  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;
> +  }
> +}
> diff --git a/MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf 
> b/MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
> new file mode 100644
> index 0000000..57e4adb
> --- /dev/null
> +++ b/MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
> @@ -0,0 +1,34 @@
> +## @file
> +#  FrameBufferBltLib - Library to perform blt operations on a frame buffer.
> +#
> +#  Copyright (c) 2006 - 2016, 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.
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = FrameBufferBltLib
> +  FILE_GUID                      = 243D3E8C-2780-4A25-9693-A410475BFCEC
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = FrameBufferBltLib
> +
> +[Sources.common]
> +  FrameBufferBltLib.c
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
> index 27efb37..eb1ca0d 100644
> --- a/MdeModulePkg/MdeModulePkg.dec
> +++ b/MdeModulePkg/MdeModulePkg.dec
> @@ -153,6 +153,10 @@ [LibraryClasses]
>    #
>    PciHostBridgeLib|Include/Library/PciHostBridgeLib.h
>  
> +  ##  @libraryclass  Provides an interface for performing UEFI Graphics 
> Output Protocol Video blt operations.
> +  ##
> +  FrameBufferBltLib|Include/Library/FrameBufferBltLib.h
> +
>  [Guids]
>    ## MdeModule package token space guid
>    # Include/Guid/MdeModulePkgTokenSpace.h
> diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc
> index abce62d..63e1f91 100644
> --- a/MdeModulePkg/MdeModulePkg.dsc
> +++ b/MdeModulePkg/MdeModulePkg.dsc
> @@ -306,6 +306,7 @@ [Components]
>    MdeModulePkg/Library/DxeIpmiLibIpmiProtocol/DxeIpmiLibIpmiProtocol.inf
>    MdeModulePkg/Library/PeiIpmiLibIpmiPpi/PeiIpmiLibIpmiPpi.inf
>    
> MdeModulePkg/Library/SmmIpmiLibSmmIpmiProtocol/SmmIpmiLibSmmIpmiProtocol.inf
> +  MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
>  
>    MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
>    MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf
> 

_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to