commit dfc8a11388b0807ada896de9ddf8276e6a740498
parent 7d37cea0dc03f4100bb2edb7acf67b0b3f13dc59
Author: Serban Stanca <sstanca@mozilla.com>
Date: Mon, 10 Nov 2025 04:24:50 +0200
Revert "Bug 1999149 - Avoid double copies from SourceSurfaceWebgl to CanvasTranslator data shmems. r=aosmond" for causing build bustages in CanvasTranslator.cpp.
This reverts commit c12eb5a680ef3b15cadbd757111efb8baafaf459.
Diffstat:
12 files changed, 64 insertions(+), 160 deletions(-)
diff --git a/dom/canvas/DrawTargetWebgl.cpp b/dom/canvas/DrawTargetWebgl.cpp
@@ -1258,7 +1258,7 @@ bool SharedContextWebgl::ReadInto(uint8_t* aDstData, int32_t aDstStride,
}
already_AddRefed<DataSourceSurface> SharedContextWebgl::ReadSnapshot(
- TextureHandle* aHandle, uint8_t* aData, int32_t aStride) {
+ TextureHandle* aHandle) {
// Allocate a data surface, map it, and read from the WebGL context into the
// surface.
SurfaceFormat format = SurfaceFormat::UNKNOWN;
@@ -1271,9 +1271,7 @@ already_AddRefed<DataSourceSurface> SharedContextWebgl::ReadSnapshot(
bounds = mCurrentTarget->GetRect();
}
RefPtr<DataSourceSurface> surface =
- aData ? Factory::CreateWrappingDataSourceSurface(aData, aStride,
- bounds.Size(), format)
- : Factory::CreateDataSourceSurface(bounds.Size(), format);
+ Factory::CreateDataSourceSurface(bounds.Size(), format);
if (!surface) {
return nullptr;
}
@@ -1285,10 +1283,6 @@ already_AddRefed<DataSourceSurface> SharedContextWebgl::ReadSnapshot(
return surface.forget();
}
-static inline int32_t GetPBOStride(int32_t aWidth, SurfaceFormat aFormat) {
- return GetAlignedStride<16>(aWidth, BytesPerPixel(aFormat));
-}
-
already_AddRefed<WebGLBuffer> SharedContextWebgl::ReadSnapshotIntoPBO(
SourceSurfaceWebgl* aOwner, TextureHandle* aHandle) {
// Allocate a PBO, and read from the WebGL context into it.
@@ -1301,8 +1295,8 @@ already_AddRefed<WebGLBuffer> SharedContextWebgl::ReadSnapshotIntoPBO(
format = mCurrentTarget->GetFormat();
bounds = mCurrentTarget->GetRect();
}
- int32_t pboStride = GetPBOStride(bounds.width, format);
- size_t bufSize = BufferSizeFromStrideAndHeight(pboStride, bounds.height);
+ int32_t stride = GetAlignedStride<16>(bounds.width, BytesPerPixel(format));
+ size_t bufSize = BufferSizeFromStrideAndHeight(stride, bounds.height);
if (!bufSize) {
return nullptr;
}
@@ -1323,7 +1317,7 @@ already_AddRefed<WebGLBuffer> SharedContextWebgl::ReadSnapshotIntoPBO(
mWebgl->UninitializedBufferData_SizeOnly(LOCAL_GL_PIXEL_PACK_BUFFER, bufSize,
LOCAL_GL_STREAM_READ);
mWebgl->BindBuffer(LOCAL_GL_PIXEL_PACK_BUFFER, 0);
- if (!ReadInto(nullptr, pboStride, format, bounds, aHandle, pbo)) {
+ if (!ReadInto(nullptr, stride, format, bounds, aHandle, pbo)) {
return nullptr;
}
@@ -1340,20 +1334,16 @@ already_AddRefed<WebGLBuffer> SharedContextWebgl::ReadSnapshotIntoPBO(
already_AddRefed<DataSourceSurface> SharedContextWebgl::ReadSnapshotFromPBO(
const RefPtr<WebGLBuffer>& aBuffer, SurfaceFormat aFormat,
- const IntSize& aSize, uint8_t* aData, int32_t aStride) {
+ const IntSize& aSize) {
// For an existing PBO where a readback has been initiated previously, create
// a new data surface and copy the PBO's data into the data surface.
- int32_t pboStride = GetPBOStride(aSize.width, aFormat);
- size_t bufSize =
- BufferSizeFromStrideAndHeight(aData ? aStride : pboStride, aSize.height);
+ int32_t stride = GetAlignedStride<16>(aSize.width, BytesPerPixel(aFormat));
+ size_t bufSize = BufferSizeFromStrideAndHeight(stride, aSize.height);
if (!bufSize) {
return nullptr;
}
RefPtr<DataSourceSurface> surface =
- aData ? Factory::CreateWrappingDataSourceSurface(aData, aStride, aSize,
- aFormat)
- : Factory::CreateDataSourceSurfaceWithStride(aSize, aFormat,
- pboStride);
+ Factory::CreateDataSourceSurfaceWithStride(aSize, aFormat, stride);
if (!surface) {
return nullptr;
}
@@ -1363,9 +1353,8 @@ already_AddRefed<DataSourceSurface> SharedContextWebgl::ReadSnapshotFromPBO(
}
mWebgl->BindBuffer(LOCAL_GL_PIXEL_PACK_BUFFER, aBuffer);
Range<uint8_t> range = {dstMap.GetData(), bufSize};
- bool success = mWebgl->AsWebGL2()->GetBufferSubData(
- LOCAL_GL_PIXEL_PACK_BUFFER, 0, range, aSize.height,
- BytesPerPixel(aFormat) * aSize.height, pboStride, dstMap.GetStride());
+ bool success = static_cast<WebGL2Context*>(mWebgl.get())
+ ->GetBufferSubData(LOCAL_GL_PIXEL_PACK_BUFFER, 0, range);
mWebgl->BindBuffer(LOCAL_GL_PIXEL_PACK_BUFFER, 0);
if (success) {
return surface.forget();
@@ -1379,8 +1368,8 @@ void SharedContextWebgl::RemoveSnapshotPBO(
MOZ_ASSERT(aOwner && buffer);
IntSize size = aOwner->GetSize();
SurfaceFormat format = aOwner->GetFormat();
- int32_t pboStride = GetPBOStride(size.width, format);
- size_t bufSize = BufferSizeFromStrideAndHeight(pboStride, size.height);
+ int32_t stride = GetAlignedStride<16>(size.width, BytesPerPixel(format));
+ size_t bufSize = BufferSizeFromStrideAndHeight(stride, size.height);
// If the queue is empty, no memory should be used. Otherwise, deduct the
// usage from the queue.
if (mSnapshotPBOs.empty()) {
@@ -1415,14 +1404,13 @@ bool DrawTargetWebgl::ReadInto(uint8_t* aDstData, int32_t aDstStride) {
}
// Utility method to install the target before reading a snapshot.
-already_AddRefed<DataSourceSurface> DrawTargetWebgl::ReadSnapshot(
- uint8_t* aData, int32_t aStride) {
+already_AddRefed<DataSourceSurface> DrawTargetWebgl::ReadSnapshot() {
AutoRestoreContext restore(this);
if (!PrepareContext(false)) {
return nullptr;
}
mProfile.OnReadback();
- return mSharedContext->ReadSnapshot(nullptr, aData, aStride);
+ return mSharedContext->ReadSnapshot();
}
already_AddRefed<WebGLBuffer> DrawTargetWebgl::ReadSnapshotIntoPBO(
@@ -3941,10 +3929,11 @@ already_AddRefed<SourceSurface> SharedContextWebgl::DownscaleBlurInput(
if (fullHandle) {
fullBounds += fullHandle->GetBounds().TopLeft();
}
- mWebgl->AsWebGL2()->BlitFramebuffer(
- fullBounds.x, fullBounds.y, fullBounds.XMost(), fullBounds.YMost(),
- halfBounds.x, halfBounds.y, halfBounds.XMost(), halfBounds.YMost(),
- LOCAL_GL_COLOR_BUFFER_BIT, LOCAL_GL_LINEAR);
+ static_cast<WebGL2Context*>(mWebgl.get())
+ ->BlitFramebuffer(fullBounds.x, fullBounds.y, fullBounds.XMost(),
+ fullBounds.YMost(), halfBounds.x, halfBounds.y,
+ halfBounds.XMost(), halfBounds.YMost(),
+ LOCAL_GL_COLOR_BUFFER_BIT, LOCAL_GL_LINEAR);
fullHandle = halfHandle;
fullTex = halfBacking->GetWebGLTexture();
diff --git a/dom/canvas/DrawTargetWebgl.h b/dom/canvas/DrawTargetWebgl.h
@@ -349,8 +349,7 @@ class SharedContextWebgl : public mozilla::RefCounted<SharedContextWebgl>,
const IntRect& aBounds, TextureHandle* aHandle = nullptr,
const RefPtr<WebGLBuffer>& aBuffer = nullptr);
already_AddRefed<DataSourceSurface> ReadSnapshot(
- TextureHandle* aHandle = nullptr, uint8_t* aData = nullptr,
- int32_t aStride = 0);
+ TextureHandle* aHandle = nullptr);
already_AddRefed<TextureHandle> WrapSnapshot(const IntSize& aSize,
SurfaceFormat aFormat,
RefPtr<WebGLTexture> aTex);
@@ -361,7 +360,7 @@ class SharedContextWebgl : public mozilla::RefCounted<SharedContextWebgl>,
SourceSurfaceWebgl* aOwner, TextureHandle* aHandle = nullptr);
already_AddRefed<DataSourceSurface> ReadSnapshotFromPBO(
const RefPtr<WebGLBuffer>& aBuffer, SurfaceFormat aFormat,
- const IntSize& aSize, uint8_t* aData = nullptr, int32_t aStride = 0);
+ const IntSize& aSize);
void RemoveSnapshotPBO(SourceSurfaceWebgl* aOwner,
already_AddRefed<WebGLBuffer> aBuffer);
void ClearSnapshotPBOs(size_t aMaxMemory = 0);
@@ -836,8 +835,7 @@ class DrawTargetWebgl : public DrawTarget, public SupportsWeakPtr {
bool ShouldUseSubpixelAA(ScaledFont* aFont, const DrawOptions& aOptions);
bool ReadInto(uint8_t* aDstData, int32_t aDstStride);
- already_AddRefed<DataSourceSurface> ReadSnapshot(uint8_t* aData = nullptr,
- int32_t aStride = 0);
+ already_AddRefed<DataSourceSurface> ReadSnapshot();
already_AddRefed<WebGLBuffer> ReadSnapshotIntoPBO(SourceSurfaceWebgl* aOwner);
already_AddRefed<TextureHandle> CopySnapshot(const IntRect& aRect);
already_AddRefed<TextureHandle> CopySnapshot() {
diff --git a/dom/canvas/SourceSurfaceWebgl.cpp b/dom/canvas/SourceSurfaceWebgl.cpp
@@ -8,7 +8,6 @@
#include "DrawTargetWebglInternal.h"
#include "WebGLBuffer.h"
-#include "mozilla/gfx/Swizzle.h"
namespace mozilla::gfx {
@@ -38,26 +37,15 @@ SourceSurfaceWebgl::~SourceSurfaceWebgl() {
// Read back the contents of the target or texture handle for data use. This
// may attempt a readback into a PBO for performance, unless forced to
// immediately read into data.
-inline bool SourceSurfaceWebgl::EnsureData(bool aForce, uint8_t* aData,
- int32_t aStride) {
+inline bool SourceSurfaceWebgl::EnsureData(bool aForce) {
if (mData) {
- if (aData) {
- DataSourceSurface::ScopedMap map(mData, MapType::READ);
- if (!map.IsMapped()) {
- return false;
- }
- SwizzleData(map.GetData(), map.GetStride(), mFormat, aData, aStride,
- mFormat, mSize);
- }
return true;
}
if (mReadBuffer) {
// If there is a pending PBO readback, then copy the contents of the PBO.
if (RefPtr<SharedContextWebgl> sharedContext = {mSharedContext}) {
- mData = sharedContext->ReadSnapshotFromPBO(mReadBuffer, mFormat, mSize,
- aData, aStride);
- mOwnsData = !mData || !aData;
+ mData = sharedContext->ReadSnapshotFromPBO(mReadBuffer, mFormat, mSize);
sharedContext->RemoveSnapshotPBO(this, mReadBuffer.forget());
}
mReadBuffer = nullptr;
@@ -69,8 +57,7 @@ inline bool SourceSurfaceWebgl::EnsureData(bool aForce, uint8_t* aData,
mReadBuffer = dt->ReadSnapshotIntoPBO(this);
}
if (!mReadBuffer) {
- mData = dt->ReadSnapshot(aData, aStride);
- mOwnsData = !mData || !aData;
+ mData = dt->ReadSnapshot();
}
} else if (mHandle) {
// Assume that the target changed, so there should be a texture handle
@@ -81,18 +68,13 @@ inline bool SourceSurfaceWebgl::EnsureData(bool aForce, uint8_t* aData,
mReadBuffer = sharedContext->ReadSnapshotIntoPBO(this, mHandle);
}
if (!mReadBuffer) {
- mData = sharedContext->ReadSnapshot(mHandle, aData, aStride);
- mOwnsData = !mData || !aData;
+ mData = sharedContext->ReadSnapshot(mHandle);
}
}
}
return mData || mReadBuffer;
}
-bool SourceSurfaceWebgl::ReadDataInto(uint8_t* aData, int32_t aStride) {
- return EnsureData(true, aData, aStride);
-}
-
bool SourceSurfaceWebgl::ForceReadFromPBO() {
if (mReadBuffer && EnsureData()) {
MOZ_ASSERT(!mReadBuffer);
@@ -105,11 +87,7 @@ uint8_t* SourceSurfaceWebgl::GetData() {
if (!EnsureData()) {
return nullptr;
}
- if (!mOwnsData) {
- mData = Factory::CopyDataSourceSurface(mData);
- mOwnsData = true;
- }
- return mData ? mData->GetData() : nullptr;
+ return mData->GetData();
}
int32_t SourceSurfaceWebgl::Stride() {
@@ -123,11 +101,7 @@ bool SourceSurfaceWebgl::Map(MapType aType, MappedSurface* aMappedSurface) {
if (!EnsureData()) {
return false;
}
- if (!mOwnsData && aType != MapType::READ) {
- mData = Factory::CopyDataSourceSurface(mData);
- mOwnsData = true;
- }
- return mData && mData->Map(aType, aMappedSurface);
+ return mData->Map(aType, aMappedSurface);
}
void SourceSurfaceWebgl::Unmap() {
@@ -204,7 +178,6 @@ void SourceSurfaceWebgl::OnUnlinkTexture(SharedContextWebgl* aContext,
}
if (!mReadBuffer) {
mData = aContext->ReadSnapshot(mHandle);
- mOwnsData = true;
}
}
mHandle = nullptr;
diff --git a/dom/canvas/SourceSurfaceWebgl.h b/dom/canvas/SourceSurfaceWebgl.h
@@ -44,16 +44,13 @@ class SourceSurfaceWebgl : public DataSourceSurface {
already_AddRefed<SourceSurface> ExtractSubrect(const IntRect& aRect) override;
- bool ReadDataInto(uint8_t* aData, int32_t aStride) override;
-
private:
friend class DrawTargetWebgl;
friend class SharedContextWebgl;
explicit SourceSurfaceWebgl(const RefPtr<SharedContextWebgl>& aSharedContext);
- bool EnsureData(bool aForce = true, uint8_t* aData = nullptr,
- int32_t aStride = 0);
+ bool EnsureData(bool aForce = true);
bool ForceReadFromPBO();
void DrawTargetWillChange(bool aNeedHandle);
@@ -71,8 +68,6 @@ class SourceSurfaceWebgl : public DataSourceSurface {
RefPtr<WebGLBuffer> mReadBuffer;
// Any data that has been read back from the WebGL context for mapping.
RefPtr<DataSourceSurface> mData;
- // Whether the data is safe to modify
- bool mOwnsData = true;
// The draw target that currently owns the texture for this surface.
WeakPtr<DrawTargetWebgl> mDT;
// The actual shared context that any WebGL resources belong to.
diff --git a/dom/canvas/WebGL2Context.h b/dom/canvas/WebGL2Context.h
@@ -30,8 +30,6 @@ class WebGL2Context final : public WebGLContext {
virtual bool IsWebGL2() const override { return true; }
- virtual WebGL2Context* AsWebGL2() override { return this; }
-
// -------------------------------------------------------------------------
// Buffer objects - WebGL2ContextBuffers.cpp
@@ -39,9 +37,7 @@ class WebGL2Context final : public WebGLContext {
uint64_t readOffset, uint64_t writeOffset,
uint64_t size) const;
bool GetBufferSubData(GLenum target, uint64_t srcByteOffset,
- const Range<uint8_t>& dest, uint64_t numRows = 0,
- uint64_t rowDataWidth = 0, uint64_t srcStride = 0,
- uint64_t destStride = 0) const;
+ const Range<uint8_t>& dest) const;
// -------------------------------------------------------------------------
// Framebuffer objects - WebGL2ContextFramebuffers.cpp
diff --git a/dom/canvas/WebGL2ContextBuffers.cpp b/dom/canvas/WebGL2ContextBuffers.cpp
@@ -78,35 +78,24 @@ void WebGL2Context::CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
}
bool WebGL2Context::GetBufferSubData(GLenum target, uint64_t srcByteOffset,
- const Range<uint8_t>& dest,
- uint64_t numRows, uint64_t rowDataWidth,
- uint64_t srcStride,
- uint64_t destStride) const {
+ const Range<uint8_t>& dest) const {
const FuncScope funcScope(*this, "getBufferSubData");
if (IsContextLost()) return false;
const auto& buffer = ValidateBufferSelection(target);
if (!buffer) return false;
- uint64_t srcLen =
- numRows > 0 ? srcStride * (numRows - 1) + rowDataWidth : dest.length();
- uint64_t destLen =
- numRows > 0 ? destStride * (numRows - 1) + rowDataWidth : dest.length();
- if (!buffer->ValidateRange(srcByteOffset, srcLen)) return false;
- if (rowDataWidth > srcStride || rowDataWidth > destStride ||
- destLen > dest.length()) {
- ErrorInvalidValue("Destination is outside buffer.");
- return false;
- }
+ const auto byteLen = dest.length();
+ if (!buffer->ValidateRange(srcByteOffset, byteLen)) return false;
////
if (!CheckedInt<GLintptr>(srcByteOffset).isValid() ||
- !CheckedInt<GLsizeiptr>(srcLen).isValid()) {
- ErrorOutOfMemory("Offset or size too large for platform.");
+ !CheckedInt<GLsizeiptr>(byteLen).isValid()) {
+ ErrorOutOfMemory("offset or size too large for platform.");
return false;
}
- const GLsizeiptr glByteLen(srcLen);
+ const GLsizeiptr glByteLen(byteLen);
////
@@ -132,7 +121,7 @@ bool WebGL2Context::GetBufferSubData(GLenum target, uint64_t srcByteOffset,
const ScopedLazyBind readBind(gl, target, buffer);
- if (srcLen) {
+ if (byteLen) {
const bool isTF = (target == LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER);
GLenum mapTarget = target;
if (isTF) {
@@ -141,20 +130,9 @@ bool WebGL2Context::GetBufferSubData(GLenum target, uint64_t srcByteOffset,
mapTarget = LOCAL_GL_ARRAY_BUFFER;
}
- const void* mappedBytes = gl->fMapBufferRange(
+ const auto mappedBytes = gl->fMapBufferRange(
mapTarget, srcByteOffset, glByteLen, LOCAL_GL_MAP_READ_BIT);
- if (numRows > 0 && (destStride != srcStride || rowDataWidth != srcStride)) {
- const uint8_t* srcRow = (const uint8_t*)mappedBytes;
- uint8_t* destRow = dest.begin().get();
- while (numRows > 0) {
- memcpy(destRow, srcRow, rowDataWidth);
- srcRow += srcStride;
- destRow += destStride;
- --numRows;
- }
- } else {
- memcpy(dest.begin().get(), mappedBytes, srcLen);
- }
+ memcpy(dest.begin().get(), mappedBytes, dest.length());
gl->fUnmapBuffer(mapTarget);
if (isTF) {
diff --git a/dom/canvas/WebGLContext.h b/dom/canvas/WebGLContext.h
@@ -77,7 +77,6 @@ class WebGLSync;
class WebGLTexture;
class WebGLTransformFeedback;
class WebGLVertexArray;
-class WebGL2Context;
namespace dom {
class Document;
@@ -1025,8 +1024,6 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr {
public:
virtual bool IsWebGL2() const { return false; }
- virtual WebGL2Context* AsWebGL2() { return nullptr; }
-
struct FailureReason {
nsCString key; // For reporting.
nsCString info;
diff --git a/gfx/2d/2D.h b/gfx/2d/2D.h
@@ -883,11 +883,6 @@ class DataSourceSurface : public SourceSurface {
*/
virtual void Invalidate(const IntRect& aDirtyRect) {}
- /**
- * Attempt to cache internal data into the supplied memory buffer.
- */
- virtual bool ReadDataInto(uint8_t* aData, int32_t aStride) { return false; }
-
protected:
Atomic<int32_t> mMapCount;
};
diff --git a/gfx/2d/Factory.cpp b/gfx/2d/Factory.cpp
@@ -952,8 +952,7 @@ already_AddRefed<DataSourceSurface> Factory::CopyDataSourceSurface(
MOZ_ASSERT(aSource->GetFormat() == SurfaceFormat::R8G8B8A8 ||
aSource->GetFormat() == SurfaceFormat::R8G8B8X8 ||
aSource->GetFormat() == SurfaceFormat::B8G8R8A8 ||
- aSource->GetFormat() == SurfaceFormat::B8G8R8X8 ||
- aSource->GetFormat() == SurfaceFormat::A8);
+ aSource->GetFormat() == SurfaceFormat::B8G8R8X8);
DataSourceSurface::ScopedMap srcMap(aSource, DataSourceSurface::READ);
if (NS_WARN_IF(!srcMap.IsMapped())) {
@@ -988,14 +987,12 @@ void Factory::CopyDataSourceSurface(DataSourceSurface* aSource,
MOZ_ASSERT(aSource->GetFormat() == SurfaceFormat::R8G8B8A8 ||
aSource->GetFormat() == SurfaceFormat::R8G8B8X8 ||
aSource->GetFormat() == SurfaceFormat::B8G8R8A8 ||
- aSource->GetFormat() == SurfaceFormat::B8G8R8X8 ||
- aSource->GetFormat() == SurfaceFormat::A8);
+ aSource->GetFormat() == SurfaceFormat::B8G8R8X8);
MOZ_ASSERT(aDest->GetFormat() == SurfaceFormat::R8G8B8A8 ||
aDest->GetFormat() == SurfaceFormat::R8G8B8X8 ||
aDest->GetFormat() == SurfaceFormat::B8G8R8A8 ||
aDest->GetFormat() == SurfaceFormat::B8G8R8X8 ||
- aDest->GetFormat() == SurfaceFormat::R5G6B5_UINT16 ||
- aDest->GetFormat() == SurfaceFormat::A8);
+ aDest->GetFormat() == SurfaceFormat::R5G6B5_UINT16);
DataSourceSurface::MappedSurface srcMap;
DataSourceSurface::MappedSurface destMap;
diff --git a/gfx/layers/ipc/CanvasChild.cpp b/gfx/layers/ipc/CanvasChild.cpp
@@ -625,7 +625,7 @@ already_AddRefed<gfx::DataSourceSurface> CanvasChild::GetDataSurface(
}
}
- RecordEvent(RecordedCacheDataSurface(aSurface));
+ RecordEvent(RecordedCacheDataSurface(aSurface, true));
if (!EnsureDataSurfaceShmem(ssSize, ssFormat)) {
return nullptr;
diff --git a/gfx/layers/ipc/CanvasTranslator.cpp b/gfx/layers/ipc/CanvasTranslator.cpp
@@ -304,15 +304,6 @@ ipc::IPCResult CanvasTranslator::RecvSetDataSurfaceBuffer(
return IPC_OK();
}
-void CanvasTranslator::DataSurfaceBufferWillChange() {
- if (RefPtr<gfx::DataSourceSurface> owner = {mDataSurfaceShmemOwner}) {
- // Force copy-on-write of contained shmem if applicable
- gfx::DataSourceSurface::ScopedMap map(
- owner, gfx::DataSourceSurface::MapType::READ_WRITE);
- mDataSurfaceShmemOwner = nullptr;
- }
-}
-
bool CanvasTranslator::SetDataSurfaceBuffer(
ipc::MutableSharedMemoryHandle&& aBufferHandle) {
MOZ_ASSERT(IsInTaskQueue());
@@ -331,7 +322,6 @@ bool CanvasTranslator::SetDataSurfaceBuffer(
return false;
}
- DataSurfaceBufferWillChange();
mDataSurfaceShmem = aBufferHandle.Map();
if (!mDataSurfaceShmem) {
return false;
@@ -355,8 +345,22 @@ void CanvasTranslator::GetDataSurface(uint64_t aSurfaceRef) {
return;
}
}
+ gfx::DataSourceSurface::ScopedMap map(dataSurface,
+ gfx::DataSourceSurface::READ);
+ if (!map.IsMapped()) {
+ return;
+ }
+
auto dstSize = dataSurface->GetSize();
+ auto srcSize = map.GetSurface()->GetSize();
gfx::SurfaceFormat format = dataSurface->GetFormat();
+ int32_t bpp = BytesPerPixel(format);
+ int32_t dataFormatWidth = dstSize.width * bpp;
+ int32_t srcStride = map.GetStride();
+ if (dataFormatWidth > srcStride || srcSize != dstSize) {
+ return;
+ }
+
int32_t dstStride =
ImageDataSerializer::ComputeRGBStride(format, dstSize.width);
auto requiredSize =
@@ -365,25 +369,14 @@ void CanvasTranslator::GetDataSurface(uint64_t aSurfaceRef) {
return;
}
- // Ensure any old references to the shmem are copied before modification.
- DataSurfaceBufferWillChange();
-
- // Try directly reading the data surface into shmem to avoid further copies.
uint8_t* dst = mDataSurfaceShmem.DataAs<uint8_t>();
- if (dataSurface->ReadDataInto(dst, dstStride)) {
- mDataSurfaceShmemOwner = dataSurface;
- return;
- }
-
- // Otherwise, map the data surface and do an explicit copy.
- gfx::DataSourceSurface::ScopedMap map(dataSurface,
- gfx::DataSourceSurface::MapType::READ);
- if (!map.IsMapped()) {
- return;
+ const uint8_t* src = map.GetData();
+ const uint8_t* endSrc = src + (srcSize.height * srcStride);
+ while (src < endSrc) {
+ memcpy(dst, src, dataFormatWidth);
+ src += srcStride;
+ dst += dstStride;
}
-
- gfx::SwizzleData(map.GetData(), map.GetStride(), format, dst, dstStride,
- format, dstSize);
}
already_AddRefed<gfx::SourceSurface> CanvasTranslator::WaitForSurface(
@@ -1005,8 +998,6 @@ void CanvasTranslator::PrepareShmem(
}
void CanvasTranslator::CacheDataSnapshots() {
- DataSurfaceBufferWillChange();
-
if (mSharedContext) {
// If there are any DrawTargetWebgls, then try to cache their framebuffers
// in software surfaces, just in case the GL context is lost. So long as
@@ -1381,8 +1372,6 @@ bool CanvasTranslator::PushRemoteTexture(
void CanvasTranslator::ClearTextureInfo() {
MOZ_ASSERT(mIPDLClosed);
- DataSurfaceBufferWillChange();
-
mUsedDataSurfaceForSurfaceDescriptor = nullptr;
mUsedWrapperForSurfaceDescriptor = nullptr;
mUsedSurfaceDescriptorForSurfaceDescriptor = Nothing();
diff --git a/gfx/layers/ipc/CanvasTranslator.h b/gfx/layers/ipc/CanvasTranslator.h
@@ -411,8 +411,6 @@ class CanvasTranslator final : public gfx::InlineTranslator,
*/
bool SetDataSurfaceBuffer(ipc::MutableSharedMemoryHandle&& aBufferHandle);
- void DataSurfaceBufferWillChange();
-
bool ReadNextEvent(EventType& aEventType);
bool HasPendingEvent();
@@ -528,7 +526,6 @@ class CanvasTranslator final : public gfx::InlineTranslator,
CanvasShmem mCurrentShmem;
gfx::MemReader mCurrentMemReader{0, 0};
ipc::SharedMemoryMapping mDataSurfaceShmem;
- ThreadSafeWeakPtr<gfx::DataSourceSurface> mDataSurfaceShmemOwner;
UniquePtr<CrossProcessSemaphore> mWriterSemaphore;
UniquePtr<CrossProcessSemaphore> mReaderSemaphore;
TextureType mTextureType = TextureType::Unknown;