public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Ruiyu Ni <ruiyu.ni@intel.com>
To: edk2-devel@lists.01.org
Cc: Justen Jordan <jordan.l.justen@intel.com>,
	Laszlo Ersek <lersek@redhat.com>
Subject: [PATCH v4 2/8] MdeModulePkg: Add FrameBufferBltLib library instance
Date: Tue, 11 Oct 2016 13:50:42 +0800	[thread overview]
Message-ID: <20161011055048.217588-3-ruiyu.ni@intel.com> (raw)
In-Reply-To: <20161011055048.217588-1-ruiyu.ni@intel.com>

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 <ruiyu.ni@intel.com>
Reviewed-by: Feng Tian <feng.tian@intel.com>
Cc: Justen Jordan <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
---
 .../Library/FrameBufferBltLib/FrameBufferBltLib.c  | 704 +++++++++++++++++++++
 .../FrameBufferBltLib/FrameBufferBltLib.inf        |  34 +
 MdeModulePkg/MdeModulePkg.dsc                      |   1 +
 3 files changed, 739 insertions(+)
 create mode 100644 MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.c
 create mode 100644 MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf

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.dsc b/MdeModulePkg/MdeModulePkg.dsc
index 214cb6c..6efd2c2 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
-- 
2.9.0.windows.1



  parent reply	other threads:[~2016-10-11  5:50 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-10-11  5:50 [PATCH v4 0/8] Add FrameBufferBltLib and GraphicsOutputDxe Ruiyu Ni
2016-10-11  5:50 ` [PATCH v4 1/8] MdeModulePkg: Add FrameBufferBltLib library class Ruiyu Ni
2016-10-11  5:50 ` Ruiyu Ni [this message]
2016-10-11 14:13   ` [PATCH v4 2/8] MdeModulePkg: Add FrameBufferBltLib library instance Laszlo Ersek
2016-10-11 14:51   ` Laszlo Ersek
2016-10-11  5:50 ` [PATCH v4 3/8] MdeModulePkg: Add GraphicsOutputDxe driver Ruiyu Ni
2016-10-11  5:50 ` [PATCH v4 4/8] OvmfPkg: Include MdeModulePkg/FrameBufferLib in OvmfPkg Ruiyu Ni
2016-10-11 14:23   ` Laszlo Ersek
2016-10-11  5:50 ` [PATCH v4 5/8] ArmVirtPkg: Include MdeModulePkg/FrameBufferLib in ArmVirtPkg Ruiyu Ni
2016-10-11 14:25   ` Laszlo Ersek
2016-10-11  5:50 ` [PATCH v4 6/8] OvmfPkg: QemuVideoDxe uses MdeModulePkg/FrameBufferLib Ruiyu Ni
2016-10-11 14:29   ` Laszlo Ersek
2016-10-11  5:50 ` [PATCH v4 7/8] OvmfPkg: Remove unused BltLib reference Ruiyu Ni
2016-10-11 14:31   ` Laszlo Ersek
2016-10-11  5:50 ` [PATCH v4 8/8] ArmVirtPkg: " Ruiyu Ni
2016-10-11 14:32   ` Laszlo Ersek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20161011055048.217588-3-ruiyu.ni@intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox