Commit 2f800f06 authored by Christopher Cameron's avatar Christopher Cameron Committed by Commit Bot

Add CHECKs to calls to IOSurfaceLookupFromMachPort

When allocating an anonymous IOSurface-backed GLImage, we have the
sequence of calls
- IOSurfaceCreate
- IOSurfaceCreateMachPort
- IOSurfaceRelease (implicitly in ScopedCFTypeRef<IOSurfaceRef>)
- IOSurfaceLookupFromMachPort
The final call persistently fails on some machines.

This adds a CHECK when that call fails, so we can assess how often
it occurs in the wild.

This also adds a call to IOSurfaceCreateMachPort and
IOSurfaceLookupFromMachPort before the implicit IOSurfaceRelease, to
see if this may be the result of a reference counting bug.

Add lots more LOG(ERROR) spew to help further diagnose this.

Cq-Include-Trybots: master.tryserver.chromium.android:android_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel
Change-Id: Ie630067759d0bdf096be907986e53afdc632b15d
Reviewed-on: https://chromium-review.googlesource.com/895142
Commit-Queue: ccameron <ccameron@chromium.org>
Reviewed-by: default avatarVictor Miura <vmiura@chromium.org>
Cr-Commit-Position: refs/heads/master@{#533240}
parent 34d90966
...@@ -55,10 +55,17 @@ GpuMemoryBufferImplIOSurface::CreateFromHandle( ...@@ -55,10 +55,17 @@ GpuMemoryBufferImplIOSurface::CreateFromHandle(
gfx::BufferFormat format, gfx::BufferFormat format,
gfx::BufferUsage usage, gfx::BufferUsage usage,
const DestructionCallback& callback) { const DestructionCallback& callback) {
if (!handle.mach_port) {
LOG(ERROR) << "Invalid IOSurface mach port returned to client.";
return nullptr;
}
base::ScopedCFTypeRef<IOSurfaceRef> io_surface( base::ScopedCFTypeRef<IOSurfaceRef> io_surface(
IOSurfaceLookupFromMachPort(handle.mach_port.get())); IOSurfaceLookupFromMachPort(handle.mach_port.get()));
if (!io_surface) if (!io_surface) {
LOG(ERROR) << "Failed to open IOSurface via mach port returned to client.";
return nullptr; return nullptr;
}
return base::WrapUnique( return base::WrapUnique(
new GpuMemoryBufferImplIOSurface(handle.id, size, format, callback, new GpuMemoryBufferImplIOSurface(handle.id, size, format, callback,
......
...@@ -34,7 +34,7 @@ GpuMemoryBufferFactoryIOSurface::CreateGpuMemoryBuffer( ...@@ -34,7 +34,7 @@ GpuMemoryBufferFactoryIOSurface::CreateGpuMemoryBuffer(
int client_id, int client_id,
SurfaceHandle surface_handle) { SurfaceHandle surface_handle) {
// Don't clear anonymous io surfaces. // Don't clear anonymous io surfaces.
bool should_clear = (client_id != 0); bool should_clear = (client_id != kAnonymousClientId);
base::ScopedCFTypeRef<IOSurfaceRef> io_surface( base::ScopedCFTypeRef<IOSurfaceRef> io_surface(
gfx::CreateIOSurface(size, format, should_clear)); gfx::CreateIOSurface(size, format, should_clear));
if (!io_surface) { if (!io_surface) {
...@@ -54,6 +54,17 @@ GpuMemoryBufferFactoryIOSurface::CreateGpuMemoryBuffer( ...@@ -54,6 +54,17 @@ GpuMemoryBufferFactoryIOSurface::CreateGpuMemoryBuffer(
handle.type = gfx::IO_SURFACE_BUFFER; handle.type = gfx::IO_SURFACE_BUFFER;
handle.id = id; handle.id = id;
handle.mach_port.reset(IOSurfaceCreateMachPort(io_surface)); handle.mach_port.reset(IOSurfaceCreateMachPort(io_surface));
// TODO(ccameron): This should never happen, but a similar call to
// IOSurfaceLookupFromMachPort is failing below. This should determine if
// the lifetime of the underlying IOSurface determines the failure.
// https://crbug.com/795649
CHECK(handle.mach_port);
base::ScopedCFTypeRef<IOSurfaceRef> io_surface_recreated(
IOSurfaceLookupFromMachPort(handle.mach_port.get()));
CHECK_NE(nullptr, io_surface_recreated.get())
<< "Failed to reconstitute still-existing IOSurface from mach port.";
return handle; return handle;
} }
...@@ -112,10 +123,17 @@ GpuMemoryBufferFactoryIOSurface::CreateAnonymousImage(const gfx::Size& size, ...@@ -112,10 +123,17 @@ GpuMemoryBufferFactoryIOSurface::CreateAnonymousImage(const gfx::Size& size,
gfx::GpuMemoryBufferHandle handle = CreateGpuMemoryBuffer( gfx::GpuMemoryBufferHandle handle = CreateGpuMemoryBuffer(
gfx::GpuMemoryBufferId(next_anonymous_image_id_++), size, format, usage, gfx::GpuMemoryBufferId(next_anonymous_image_id_++), size, format, usage,
kAnonymousClientId, gpu::kNullSurfaceHandle); kAnonymousClientId, gpu::kNullSurfaceHandle);
if (handle.is_null())
return scoped_refptr<gl::GLImage>();
base::ScopedCFTypeRef<IOSurfaceRef> io_surface; base::ScopedCFTypeRef<IOSurfaceRef> io_surface(
io_surface.reset(IOSurfaceLookupFromMachPort(handle.mach_port.get())); IOSurfaceLookupFromMachPort(handle.mach_port.get()));
DCHECK_NE(nullptr, io_surface.get()); // TODO(ccameron): This should never happen, but has been seen in the wild. If
// this happens frequently, it can be replaced by directly using the allocated
// IOSurface, rather than going through the handle creation.
// https://crbug.com/795649
CHECK_NE(nullptr, io_surface.get())
<< "Failed to reconstitute just-created IOSurface from mach port.";
scoped_refptr<gl::GLImageIOSurface> image( scoped_refptr<gl::GLImageIOSurface> image(
gl::GLImageIOSurface::Create(size, internalformat)); gl::GLImageIOSurface::Create(size, internalformat));
......
...@@ -148,7 +148,7 @@ void AcceleratedWidgetMac::UpdateCALayerTree( ...@@ -148,7 +148,7 @@ void AcceleratedWidgetMac::UpdateCALayerTree(
GotCALayerFrame(base::scoped_nsobject<CALayer>(remote_layer_.get(), GotCALayerFrame(base::scoped_nsobject<CALayer>(remote_layer_.get(),
base::scoped_policy::RETAIN), base::scoped_policy::RETAIN),
ca_layer_params.pixel_size, ca_layer_params.scale_factor); ca_layer_params.pixel_size, ca_layer_params.scale_factor);
} else { } else if (ca_layer_params.io_surface_mach_port) {
base::ScopedCFTypeRef<IOSurfaceRef> io_surface( base::ScopedCFTypeRef<IOSurfaceRef> io_surface(
IOSurfaceLookupFromMachPort(ca_layer_params.io_surface_mach_port)); IOSurfaceLookupFromMachPort(ca_layer_params.io_surface_mach_port));
if (!io_surface) { if (!io_surface) {
...@@ -156,6 +156,11 @@ void AcceleratedWidgetMac::UpdateCALayerTree( ...@@ -156,6 +156,11 @@ void AcceleratedWidgetMac::UpdateCALayerTree(
} }
GotIOSurfaceFrame(io_surface, ca_layer_params.pixel_size, GotIOSurfaceFrame(io_surface, ca_layer_params.pixel_size,
ca_layer_params.scale_factor); ca_layer_params.scale_factor);
} else {
LOG(ERROR) << "Frame had neither valid CAContext nor valid IOSurface.";
base::ScopedCFTypeRef<IOSurfaceRef> io_surface;
GotIOSurfaceFrame(io_surface, ca_layer_params.pixel_size,
ca_layer_params.scale_factor);
} }
if (view_) if (view_)
view_->AcceleratedWidgetSwapCompleted(); view_->AcceleratedWidgetSwapCompleted();
......
...@@ -220,6 +220,10 @@ bool GLImageIOSurface::Initialize(IOSurfaceRef io_surface, ...@@ -220,6 +220,10 @@ bool GLImageIOSurface::Initialize(IOSurfaceRef io_surface,
gfx::BufferFormat format) { gfx::BufferFormat format) {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(!io_surface_); DCHECK(!io_surface_);
if (!io_surface) {
LOG(ERROR) << "Invalid IOSurface";
return false;
}
if (!ValidInternalFormat(internalformat_)) { if (!ValidInternalFormat(internalformat_)) {
LOG(ERROR) << "Invalid internalformat: " LOG(ERROR) << "Invalid internalformat: "
......
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