summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorsievers <sievers@chromium.org>2014-11-17 18:10:35 -0800
committerCommit bot <commit-bot@chromium.org>2014-11-18 02:10:52 +0000
commit2384f2bddc7a837f97c5d128c75e603f87f9f657 (patch)
treec6c6faaef3f3d2b9e60dc9d7a0a0db1e710051f1 /gpu
parent562c49c8edf16a40ef3f76fb6a57d7ac17331216 (diff)
downloadchromium_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.gn1
-rw-r--r--gpu/command_buffer/service/BUILD.gn2
-rw-r--r--gpu/command_buffer/service/feature_info_unittest.cc1
-rw-r--r--gpu/command_buffer/service/gles2_cmd_clear_framebuffer.cc188
-rw-r--r--gpu/command_buffer/service/gles2_cmd_clear_framebuffer.h54
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc26
-rw-r--r--gpu/command_buffer/tests/gl_clear_framebuffer_unittest.cc200
-rw-r--r--gpu/command_buffer/tests/gl_manager.cc11
-rw-r--r--gpu/command_buffer/tests/gl_manager.h6
-rw-r--r--gpu/command_buffer_service.gypi2
-rw-r--r--gpu/config/gpu_driver_bug_list_json.cc19
-rw-r--r--gpu/config/gpu_driver_bug_workaround_type.h2
-rw-r--r--gpu/gpu.gyp1
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',