Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Unified Diff: gpu/command_buffer/service/gles2_cmd_srgb_converter.cc

Issue 2318313004: emulate srgb format for generateMipmap (Closed)
Patch Set: srgb-generateMipmap Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..53d68225e098bb33913766509c6fccacdcadcc60 100644
--- a/gpu/command_buffer/service/gles2_cmd_srgb_converter.cc
+++ b/gpu/command_buffer/service/gles2_cmd_srgb_converter.cc
@@ -322,5 +322,265 @@ void SRGBConverter::Blit(
decoder->RestoreGlobalState();
}
+void SRGBConverter::InitializeSRGBEncoder(const gles2::GLES2Decoder* decoder) {
+ if (srgb_encoder_initialized_) {
+ return;
+ }
+
+ GLuint srgb_encoder_program_ = 0;
+
+ std::array<GLuint, 1> srgb_encoder_textures_ = {{0}};
+ GLuint srgb_encoder_fbo_ = 0;
+ GLuint srgb_encoder_vao_ = 0;
+
+ srgb_encoder_program_ = glCreateProgram();
+
+ const char* vs_source =
+ "#version 150\n"
+ "out vec2 v_texcoord;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " const vec2 quad_positions[6] = vec2[6]\n"
+ " (\n"
+ " vec2(0.0f, 0.0f),\n"
+ " vec2(0.0f, 1.0f),\n"
+ " vec2(1.0f, 0.0f),\n"
+ "\n"
+ " vec2(0.0f, 1.0f),\n"
+ " vec2(1.0f, 0.0f),\n"
+ " vec2(1.0f, 1.0f)\n"
+ " );\n"
+ "\n"
+ " vec2 xy = vec2((quad_positions[gl_VertexID] * 2.0) - 1.0);\n"
+ " gl_Position = vec4(xy, 0.0, 1.0);\n"
+ " v_texcoord = quad_positions[gl_VertexID];\n"
+ "}\n";
+
+ // Compile the vertex shader
+ GLuint vs = glCreateShader(GL_VERTEX_SHADER);
+ CompileShader(vs, vs_source);
+ glAttachShader(srgb_encoder_program_, vs);
+ glDeleteShader(vs);
+
+ // Compile the fragment shader
+
+ // Sampling texels from a srgb texture to a linear image, it will convert
+ // the srgb color space to linear color space automatically as a part of
+ // filtering. See the section <sRGB Texture Color Conversion> in GLES and
+ // OpenGL spec. So in decoder, we don't need to decode again.
+ // However, sampling texels from a linear texture to a srgb image, it will
+ // not convert linear to srgb automatically. Shader should always operates
+ // in linear space. So in encoder, we need to encode explicitly in shader.
+ const char* fs_source =
+ "#version 150\n"
+ "uniform sampler2D u_source_texture;\n"
+ "in vec2 v_texcoord;\n"
+ "out vec4 output_color;\n"
+ "\n"
+ "float encode(float color)\n"
+ "{\n"
+ " float encoded_color;\n"
+ " if (color <= 0.0) {\n"
+ " return 0.0;\n"
+ " } else if (color < 0.0031308) {\n"
+ " return color * 12.92;\n"
+ " } else if (color < 1) {\n"
+ " return pow(color, 0.41666) * 1.055 - 0.055;\n"
+ " } else {\n"
+ " return 1.0;\n"
+ " }\n"
+ "}\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " vec4 c = texture(u_source_texture, v_texcoord);\n"
+ " output_color = vec4(encode(c.r), encode(c.g), encode(c.b), c.a);\n"
+ "}\n";
+ /* const char* fs_source =
+ "#version 150\n"
+ "uniform sampler2D u_source_texture;\n"
+ "in vec2 v_texcoord;\n"
+ "out vec4 output_color;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " vec4 c = texture(u_source_texture, v_texcoord);\n"
+ " output_color = c;\n"
+ "}\n";*/
+
+ GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
+ CompileShader(fs, fs_source);
+ glAttachShader(srgb_encoder_program_, fs);
+ glDeleteShader(fs);
+
+ glLinkProgram(srgb_encoder_program_);
+#ifndef NDEBUG
+ GLint linked = 0;
+ glGetProgramiv(srgb_encoder_program_, GL_LINK_STATUS, &linked);
+ if (!linked) {
+ DLOG(ERROR) << "SRGB Encoder for BlitFramebuffer: program link failure.";
+ }
+#endif
+
+ GLuint texture_uniform =
+ glGetUniformLocation(srgb_encoder_program_, "u_source_texture");
+ glUseProgram(srgb_encoder_program_);
+ glUniform1i(texture_uniform, 0);
+
+ glGenTextures(srgb_encoder_textures_.size(), srgb_encoder_textures_.data());
+ glActiveTexture(GL_TEXTURE0);
+ for (auto srgb_encoder_texture : srgb_encoder_textures_) {
+ glBindTexture(GL_TEXTURE_2D, srgb_encoder_texture);
+
+ // Use linear, non-mipmapped sampling with the srgb encoder texture
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ }
+
+ glGenFramebuffersEXT(1, &srgb_encoder_fbo_);
+ glGenVertexArraysOES(1, &srgb_encoder_vao_);
+
+ decoder->RestoreTextureUnitBindings(0);
+ decoder->RestoreActiveTexture();
+ decoder->RestoreProgramBindings();
+
+ srgb_encoder_initialized_ = true;
+}
yunchao 2016/09/19 15:25:48 Please remove this function above, Yizhou.
yizhou.jiang 2016/09/20 07:00:27 Done.
+
+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);
+
+ GLenum error = glCheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER);
+ error = glGetError();
yunchao 2016/09/19 15:25:48 please remove the debugging code.
yizhou.jiang 2016/09/20 07:00:27 Done.
+
+ glBindTexture(GL_TEXTURE_2D, srgb_converter_textures_[0]);
+ glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, GL_SRGB,
+ GL_UNSIGNED_BYTE, nullptr);
yunchao 2016/09/19 15:25:48 This is not necessary, copyTexImage2D will allocat
yizhou.jiang 2016/09/20 07:00:27 Done.
+ glCopyTexImage2D(GL_TEXTURE_2D, 0, internal_format, 0, 0, width, height, 0);
+ error = glGetError();
+ unsigned char bytes3[width * height * 4];
+ glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, bytes3);
yunchao 2016/09/19 15:25:48 please remove debug code
yizhou.jiang 2016/09/20 07:00:27 Done.
+
+ // 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);
+
+ error = glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER);
+ error = glGetError();
+ unsigned char bytes2[width * height * 4];
+ glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, bytes2);
yunchao 2016/09/19 15:25:47 remove debug code
yizhou.jiang 2016/09/20 07:00:27 Done.
+
+ // bind texture with srgb format and render with srgb_decoder_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);
+ glEnable(GL_BLEND);
yunchao 2016/09/19 15:25:48 glDisable blend
yizhou.jiang 2016/09/20 07:00:27 Done.
+ glDisable(GL_DITHER);
+
+ glBindVertexArrayOES(srgb_converter_vao_);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, srgb_converter_textures_[0]);
+
+ error = glGetError();
yunchao 2016/09/19 15:25:48 remove debug code
yizhou.jiang 2016/09/20 07:00:27 Done.
+
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+
+ error = glGetError();
+ unsigned char bytes1[width * height * 4];
+ glBindFramebufferEXT(GL_READ_FRAMEBUFFER, srgb_decoder_fbo_);
+ glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, bytes1);
yunchao 2016/09/19 15:25:47 remove debug code
yizhou.jiang 2016/09/20 07:00:27 Done.
+
+ // 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);
+
+ error = glGetError();
yunchao 2016/09/19 15:25:47 remove debug code
yizhou.jiang 2016/09/20 07:00:27 Done.
+
+ // bind tex with rgba format and render with srgb_encoder_program_
+
+ glClearColor(0, 0, 0, 255);
yunchao 2016/09/19 15:25:47 It is not necessary to set clear color.
yizhou.jiang 2016/09/20 07:00:27 Done.
+ glBindTexture(GL_TEXTURE_2D, tex->service_id());
+ glBindFramebufferEXT(GL_FRAMEBUFFER, srgb_encoder_fbo_);
+
+ //InitializeSRGBEncoder(decoder);
+ //glUseProgram(srgb_encoder_program_);
+
+ /*glDeleteProgram(srgb_converter_program_);
+ srgb_converter_program_ = 0;
+ srgb_converter_initialized_ = false;
+ InitializeSRGBConverterProgram();
+ */
yunchao 2016/09/19 15:25:47 remove debug code.
yizhou.jiang 2016/09/20 07:00:27 Done.
+ glUseProgram(srgb_converter_program_);
+
+ glBindVertexArrayOES(srgb_converter_vao_);
yunchao 2016/09/19 15:25:48 These two lines are not necessary, you have called
yizhou.jiang 2016/09/20 07:00:27 Done.
+
+ for (GLint level = base_level; level < mipmap_level; level++) {
+ glBindTexture(GL_TEXTURE_2D, tex->service_id());
yunchao 2016/09/19 15:25:47 This is not necessary.
yizhou.jiang 2016/09/20 07:00:26 Done.
+ glBindFramebufferEXT(GL_FRAMEBUFFER, srgb_encoder_fbo_);
yunchao 2016/09/19 15:25:48 move this outside the for loop.
yizhou.jiang 2016/09/20 07:00:27 Done.
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D, tex->service_id(), level);
+
+ error = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
+ error = glGetError();
+ unsigned char bytes2[width * height * 4];
+ glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, bytes2);
yunchao 2016/09/19 15:25:48 remove debug code.
yizhou.jiang 2016/09/20 07:00:27 Done.
+
+ glActiveTexture(GL_TEXTURE0);
yunchao 2016/09/19 15:25:48 This is not necessary.
yizhou.jiang 2016/09/20 07:00:27 Done.
+ glBindTexture(GL_TEXTURE_2D, srgb_converter_textures_[1]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level);
yunchao 2016/09/19 15:25:48 move these two lines outside the for loop.
yizhou.jiang 2016/09/20 07:00:27 Done.
+ glViewport(0, 0, width, height);
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+
+ error = glGetError();
+ unsigned char bytes[width * height * 4];
+ glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, bytes);
yunchao 2016/09/19 15:25:48 remove the debug code.
yizhou.jiang 2016/09/20 07:00:27 Done.
+
+ 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

Powered by Google App Engine
This is Rietveld 408576698