Skip to content

Commit

Permalink
IOSurfaceImageBacking: Fork from GLImageBacking
Browse files Browse the repository at this point in the history
Rename GLImageBackingFactory to IOSurfaceImageBackingFactory, because
it is only use on macOS for IOSurface-backed GLImages.

Fork GLImageBacking to IOSurfaceImageBacking. Remove all IS_MAC
sections from GLImageBacking and all !IS_MAC sections from the new
IOSurfaceImageBacking.

Bug: 1310033
Change-Id: Ic2a2465429f79949908cf2186d3c920b00502138
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3968036
Reviewed-by: Vasiliy Telezhnikov <vasilyt@chromium.org>
Commit-Queue: ccameron chromium <ccameron@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1062814}
  • Loading branch information
ccameron-chromium authored and Chromium LUCI CQ committed Oct 24, 2022
1 parent 6ea28ce commit 792c251
Show file tree
Hide file tree
Showing 15 changed files with 1,184 additions and 365 deletions.
6 changes: 4 additions & 2 deletions gpu/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,6 @@ test("gl_tests") {
use_xvfb = use_xvfb_in_this_config

sources = [
"command_buffer/service/shared_image/gl_image_backing_factory_unittest.cc",
"command_buffer/service/shared_image/gl_texture_image_backing_factory_unittest.cc",
"command_buffer/service/shared_image/shared_image_factory_unittest.cc",
"command_buffer/service/shared_image/shared_image_manager_unittest.cc",
Expand Down Expand Up @@ -422,7 +421,10 @@ test("gl_tests") {
]
} else if (is_mac) {
frameworks = [ "IOSurface.framework" ]
sources += [ "command_buffer/service/shared_image/iosurface_image_backing_factory_unittest.cc" ]
sources += [
"command_buffer/service/shared_image/gl_image_backing_factory_unittest.cc",
"command_buffer/service/shared_image/iosurface_image_backing_factory_unittest.cc",
]
} else if (is_win) {
deps += [
"//ui/platform_window",
Expand Down
5 changes: 3 additions & 2 deletions gpu/command_buffer/service/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,6 @@ target(link_target_type, "gles2_sources") {
"shared_image/gl_common_image_backing_factory.h",
"shared_image/gl_image_backing.cc",
"shared_image/gl_image_backing.h",
"shared_image/gl_image_backing_factory.cc",
"shared_image/gl_image_backing_factory.h",
"shared_image/gl_repack_utils.cc",
"shared_image/gl_repack_utils.h",
"shared_image/gl_texture_image_backing.cc",
Expand Down Expand Up @@ -457,6 +455,9 @@ target(link_target_type, "gles2_sources") {
if (is_mac) {
deps += [ "//components/viz/common:metal_context_provider" ]
sources += [
"shared_image/gl_image_backing_factory.cc",
"shared_image/iosurface_image_backing.h",
"shared_image/iosurface_image_backing.mm",
"shared_image/iosurface_image_backing_factory.h",
"shared_image/iosurface_image_backing_factory.mm",
]
Expand Down
129 changes: 10 additions & 119 deletions gpu/command_buffer/service/shared_image/gl_image_backing.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@
#include "ui/gl/scoped_binders.h"
#include "ui/gl/trace_util.h"

#if BUILDFLAG(IS_MAC)
#include "gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.h"
#endif

namespace gpu {

namespace {
Expand Down Expand Up @@ -351,12 +347,7 @@ GLImageBacking::GLImageBacking(scoped_refptr<gl::GLImage> image,
weak_factory_(this) {
DCHECK(image_);
#if BUILDFLAG(IS_MAC)
// NOTE: Mac currently retains GLTexture and reuses it. Not sure if this is
// best approach as it can lead to issues with context losses.
if (!gl_texture_retained_for_legacy_mailbox_) {
RetainGLTexture();
gl_texture_retained_for_legacy_mailbox_ = true;
}
NOTREACHED();
#endif
}

Expand Down Expand Up @@ -516,25 +507,19 @@ GLImageBacking::ProduceGLTexturePassthrough(SharedImageManager* manager,
std::unique_ptr<OverlayImageRepresentation> GLImageBacking::ProduceOverlay(
SharedImageManager* manager,
MemoryTypeTracker* tracker) {
#if BUILDFLAG(IS_MAC) || defined(USE_OZONE) || BUILDFLAG(IS_WIN)
#if defined(USE_OZONE) || BUILDFLAG(IS_WIN)
return std::make_unique<OverlayGLImageRepresentation>(manager, this, tracker,
image_);
#else // !(BUILDFLAG(IS_MAC) || defined(USE_OZONE) || BUILDFLAG(IS_WIN))
#else // || defined(USE_OZONE) || BUILDFLAG(IS_WIN))
return SharedImageBacking::ProduceOverlay(manager, tracker);
#endif // BUILDFLAG(IS_MAC) || defined(USE_OZONE) || BUILDFLAG(IS_WIN)
#endif // defined(USE_OZONE) || BUILDFLAG(IS_WIN)
}

std::unique_ptr<DawnImageRepresentation> GLImageBacking::ProduceDawn(
SharedImageManager* manager,
MemoryTypeTracker* tracker,
WGPUDevice device,
WGPUBackendType backend_type) {
#if BUILDFLAG(IS_MAC)
auto result = IOSurfaceImageBackingFactory::ProduceDawn(
manager, this, tracker, device, image_);
if (result)
return result;
#endif // BUILDFLAG(IS_MAC)
if (!factory()) {
DLOG(ERROR) << "No SharedImageFactory to create a dawn representation.";
return nullptr;
Expand All @@ -557,21 +542,12 @@ std::unique_ptr<SkiaImageRepresentation> GLImageBacking::ProduceSkia(
}

if (!cached_promise_texture_) {
if (context_state->GrContextIsMetal()) {
#if BUILDFLAG(IS_MAC)
cached_promise_texture_ =
IOSurfaceImageBackingFactory::ProduceSkiaPromiseTextureMetal(
this, context_state, image_);
DCHECK(cached_promise_texture_);
#endif
} else {
GrBackendTexture backend_texture;
GetGrBackendTexture(context_state->feature_info(), GetGLTarget(), size(),
GetGLServiceId(), format().resource_format(),
context_state->gr_context()->threadSafeProxy(),
&backend_texture);
cached_promise_texture_ = SkPromiseImageTexture::Make(backend_texture);
}
GrBackendTexture backend_texture;
GetGrBackendTexture(context_state->feature_info(), GetGLTarget(), size(),
GetGLServiceId(), format().resource_format(),
context_state->gr_context()->threadSafeProxy(),
&backend_texture);
cached_promise_texture_ = SkPromiseImageTexture::Make(backend_texture);
}
return std::make_unique<SkiaGLCommonRepresentation>(
manager, this, gl_client, std::move(context_state),
Expand Down Expand Up @@ -619,18 +595,6 @@ void GLImageBacking::Update(std::unique_ptr<gfx::GpuFence> in_fence) {
}

bool GLImageBacking::GLTextureImageRepresentationBeginAccess(bool readonly) {
#if BUILDFLAG(IS_MAC)
DCHECK(!ongoing_write_access_);
if (readonly) {
num_ongoing_read_accesses_++;
} else {
if (!(usage() & SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE)) {
DCHECK(num_ongoing_read_accesses_ == 0);
}
ongoing_write_access_ = true;
}
#endif

if (!release_fence_.is_null()) {
auto fence = gfx::GpuFence(std::move(release_fence_));
if (gl::GLFence::IsGpuFenceSupported()) {
Expand All @@ -643,73 +607,6 @@ bool GLImageBacking::GLTextureImageRepresentationBeginAccess(bool readonly) {
}

void GLImageBacking::GLTextureImageRepresentationEndAccess(bool readonly) {
#if BUILDFLAG(IS_MAC)
if (readonly) {
DCHECK(num_ongoing_read_accesses_ > 0);
if (!(usage() & SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE)) {
DCHECK(!ongoing_write_access_);
}
num_ongoing_read_accesses_--;
} else {
DCHECK(ongoing_write_access_);
if (!(usage() & SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE)) {
DCHECK(num_ongoing_read_accesses_ == 0);
}
ongoing_write_access_ = false;
}

// 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();
}

// When SwANGLE is used as the GL implementation, it holds an internal
// texture. We have to call ReleaseTexImage here to trigger a copy from that
// internal texture to the IOSurface (the next Bind() will then trigger an
// IOSurface->internal texture copy). We do this only when there are no
// ongoing reads in order to ensure that it does not result in the GLES2
// decoders needing to perform on-demand binding (rather, the binding will be
// performed at the next BeginAccess()). Note that it is not sufficient to
// release the image only at the end of a write: the CPU can write directly to
// the IOSurface when the GPU is not accessing the internal texture (in the
// case of zero-copy raster), and any such IOSurface-side modifications need
// to be copied to the internal texture via a Bind() when the GPU starts a
// subsequent read. Note also that this logic assumes that writes are
// serialized with respect to reads (so that the end of a write always
// triggers a release and copy). By design, GLImageBackingFactory enforces
// this property for this use case.
bool needs_sync_for_swangle =
(gl::GetANGLEImplementation() == gl::ANGLEImplementation::kSwiftShader &&
(num_ongoing_read_accesses_ == 0));

// Similarly, when ANGLE's metal backend is used, we have to signal a call to
// waitUntilScheduled() using the same method on EndAccess to ensure IOSurface
// synchronization. In this case, it is sufficient to release the image at the
// end of a write. As above, GLImageBackingFactory enforces serialization of
// reads and writes for this use case.
// TODO(https://anglebug.com/7626): Enable on Metal only when
// CPU_READ or SCANOUT is specified. When doing so, adjust the conditions for
// disallowing concurrent read/write in GLImageBackingFactory as suitable.
bool needs_sync_for_metal =
(gl::GetANGLEImplementation() == gl::ANGLEImplementation::kMetal &&
!readonly);

bool needs_synchronization =
IsPassthrough() && (needs_sync_for_swangle || needs_sync_for_metal);
if (needs_synchronization &&
image_->ShouldBindOrCopy() == gl::GLImage::BIND) {
const GLenum target = GetGLTarget();
gl::ScopedTextureBinder binder(target, passthrough_texture_->service_id());
if (!passthrough_texture_->is_bind_pending()) {
image_->ReleaseTexImage(target);
image_bind_or_copy_needed_ = true;
passthrough_texture_->set_is_bind_pending(true);
}
}
#else

// If the image will be used for an overlay, we insert a fence that can be
// used by OutputPresenter to synchronize image writes with presentation.
if (!readonly && usage() & SHARED_IMAGE_USAGE_SCANOUT &&
Expand All @@ -729,7 +626,6 @@ void GLImageBacking::GLTextureImageRepresentationEndAccess(bool readonly) {
last_write_gl_fence_ = gl::GLFence::CreateForGpuFence();
DCHECK(last_write_gl_fence_);
}
#endif
}

void GLImageBacking::GLTextureImageRepresentationRelease(bool has_context) {
Expand Down Expand Up @@ -794,10 +690,6 @@ void GLImageBacking::InitializePixels(GLenum format,
GLenum type,
const uint8_t* data) {
DCHECK_EQ(image_->ShouldBindOrCopy(), gl::GLImage::BIND);
#if BUILDFLAG(IS_MAC)
if (IOSurfaceImageBackingFactory::InitializePixels(this, image_, data))
return;
#else
RetainGLTexture();
BindOrCopyImageIfNeeded();

Expand All @@ -810,7 +702,6 @@ void GLImageBacking::InitializePixels(GLenum format,
api->glTexSubImage2DFn(target, 0, 0, 0, size().width(), size().height(),
format, type, data);
ReleaseGLTexture(true /* have_context */);
#endif
}

} // namespace gpu
11 changes: 0 additions & 11 deletions gpu/command_buffer/service/shared_image/gl_image_backing.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,17 +249,6 @@ class GPU_GLES2_EXPORT GLImageBacking
bool BindOrCopyImageIfNeeded();
bool image_bind_or_copy_needed_ = true;

// TODO(blundell): Eliminate all usage of BUILDFLAG(IS_MAC) in this file (as
// well as the .cc file) once GLImageBacking is used only on Mac.
#if BUILDFLAG(IS_MAC)
// Used to determine whether to release the texture in EndAccess() in use
// cases that need to ensure IOSurface synchronization.
uint num_ongoing_read_accesses_ = 0;
// Used with the above variable to catch cases where clients are performing
// disallowed concurrent read/write accesses.
bool ongoing_write_access_ = false;
#endif

void RetainGLTexture();
void ReleaseGLTexture(bool have_context);
size_t gl_texture_retain_count_ = 0;
Expand Down
Loading

0 comments on commit 792c251

Please sign in to comment.