Commit ca3fb820 authored by Vasiliy Telezhnikov's avatar Vasiliy Telezhnikov Committed by Commit Bot

RefCount texture in SharedImageBackingEglImage

After https://crrev.com/2390861 we started to use source texture for all
operations on original context. SharedImageBacking are ref-counted by
their representation, but the source_texture was deleted when client
deletes shared image (i.e when FactoryRepresentation is deleted). This
is problematic as shared image could be deleted before raster finished.

This CL adds ref-counted wrapper to source texture to keep it alive
until last representation on original context and thread is alive.

Bug: 1127320
Change-Id: I395f6177b752acc163f05f2d365073c67a25991a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2407182
Commit-Queue: Vasiliy Telezhnikov <vasilyt@chromium.org>
Reviewed-by: default avatarPeng Huang <penghuang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#806502}
parent dd5c0ffe
...@@ -17,25 +17,43 @@ ...@@ -17,25 +17,43 @@
namespace gpu { namespace gpu {
class SharedImageBackingEglImage::TextureHolder
: public base::RefCounted<TextureHolder> {
public:
TextureHolder(gles2::Texture* texture) : texture_(texture) {}
void MarkContextLost() { context_lost_ = true; }
gles2::Texture* texture() { return texture_; }
private:
friend class base::RefCounted<TextureHolder>;
~TextureHolder() { texture_->RemoveLightweightRef(!context_lost_); }
gles2::Texture* const texture_;
bool context_lost_ = false;
};
// Implementation of SharedImageRepresentationGLTexture which uses GL texture // Implementation of SharedImageRepresentationGLTexture which uses GL texture
// which is an EGLImage sibling. // which is an EGLImage sibling.
class SharedImageRepresentationEglImageGLTexture class SharedImageRepresentationEglImageGLTexture
: public SharedImageRepresentationGLTexture { : public SharedImageRepresentationGLTexture {
public: public:
SharedImageRepresentationEglImageGLTexture(SharedImageManager* manager, using TextureHolder = SharedImageBackingEglImage::TextureHolder;
SharedImageBacking* backing, SharedImageRepresentationEglImageGLTexture(
MemoryTypeTracker* tracker, SharedImageManager* manager,
gles2::Texture* texture, SharedImageBacking* backing,
bool should_delete_texture) MemoryTypeTracker* tracker,
scoped_refptr<TextureHolder> texture_holder)
: SharedImageRepresentationGLTexture(manager, backing, tracker), : SharedImageRepresentationGLTexture(manager, backing, tracker),
texture_(texture), texture_holder_(std::move(texture_holder)) {}
should_delete_texture_(should_delete_texture) {}
~SharedImageRepresentationEglImageGLTexture() override { ~SharedImageRepresentationEglImageGLTexture() override {
EndAccess(); EndAccess();
if (!has_context())
if (texture_ && should_delete_texture_) texture_holder_->MarkContextLost();
texture_->RemoveLightweightRef(has_context()); texture_holder_.reset();
} }
bool BeginAccess(GLenum mode) override { bool BeginAccess(GLenum mode) override {
...@@ -69,7 +87,7 @@ class SharedImageRepresentationEglImageGLTexture ...@@ -69,7 +87,7 @@ class SharedImageRepresentationEglImageGLTexture
mode_ = RepresentationAccessMode::kNone; mode_ = RepresentationAccessMode::kNone;
} }
gles2::Texture* GetTexture() override { return texture_; } gles2::Texture* GetTexture() override { return texture_holder_->texture(); }
bool SupportsMultipleConcurrentReadAccess() override { return true; } bool SupportsMultipleConcurrentReadAccess() override { return true; }
...@@ -78,8 +96,7 @@ class SharedImageRepresentationEglImageGLTexture ...@@ -78,8 +96,7 @@ class SharedImageRepresentationEglImageGLTexture
return static_cast<SharedImageBackingEglImage*>(backing()); return static_cast<SharedImageBackingEglImage*>(backing());
} }
gles2::Texture* texture_; scoped_refptr<TextureHolder> texture_holder_;
const bool should_delete_texture_;
RepresentationAccessMode mode_ = RepresentationAccessMode::kNone; RepresentationAccessMode mode_ = RepresentationAccessMode::kNone;
DISALLOW_COPY_AND_ASSIGN(SharedImageRepresentationEglImageGLTexture); DISALLOW_COPY_AND_ASSIGN(SharedImageRepresentationEglImageGLTexture);
}; };
...@@ -114,14 +131,16 @@ SharedImageBackingEglImage::SharedImageBackingEglImage( ...@@ -114,14 +131,16 @@ SharedImageBackingEglImage::SharedImageBackingEglImage(
// On some GPUs (NVidia) keeping reference to egl image itself is not enough, // On some GPUs (NVidia) keeping reference to egl image itself is not enough,
// we must keep reference to at least one sibling. // we must keep reference to at least one sibling.
if (workarounds.dont_delete_source_texture_for_egl_image) { if (workarounds.dont_delete_source_texture_for_egl_image) {
source_texture_ = GenEGLImageSibling(); auto* texture = GenEGLImageSibling();
if (texture)
source_texture_holder_ = base::MakeRefCounted<TextureHolder>(texture);
} }
} }
SharedImageBackingEglImage::~SharedImageBackingEglImage() { SharedImageBackingEglImage::~SharedImageBackingEglImage() {
// Un-Register this backing from the |batch_access_manager_|. // Un-Register this backing from the |batch_access_manager_|.
batch_access_manager_->UnregisterEglBacking(this); batch_access_manager_->UnregisterEglBacking(this);
DCHECK(!source_texture_); DCHECK(!source_texture_holder_);
} }
void SharedImageBackingEglImage::Update( void SharedImageBackingEglImage::Update(
...@@ -141,17 +160,21 @@ SharedImageBackingEglImage::ProduceGLTexture(SharedImageManager* manager, ...@@ -141,17 +160,21 @@ SharedImageBackingEglImage::ProduceGLTexture(SharedImageManager* manager,
// On some GPUs (Mali, mostly Android 9, like J7) glTexSubImage fails on egl // On some GPUs (Mali, mostly Android 9, like J7) glTexSubImage fails on egl
// image sibling. So we use the original texture if we're on the same gl // image sibling. So we use the original texture if we're on the same gl
// context. see https://crbug.com/1117370 // context. see https://crbug.com/1117370
if (source_texture_ && created_on_context_ == gl::g_current_gl_context) { // If we're on the same context we're on the same thread, so
// source_texture_holder_ is accessed only from thread we created it and
// doesn't need lock.
if (created_on_context_ == gl::g_current_gl_context &&
source_texture_holder_) {
return std::make_unique<SharedImageRepresentationEglImageGLTexture>( return std::make_unique<SharedImageRepresentationEglImageGLTexture>(
manager, this, tracker, source_texture_, manager, this, tracker, source_texture_holder_);
/*should_delete_texture=*/false);
} }
auto* texture = GenEGLImageSibling(); auto* texture = GenEGLImageSibling();
if (!texture) if (!texture)
return nullptr; return nullptr;
auto texture_holder = base::MakeRefCounted<TextureHolder>(texture);
return std::make_unique<SharedImageRepresentationEglImageGLTexture>( return std::make_unique<SharedImageRepresentationEglImageGLTexture>(
manager, this, tracker, texture, /*should_delete_texture=*/true); manager, this, tracker, std::move(texture_holder));
} }
std::unique_ptr<SharedImageRepresentationSkia> std::unique_ptr<SharedImageRepresentationSkia>
...@@ -332,10 +355,9 @@ void SharedImageBackingEglImage::MarkForDestruction() { ...@@ -332,10 +355,9 @@ void SharedImageBackingEglImage::MarkForDestruction() {
AutoLock auto_lock(this); AutoLock auto_lock(this);
DCHECK(!have_context() || created_on_context_ == gl::g_current_gl_context); DCHECK(!have_context() || created_on_context_ == gl::g_current_gl_context);
if (source_texture_) { if (!have_context())
source_texture_->RemoveLightweightRef(have_context()); source_texture_holder_->MarkContextLost();
source_texture_ = nullptr; source_texture_holder_.reset();
}
} }
} // namespace gpu } // namespace gpu
...@@ -73,6 +73,7 @@ class SharedImageBackingEglImage : public ClearTrackingSharedImageBacking { ...@@ -73,6 +73,7 @@ class SharedImageBackingEglImage : public ClearTrackingSharedImageBacking {
private: private:
friend class SharedImageBatchAccessManager; friend class SharedImageBatchAccessManager;
friend class SharedImageRepresentationEglImageGLTexture; friend class SharedImageRepresentationEglImageGLTexture;
class TextureHolder;
// Use to create EGLImage texture target from the same EGLImage object. // Use to create EGLImage texture target from the same EGLImage object.
gles2::Texture* GenEGLImageSibling(); gles2::Texture* GenEGLImageSibling();
...@@ -81,7 +82,7 @@ class SharedImageBackingEglImage : public ClearTrackingSharedImageBacking { ...@@ -81,7 +82,7 @@ class SharedImageBackingEglImage : public ClearTrackingSharedImageBacking {
const GLuint gl_format_; const GLuint gl_format_;
const GLuint gl_type_; const GLuint gl_type_;
gles2::Texture* source_texture_ = nullptr; scoped_refptr<TextureHolder> source_texture_holder_;
gl::GLApi* created_on_context_; gl::GLApi* created_on_context_;
// This class encapsulates the EGLImage object for android. // This class encapsulates the EGLImage object for android.
......
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