Index: gpu/command_buffer/service/gles2_cmd_clear_framebuffer.cc |
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 0000000000000000000000000000000000000000..765dcb9e3d0b32f529041c2215288e5089a9f172 |
--- /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 |