Commit 3c753781 authored by Daniel Nicoara's avatar Daniel Nicoara Committed by Commit Bot

Perform glFlush only on NVIDIA platforms

EGL_EXT_image_flush_external is broken on NVIDIA and causes image
corruption.

corruption.

Bug: 833975
Test: Ran on nyan_big, samus and veyron_jerry and verified there is no
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel
Change-Id: I218bb111470e7db18906834f43fd1ad92f28b4bc
Reviewed-on: https://chromium-review.googlesource.com/1017236Reviewed-by: default avatarDaniele Castagna <dcastagna@chromium.org>
Reviewed-by: default avatarKenneth Russell <kbr@chromium.org>
Commit-Queue: Daniel Nicoara <dnicoara@chromium.org>
Cr-Commit-Position: refs/heads/master@{#552121}
parent 015a217b
......@@ -3342,6 +3342,9 @@ gpu::ContextResult GLES2DecoderImpl::Initialize(
if (workarounds().rely_on_implicit_sync_for_swap_buffers)
surface_->SetRelyOnImplicitSync();
if (workarounds().force_gl_flush_on_swap_buffers)
surface_->SetForceGlFlushOnSwapBuffers();
// Create GPU Tracer for timing values.
gpu_tracer_.reset(new GPUTracer(this));
......
......@@ -2924,6 +2924,18 @@
"features": [
"max_msaa_sample_count_4"
]
},
{
"id": 269,
"cr_bugs": [833975],
"description": "Workaround for broken EGL_IMAGE_EXTERNAL_FLUSH_EXT implementation on NVIDIA",
"os": {
"type": "chromeos"
},
"gl_vendor": "NVIDIA.*",
"features": [
"force_gl_flush_on_swap_buffers"
]
}
]
}
......@@ -52,6 +52,7 @@ flush_on_framebuffer_change
force_cube_complete
force_cube_map_positive_x_allocation
force_discrete_gpu
force_gl_flush_on_swap_buffers
force_integrated_gpu
force_int_or_srgb_cube_texture_complete
force_update_scissor_state_when_binding_fbo0
......
......@@ -221,6 +221,12 @@ void GLSurface::SetRelyOnImplicitSync() {
// It is fine to ignore this call in those cases.
}
void GLSurface::SetForceGlFlushOnSwapBuffers() {
// Some GLSurface derived classes might not implement this workaround while
// still being allocated on devices where the workaround is enabled.
// It is fine to ignore this call in those cases.
}
bool GLSurface::SupportsSwapTimestamps() const {
return false;
}
......@@ -456,6 +462,10 @@ void GLSurfaceAdapter::SetRelyOnImplicitSync() {
surface_->SetRelyOnImplicitSync();
}
void GLSurfaceAdapter::SetForceGlFlushOnSwapBuffers() {
surface_->SetForceGlFlushOnSwapBuffers();
}
bool GLSurfaceAdapter::SupportsSwapTimestamps() const {
return surface_->SupportsSwapTimestamps();
}
......
......@@ -270,6 +270,9 @@ class GL_EXPORT GLSurface : public base::RefCounted<GLSurface> {
// Tells the surface to rely on implicit sync when swapping buffers.
virtual void SetRelyOnImplicitSync();
// Tells the surface to perform a glFlush() before swapping buffers.
virtual void SetForceGlFlushOnSwapBuffers();
// Support for eglGetFrameTimestamps.
virtual bool SupportsSwapTimestamps() const;
virtual void SetEnableSwapTimestamps();
......@@ -363,6 +366,7 @@ class GL_EXPORT GLSurfaceAdapter : public GLSurface {
gfx::Vector2d GetDrawOffset() const override;
void WaitForSnapshotRendering() override;
void SetRelyOnImplicitSync() override;
void SetForceGlFlushOnSwapBuffers() override;
bool SupportsSwapTimestamps() const override;
void SetEnableSwapTimestamps() override;
......
......@@ -119,7 +119,9 @@ void GbmSurfaceless::SwapBuffersAsync(
// TODO(dcastagna): remove glFlush since eglImageFlushExternalEXT called on
// the image should be enough (crbug.com/720045).
glFlush();
if (requires_gl_flush_on_swap_buffers_)
glFlush();
unsubmitted_frames_.back()->Flush();
auto surface_swap_callback =
......@@ -204,6 +206,10 @@ void GbmSurfaceless::SetRelyOnImplicitSync() {
rely_on_implicit_sync_ = true;
}
void GbmSurfaceless::SetForceGlFlushOnSwapBuffers() {
requires_gl_flush_on_swap_buffers_ = true;
}
GbmSurfaceless::~GbmSurfaceless() {
Destroy(); // The EGL surface must be destroyed before SurfaceOzone.
surface_factory_->UnregisterSurface(window_->widget());
......
......@@ -65,6 +65,7 @@ class GbmSurfaceless : public gl::SurfacelessEGL {
const PresentationCallback& presentation_callback) override;
EGLConfig GetConfig() override;
void SetRelyOnImplicitSync() override;
void SetForceGlFlushOnSwapBuffers() override;
protected:
~GbmSurfaceless() override;
......@@ -113,6 +114,7 @@ class GbmSurfaceless : public gl::SurfacelessEGL {
// Conservatively assume we begin on a device that requires
// explicit synchronization.
bool is_on_external_drm_device_ = true;
bool requires_gl_flush_on_swap_buffers_ = false;
base::WeakPtrFactory<GbmSurfaceless> weak_factory_;
......
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