Commit 1739307c authored by Eric Karl's avatar Eric Karl Committed by Commit Bot

Fix issue with ScopedReadAccess outliving SharedImage representation.

Adds tracking to detect this issue earlier and CHECK with a more
informative error message. Also fixes one known case of incorrect
destruction order.

Bug: 1040275
Change-Id: Id611b56a605b738bd1088940460a5a62182bfefa
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1993671
Auto-Submit: Eric Karl <ericrk@chromium.org>
Reviewed-by: default avatarKhushal <khushalsagar@chromium.org>
Commit-Queue: Eric Karl <ericrk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#730248}
parent 56373214
...@@ -50,7 +50,8 @@ ImageContextImpl::~ImageContextImpl() { ...@@ -50,7 +50,8 @@ ImageContextImpl::~ImageContextImpl() {
void ImageContextImpl::OnContextLost() { void ImageContextImpl::OnContextLost() {
if (representation_) { if (representation_) {
representation_->OnContextLost(); representation_->OnContextLost();
representation_ = nullptr; representation_scoped_read_access_.reset();
representation_.reset();
} }
if (fallback_context_state_) { if (fallback_context_state_) {
......
...@@ -19,6 +19,10 @@ SharedImageRepresentation::SharedImageRepresentation( ...@@ -19,6 +19,10 @@ SharedImageRepresentation::SharedImageRepresentation(
} }
SharedImageRepresentation::~SharedImageRepresentation() { SharedImageRepresentation::~SharedImageRepresentation() {
// CHECK here as we'll crash later anyway, and this makes it clearer what the
// error is.
CHECK(!has_scoped_access_) << "Destroying a SharedImageRepresentation with "
"outstanding Scoped*Access objects.";
manager_->OnRepresentationDestroyed(backing_->mailbox(), this); manager_->OnRepresentationDestroyed(backing_->mailbox(), this);
} }
...@@ -85,10 +89,10 @@ SharedImageRepresentationSkia::ScopedWriteAccess::ScopedWriteAccess( ...@@ -85,10 +89,10 @@ SharedImageRepresentationSkia::ScopedWriteAccess::ScopedWriteAccess(
util::PassKey<SharedImageRepresentationSkia> /* pass_key */, util::PassKey<SharedImageRepresentationSkia> /* pass_key */,
SharedImageRepresentationSkia* representation, SharedImageRepresentationSkia* representation,
sk_sp<SkSurface> surface) sk_sp<SkSurface> surface)
: representation_(representation), surface_(std::move(surface)) {} : ScopedAccessBase(representation), surface_(std::move(surface)) {}
SharedImageRepresentationSkia::ScopedWriteAccess::~ScopedWriteAccess() { SharedImageRepresentationSkia::ScopedWriteAccess::~ScopedWriteAccess() {
representation_->EndWriteAccess(std::move(surface_)); representation()->EndWriteAccess(std::move(surface_));
} }
std::unique_ptr<SharedImageRepresentationSkia::ScopedWriteAccess> std::unique_ptr<SharedImageRepresentationSkia::ScopedWriteAccess>
...@@ -127,11 +131,11 @@ SharedImageRepresentationSkia::ScopedReadAccess::ScopedReadAccess( ...@@ -127,11 +131,11 @@ SharedImageRepresentationSkia::ScopedReadAccess::ScopedReadAccess(
util::PassKey<SharedImageRepresentationSkia> /* pass_key */, util::PassKey<SharedImageRepresentationSkia> /* pass_key */,
SharedImageRepresentationSkia* representation, SharedImageRepresentationSkia* representation,
sk_sp<SkPromiseImageTexture> promise_image_texture) sk_sp<SkPromiseImageTexture> promise_image_texture)
: representation_(representation), : ScopedAccessBase(representation),
promise_image_texture_(std::move(promise_image_texture)) {} promise_image_texture_(std::move(promise_image_texture)) {}
SharedImageRepresentationSkia::ScopedReadAccess::~ScopedReadAccess() { SharedImageRepresentationSkia::ScopedReadAccess::~ScopedReadAccess() {
representation_->EndReadAccess(); representation()->EndReadAccess();
} }
std::unique_ptr<SharedImageRepresentationSkia::ScopedReadAccess> std::unique_ptr<SharedImageRepresentationSkia::ScopedReadAccess>
...@@ -153,6 +157,12 @@ SharedImageRepresentationSkia::BeginScopedReadAccess( ...@@ -153,6 +157,12 @@ SharedImageRepresentationSkia::BeginScopedReadAccess(
std::move(promise_image_texture)); std::move(promise_image_texture));
} }
SharedImageRepresentationOverlay::ScopedReadAccess::ScopedReadAccess(
util::PassKey<SharedImageRepresentationOverlay> pass_key,
SharedImageRepresentationOverlay* representation,
gl::GLImage* gl_image)
: ScopedAccessBase(representation), gl_image_(gl_image) {}
std::unique_ptr<SharedImageRepresentationOverlay::ScopedReadAccess> std::unique_ptr<SharedImageRepresentationOverlay::ScopedReadAccess>
SharedImageRepresentationOverlay::BeginScopedReadAccess(bool needs_gl_image) { SharedImageRepresentationOverlay::BeginScopedReadAccess(bool needs_gl_image) {
if (!IsCleared()) { if (!IsCleared()) {
...@@ -170,10 +180,10 @@ SharedImageRepresentationDawn::ScopedAccess::ScopedAccess( ...@@ -170,10 +180,10 @@ SharedImageRepresentationDawn::ScopedAccess::ScopedAccess(
util::PassKey<SharedImageRepresentationDawn> /* pass_key */, util::PassKey<SharedImageRepresentationDawn> /* pass_key */,
SharedImageRepresentationDawn* representation, SharedImageRepresentationDawn* representation,
WGPUTexture texture) WGPUTexture texture)
: representation_(representation), texture_(texture) {} : ScopedAccessBase(representation), texture_(texture) {}
SharedImageRepresentationDawn::ScopedAccess::~ScopedAccess() { SharedImageRepresentationDawn::ScopedAccess::~ScopedAccess() {
representation_->EndAccess(); representation()->EndAccess();
} }
std::unique_ptr<SharedImageRepresentationDawn::ScopedAccess> std::unique_ptr<SharedImageRepresentationDawn::ScopedAccess>
......
...@@ -78,11 +78,36 @@ class GPU_GLES2_EXPORT SharedImageRepresentation { ...@@ -78,11 +78,36 @@ class GPU_GLES2_EXPORT SharedImageRepresentation {
SharedImageBacking* backing() const { return backing_; } SharedImageBacking* backing() const { return backing_; }
bool has_context() const { return has_context_; } bool has_context() const { return has_context_; }
// Helper class for derived classes' Scoped*Access objects. Has tracking to
// ensure a Scoped*Access does not outlive the representation it's associated
// with.
template <typename RepresentationClass>
class ScopedAccessBase {
public:
ScopedAccessBase(RepresentationClass* representation)
: representation_(representation) {
DCHECK(!representation_->has_scoped_access_);
representation_->has_scoped_access_ = true;
}
~ScopedAccessBase() {
DCHECK(representation_->has_scoped_access_);
representation_->has_scoped_access_ = false;
}
RepresentationClass* representation() { return representation_; }
private:
RepresentationClass* const representation_;
DISALLOW_COPY_AND_ASSIGN(ScopedAccessBase);
};
private: private:
SharedImageManager* const manager_; SharedImageManager* const manager_;
SharedImageBacking* const backing_; SharedImageBacking* const backing_;
MemoryTypeTracker* const tracker_; MemoryTypeTracker* const tracker_;
bool has_context_ = true; bool has_context_ = true;
bool has_scoped_access_ = false;
}; };
class SharedImageRepresentationFactoryRef : public SharedImageRepresentation { class SharedImageRepresentationFactoryRef : public SharedImageRepresentation {
...@@ -106,20 +131,16 @@ class SharedImageRepresentationFactoryRef : public SharedImageRepresentation { ...@@ -106,20 +131,16 @@ class SharedImageRepresentationFactoryRef : public SharedImageRepresentation {
class GPU_GLES2_EXPORT SharedImageRepresentationGLTextureBase class GPU_GLES2_EXPORT SharedImageRepresentationGLTextureBase
: public SharedImageRepresentation { : public SharedImageRepresentation {
public: public:
class ScopedAccess { class ScopedAccess
: public ScopedAccessBase<SharedImageRepresentationGLTextureBase> {
public: public:
ScopedAccess(util::PassKey<SharedImageRepresentationGLTextureBase> pass_key, ScopedAccess(util::PassKey<SharedImageRepresentationGLTextureBase> pass_key,
SharedImageRepresentationGLTextureBase* representation) SharedImageRepresentationGLTextureBase* representation)
: representation_(representation) {} : ScopedAccessBase(representation) {}
~ScopedAccess() { ~ScopedAccess() {
representation_->UpdateClearedStateOnEndAccess(); representation()->UpdateClearedStateOnEndAccess();
representation_->EndAccess(); representation()->EndAccess();
} }
private:
SharedImageRepresentationGLTextureBase* representation_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(ScopedAccess);
}; };
SharedImageRepresentationGLTextureBase(SharedImageManager* manager, SharedImageRepresentationGLTextureBase(SharedImageManager* manager,
...@@ -183,7 +204,8 @@ class GPU_GLES2_EXPORT SharedImageRepresentationGLTexturePassthrough ...@@ -183,7 +204,8 @@ class GPU_GLES2_EXPORT SharedImageRepresentationGLTexturePassthrough
class GPU_GLES2_EXPORT SharedImageRepresentationSkia class GPU_GLES2_EXPORT SharedImageRepresentationSkia
: public SharedImageRepresentation { : public SharedImageRepresentation {
public: public:
class GPU_GLES2_EXPORT ScopedWriteAccess { class GPU_GLES2_EXPORT ScopedWriteAccess
: public ScopedAccessBase<SharedImageRepresentationSkia> {
public: public:
ScopedWriteAccess(util::PassKey<SharedImageRepresentationSkia> pass_key, ScopedWriteAccess(util::PassKey<SharedImageRepresentationSkia> pass_key,
SharedImageRepresentationSkia* representation, SharedImageRepresentationSkia* representation,
...@@ -193,13 +215,11 @@ class GPU_GLES2_EXPORT SharedImageRepresentationSkia ...@@ -193,13 +215,11 @@ class GPU_GLES2_EXPORT SharedImageRepresentationSkia
SkSurface* surface() const { return surface_.get(); } SkSurface* surface() const { return surface_.get(); }
private: private:
SharedImageRepresentationSkia* const representation_;
sk_sp<SkSurface> surface_; sk_sp<SkSurface> surface_;
DISALLOW_COPY_AND_ASSIGN(ScopedWriteAccess);
}; };
class GPU_GLES2_EXPORT ScopedReadAccess { class GPU_GLES2_EXPORT ScopedReadAccess
: public ScopedAccessBase<SharedImageRepresentationSkia> {
public: public:
ScopedReadAccess(util::PassKey<SharedImageRepresentationSkia> pass_key, ScopedReadAccess(util::PassKey<SharedImageRepresentationSkia> pass_key,
SharedImageRepresentationSkia* representation, SharedImageRepresentationSkia* representation,
...@@ -211,10 +231,7 @@ class GPU_GLES2_EXPORT SharedImageRepresentationSkia ...@@ -211,10 +231,7 @@ class GPU_GLES2_EXPORT SharedImageRepresentationSkia
} }
private: private:
SharedImageRepresentationSkia* const representation_;
sk_sp<SkPromiseImageTexture> promise_image_texture_; sk_sp<SkPromiseImageTexture> promise_image_texture_;
DISALLOW_COPY_AND_ASSIGN(ScopedReadAccess);
}; };
SharedImageRepresentationSkia(SharedImageManager* manager, SharedImageRepresentationSkia(SharedImageManager* manager,
...@@ -280,7 +297,8 @@ class GPU_GLES2_EXPORT SharedImageRepresentationDawn ...@@ -280,7 +297,8 @@ class GPU_GLES2_EXPORT SharedImageRepresentationDawn
MemoryTypeTracker* tracker) MemoryTypeTracker* tracker)
: SharedImageRepresentation(manager, backing, tracker) {} : SharedImageRepresentation(manager, backing, tracker) {}
class GPU_GLES2_EXPORT ScopedAccess { class GPU_GLES2_EXPORT ScopedAccess
: public ScopedAccessBase<SharedImageRepresentationDawn> {
public: public:
ScopedAccess(util::PassKey<SharedImageRepresentationDawn> pass_key, ScopedAccess(util::PassKey<SharedImageRepresentationDawn> pass_key,
SharedImageRepresentationDawn* representation, SharedImageRepresentationDawn* representation,
...@@ -290,10 +308,7 @@ class GPU_GLES2_EXPORT SharedImageRepresentationDawn ...@@ -290,10 +308,7 @@ class GPU_GLES2_EXPORT SharedImageRepresentationDawn
WGPUTexture texture() const { return texture_; } WGPUTexture texture() const { return texture_; }
private: private:
SharedImageRepresentationDawn* representation_ = nullptr;
WGPUTexture texture_ = 0; WGPUTexture texture_ = 0;
DISALLOW_COPY_AND_ASSIGN(ScopedAccess);
}; };
// Calls BeginAccess and returns a ScopedAccess object which will EndAccess // Calls BeginAccess and returns a ScopedAccess object which will EndAccess
...@@ -318,24 +333,19 @@ class GPU_GLES2_EXPORT SharedImageRepresentationOverlay ...@@ -318,24 +333,19 @@ class GPU_GLES2_EXPORT SharedImageRepresentationOverlay
MemoryTypeTracker* tracker) MemoryTypeTracker* tracker)
: SharedImageRepresentation(manager, backing, tracker) {} : SharedImageRepresentation(manager, backing, tracker) {}
class ScopedReadAccess { class ScopedReadAccess
: public ScopedAccessBase<SharedImageRepresentationOverlay> {
public: public:
ScopedReadAccess(util::PassKey<SharedImageRepresentationOverlay> pass_key, ScopedReadAccess(util::PassKey<SharedImageRepresentationOverlay> pass_key,
SharedImageRepresentationOverlay* representation, SharedImageRepresentationOverlay* representation,
gl::GLImage* gl_image) gl::GLImage* gl_image);
: representation_(representation), gl_image_(gl_image) {} ~ScopedReadAccess() { representation()->EndReadAccess(); }
~ScopedReadAccess() {
if (representation_)
representation_->EndReadAccess();
}
gl::GLImage* gl_image() const { gl::GLImage* gl_image() const {
DCHECK(representation_);
return gl_image_; return gl_image_;
} }
private: private:
SharedImageRepresentationOverlay* representation_;
gl::GLImage* gl_image_; gl::GLImage* gl_image_;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment