Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2016 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. | |
| 4 | |
| 5 #include "gpu/command_buffer/service/gles2_cmd_srgb_converter.h" | |
| 6 | |
| 7 #include "gpu/command_buffer/service/texture_manager.h" | |
| 8 #include "ui/gl/gl_version_info.h" | |
| 9 | |
| 10 namespace { | |
| 11 | |
| 12 void CompileShader(GLuint shader, const char* shader_source) { | |
| 13 glShaderSource(shader, 1, &shader_source, 0); | |
| 14 glCompileShader(shader); | |
| 15 #ifndef NDEBUG | |
| 16 GLint compile_status; | |
| 17 glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status); | |
| 18 if (GL_TRUE != compile_status) | |
| 19 DLOG(ERROR) << "CopyTexImage: shader compilation failure."; | |
| 20 #endif | |
| 21 } | |
| 22 | |
| 23 } // anonymous namespace | |
| 24 | |
| 25 namespace gpu { | |
| 26 namespace gles2 { | |
| 27 | |
| 28 SRGBConverter::SRGBConverter( | |
| 29 const gles2::FeatureInfo* feature_info) | |
| 30 : feature_info_(feature_info) { | |
| 31 } | |
| 32 | |
| 33 SRGBConverter::~SRGBConverter() {} | |
| 34 | |
| 35 // Vertex shader, shared by both decoder program and encoder program | |
| 36 const char* vs_source = | |
|
piman
2016/09/08 19:39:18
nit: static, as to not pollute the namespace.
| |
| 37 "#version 150\n" | |
| 38 "out vec2 v_texcoord;\n" | |
| 39 "\n" | |
| 40 "void main()\n" | |
| 41 "{\n" | |
| 42 " const vec2 quad_positions[6] = vec2[6]\n" | |
| 43 " (\n" | |
| 44 " vec2(0.0f, 0.0f),\n" | |
| 45 " vec2(0.0f, 1.0f),\n" | |
| 46 " vec2(1.0f, 0.0f),\n" | |
| 47 "\n" | |
| 48 " vec2(0.0f, 1.0f),\n" | |
| 49 " vec2(1.0f, 0.0f),\n" | |
| 50 " vec2(1.0f, 1.0f)\n" | |
| 51 " );\n" | |
| 52 "\n" | |
| 53 " vec2 xy = vec2((quad_positions[gl_VertexID] * 2.0) - 1.0);\n" | |
| 54 " gl_Position = vec4(xy, 0.0, 1.0);\n" | |
| 55 " v_texcoord = quad_positions[gl_VertexID];\n" | |
| 56 "}\n"; | |
| 57 | |
| 58 void SRGBConverter::InitializeSRGBDecoder( | |
| 59 const gles2::GLES2Decoder* decoder) { | |
| 60 if (srgb_decoder_initialized_) { | |
| 61 return; | |
| 62 } | |
| 63 | |
| 64 srgb_decoder_program_ = glCreateProgram(); | |
| 65 | |
| 66 // Compile the vertex shader | |
| 67 GLuint vs = glCreateShader(GL_VERTEX_SHADER); | |
| 68 CompileShader(vs, vs_source); | |
| 69 glAttachShader(srgb_decoder_program_, vs); | |
| 70 glDeleteShader(vs); | |
| 71 | |
| 72 // Compile the fragment shader | |
| 73 | |
| 74 // Sampling texels from a srgb texture to a linear image, it will convert | |
| 75 // the srgb color space to linear color space automatically as a part of | |
| 76 // filtering. See the section <sRGB Texture Color Conversion> in GLES and | |
| 77 // OpenGL spec. | |
| 78 // However, sampling texels from a linear texture to a srgb image, it will | |
| 79 // not convert linear to srgb automatically. There is no similar words in | |
| 80 // <sRGB Texture Color Conversion> or other sections in GLES/OGL spec. | |
| 81 // So we don't need to do manual decoding in decoder program, but we need | |
| 82 // to do encoder in encoder program. | |
| 83 const char* fs_source = | |
| 84 "#version 150\n" | |
| 85 "uniform sampler2D u_source_texture;\n" | |
| 86 "in vec2 v_texcoord;\n" | |
| 87 "out vec4 output_color;\n" | |
| 88 "\n" | |
| 89 /* "float decode(float color)\n" | |
| 90 "{\n" | |
| 91 " float decoded_color;\n" | |
| 92 " if (color <= 0.04045) {\n" | |
| 93 " decoded_color = color / 12.92;\n" | |
| 94 " } else {\n" | |
| 95 " decoded_color = (color + 0.055) / 1.055;\n" | |
| 96 " decoded_color = pow(decoded_color, 2.4);\n" | |
| 97 " }\n" | |
| 98 " return decoded_color;\n" | |
| 99 "}\n" | |
| 100 "\n" */ | |
| 101 "void main()\n" | |
| 102 "{\n" | |
| 103 " vec4 c = texture(u_source_texture, v_texcoord);\n" | |
| 104 //" output_color = vec4(decode(c.r), decode(c.g), decode(c.b), c.a);\n" | |
| 105 " output_color = c;\n" | |
| 106 "}\n"; | |
| 107 | |
| 108 GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); | |
| 109 CompileShader(fs, fs_source); | |
| 110 glAttachShader(srgb_decoder_program_, fs); | |
| 111 glDeleteShader(fs); | |
| 112 | |
| 113 glLinkProgram(srgb_decoder_program_); | |
| 114 #ifndef NDEBUG | |
| 115 GLint linked = 0; | |
| 116 glGetProgramiv(srgb_decoder_program_, GL_LINK_STATUS, &linked); | |
| 117 if (!linked) { | |
| 118 DLOG(ERROR) << "BlitFramebuffer: program link failure."; | |
| 119 } | |
| 120 #endif | |
| 121 | |
| 122 GLuint texture_uniform = | |
| 123 glGetUniformLocation(srgb_decoder_program_, "u_source_texture"); | |
| 124 glUseProgram(srgb_decoder_program_); | |
| 125 glUniform1i(texture_uniform, 0); | |
| 126 | |
| 127 glGenTextures(srgb_decoder_textures_.size(), srgb_decoder_textures_.data()); | |
| 128 glActiveTexture(GL_TEXTURE0); | |
| 129 for (auto srgb_decoder_texture : srgb_decoder_textures_) { | |
| 130 glBindTexture(GL_TEXTURE_2D, srgb_decoder_texture); | |
| 131 | |
| 132 // Use linear, non-mipmapped sampling with the srgb decoder texture | |
| 133 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
| 134 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
| 135 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
| 136 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
| 137 } | |
| 138 | |
| 139 glGenFramebuffersEXT(1, &srgb_decoder_fbo_); | |
| 140 glGenVertexArraysOES(1, &srgb_decoder_vao_); | |
| 141 | |
| 142 decoder->RestoreTextureUnitBindings(0); | |
| 143 decoder->RestoreActiveTexture(); | |
| 144 decoder->RestoreProgramBindings(); | |
| 145 | |
| 146 srgb_decoder_initialized_ = true; | |
| 147 } | |
| 148 | |
| 149 void SRGBConverter::InitializeSRGBEncoder( | |
| 150 const gles2::GLES2Decoder* decoder) { | |
| 151 if (srgb_encoder_initialized_) { | |
| 152 return; | |
| 153 } | |
| 154 | |
| 155 srgb_encoder_program_ = glCreateProgram(); | |
| 156 | |
| 157 // Compile the vertex shader | |
| 158 GLuint vs = glCreateShader(GL_VERTEX_SHADER); | |
| 159 CompileShader(vs, vs_source); | |
| 160 glAttachShader(srgb_encoder_program_, vs); | |
| 161 glDeleteShader(vs); | |
| 162 | |
| 163 // Compile the fragment shader | |
| 164 | |
| 165 // Sampling texels from a srgb texture to a linear image, it will convert | |
| 166 // the srgb color space to linear color space automatically as a part of | |
| 167 // filtering. See the section <sRGB Texture Color Conversion> in GLES and | |
| 168 // OpenGL spec. | |
| 169 // However, sampling texels from a linear texture to a srgb image, it will | |
| 170 // not convert linear to srgb automatically. There is no similar words in | |
| 171 // <sRGB Texture Color Conversion> or other sections in GLES/OGL spec. | |
| 172 // So we don't need to do manual decoding in decoder program, but we need | |
| 173 const char* fs_source = | |
| 174 "#version 150\n" | |
| 175 "uniform sampler2D u_source_texture;\n" | |
| 176 "in vec2 v_texcoord;\n" | |
| 177 "out vec4 output_color;\n" | |
| 178 "\n" | |
| 179 "float encode(float color)\n" | |
| 180 "{\n" | |
| 181 " float encoded_color;\n" | |
| 182 " if (color <= 0.0) {\n" | |
| 183 " return 0.0;\n" | |
| 184 " } else if (color < 0.0031308) {\n" | |
| 185 " return color * 12.92;\n" | |
| 186 " } else if (color < 1) {\n" | |
| 187 " return pow(color, 0.41666) * 1.055 - 0.055;\n" | |
| 188 " } else {\n" | |
| 189 " return 1.0;\n" | |
| 190 " }\n" | |
| 191 "}\n" | |
| 192 "\n" | |
| 193 "void main()\n" | |
| 194 "{\n" | |
| 195 " vec4 c = texture(u_source_texture, v_texcoord);\n" | |
| 196 " output_color = vec4(encode(c.r), encode(c.g), encode(c.b), c.a);\n" | |
| 197 "}\n"; | |
| 198 | |
| 199 GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); | |
| 200 CompileShader(fs, fs_source); | |
| 201 glAttachShader(srgb_encoder_program_, fs); | |
| 202 glDeleteShader(fs); | |
| 203 | |
| 204 glLinkProgram(srgb_encoder_program_); | |
| 205 #ifndef NDEBUG | |
| 206 GLint linked = 0; | |
| 207 glGetProgramiv(srgb_encoder_program_, GL_LINK_STATUS, &linked); | |
| 208 if (!linked) { | |
| 209 DLOG(ERROR) << "SRGB Encoder for BlitFramebuffer: program link failure."; | |
| 210 } | |
| 211 #endif | |
| 212 | |
| 213 GLuint texture_uniform = | |
| 214 glGetUniformLocation(srgb_encoder_program_, "u_source_texture"); | |
| 215 glUseProgram(srgb_encoder_program_); | |
| 216 glUniform1i(texture_uniform, 0); | |
| 217 | |
| 218 glGenTextures(srgb_encoder_textures_.size(), srgb_encoder_textures_.data()); | |
| 219 glActiveTexture(GL_TEXTURE0); | |
| 220 for (auto srgb_encoder_texture : srgb_encoder_textures_) { | |
| 221 glBindTexture(GL_TEXTURE_2D, srgb_encoder_texture); | |
| 222 | |
| 223 // Use linear, non-mipmapped sampling with the srgb encoder texture | |
| 224 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
| 225 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
| 226 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
| 227 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
| 228 } | |
| 229 | |
| 230 glGenFramebuffersEXT(1, &srgb_encoder_fbo_); | |
| 231 glGenVertexArraysOES(1, &srgb_encoder_vao_); | |
| 232 | |
| 233 decoder->RestoreTextureUnitBindings(0); | |
| 234 decoder->RestoreActiveTexture(); | |
| 235 decoder->RestoreProgramBindings(); | |
| 236 | |
| 237 srgb_encoder_initialized_ = true; | |
| 238 } | |
| 239 | |
| 240 void SRGBConverter::Destroy() { | |
| 241 if (srgb_decoder_initialized_) { | |
| 242 glDeleteProgram(srgb_decoder_program_); | |
| 243 srgb_decoder_program_ = 0; | |
| 244 | |
| 245 glDeleteTextures(srgb_decoder_textures_.size(), | |
| 246 srgb_decoder_textures_.data()); | |
| 247 srgb_decoder_textures_.fill(0); | |
| 248 | |
| 249 glDeleteFramebuffersEXT(1, &srgb_decoder_fbo_); | |
| 250 srgb_decoder_fbo_ = 0; | |
| 251 | |
| 252 glDeleteVertexArraysOES(1, &srgb_decoder_vao_); | |
| 253 srgb_decoder_vao_ = 0; | |
| 254 | |
| 255 srgb_decoder_initialized_ = false; | |
| 256 } | |
| 257 | |
| 258 if (srgb_encoder_initialized_) { | |
| 259 glDeleteProgram(srgb_encoder_program_); | |
| 260 srgb_encoder_program_ = 0; | |
| 261 | |
| 262 glDeleteTextures(srgb_encoder_textures_.size(), | |
| 263 srgb_encoder_textures_.data()); | |
| 264 srgb_encoder_textures_.fill(0); | |
| 265 | |
| 266 glDeleteFramebuffersEXT(1, &srgb_encoder_fbo_); | |
| 267 srgb_encoder_fbo_ = 0; | |
| 268 | |
| 269 glDeleteVertexArraysOES(1, &srgb_encoder_vao_); | |
| 270 srgb_encoder_vao_ = 0; | |
| 271 | |
| 272 srgb_encoder_initialized_ = false; | |
| 273 } | |
| 274 } | |
| 275 | |
| 276 void SRGBConverter::SRGBToLinear( | |
| 277 const gles2::GLES2Decoder* decoder, | |
| 278 GLint srcX0, | |
| 279 GLint srcY0, | |
| 280 GLint srcX1, | |
| 281 GLint srcY1, | |
| 282 GLint dstX0, | |
| 283 GLint dstY0, | |
| 284 GLint dstX1, | |
| 285 GLint dstY1, | |
| 286 GLbitfield mask, | |
| 287 GLenum filter, | |
| 288 const gfx::Size& framebuffer_size, | |
| 289 GLuint src_framebuffer, | |
| 290 GLenum src_framebuffer_internal_format, | |
| 291 GLuint dst_framebuffer) { | |
| 292 // This function convert srgb image in src fb to linear image in dst fb, | |
| 293 // The steps are: | |
| 294 // 1) Copy and crop the pixels from source srgb image to a temp srgb texture. | |
| 295 // 2) Sampling from the srgb texture and drawing to a temp linear texture. | |
| 296 // Durint this step, color space is converted from srgb to linear. | |
| 297 // 3) Finally, blit pixels from the linear texture to the target, which is | |
| 298 // also a linear image. | |
| 299 DCHECK(srgb_decoder_initialized_); | |
| 300 | |
| 301 // Copy the image from framebuffer to the first srgb decoder texture | |
| 302 // TODO(yunchao) If the read buffer is a fbo texture, we can sample | |
| 303 // directly from that texture. In this way, we can save gpu memory. | |
| 304 glBindFramebufferEXT(GL_FRAMEBUFFER, src_framebuffer); | |
| 305 glActiveTexture(GL_TEXTURE0); | |
| 306 glBindTexture(GL_TEXTURE_2D, srgb_decoder_textures_[0]); | |
| 307 | |
| 308 // We should not copy pixels outside of the read framebuffer. If we read | |
| 309 // these pixels, they would become in-bound during BlitFramebuffer. However, | |
| 310 // Out-of-bounds pixels will be initialized to 0 in CopyTexSubImage. But they | |
| 311 // should read as if the GL_CLAMP_TO_EDGE texture mapping mode were applied | |
| 312 // during BlitFramebuffer when the filter is GL_LINEAR. | |
| 313 GLuint x = srcX1 > srcX0 ? srcX0 : srcX1; | |
| 314 GLuint y = srcY1 > srcY0 ? srcY0 : srcY1; | |
| 315 GLuint width = srcX1 > srcX0 ? srcX1 - srcX0 : srcX0 - srcX1; | |
| 316 GLuint height = srcY1 > srcY0 ? srcY1 - srcY0 : srcY0 - srcY1; | |
| 317 gfx::Rect c(0, 0, framebuffer_size.width(), framebuffer_size.height()); | |
| 318 c.Intersect(gfx::Rect(x, y, width, height)); | |
| 319 GLuint xoffset = c.x() - x; | |
| 320 GLuint yoffset = c.y() - y; | |
| 321 glCopyTexImage2D(GL_TEXTURE_2D, 0, src_framebuffer_internal_format, | |
| 322 c.x(), c.y(), c.width(), c.height(), 0); | |
| 323 | |
| 324 // Make a temporary framebuffer using the second srgb decoder texture to | |
| 325 // render the converted (srgb to linear) result to. | |
| 326 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); | |
| 327 | |
| 328 glBindTexture(GL_TEXTURE_2D, srgb_decoder_textures_[1]); | |
| 329 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, | |
| 330 c.width(), c.height(), | |
| 331 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); | |
| 332 glBindFramebufferEXT(GL_FRAMEBUFFER, srgb_decoder_fbo_); | |
| 333 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | |
| 334 GL_TEXTURE_2D, srgb_decoder_textures_[1], 0); | |
| 335 | |
| 336 // Render to the second srgb decoder texture, | |
| 337 // sampling from the first srgb decoder texture. | |
| 338 glUseProgram(srgb_decoder_program_); | |
| 339 glViewport(0, 0, width, height); | |
| 340 glDisable(GL_SCISSOR_TEST); | |
| 341 glDisable(GL_DEPTH_TEST); | |
| 342 glDisable(GL_STENCIL_TEST); | |
| 343 glDisable(GL_CULL_FACE); | |
| 344 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | |
| 345 glDepthMask(GL_FALSE); | |
| 346 glDisable(GL_BLEND); | |
| 347 glDisable(GL_DITHER); | |
| 348 | |
| 349 glBindTexture(GL_TEXTURE_2D, srgb_decoder_textures_[0]); | |
| 350 glBindVertexArrayOES(srgb_decoder_vao_); | |
| 351 | |
| 352 glDrawArrays(GL_TRIANGLES, 0, 6); | |
| 353 | |
| 354 // Finally, bind the temporary framebuffer as read framebuffer, | |
| 355 // blit the converted texture in temp fbo to the destination texture | |
| 356 // in destination framebuffer. | |
| 357 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, srgb_decoder_fbo_); | |
| 358 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, dst_framebuffer); | |
| 359 // Note that the source region has been changed in temp framebuffer. | |
| 360 // The xoffset/yoffset can make bliting clamp to the correct edge if | |
| 361 // CLAMP_TO_EDGE is necessary. | |
| 362 glBlitFramebuffer(srcX0 < srcX1 ? 0 - xoffset : width - xoffset, | |
| 363 srcY0 < srcY1 ? 0 - yoffset : height - yoffset, | |
| 364 srcX0 < srcX1 ? width - xoffset : 0 - xoffset, | |
| 365 srcY0 < srcY1 ? height - yoffset : 0 - yoffset, | |
| 366 dstX0, dstY0, dstX1, dstY1, mask, filter); | |
| 367 | |
| 368 // Restore state | |
| 369 decoder->RestoreAllAttributes(); | |
| 370 decoder->RestoreTextureUnitBindings(0); | |
| 371 decoder->RestoreActiveTexture(); | |
| 372 decoder->RestoreProgramBindings(); | |
| 373 decoder->RestoreBufferBindings(); | |
| 374 decoder->RestoreFramebufferBindings(); | |
| 375 decoder->RestoreGlobalState(); | |
| 376 } | |
| 377 | |
| 378 void SRGBConverter::LinearToSRGB( | |
| 379 const gles2::GLES2Decoder* decoder, | |
| 380 GLint srcX0, | |
| 381 GLint srcY0, | |
| 382 GLint srcX1, | |
| 383 GLint srcY1, | |
| 384 GLint dstX0, | |
| 385 GLint dstY0, | |
| 386 GLint dstX1, | |
| 387 GLint dstY1, | |
| 388 GLbitfield mask, | |
| 389 GLenum filter, | |
| 390 GLuint src_framebuffer, | |
| 391 GLenum src_framebuffer_internal_format, | |
| 392 GLenum src_framebuffer_format, | |
| 393 GLenum src_framebuffer_type, | |
| 394 GLuint dst_framebuffer) { | |
| 395 // This function convert linear image in src fb to srgb image in dst fb. | |
| 396 // The steps are: | |
| 397 // 1) BlitFramebuffer from source linear image to a temp linear texture. | |
| 398 // 2) Sampling from the linear texture and drawing to the target srgb | |
| 399 // image. During this step, color space is converted from linear to srgb. | |
| 400 | |
| 401 DCHECK(srgb_encoder_initialized_); | |
| 402 | |
| 403 // Create a temp linear texture as draw buffer. BlitFramebuffer from | |
| 404 // source linear image to the temp linear texture. Filtering is done | |
| 405 // during bliting. Note that the src and dst coordinates may be reversed. | |
| 406 glActiveTexture(GL_TEXTURE0); | |
| 407 glBindTexture(GL_TEXTURE_2D, srgb_encoder_textures_[0]); | |
| 408 | |
| 409 GLuint width = dstX1 > dstX0 ? dstX1 - dstX0 : dstX0 - dstX1; | |
| 410 GLuint height = dstY1 > dstY0 ? dstY1 - dstY0 : dstY0 - dstY1; | |
| 411 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); | |
| 412 glTexImage2D(GL_TEXTURE_2D, 0, src_framebuffer_internal_format, | |
| 413 width, height, | |
| 414 0, src_framebuffer_format, src_framebuffer_type, nullptr); | |
| 415 | |
| 416 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, srgb_encoder_fbo_); | |
| 417 glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | |
| 418 GL_TEXTURE_2D, srgb_encoder_textures_[0], 0); | |
| 419 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, src_framebuffer); | |
| 420 glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, | |
| 421 dstX0 < dstX1 ? 0 : width, | |
| 422 dstY0 < dstY1 ? 0 : height, | |
| 423 dstX0 < dstX1 ? width : 0, | |
| 424 dstY0 < dstY1 ? height : 0, | |
| 425 mask, filter); | |
| 426 | |
| 427 // Sampling from the linear texture and drawing to the target srgb image. | |
| 428 // During this step, color space is converted from linear to srgb. We should | |
| 429 // set appropriate viewport to draw to the correct location in target FB. | |
| 430 GLuint xoffset = dstX0 < dstX1 ? dstX0 : dstX1; | |
| 431 GLuint yoffset = dstY0 < dstY1 ? dstY0 : dstY1; | |
| 432 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, dst_framebuffer); | |
| 433 glUseProgram(srgb_encoder_program_); | |
| 434 glViewport(xoffset, yoffset, width, height); | |
| 435 glDisable(GL_SCISSOR_TEST); | |
| 436 glDisable(GL_DEPTH_TEST); | |
| 437 glDisable(GL_STENCIL_TEST); | |
| 438 glDisable(GL_CULL_FACE); | |
| 439 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | |
| 440 glDepthMask(GL_FALSE); | |
| 441 glDisable(GL_BLEND); | |
| 442 glDisable(GL_DITHER); | |
| 443 | |
| 444 glBindTexture(GL_TEXTURE_2D, srgb_encoder_textures_[0]); | |
| 445 glBindVertexArrayOES(srgb_encoder_vao_); | |
| 446 | |
| 447 glDrawArrays(GL_TRIANGLES, 0, 6); | |
| 448 | |
| 449 // Restore state | |
| 450 decoder->RestoreAllAttributes(); | |
| 451 decoder->RestoreTextureUnitBindings(0); | |
| 452 decoder->RestoreActiveTexture(); | |
| 453 decoder->RestoreProgramBindings(); | |
| 454 decoder->RestoreBufferBindings(); | |
| 455 decoder->RestoreFramebufferBindings(); | |
| 456 decoder->RestoreGlobalState(); | |
| 457 } | |
| 458 | |
| 459 } // namespace gles2. | |
| 460 } // namespace gpu | |
| OLD | NEW |