Elim cr-checkbox
[chromium-blink-merge.git] / gpu / command_buffer / service / gles2_cmd_clear_framebuffer.cc
blobe8057912bbb0f8f8c81e4a4b6fca3f509b25590b
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "gpu/command_buffer/service/gles2_cmd_clear_framebuffer.h"
7 #include "base/basictypes.h"
8 #include "gpu/command_buffer/service/gl_utils.h"
9 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
10 #include "ui/gfx/geometry/size.h"
12 namespace {
14 #define SHADER(src) \
15 "#ifdef GL_ES\n" \
16 "precision mediump float;\n" \
17 "#endif\n" #src
19 const char* g_vertex_shader_source = {
20 SHADER(
21 uniform float u_clear_depth;
22 attribute vec4 a_position;
23 void main(void) {
24 gl_Position = vec4(a_position.x, a_position.y, u_clear_depth, 1.0);
29 const char* g_fragment_shader_source = {
30 SHADER(
31 uniform vec4 u_clear_color;
32 void main(void) {
33 gl_FragColor = u_clear_color;
38 void CompileShader(GLuint shader, const char* shader_source) {
39 glShaderSource(shader, 1, &shader_source, 0);
40 glCompileShader(shader);
41 #if DCHECK_IS_ON()
42 GLint compile_status = GL_FALSE;
43 glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status);
44 if (GL_TRUE != compile_status) {
45 char buffer[1024];
46 GLsizei length = 0;
47 glGetShaderInfoLog(shader, sizeof(buffer), &length, buffer);
48 std::string log(buffer, length);
49 DLOG(ERROR) << "Error compiling shader: " << log;
50 DLOG(ERROR) << "Shader compilation failure.";
52 #endif
55 } // namespace
57 namespace gpu {
59 ClearFramebufferResourceManager::ClearFramebufferResourceManager(
60 const gles2::GLES2Decoder* decoder)
61 : initialized_(false), program_(0u), buffer_id_(0u) {
62 Initialize(decoder);
65 ClearFramebufferResourceManager::~ClearFramebufferResourceManager() {
66 Destroy();
67 DCHECK(!buffer_id_);
70 void ClearFramebufferResourceManager::Initialize(
71 const gles2::GLES2Decoder* decoder) {
72 static_assert(
73 kVertexPositionAttrib == 0u,
74 "kVertexPositionAttrib must be 0");
75 DCHECK(!buffer_id_);
77 glGenBuffersARB(1, &buffer_id_);
78 glBindBuffer(GL_ARRAY_BUFFER, buffer_id_);
79 const GLfloat kQuadVertices[] = {-1.0f, -1.0f,
80 1.0f, -1.0f,
81 1.0f, 1.0f,
82 -1.0f, 1.0f};
83 glBufferData(
84 GL_ARRAY_BUFFER, sizeof(kQuadVertices), kQuadVertices, GL_STATIC_DRAW);
85 decoder->RestoreBufferBindings();
86 initialized_ = true;
89 void ClearFramebufferResourceManager::Destroy() {
90 if (!initialized_)
91 return;
93 glDeleteProgram(program_);
94 glDeleteBuffersARB(1, &buffer_id_);
95 buffer_id_ = 0;
98 void ClearFramebufferResourceManager::ClearFramebuffer(
99 const gles2::GLES2Decoder* decoder,
100 const gfx::Size& framebuffer_size,
101 GLbitfield mask,
102 GLfloat clear_color_red,
103 GLfloat clear_color_green,
104 GLfloat clear_color_blue,
105 GLfloat clear_color_alpha,
106 GLfloat clear_depth_value,
107 GLint clear_stencil_value) {
108 if (!initialized_) {
109 DLOG(ERROR) << "Uninitialized manager.";
110 return;
113 if (!program_) {
114 program_ = glCreateProgram();
115 GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
116 CompileShader(vertex_shader, g_vertex_shader_source);
117 glAttachShader(program_, vertex_shader);
118 GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
119 CompileShader(fragment_shader, g_fragment_shader_source);
120 glAttachShader(program_, fragment_shader);
121 glBindAttribLocation(program_, kVertexPositionAttrib, "a_position");
122 glLinkProgram(program_);
123 #if DCHECK_IS_ON()
124 GLint linked = GL_FALSE;
125 glGetProgramiv(program_, GL_LINK_STATUS, &linked);
126 if (GL_TRUE != linked)
127 DLOG(ERROR) << "Program link failure.";
128 #endif
129 depth_handle_ = glGetUniformLocation(program_, "u_clear_depth");
130 color_handle_ = glGetUniformLocation(program_, "u_clear_color");
131 glDeleteShader(fragment_shader);
132 glDeleteShader(vertex_shader);
134 glUseProgram(program_);
136 #if DCHECK_IS_ON()
137 glValidateProgram(program_);
138 GLint validation_status = GL_FALSE;
139 glGetProgramiv(program_, GL_VALIDATE_STATUS, &validation_status);
140 if (GL_TRUE != validation_status)
141 DLOG(ERROR) << "Invalid shader.";
142 #endif
144 decoder->ClearAllAttributes();
145 glEnableVertexAttribArray(kVertexPositionAttrib);
147 glBindBuffer(GL_ARRAY_BUFFER, buffer_id_);
148 glVertexAttribPointer(kVertexPositionAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
150 glUniform1f(depth_handle_, clear_depth_value);
151 glUniform4f(color_handle_, clear_color_red, clear_color_green,
152 clear_color_blue, clear_color_alpha);
154 if (!(mask & GL_COLOR_BUFFER_BIT)) {
155 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
158 if (mask & GL_DEPTH_BUFFER_BIT) {
159 glEnable(GL_DEPTH_TEST);
160 glDepthFunc(GL_ALWAYS);
161 } else {
162 glDisable(GL_DEPTH_TEST);
163 glDepthMask(GL_FALSE);
166 if (mask & GL_STENCIL_BUFFER_BIT) {
167 glEnable(GL_STENCIL_TEST);
168 glStencilFunc(GL_ALWAYS, clear_stencil_value, 0xFF);
169 glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
170 } else {
171 glDisable(GL_STENCIL_TEST);
172 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
173 glStencilMask(0);
176 glDisable(GL_CULL_FACE);
177 glDisable(GL_BLEND);
178 glDisable(GL_POLYGON_OFFSET_FILL);
180 glViewport(0, 0, framebuffer_size.width(), framebuffer_size.height());
181 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
183 decoder->RestoreAllAttributes();
184 decoder->RestoreProgramBindings();
185 decoder->RestoreBufferBindings();
186 decoder->RestoreGlobalState();
189 } // namespace gpu