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( ...@@ -3342,6 +3342,9 @@ gpu::ContextResult GLES2DecoderImpl::Initialize(
if (workarounds().rely_on_implicit_sync_for_swap_buffers) if (workarounds().rely_on_implicit_sync_for_swap_buffers)
surface_->SetRelyOnImplicitSync(); surface_->SetRelyOnImplicitSync();
if (workarounds().force_gl_flush_on_swap_buffers)
surface_->SetForceGlFlushOnSwapBuffers();
// Create GPU Tracer for timing values. // Create GPU Tracer for timing values.
gpu_tracer_.reset(new GPUTracer(this)); gpu_tracer_.reset(new GPUTracer(this));
......
...@@ -2924,6 +2924,18 @@ ...@@ -2924,6 +2924,18 @@
"features": [ "features": [
"max_msaa_sample_count_4" "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 ...@@ -52,6 +52,7 @@ flush_on_framebuffer_change
force_cube_complete force_cube_complete
force_cube_map_positive_x_allocation force_cube_map_positive_x_allocation
force_discrete_gpu force_discrete_gpu
force_gl_flush_on_swap_buffers
force_integrated_gpu force_integrated_gpu
force_int_or_srgb_cube_texture_complete force_int_or_srgb_cube_texture_complete
force_update_scissor_state_when_binding_fbo0 force_update_scissor_state_when_binding_fbo0
......
...@@ -221,6 +221,12 @@ void GLSurface::SetRelyOnImplicitSync() { ...@@ -221,6 +221,12 @@ void GLSurface::SetRelyOnImplicitSync() {
// It is fine to ignore this call in those cases. // 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 { bool GLSurface::SupportsSwapTimestamps() const {
return false; return false;
} }
...@@ -456,6 +462,10 @@ void GLSurfaceAdapter::SetRelyOnImplicitSync() { ...@@ -456,6 +462,10 @@ void GLSurfaceAdapter::SetRelyOnImplicitSync() {
surface_->SetRelyOnImplicitSync(); surface_->SetRelyOnImplicitSync();
} }
void GLSurfaceAdapter::SetForceGlFlushOnSwapBuffers() {
surface_->SetForceGlFlushOnSwapBuffers();
}
bool GLSurfaceAdapter::SupportsSwapTimestamps() const { bool GLSurfaceAdapter::SupportsSwapTimestamps() const {
return surface_->SupportsSwapTimestamps(); return surface_->SupportsSwapTimestamps();
} }
......
...@@ -270,6 +270,9 @@ class GL_EXPORT GLSurface : public base::RefCounted<GLSurface> { ...@@ -270,6 +270,9 @@ class GL_EXPORT GLSurface : public base::RefCounted<GLSurface> {
// Tells the surface to rely on implicit sync when swapping buffers. // Tells the surface to rely on implicit sync when swapping buffers.
virtual void SetRelyOnImplicitSync(); virtual void SetRelyOnImplicitSync();
// Tells the surface to perform a glFlush() before swapping buffers.
virtual void SetForceGlFlushOnSwapBuffers();
// Support for eglGetFrameTimestamps. // Support for eglGetFrameTimestamps.
virtual bool SupportsSwapTimestamps() const; virtual bool SupportsSwapTimestamps() const;
virtual void SetEnableSwapTimestamps(); virtual void SetEnableSwapTimestamps();
...@@ -363,6 +366,7 @@ class GL_EXPORT GLSurfaceAdapter : public GLSurface { ...@@ -363,6 +366,7 @@ class GL_EXPORT GLSurfaceAdapter : public GLSurface {
gfx::Vector2d GetDrawOffset() const override; gfx::Vector2d GetDrawOffset() const override;
void WaitForSnapshotRendering() override; void WaitForSnapshotRendering() override;
void SetRelyOnImplicitSync() override; void SetRelyOnImplicitSync() override;
void SetForceGlFlushOnSwapBuffers() override;
bool SupportsSwapTimestamps() const override; bool SupportsSwapTimestamps() const override;
void SetEnableSwapTimestamps() override; void SetEnableSwapTimestamps() override;
......
...@@ -119,7 +119,9 @@ void GbmSurfaceless::SwapBuffersAsync( ...@@ -119,7 +119,9 @@ void GbmSurfaceless::SwapBuffersAsync(
// TODO(dcastagna): remove glFlush since eglImageFlushExternalEXT called on // TODO(dcastagna): remove glFlush since eglImageFlushExternalEXT called on
// the image should be enough (crbug.com/720045). // the image should be enough (crbug.com/720045).
glFlush(); if (requires_gl_flush_on_swap_buffers_)
glFlush();
unsubmitted_frames_.back()->Flush(); unsubmitted_frames_.back()->Flush();
auto surface_swap_callback = auto surface_swap_callback =
...@@ -204,6 +206,10 @@ void GbmSurfaceless::SetRelyOnImplicitSync() { ...@@ -204,6 +206,10 @@ void GbmSurfaceless::SetRelyOnImplicitSync() {
rely_on_implicit_sync_ = true; rely_on_implicit_sync_ = true;
} }
void GbmSurfaceless::SetForceGlFlushOnSwapBuffers() {
requires_gl_flush_on_swap_buffers_ = true;
}
GbmSurfaceless::~GbmSurfaceless() { GbmSurfaceless::~GbmSurfaceless() {
Destroy(); // The EGL surface must be destroyed before SurfaceOzone. Destroy(); // The EGL surface must be destroyed before SurfaceOzone.
surface_factory_->UnregisterSurface(window_->widget()); surface_factory_->UnregisterSurface(window_->widget());
......
...@@ -65,6 +65,7 @@ class GbmSurfaceless : public gl::SurfacelessEGL { ...@@ -65,6 +65,7 @@ class GbmSurfaceless : public gl::SurfacelessEGL {
const PresentationCallback& presentation_callback) override; const PresentationCallback& presentation_callback) override;
EGLConfig GetConfig() override; EGLConfig GetConfig() override;
void SetRelyOnImplicitSync() override; void SetRelyOnImplicitSync() override;
void SetForceGlFlushOnSwapBuffers() override;
protected: protected:
~GbmSurfaceless() override; ~GbmSurfaceless() override;
...@@ -113,6 +114,7 @@ class GbmSurfaceless : public gl::SurfacelessEGL { ...@@ -113,6 +114,7 @@ class GbmSurfaceless : public gl::SurfacelessEGL {
// Conservatively assume we begin on a device that requires // Conservatively assume we begin on a device that requires
// explicit synchronization. // explicit synchronization.
bool is_on_external_drm_device_ = true; bool is_on_external_drm_device_ = true;
bool requires_gl_flush_on_swap_buffers_ = false;
base::WeakPtrFactory<GbmSurfaceless> weak_factory_; 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