Verified Commit 28e9f42a authored by Lee Salzman's avatar Lee Salzman Committed by Pier Angelo Vendrame
Browse files

Bug 1991040. r=gfx-reviewers,aosmond,ahale a=RyanVM

parent 0929bdcb
Loading
Loading
Loading
Loading
+36 −12
Original line number Diff line number Diff line
@@ -1928,10 +1928,29 @@ bool SharedContextWebgl::UploadSurface(DataSourceSurface* aData,
                                       const IntPoint& aDstOffset, bool aInit,
                                       bool aZero,
                                       const RefPtr<WebGLTexture>& aTex) {
  webgl::TexUnpackBlobDesc texDesc = {
      LOCAL_GL_TEXTURE_2D,
      {uint32_t(aSrcRect.width), uint32_t(aSrcRect.height), 1}};
  webgl::TexUnpackBlobDesc texDesc = {LOCAL_GL_TEXTURE_2D};
  IntRect srcRect(aSrcRect);
  IntPoint dstOffset(aDstOffset);
  if (srcRect.IsEmpty()) {
    return true;
  }
  if (aData) {
    // If the source rect could not possibly overlap the surface, then it is
    // effectively empty with nothing to upload.
    srcRect = srcRect.SafeIntersect(IntRect(IntPoint(0, 0), aData->GetSize()));
    if (srcRect.IsEmpty()) {
      return true;
    }
    // If there is a non-empty rect remaining, then ensure the dest offset
    // reflects the change in source rect.
    dstOffset += srcRect.TopLeft() - aSrcRect.TopLeft();

    // Ensure source data matches the expected format size.
    int32_t bpp = BytesPerPixel(aFormat);
    if (bpp != BytesPerPixel(aData->GetFormat())) {
      return false;
    }

    // The surface needs to be uploaded to its backing texture either to
    // initialize or update the texture handle contents. Map the data
    // contents of the surface so it can be read.
@@ -1940,13 +1959,11 @@ bool SharedContextWebgl::UploadSurface(DataSourceSurface* aData,
      return false;
    }
    int32_t stride = map.GetStride();
    int32_t bpp = BytesPerPixel(aFormat);
    // Get the data pointer range considering the sampling rect offset and
    // size.
    Span<const uint8_t> range(
        map.GetData() + aSrcRect.y * size_t(stride) + aSrcRect.x * bpp,
        std::max(aSrcRect.height - 1, 0) * size_t(stride) +
            aSrcRect.width * bpp);
        map.GetData() + srcRect.y * size_t(stride) + srcRect.x * bpp,
        std::max(srcRect.height - 1, 0) * size_t(stride) + srcRect.width * bpp);
    texDesc.cpuData = Some(range);
    // If the stride happens to be 4 byte aligned, assume that is the
    // desired alignment regardless of format (even A8). Otherwise, we
@@ -1956,10 +1973,16 @@ bool SharedContextWebgl::UploadSurface(DataSourceSurface* aData,
  } else if (aZero) {
    // Create a PBO filled with zero data to initialize the texture data and
    // avoid slow initialization inside WebGL.
    MOZ_ASSERT(aSrcRect.TopLeft() == IntPoint(0, 0));
    size_t size =
        size_t(GetAlignedStride<4>(aSrcRect.width, BytesPerPixel(aFormat))) *
        aSrcRect.height;
    if (srcRect.TopLeft() != IntPoint(0, 0)) {
      MOZ_ASSERT_UNREACHABLE("Invalid origin for texture initialization.");
      return false;
    }
    int32_t stride = GetAlignedStride<4>(srcRect.width, BytesPerPixel(aFormat));
    if (stride <= 0) {
      MOZ_ASSERT_UNREACHABLE("Invalid stride for texture initialization.");
      return false;
    }
    size_t size = size_t(stride) * srcRect.height;
    if (!mZeroBuffer || size > mZeroSize) {
      mZeroBuffer = mWebgl->CreateBuffer();
      mZeroSize = size;
@@ -1973,6 +1996,7 @@ bool SharedContextWebgl::UploadSurface(DataSourceSurface* aData,
    }
    texDesc.pboOffset = Some(0);
  }
  texDesc.size = uvec3(uint32_t(srcRect.width), uint32_t(srcRect.height), 1);
  // Upload as RGBA8 to avoid swizzling during upload. Surfaces provide
  // data as BGRA, but we manually swizzle that in the shader. An A8
  // surface will be stored as an R8 texture that will also be swizzled
@@ -1987,7 +2011,7 @@ bool SharedContextWebgl::UploadSurface(DataSourceSurface* aData,
    mWebgl->BindTexture(LOCAL_GL_TEXTURE_2D, aTex);
  }
  mWebgl->TexImage(0, aInit ? intFormat : 0,
                   {uint32_t(aDstOffset.x), uint32_t(aDstOffset.y), 0}, texPI,
                   {uint32_t(dstOffset.x), uint32_t(dstOffset.y), 0}, texPI,
                   texDesc);
  if (aTex) {
    mWebgl->BindTexture(LOCAL_GL_TEXTURE_2D, mLastTexture);