Bug 1771007 - Avoid sending SourceSurfaceWebgl off-thread. r=jrmuizel,gfx-reviewers

BorrowSnapshot can be called by OffScreenCanvas in various places that may send
a SourceSurfaceWebgl to the main thread. If it did not originate from the main
thread, then this can cause multiple threads to use it. In general we want to
avoid this. For now, override BorrowSnapshot and make it always force a Skia
snapshot that can be safely shared between threads instead of SourceSurfaceWebgl.

Differential Revision: https://phabricator.services.mozilla.com/D152417
This commit is contained in:
Lee Salzman 2022-07-26 01:28:48 +00:00
Родитель b7ed12cb3c
Коммит 11df7a2ec5
6 изменённых файлов: 29 добавлений и 27 удалений

Просмотреть файл

@ -650,27 +650,28 @@ already_AddRefed<TextureHandle> DrawTargetWebgl::CopySnapshot() {
return mSharedContext->CopySnapshot();
}
// Borrow a snapshot that may be used by another thread for composition. Only
// Skia snapshots are safe to pass around.
already_AddRefed<SourceSurface> DrawTargetWebgl::GetDataSnapshot() {
if (!mSkiaValid) {
ReadIntoSkia();
} else if (mSkiaLayer) {
FlattenSkia();
}
return mSkia->Snapshot(mFormat);
}
already_AddRefed<SourceSurface> DrawTargetWebgl::Snapshot() {
// If already using the Skia fallback, then just snapshot that.
if (mSkiaValid) {
if (mSkiaLayer) {
FlattenSkia();
}
return mSkia->Snapshot(mFormat);
return GetDataSnapshot();
}
// There's no valid Skia snapshot, so we need to get one from the WebGL
// context.
if (!mSnapshot) {
// First just try to create a copy-on-write reference to this target.
RefPtr<SourceSurfaceWebgl> snapshot = new SourceSurfaceWebgl;
if (snapshot->Init(this)) {
mSnapshot = snapshot;
} else {
// Otherwse, we have to just read back the framebuffer contents. This may
// fail if the WebGL context is lost.
mSnapshot = ReadSnapshot();
}
// Create a copy-on-write reference to this target.
mSnapshot = new SourceSurfaceWebgl(this);
}
return do_AddRef(mSnapshot);
}

Просмотреть файл

@ -305,6 +305,7 @@ class DrawTargetWebgl : public DrawTarget, public SupportsWeakPtr {
BackendType GetBackendType() const override { return BackendType::WEBGL; }
IntSize GetSize() const override { return mSize; }
already_AddRefed<SourceSurface> GetDataSnapshot();
already_AddRefed<SourceSurface> Snapshot() override;
already_AddRefed<SourceSurface> GetBackingSurface() override;
void DetachAllSnapshots() override;

Просмотреть файл

@ -9,7 +9,11 @@
namespace mozilla::gfx {
SourceSurfaceWebgl::SourceSurfaceWebgl() = default;
SourceSurfaceWebgl::SourceSurfaceWebgl(DrawTargetWebgl* aDT)
: mFormat(aDT->GetFormat()),
mSize(aDT->GetSize()),
mDT(aDT),
mSharedContext(aDT->mSharedContext) {}
SourceSurfaceWebgl::~SourceSurfaceWebgl() {
if (mHandle) {
@ -18,16 +22,6 @@ SourceSurfaceWebgl::~SourceSurfaceWebgl() {
}
}
bool SourceSurfaceWebgl::Init(DrawTargetWebgl* aDT) {
MOZ_ASSERT(!mDT);
MOZ_ASSERT(aDT);
mDT = aDT;
mSharedContext = aDT->mSharedContext;
mSize = aDT->GetSize();
mFormat = aDT->GetFormat();
return true;
}
// Read back the contents of the target or texture handle for data use.
inline bool SourceSurfaceWebgl::EnsureData() {
if (mData) {

Просмотреть файл

@ -22,11 +22,9 @@ class SourceSurfaceWebgl : public DataSourceSurface {
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceWebgl, override)
SourceSurfaceWebgl();
explicit SourceSurfaceWebgl(DrawTargetWebgl* aDT);
virtual ~SourceSurfaceWebgl();
bool Init(DrawTargetWebgl* aDT);
SurfaceType GetType() const override { return SurfaceType::WEBGL; }
IntSize GetSize() const override { return mSize; }
SurfaceFormat GetFormat() const override { return mFormat; }

Просмотреть файл

@ -132,6 +132,12 @@ bool PersistentBufferProviderAccelerated::ReturnDrawTarget(
return result;
}
already_AddRefed<gfx::SourceSurface>
PersistentBufferProviderAccelerated::BorrowSnapshot() {
mSnapshot = GetDrawTargetWebgl()->GetDataSnapshot();
return do_AddRef(mSnapshot);
}
bool PersistentBufferProviderAccelerated::RequiresRefresh() const {
return GetDrawTargetWebgl()->RequiresRefresh();
}

Просмотреть файл

@ -156,6 +156,8 @@ class PersistentBufferProviderAccelerated
bool ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT) override;
already_AddRefed<gfx::SourceSurface> BorrowSnapshot() override;
bool RequiresRefresh() const override;
void OnMemoryPressure() override;