diff options
author | sievers <sievers@chromium.org> | 2014-11-17 18:10:35 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-11-18 02:10:52 +0000 |
commit | 2384f2bddc7a837f97c5d128c75e603f87f9f657 (patch) | |
tree | c6c6faaef3f3d2b9e60dc9d7a0a0db1e710051f1 /gpu | |
parent | 562c49c8edf16a40ef3f76fb6a57d7ac17331216 (diff) | |
download | chromium_src-2384f2bddc7a837f97c5d128c75e603f87f9f657.zip chromium_src-2384f2bddc7a837f97c5d128c75e603f87f9f657.tar.gz chromium_src-2384f2bddc7a837f97c5d128c75e603f87f9f657.tar.bz2 |
gpu: Implement shader glClear() blit for broken IMG drivers
BUG=421271,434094
Review URL: https://codereview.chromium.org/719503003
Cr-Commit-Position: refs/heads/master@{#304545}
Diffstat (limited to 'gpu')
-rw-r--r-- | gpu/BUILD.gn | 1 | ||||
-rw-r--r-- | gpu/command_buffer/service/BUILD.gn | 2 | ||||
-rw-r--r-- | gpu/command_buffer/service/feature_info_unittest.cc | 1 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_clear_framebuffer.cc | 188 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_clear_framebuffer.h | 54 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.cc | 26 | ||||
-rw-r--r-- | gpu/command_buffer/tests/gl_clear_framebuffer_unittest.cc | 200 | ||||
-rw-r--r-- | gpu/command_buffer/tests/gl_manager.cc | 11 | ||||
-rw-r--r-- | gpu/command_buffer/tests/gl_manager.h | 6 | ||||
-rw-r--r-- | gpu/command_buffer_service.gypi | 2 | ||||
-rw-r--r-- | gpu/config/gpu_driver_bug_list_json.cc | 19 | ||||
-rw-r--r-- | gpu/config/gpu_driver_bug_workaround_type.h | 2 | ||||
-rw-r--r-- | gpu/gpu.gyp | 1 |
13 files changed, 511 insertions, 2 deletions
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn index ce9f9d0..d918e9f 100644 --- a/gpu/BUILD.gn +++ b/gpu/BUILD.gn @@ -70,6 +70,7 @@ test("gl_tests") { "command_buffer/tests/gl_bind_uniform_location_unittest.cc", "command_buffer/tests/gl_chromium_framebuffer_multisample_unittest.cc", "command_buffer/tests/gl_chromium_path_rendering_unittest.cc", + "command_buffer/tests/gl_clear_framebuffer_unittest.cc", "command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc", "command_buffer/tests/gl_depth_texture_unittest.cc", "command_buffer/tests/gl_gpu_memory_buffer_unittest.cc", diff --git a/gpu/command_buffer/service/BUILD.gn b/gpu/command_buffer/service/BUILD.gn index 4013c3a..1c43029 100644 --- a/gpu/command_buffer/service/BUILD.gn +++ b/gpu/command_buffer/service/BUILD.gn @@ -44,6 +44,8 @@ source_set("service") { "feature_info.cc", "framebuffer_manager.h", "framebuffer_manager.cc", + "gles2_cmd_clear_framebuffer.cc", + "gles2_cmd_clear_framebuffer.h", "gles2_cmd_copy_texture_chromium.cc", "gles2_cmd_copy_texture_chromium.h", "gles2_cmd_decoder.h", diff --git a/gpu/command_buffer/service/feature_info_unittest.cc b/gpu/command_buffer/service/feature_info_unittest.cc index 88a0a37..53dbf6c 100644 --- a/gpu/command_buffer/service/feature_info_unittest.cc +++ b/gpu/command_buffer/service/feature_info_unittest.cc @@ -134,6 +134,7 @@ TEST_F(FeatureInfoTest, Basic) { #undef GPU_OP EXPECT_EQ(0, info_->workarounds().max_texture_size); EXPECT_EQ(0, info_->workarounds().max_cube_map_texture_size); + EXPECT_FALSE(info_->workarounds().gl_clear_broken); // Test good types. { diff --git a/gpu/command_buffer/service/gles2_cmd_clear_framebuffer.cc b/gpu/command_buffer/service/gles2_cmd_clear_framebuffer.cc new file mode 100644 index 0000000..765dcb9 --- /dev/null +++ b/gpu/command_buffer/service/gles2_cmd_clear_framebuffer.cc @@ -0,0 +1,188 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "gpu/command_buffer/service/gles2_cmd_clear_framebuffer.h" + +#include "base/basictypes.h" +#include "gpu/command_buffer/service/gl_utils.h" +#include "gpu/command_buffer/service/gles2_cmd_decoder.h" + +namespace { + +#define SHADER(src) \ + "#ifdef GL_ES\n" \ + "precision mediump float;\n" \ + "#endif\n" #src + +const char* g_vertex_shader_source = { + SHADER( + uniform float u_clear_depth; + attribute vec4 a_position; + void main(void) { + gl_Position = vec4(a_position.x, a_position.y, u_clear_depth, 1.0); + } + ), +}; + +const char* g_fragment_shader_source = { + SHADER( + uniform vec4 u_clear_color; + void main(void) { + gl_FragColor = u_clear_color; + } + ), +}; + +void CompileShader(GLuint shader, const char* shader_source) { + glShaderSource(shader, 1, &shader_source, 0); + glCompileShader(shader); +#if DCHECK_IS_ON + GLint compile_status = GL_FALSE; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status); + if (GL_TRUE != compile_status) { + char buffer[1024]; + GLsizei length = 0; + glGetShaderInfoLog(shader, sizeof(buffer), &length, buffer); + std::string log(buffer, length); + DLOG(ERROR) << "Error compiling shader: " << log; + DLOG(ERROR) << "Shader compilation failure."; + } +#endif +} + +} // namespace + +namespace gpu { + +ClearFramebufferResourceManager::ClearFramebufferResourceManager( + const gles2::GLES2Decoder* decoder) + : initialized_(false), program_(0u), buffer_id_(0u) { + Initialize(decoder); +} + +ClearFramebufferResourceManager::~ClearFramebufferResourceManager() { + Destroy(); + DCHECK(!buffer_id_); +} + +void ClearFramebufferResourceManager::Initialize( + const gles2::GLES2Decoder* decoder) { + COMPILE_ASSERT( + kVertexPositionAttrib == 0u, + Position_attribs_must_be_0); + DCHECK(!buffer_id_); + + glGenBuffersARB(1, &buffer_id_); + glBindBuffer(GL_ARRAY_BUFFER, buffer_id_); + const GLfloat kQuadVertices[] = {-1.0f, -1.0f, + 1.0f, -1.0f, + 1.0f, 1.0f, + -1.0f, 1.0f}; + glBufferData( + GL_ARRAY_BUFFER, sizeof(kQuadVertices), kQuadVertices, GL_STATIC_DRAW); + decoder->RestoreBufferBindings(); + initialized_ = true; +} + +void ClearFramebufferResourceManager::Destroy() { + if (!initialized_) + return; + + glDeleteProgram(program_); + glDeleteBuffersARB(1, &buffer_id_); + buffer_id_ = 0; +} + +void ClearFramebufferResourceManager::ClearFramebuffer( + const gles2::GLES2Decoder* decoder, + const gfx::Size& framebuffer_size, + GLbitfield mask, + GLfloat clear_color_red, + GLfloat clear_color_green, + GLfloat clear_color_blue, + GLfloat clear_color_alpha, + GLfloat clear_depth_value, + GLint clear_stencil_value) { + if (!initialized_) { + DLOG(ERROR) << "Uninitialized manager."; + return; + } + + if (!program_) { + program_ = glCreateProgram(); + GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); + CompileShader(vertex_shader, g_vertex_shader_source); + glAttachShader(program_, vertex_shader); + GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); + CompileShader(fragment_shader, g_fragment_shader_source); + glAttachShader(program_, fragment_shader); + glBindAttribLocation(program_, kVertexPositionAttrib, "a_position"); + glLinkProgram(program_); +#if DCHECK_IS_ON + GLint linked = GL_FALSE; + glGetProgramiv(program_, GL_LINK_STATUS, &linked); + if (GL_TRUE != linked) + DLOG(ERROR) << "Program link failure."; +#endif + depth_handle_ = glGetUniformLocation(program_, "u_clear_depth"); + color_handle_ = glGetUniformLocation(program_, "u_clear_color"); + glDeleteShader(fragment_shader); + glDeleteShader(vertex_shader); + } + glUseProgram(program_); + +#if DCHECK_IS_ON + glValidateProgram(program_); + GLint validation_status = GL_FALSE; + glGetProgramiv(program_, GL_VALIDATE_STATUS, &validation_status); + if (GL_TRUE != validation_status) + DLOG(ERROR) << "Invalid shader."; +#endif + + decoder->ClearAllAttributes(); + glEnableVertexAttribArray(kVertexPositionAttrib); + + glBindBuffer(GL_ARRAY_BUFFER, buffer_id_); + glVertexAttribPointer(kVertexPositionAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0); + + glUniform1f(depth_handle_, clear_depth_value); + glUniform4f(color_handle_, clear_color_red, clear_color_green, + clear_color_blue, clear_color_alpha); + + if (!(mask & GL_COLOR_BUFFER_BIT)) { + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + } + + if (mask & GL_DEPTH_BUFFER_BIT) { + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_ALWAYS); + } else { + glDisable(GL_DEPTH_TEST); + glDepthMask(GL_FALSE); + } + + if (mask & GL_STENCIL_BUFFER_BIT) { + glEnable(GL_STENCIL_TEST); + glStencilFunc(GL_ALWAYS, clear_stencil_value, 0xFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + } else { + glDisable(GL_STENCIL_TEST); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glStencilMask(0); + } + + glDisable(GL_CULL_FACE); + glDisable(GL_BLEND); + glDisable(GL_POLYGON_OFFSET_FILL); + + glViewport(0, 0, framebuffer_size.width(), framebuffer_size.height()); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + decoder->RestoreAllAttributes(); + decoder->RestoreProgramBindings(); + decoder->RestoreBufferBindings(); + decoder->RestoreGlobalState(); +} + +} // namespace gpu diff --git a/gpu/command_buffer/service/gles2_cmd_clear_framebuffer.h b/gpu/command_buffer/service/gles2_cmd_clear_framebuffer.h new file mode 100644 index 0000000..6b533f5 --- /dev/null +++ b/gpu/command_buffer/service/gles2_cmd_clear_framebuffer.h @@ -0,0 +1,54 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_CLEAR_FRAMEBUFFER_H_ +#define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_CLEAR_FRAMEBUFFER_H_ + +#include "gpu/command_buffer/service/gl_utils.h" +#include "gpu/gpu_export.h" + +namespace gfx { +class Size; +} + +namespace gpu { +namespace gles2 { +class GLES2Decoder; +} + +class GPU_EXPORT ClearFramebufferResourceManager { + public: + ClearFramebufferResourceManager(const gles2::GLES2Decoder* decoder); + ~ClearFramebufferResourceManager(); + + + void ClearFramebuffer(const gles2::GLES2Decoder* decoder, + const gfx::Size& framebuffer_size, + GLbitfield mask, + GLfloat clear_color_red, + GLfloat clear_color_green, + GLfloat clear_color_blue, + GLfloat clear_color_alpha, + GLfloat clear_depth_value, + GLint clear_stencil_value); + + private: + void Initialize(const gles2::GLES2Decoder* decoder); + void Destroy(); + + // The attributes used during invocation of the extension. + static const GLuint kVertexPositionAttrib = 0; + + bool initialized_; + GLuint program_; + GLuint depth_handle_; + GLuint color_handle_; + GLuint buffer_id_; + + DISALLOW_COPY_AND_ASSIGN(ClearFramebufferResourceManager); +}; + +} // namespace gpu. + +#endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_CLEAR_FRAMEBUFFER_H_ diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 5dd9f64..dec594b 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -41,6 +41,7 @@ #include "gpu/command_buffer/service/feature_info.h" #include "gpu/command_buffer/service/framebuffer_manager.h" #include "gpu/command_buffer/service/gl_utils.h" +#include "gpu/command_buffer/service/gles2_cmd_clear_framebuffer.h" #include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" #include "gpu/command_buffer/service/gles2_cmd_validation.h" #include "gpu/command_buffer/service/gpu_state_tracer.h" @@ -1840,6 +1841,7 @@ class GLES2DecoderImpl : public GLES2Decoder, #endif scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_; + scoped_ptr<ClearFramebufferResourceManager> clear_framebuffer_blit_; // Cached values of the currently assigned viewport dimensions. GLsizei viewport_max_width_; @@ -2764,6 +2766,14 @@ bool GLES2DecoderImpl::Initialize( AsyncPixelTransferManager::Create(context.get())); async_pixel_transfer_manager_->Initialize(texture_manager()); + if (workarounds().gl_clear_broken) { + DCHECK(!clear_framebuffer_blit_.get()); + LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glClearWorkaroundInit"); + clear_framebuffer_blit_.reset(new ClearFramebufferResourceManager(this)); + if (LOCAL_PEEK_GL_ERROR("glClearWorkaroundInit") != GL_NO_ERROR) + return false; + } + framebuffer_manager()->AddObserver(this); return true; @@ -3549,6 +3559,8 @@ void GLES2DecoderImpl::Destroy(bool have_context) { copy_texture_CHROMIUM_.reset(); } + clear_framebuffer_blit_.reset(); + if (state_.current_program.get()) { program_manager()->UnuseProgram(shader_manager(), state_.current_program.get()); @@ -3614,6 +3626,7 @@ void GLES2DecoderImpl::Destroy(bool have_context) { state_.current_program = NULL; copy_texture_CHROMIUM_.reset(); + clear_framebuffer_blit_.reset(); if (query_manager_.get()) { query_manager_->Destroy(have_context); @@ -5106,6 +5119,19 @@ error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) { if (CheckBoundFramebuffersValid("glClear")) { ApplyDirtyState(); ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get()); + if (workarounds().gl_clear_broken) { + ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::ClearWorkaround", + GetErrorState()); + if (!BoundFramebufferHasDepthAttachment()) + mask &= ~GL_DEPTH_BUFFER_BIT; + if (!BoundFramebufferHasStencilAttachment()) + mask &= ~GL_STENCIL_BUFFER_BIT; + clear_framebuffer_blit_->ClearFramebuffer( + this, GetBoundReadFrameBufferSize(), mask, state_.color_clear_red, + state_.color_clear_green, state_.color_clear_blue, + state_.color_clear_alpha, state_.depth_clear, state_.stencil_clear); + return error::kNoError; + } glClear(mask); } return error::kNoError; diff --git a/gpu/command_buffer/tests/gl_clear_framebuffer_unittest.cc b/gpu/command_buffer/tests/gl_clear_framebuffer_unittest.cc new file mode 100644 index 0000000..8a925c8 --- /dev/null +++ b/gpu/command_buffer/tests/gl_clear_framebuffer_unittest.cc @@ -0,0 +1,200 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GL_GLEXT_PROTOTYPES +#define GL_GLEXT_PROTOTYPES +#endif + +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> +#include <GLES2/gl2extchromium.h> + +#include <vector> + +#include "base/command_line.h" +#include "base/strings/string_number_conversions.h" +#include "gpu/command_buffer/service/gpu_switches.h" +#include "gpu/command_buffer/tests/gl_manager.h" +#include "gpu/command_buffer/tests/gl_test_utils.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace gpu { + +// A collection of tests that exercise the glClear workaround. +class GLClearFramebufferTest : public testing::TestWithParam<bool> { + public: + GLClearFramebufferTest() : color_handle_(0u), depth_handle_(0u) {} + + protected: + void SetUp() override { + if (GetParam()) { + // Force the glClear() workaround so we can test it here. + CommandLine command_line(base::CommandLine::NO_PROGRAM); + command_line.AppendSwitchASCII(switches::kGpuDriverBugWorkarounds, + base::IntToString(gpu::GL_CLEAR_BROKEN)); + gl_.InitializeWithCommandLine(GLManager::Options(), &command_line); + DCHECK(gl_.workarounds().gl_clear_broken); + } else { + gl_.Initialize(GLManager::Options()); + DCHECK(!gl_.workarounds().gl_clear_broken); + } + } + + void InitDraw(); + void SetDrawColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a); + void SetDrawDepth(GLfloat depth); + void DrawQuad(); + + void TearDown() override { + GLTestHelper::CheckGLError("no errors", __LINE__); + gl_.Destroy(); + } + + private: + GLManager gl_; + GLuint color_handle_; + GLuint depth_handle_; +}; + +void GLClearFramebufferTest::InitDraw() { + static const char* v_shader_str = + "attribute vec4 a_Position;\n" + "uniform float u_depth;\n" + "void main()\n" + "{\n" + " gl_Position = a_Position;\n" + " gl_Position.z = u_depth;\n" + "}\n"; + static const char* f_shader_str = + "precision mediump float;\n" + "uniform vec4 u_draw_color;\n" + "void main()\n" + "{\n" + " gl_FragColor = u_draw_color;\n" + "}\n"; + + GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str); + DCHECK(program); + glUseProgram(program); + GLuint position_loc = glGetAttribLocation(program, "a_Position"); + + GLTestHelper::SetupUnitQuad(position_loc); + color_handle_ = glGetUniformLocation(program, "u_draw_color"); + DCHECK(color_handle_ != static_cast<GLuint>(-1)); + depth_handle_ = glGetUniformLocation(program, "u_depth"); + DCHECK(depth_handle_ != static_cast<GLuint>(-1)); +} + +void GLClearFramebufferTest::SetDrawColor(GLfloat r, + GLfloat g, + GLfloat b, + GLfloat a) { + glUniform4f(color_handle_, r, g, b, a); +} + +void GLClearFramebufferTest::SetDrawDepth(GLfloat depth) { + glUniform1f(depth_handle_, depth); +} + +void GLClearFramebufferTest::DrawQuad() { + glDrawArrays(GL_TRIANGLES, 0, 6); +} + +INSTANTIATE_TEST_CASE_P(GLClearFramebufferTestWithParam, + GLClearFramebufferTest, + ::testing::Values(true, false)); + +TEST_P(GLClearFramebufferTest, ClearColor) { + glClearColor(1.0f, 0.5f, 0.25f, 0.5f); + glClear(GL_COLOR_BUFFER_BIT); + + // Verify. + const uint8 expected[] = {255, 128, 64, 128}; + EXPECT_TRUE( + GLTestHelper::CheckPixels(0, 0, 1, 1, 1 /* tolerance */, expected)); +} + +TEST_P(GLClearFramebufferTest, ClearColorWithMask) { + glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE); + glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + // Verify. + const uint8 expected[] = {255, 0, 0, 0}; + EXPECT_TRUE( + GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, expected)); +} + +// crbug.com/434094 +#if !defined(OS_MACOSX) +TEST_P(GLClearFramebufferTest, ClearColorWithScissor) { + glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + // Verify. + const uint8 expected[] = {255, 255, 255, 255}; + EXPECT_TRUE( + GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, expected)); + + glScissor(0, 0, 0, 0); + glEnable(GL_SCISSOR_TEST); + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + + // Verify - no changes. + EXPECT_TRUE( + GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, expected)); +} +#endif + +TEST_P(GLClearFramebufferTest, ClearDepthStencil) { + const GLuint kStencilRef = 1 << 2; + InitDraw(); + SetDrawColor(1.0f, 0.0f, 0.0f, 1.0f); + DrawQuad(); + // Verify. + const uint8 kRed[] = {255, 0, 0, 255}; + const uint8 kGreen[] = {0, 255, 0, 255}; + EXPECT_TRUE( + GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, kRed)); + + glClearStencil(kStencilRef); + glClear(GL_STENCIL_BUFFER_BIT); + glEnable(GL_STENCIL_TEST); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glStencilFunc(GL_NOTEQUAL, kStencilRef, 0xFFFFFFFF); + + SetDrawColor(0.0f, 1.0f, 0.0f, 1.0f); + DrawQuad(); + // Verify - stencil should have failed, so still red. + EXPECT_TRUE( + GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, kRed)); + + glStencilFunc(GL_EQUAL, kStencilRef, 0xFFFFFFFF); + DrawQuad(); + // Verify - stencil should have passed, so green. + EXPECT_TRUE( + GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, kGreen)); + + glEnable(GL_DEPTH_TEST); + glClearDepthf(0.0f); + glClear(GL_DEPTH_BUFFER_BIT); + + SetDrawDepth(0.5f); + SetDrawColor(1.0f, 0.0f, 0.0f, 1.0f); + DrawQuad(); + // Verify - depth test should have failed, so still green. + EXPECT_TRUE( + GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, kGreen)); + + glClearDepthf(0.9f); + glClear(GL_DEPTH_BUFFER_BIT); + DrawQuad(); + // Verify - depth test should have passed, so red. + EXPECT_TRUE( + GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, kRed)); +} + +} // namespace gpu diff --git a/gpu/command_buffer/tests/gl_manager.cc b/gpu/command_buffer/tests/gl_manager.cc index ebd821c..c09901f 100644 --- a/gpu/command_buffer/tests/gl_manager.cc +++ b/gpu/command_buffer/tests/gl_manager.cc @@ -139,6 +139,10 @@ scoped_ptr<gfx::GpuMemoryBuffer> GLManager::CreateGpuMemoryBuffer( } void GLManager::Initialize(const GLManager::Options& options) { + InitializeWithCommandLine(options, nullptr); +} +void GLManager::InitializeWithCommandLine(const GLManager::Options& options, + base::CommandLine* command_line) { const int32 kCommandBufferSize = 1024 * 1024; const size_t kStartTransferBufferSize = 4 * 1024 * 1024; const size_t kMinTransferBufferSize = 1 * 256 * 1024; @@ -186,14 +190,19 @@ void GLManager::Initialize(const GLManager::Options& options) { attrib_helper.blue_size = 8; attrib_helper.alpha_size = 8; attrib_helper.depth_size = 16; + attrib_helper.stencil_size = 8; attrib_helper.Serialize(&attribs); + DCHECK(!command_line || !context_group); if (!context_group) { + scoped_refptr<gles2::FeatureInfo> feature_info; + if (command_line) + feature_info = new gles2::FeatureInfo(*command_line); context_group = new gles2::ContextGroup(mailbox_manager_.get(), NULL, new gpu::gles2::ShaderTranslatorCache, - NULL, + feature_info, options.bind_generates_resource); } diff --git a/gpu/command_buffer/tests/gl_manager.h b/gpu/command_buffer/tests/gl_manager.h index 03ed6a1..7a3eb2c 100644 --- a/gpu/command_buffer/tests/gl_manager.h +++ b/gpu/command_buffer/tests/gl_manager.h @@ -13,6 +13,10 @@ #include "ui/gfx/gpu_memory_buffer.h" #include "ui/gfx/size.h" +namespace base { +class CommandLine; +} + namespace gfx { class GLContext; @@ -66,6 +70,8 @@ class GLManager : private GpuControl { gfx::GpuMemoryBuffer::Format format); void Initialize(const Options& options); + void InitializeWithCommandLine(const Options& options, + base::CommandLine* command_line); void Destroy(); void MakeCurrent(); diff --git a/gpu/command_buffer_service.gypi b/gpu/command_buffer_service.gypi index 13ffe94..c276d432 100644 --- a/gpu/command_buffer_service.gypi +++ b/gpu/command_buffer_service.gypi @@ -62,6 +62,8 @@ 'command_buffer/service/feature_info.cc', 'command_buffer/service/framebuffer_manager.h', 'command_buffer/service/framebuffer_manager.cc', + 'command_buffer/service/gles2_cmd_clear_framebuffer.cc', + 'command_buffer/service/gles2_cmd_clear_framebuffer.h', 'command_buffer/service/gles2_cmd_copy_texture_chromium.cc', 'command_buffer/service/gles2_cmd_copy_texture_chromium.h', 'command_buffer/service/gles2_cmd_decoder.h', diff --git a/gpu/config/gpu_driver_bug_list_json.cc b/gpu/config/gpu_driver_bug_list_json.cc index e1e9650..525f848 100644 --- a/gpu/config/gpu_driver_bug_list_json.cc +++ b/gpu/config/gpu_driver_bug_list_json.cc @@ -19,7 +19,7 @@ const char kGpuDriverBugListJson[] = LONG_STRING_CONST( { "name": "gpu driver bug list", // Please update the version number whenever you change this file. - "version": "7.8", + "version": "7.9", "entries": [ { "id": 1, @@ -1067,6 +1067,23 @@ LONG_STRING_CONST( "features": [ "disable_egl_khr_wait_sync" ] + }, + { + "id": 95, + "cr_bugs": [421271], + "description": "glClear does not always work on these drivers", + "os": { + "type": "android" + }, + "gl_type": "gles", + "gl_version": { + "op": "<", + "value": "3.0" + }, + "gl_vendor": "Imagination.*", + "features": [ + "gl_clear_broken" + ] } ] } diff --git a/gpu/config/gpu_driver_bug_workaround_type.h b/gpu/config/gpu_driver_bug_workaround_type.h index 0cd9761..841a470 100644 --- a/gpu/config/gpu_driver_bug_workaround_type.h +++ b/gpu/config/gpu_driver_bug_workaround_type.h @@ -54,6 +54,8 @@ force_gl_finish_after_compositing) \ GPU_OP(FORCE_INTEGRATED_GPU, \ force_integrated_gpu) \ + GPU_OP(GL_CLEAR_BROKEN, \ + gl_clear_broken) \ GPU_OP(INIT_GL_POSITION_IN_VERTEX_SHADER, \ init_gl_position_in_vertex_shader) \ GPU_OP(INIT_TEXTURE_MAX_ANISOTROPY, \ diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp index ddecf45..5a9deb1d 100644 --- a/gpu/gpu.gyp +++ b/gpu/gpu.gyp @@ -321,6 +321,7 @@ 'command_buffer/tests/gl_bind_uniform_location_unittest.cc', 'command_buffer/tests/gl_chromium_framebuffer_multisample_unittest.cc', 'command_buffer/tests/gl_chromium_path_rendering_unittest.cc', + 'command_buffer/tests/gl_clear_framebuffer_unittest.cc', 'command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc', 'command_buffer/tests/gl_depth_texture_unittest.cc', 'command_buffer/tests/gl_gpu_memory_buffer_unittest.cc', |