Commit 5173392b authored by Christopher Cameron's avatar Christopher Cameron Committed by Commit Bot

macOS/Metal: Fix GL/WebGPU synchronization

This makes SharedImageBackingGLImage work with WebGPU. After
this, it will be possible to delete SharedImageBackingIOSurface.

Merge all of the Client interfaces into a single
SharedImageRepresentationGLTextureClient interface, now that they
all came the same functions.

Bug: 894929
Change-Id: I9990e66a438d97d411788485e244182b640fe9cf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2293618
Commit-Queue: ccameron <ccameron@chromium.org>
Reviewed-by: default avatarGeoff Lang <geofflang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#787842}
parent b8347d7b
......@@ -304,7 +304,7 @@ size_t EstimatedSize(viz::ResourceFormat format, const gfx::Size& size) {
SharedImageRepresentationGLTextureImpl::SharedImageRepresentationGLTextureImpl(
SharedImageManager* manager,
SharedImageBacking* backing,
Client* client,
SharedImageRepresentationGLTextureClient* client,
MemoryTypeTracker* tracker,
gles2::Texture* texture)
: SharedImageRepresentationGLTexture(manager, backing, tracker),
......@@ -316,11 +316,16 @@ gles2::Texture* SharedImageRepresentationGLTextureImpl::GetTexture() {
}
bool SharedImageRepresentationGLTextureImpl::BeginAccess(GLenum mode) {
if (client_)
return client_->OnGLTextureBeginAccess(mode);
if (client_ && mode != GL_SHARED_IMAGE_ACCESS_MODE_OVERLAY_CHROMIUM)
return client_->SharedImageRepresentationGLTextureBeginAccess();
return true;
}
void SharedImageRepresentationGLTextureImpl::EndAccess() {
if (client_)
return client_->SharedImageRepresentationGLTextureEndAccess();
}
///////////////////////////////////////////////////////////////////////////////
// SharedImageRepresentationGLTexturePassthroughImpl
......@@ -328,7 +333,7 @@ SharedImageRepresentationGLTexturePassthroughImpl::
SharedImageRepresentationGLTexturePassthroughImpl(
SharedImageManager* manager,
SharedImageBacking* backing,
Client* client,
SharedImageRepresentationGLTextureClient* client,
MemoryTypeTracker* tracker,
scoped_refptr<gles2::TexturePassthrough> texture_passthrough)
: SharedImageRepresentationGLTexturePassthrough(manager, backing, tracker),
......@@ -345,11 +350,16 @@ SharedImageRepresentationGLTexturePassthroughImpl::GetTexturePassthrough() {
bool SharedImageRepresentationGLTexturePassthroughImpl::BeginAccess(
GLenum mode) {
if (client_)
return client_->OnGLTexturePassthroughBeginAccess(mode);
if (client_ && mode != GL_SHARED_IMAGE_ACCESS_MODE_OVERLAY_CHROMIUM)
return client_->SharedImageRepresentationGLTextureBeginAccess();
return true;
}
void SharedImageRepresentationGLTexturePassthroughImpl::EndAccess() {
if (client_)
return client_->SharedImageRepresentationGLTextureEndAccess();
}
///////////////////////////////////////////////////////////////////////////////
// SharedImageBackingGLCommon
......@@ -396,7 +406,7 @@ void SharedImageBackingGLCommon::MakeTextureAndSetParameters(
SharedImageRepresentationSkiaImpl::SharedImageRepresentationSkiaImpl(
SharedImageManager* manager,
SharedImageBacking* backing,
Client* client,
SharedImageRepresentationGLTextureClient* client,
scoped_refptr<SharedContextState> context_state,
sk_sp<SkPromiseImageTexture> promise_texture,
MemoryTypeTracker* tracker)
......@@ -424,14 +434,18 @@ sk_sp<SkSurface> SharedImageRepresentationSkiaImpl::BeginWriteAccess(
std::vector<GrBackendSemaphore>* begin_semaphores,
std::vector<GrBackendSemaphore>* end_semaphores) {
CheckContext();
if (client_ && !client_->OnSkiaBeginWriteAccess())
return nullptr;
if (client_) {
DCHECK(context_state_->GrContextIsGL());
if (!client_->SharedImageRepresentationGLTextureBeginAccess())
return nullptr;
}
if (write_surface_)
return nullptr;
if (!promise_texture_) {
if (!promise_texture_)
return nullptr;
}
SkColorType sk_color_type = viz::ResourceFormatToClosestSkColorType(
/*gpu_compositing=*/true, format());
auto surface = SkSurface::MakeFromBackendTexture(
......@@ -449,19 +463,26 @@ void SharedImageRepresentationSkiaImpl::EndWriteAccess(
CheckContext();
// TODO(ericrk): Keep the surface around for re-use.
write_surface_ = nullptr;
if (client_)
client_->SharedImageRepresentationGLTextureEndAccess();
}
sk_sp<SkPromiseImageTexture> SharedImageRepresentationSkiaImpl::BeginReadAccess(
std::vector<GrBackendSemaphore>* begin_semaphores,
std::vector<GrBackendSemaphore>* end_semaphores) {
CheckContext();
if (client_ && !client_->OnSkiaBeginReadAccess())
return nullptr;
if (client_) {
DCHECK(context_state_->GrContextIsGL());
if (!client_->SharedImageRepresentationGLTextureBeginAccess())
return nullptr;
}
return promise_texture_;
}
void SharedImageRepresentationSkiaImpl::EndReadAccess() {
// TODO(ericrk): Handle begin/end correctness checks.
if (client_)
client_->SharedImageRepresentationGLTextureEndAccess();
}
bool SharedImageRepresentationSkiaImpl::SupportsMultipleConcurrentReadAccess() {
......@@ -814,6 +835,7 @@ SharedImageBackingGLImage::ProduceSkia(
SharedImageManager* manager,
MemoryTypeTracker* tracker,
scoped_refptr<SharedContextState> context_state) {
SharedImageRepresentationGLTextureClient* gl_client = nullptr;
if (!cached_promise_texture_) {
if (context_state->GrContextIsMetal()) {
#if defined(OS_MACOSX)
......@@ -823,6 +845,7 @@ SharedImageBackingGLImage::ProduceSkia(
DCHECK(cached_promise_texture_);
#endif
} else {
gl_client = this;
GrBackendTexture backend_texture;
GetGrBackendTexture(context_state->feature_info(), GetGLTarget(), size(),
GetGLServiceId(), format(), &backend_texture);
......@@ -830,8 +853,8 @@ SharedImageBackingGLImage::ProduceSkia(
}
}
return std::make_unique<SharedImageRepresentationSkiaImpl>(
manager, this, this, std::move(context_state), cached_promise_texture_,
tracker);
manager, this, gl_client, std::move(context_state),
cached_promise_texture_, tracker);
}
std::unique_ptr<SharedImageRepresentationGLTexture>
......@@ -897,24 +920,20 @@ void SharedImageBackingGLImage::Update(
image_bind_or_copy_needed_ = true;
}
bool SharedImageBackingGLImage::OnGLTextureBeginAccess(GLenum mode) {
if (mode == GL_SHARED_IMAGE_ACCESS_MODE_OVERLAY_CHROMIUM)
return true;
return BindOrCopyImageIfNeeded();
}
bool SharedImageBackingGLImage::OnGLTexturePassthroughBeginAccess(GLenum mode) {
if (mode == GL_SHARED_IMAGE_ACCESS_MODE_OVERLAY_CHROMIUM)
return true;
return BindOrCopyImageIfNeeded();
}
bool SharedImageBackingGLImage::OnSkiaBeginReadAccess() {
bool SharedImageBackingGLImage::
SharedImageRepresentationGLTextureBeginAccess() {
return BindOrCopyImageIfNeeded();
}
bool SharedImageBackingGLImage::OnSkiaBeginWriteAccess() {
return BindOrCopyImageIfNeeded();
void SharedImageBackingGLImage::SharedImageRepresentationGLTextureEndAccess() {
#if defined(OS_MACOSX)
// If this image could potentially be shared with Metal via WebGPU, then flush
// the GL context to ensure Metal will see it.
if (usage() & SHARED_IMAGE_USAGE_WEBGPU) {
gl::GLApi* api = gl::g_current_gl_context;
api->glFlushFn();
}
#endif
}
bool SharedImageBackingGLImage::BindOrCopyImageIfNeeded() {
......@@ -1333,7 +1352,12 @@ SharedImageBackingFactoryGLTexture::CreateSharedImageInternal(
return nullptr;
}
#if defined(OS_MACOSX)
const bool use_buffer =
usage & (SHARED_IMAGE_USAGE_SCANOUT | SHARED_IMAGE_USAGE_WEBGPU);
#else
const bool use_buffer = usage & SHARED_IMAGE_USAGE_SCANOUT;
#endif
if (use_buffer && !format_info.allow_scanout) {
LOG(ERROR) << "CreateSharedImage: SCANOUT shared images unavailable";
return nullptr;
......
......@@ -11,27 +11,33 @@
namespace gpu {
// Interface through which a representation that has a GL texture calls into its
// GLImage backing.
class SharedImageRepresentationGLTextureClient {
public:
virtual bool SharedImageRepresentationGLTextureBeginAccess() = 0;
virtual void SharedImageRepresentationGLTextureEndAccess() = 0;
};
// Representation of a SharedImageBackingGLTexture or SharedImageBackingGLImage
// as a GL Texture.
class SharedImageRepresentationGLTextureImpl
: public SharedImageRepresentationGLTexture {
public:
class Client {
public:
virtual bool OnGLTextureBeginAccess(GLenum mode) = 0;
};
SharedImageRepresentationGLTextureImpl(SharedImageManager* manager,
SharedImageBacking* backing,
Client* client,
MemoryTypeTracker* tracker,
gles2::Texture* texture);
SharedImageRepresentationGLTextureImpl(
SharedImageManager* manager,
SharedImageBacking* backing,
SharedImageRepresentationGLTextureClient* client,
MemoryTypeTracker* tracker,
gles2::Texture* texture);
private:
// SharedImageRepresentationGLTexture:
gles2::Texture* GetTexture() override;
bool BeginAccess(GLenum mode) override;
void EndAccess() override;
Client* const client_ = nullptr;
SharedImageRepresentationGLTextureClient* const client_ = nullptr;
gles2::Texture* texture_;
};
......@@ -47,7 +53,7 @@ class SharedImageRepresentationGLTexturePassthroughImpl
SharedImageRepresentationGLTexturePassthroughImpl(
SharedImageManager* manager,
SharedImageBacking* backing,
Client* client,
SharedImageRepresentationGLTextureClient* client,
MemoryTypeTracker* tracker,
scoped_refptr<gles2::TexturePassthrough> texture_passthrough);
~SharedImageRepresentationGLTexturePassthroughImpl() override;
......@@ -57,8 +63,9 @@ class SharedImageRepresentationGLTexturePassthroughImpl
const scoped_refptr<gles2::TexturePassthrough>& GetTexturePassthrough()
override;
bool BeginAccess(GLenum mode) override;
void EndAccess() override;
Client* const client_ = nullptr;
SharedImageRepresentationGLTextureClient* const client_ = nullptr;
scoped_refptr<gles2::TexturePassthrough> texture_passthrough_;
};
......@@ -103,7 +110,7 @@ class SharedImageRepresentationSkiaImpl : public SharedImageRepresentationSkia {
SharedImageRepresentationSkiaImpl(
SharedImageManager* manager,
SharedImageBacking* backing,
Client* client,
SharedImageRepresentationGLTextureClient* client,
scoped_refptr<SharedContextState> context_state,
sk_sp<SkPromiseImageTexture> promise_texture,
MemoryTypeTracker* tracker);
......@@ -128,7 +135,7 @@ class SharedImageRepresentationSkiaImpl : public SharedImageRepresentationSkia {
void CheckContext();
Client* const client_ = nullptr;
SharedImageRepresentationGLTextureClient* const client_ = nullptr;
scoped_refptr<SharedContextState> context_state_;
sk_sp<SkPromiseImageTexture> promise_texture_;
......@@ -201,9 +208,7 @@ class SharedImageBackingGLTexture : public SharedImageBacking {
// mailbox implementation.
class SharedImageBackingGLImage
: public SharedImageBacking,
public SharedImageRepresentationGLTextureImpl::Client,
public SharedImageRepresentationGLTexturePassthroughImpl::Client,
public SharedImageRepresentationSkiaImpl::Client {
public SharedImageRepresentationGLTextureClient {
public:
SharedImageBackingGLImage(
scoped_refptr<gl::GLImage> image,
......@@ -257,15 +262,9 @@ class SharedImageBackingGLImage
MemoryTypeTracker* tracker) override;
void Update(std::unique_ptr<gfx::GpuFence> in_fence) override;
// SharedImageRepresentationGLTextureImpl::Client:
bool OnGLTextureBeginAccess(GLenum mode) override;
// SharedImageRepresentationGLTexturePassthroughImpl::Client:
bool OnGLTexturePassthroughBeginAccess(GLenum mode) override;
// SharedImageRepresentationGLTextureImpl::Client:
bool OnSkiaBeginReadAccess() override;
bool OnSkiaBeginWriteAccess() override;
// SharedImageRepresentationGLTextureClient:
bool SharedImageRepresentationGLTextureBeginAccess() override;
void SharedImageRepresentationGLTextureEndAccess() override;
bool IsPassthrough() const { return is_passthrough_; }
......
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