Index: gpu/command_buffer/service/gles2_cmd_srgb_converter.cc |
diff --git a/gpu/command_buffer/service/gles2_cmd_srgb_converter.cc b/gpu/command_buffer/service/gles2_cmd_srgb_converter.cc |
index ffbaf3059e5384432e264139e5a5b321788246b6..c03b8ab0b449d4faa59dde9d3214afd256ba4ae5 100644 |
--- a/gpu/command_buffer/service/gles2_cmd_srgb_converter.cc |
+++ b/gpu/command_buffer/service/gles2_cmd_srgb_converter.cc |
@@ -322,5 +322,95 @@ void SRGBConverter::Blit( |
decoder->RestoreGlobalState(); |
} |
+void SRGBConverter::SRGBGenerateMipmap(const gles2::GLES2Decoder* decoder, |
+ Texture* tex, |
+ GLenum target) { |
+ DCHECK(srgb_converter_initialized_); |
+ |
+ GLsizei width; |
+ GLsizei height; |
+ GLsizei depth; |
+ GLenum type = 0; |
+ GLenum internal_format = 0; |
+ GLsizei base_level = tex->base_level(); |
+ tex->GetLevelSize(target, base_level, &width, &height, &depth); |
+ tex->GetLevelType(target, 0, &type, &internal_format); |
+ const GLint mipmap_level = |
+ TextureManager::ComputeMipMapCount(target, width, height, depth); |
+ |
+ // copy tex to srgb_decoder_textures_[0] with srgb format |
+ glBindTexture(target, tex->service_id()); |
+ glBindFramebufferEXT(GL_READ_FRAMEBUFFER, srgb_decoder_fbo_); |
+ glFramebufferTexture2DEXT(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
+ GL_TEXTURE_2D, tex->service_id(), 0); |
+ |
+ glBindTexture(GL_TEXTURE_2D, srgb_converter_textures_[0]); |
+ glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, GL_SRGB, |
+ GL_UNSIGNED_BYTE, nullptr); |
+ glCopyTexImage2D(GL_TEXTURE_2D, 0, internal_format, 0, 0, width, height, 0); |
+ |
+ // bind srgb_decoder_textures_[1] to draw framebuffer |
+ glBindTexture(GL_TEXTURE_2D, srgb_converter_textures_[1]); |
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, |
+ GL_UNSIGNED_BYTE, nullptr); |
+ glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, srgb_decoder_fbo_); |
+ glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
+ GL_TEXTURE_2D, srgb_converter_textures_[1], 0); |
+ |
+ // bind texture with srgb format and render with srgb_converter_program_ |
+ glUseProgram(srgb_converter_program_); |
+ glViewport(0, 0, width, height); |
+ glDisable(GL_SCISSOR_TEST); |
+ glDisable(GL_DEPTH_TEST); |
+ glDisable(GL_STENCIL_TEST); |
+ glDisable(GL_CULL_FACE); |
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |
+ glDepthMask(GL_FALSE); |
+ glDisable(GL_BLEND); |
+ glDisable(GL_DITHER); |
+ |
+ glBindVertexArrayOES(srgb_converter_vao_); |
+ glActiveTexture(GL_TEXTURE0); |
+ glBindTexture(GL_TEXTURE_2D, srgb_converter_textures_[0]); |
+ glDrawArrays(GL_TRIANGLES, 0, 6); |
+ |
+ // generateMipmap for tex and srgb_decoder_textures_[1] |
+ glBindTexture(GL_TEXTURE_2D, tex->service_id()); |
+ glGenerateMipmapEXT(GL_TEXTURE_2D); |
+ glBindTexture(GL_TEXTURE_2D, srgb_converter_textures_[1]); |
+ glGenerateMipmapEXT(GL_TEXTURE_2D); |
+ |
+ // bind tex with rgba format and render with srgb_converter_program_ |
+ glUseProgram(srgb_converter_program_); |
+ glBindVertexArrayOES(srgb_converter_vao_); |
+ |
+ for (GLint level = base_level; level < mipmap_level; level++) { |
+ glBindTexture(GL_TEXTURE_2D, tex->service_id()); |
+ glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, srgb_encoder_fbo_); |
+ glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
+ GL_TEXTURE_2D, tex->service_id(), level); |
+ |
+ glActiveTexture(GL_TEXTURE0); |
+ glBindTexture(GL_TEXTURE_2D, srgb_converter_textures_[1]); |
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level); |
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, |
+ GL_NEAREST_MIPMAP_NEAREST); |
+ |
+ glViewport(0, 0, width, height); |
+ glDrawArrays(GL_TRIANGLES, 0, 6); |
+ width /= 2; |
+ height /= 2; |
+ } |
+ |
+ // Restore state |
+ decoder->RestoreAllAttributes(); |
+ decoder->RestoreTextureUnitBindings(0); |
+ decoder->RestoreActiveTexture(); |
+ decoder->RestoreProgramBindings(); |
+ decoder->RestoreBufferBindings(); |
+ decoder->RestoreFramebufferBindings(); |
+ decoder->RestoreGlobalState(); |
+} |
+ |
} // namespace gles2. |
} // namespace gpu |