Chromium Code Reviews| Index: gpu/command_buffer/service/feature_info.cc |
| diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc |
| index a8b497fd6f5ad735068aab7e5f119b932894f3d7..6ea1adf01ba910eee917bad1d6b48e2452371007 100644 |
| --- a/gpu/command_buffer/service/feature_info.cc |
| +++ b/gpu/command_buffer/service/feature_info.cc |
| @@ -106,6 +106,102 @@ class ScopedPixelUnpackBufferOverride { |
| GLint orig_binding_; |
| }; |
| +bool IsWebGLDrawBuffersSupported(bool has_depth_texture, |
| + bool has_depth_stencil_texture) { |
| + // This is called after we make sure GL_EXT_draw_buffers is supported. |
| + |
| + GLint fb_binding = 0; |
| + GLint tex_binding = 0; |
| + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fb_binding); |
| + glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex_binding); |
| + |
| + GLint max_draw_buffers = 0; |
| + GLint max_color_attachments = 0; |
| + glGetIntegerv(GL_MAX_DRAW_BUFFERS, &max_draw_buffers); |
| + glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments); |
| + if (max_draw_buffers < 4 || max_color_attachments < 4) |
| + return false; |
| + |
| + GLuint fbo; |
| + glGenFramebuffersEXT(1, &fbo); |
| + glBindFramebufferEXT(GL_FRAMEBUFFER, fbo); |
| + |
| + GLuint depth_stencil = 0; |
| + if (has_depth_stencil_texture) { |
| + glGenTextures(1, &depth_stencil); |
| + glBindTexture(GL_TEXTURE_2D, depth_stencil); |
| + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, 1, 1, 0, GL_DEPTH_STENCIL, |
|
Zhenyao Mo
2017/02/23 00:12:43
Juts want to make sure this (unsized internal form
Ken Russell (switch to Gerrit)
2017/02/23 01:46:26
I don't remember exactly at this point -- but grep
|
| + GL_UNSIGNED_INT_24_8, nullptr); |
| + } |
| + |
| + GLuint depth = 0; |
| + if (has_depth_texture) { |
| + glGenTextures(1, &depth); |
| + glBindTexture(GL_TEXTURE_2D, depth); |
| + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1, 1, 0, |
|
Zhenyao Mo
2017/02/23 00:12:43
Same here.
|
| + GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); |
| + } |
| + |
| + GLint max_allowed_buffers = std::min(max_draw_buffers, max_color_attachments); |
| + std::vector<GLuint> colors(max_allowed_buffers, 0); |
| + glGenTextures(max_allowed_buffers, colors.data()); |
| + |
| + bool result = true; |
| + for (GLint i = 0; i < max_allowed_buffers; ++i) { |
| + GLint color = colors[i]; |
| + glBindTexture(GL_TEXTURE_2D, color); |
| + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, |
| + nullptr); |
| + glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, |
| + GL_TEXTURE_2D, color, 0); |
| + if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) != |
| + GL_FRAMEBUFFER_COMPLETE) { |
| + result = false; |
| + break; |
| + } |
| + if (has_depth_texture) { |
| + glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, |
| + GL_TEXTURE_2D, depth, 0); |
| + if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) != |
| + GL_FRAMEBUFFER_COMPLETE) { |
| + result = false; |
| + break; |
| + } |
| + glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, |
| + GL_TEXTURE_2D, 0, 0); |
| + } |
| + if (has_depth_stencil_texture) { |
| + // For ES 2.0 contexts DEPTH_STENCIL is not available natively, so we |
| + // emulate it at the command buffer level for WebGL contexts. |
| + glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, |
| + GL_TEXTURE_2D, depth_stencil, 0); |
| + if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) != |
| + GL_FRAMEBUFFER_COMPLETE) { |
| + result = false; |
| + break; |
| + } |
| + glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, |
| + GL_TEXTURE_2D, 0, 0); |
| + } |
| + } |
| + |
| + glBindFramebufferEXT(GL_FRAMEBUFFER, static_cast<GLuint>(fb_binding)); |
| + glDeleteFramebuffersEXT(1, &fbo); |
| + |
| + glBindTexture(GL_TEXTURE_2D, static_cast<GLuint>(tex_binding)); |
| + if (has_depth_texture) { |
| + glDeleteTextures(1, &depth); |
| + } |
| + if (has_depth_stencil_texture) { |
| + glDeleteTextures(1, &depth_stencil); |
| + } |
| + glDeleteTextures(colors.size(), colors.data()); |
| + |
| + DCHECK(glGetError() == GL_NO_ERROR); |
| + |
| + return result; |
| +} |
| + |
| } // anonymous namespace. |
| FeatureInfo::FeatureFlags::FeatureFlags() {} |
| @@ -468,6 +564,7 @@ void FeatureInfo::InitializeFeatures() { |
| GL_DEPTH_COMPONENT); |
| } |
| + bool enable_depth_stencil_texture = false; |
| if (extensions.Contains("GL_EXT_packed_depth_stencil") || |
| extensions.Contains("GL_OES_packed_depth_stencil") || |
| gl_version_info_->is_es3 || |
| @@ -475,6 +572,7 @@ void FeatureInfo::InitializeFeatures() { |
| AddExtensionString("GL_OES_packed_depth_stencil"); |
| feature_flags_.packed_depth24_stencil8 = true; |
| if (enable_depth_texture) { |
| + enable_depth_stencil_texture = true; |
| validators_.texture_internal_format.AddValue(GL_DEPTH_STENCIL); |
| validators_.texture_format.AddValue(GL_DEPTH_STENCIL); |
| validators_.pixel_type.AddValue(GL_UNSIGNED_INT_24_8); |
| @@ -1161,10 +1259,14 @@ void FeatureInfo::InitializeFeatures() { |
| extensions.Contains("GL_EXT_draw_buffers"); |
| bool can_emulate_es2_draw_buffers_on_es3_nv = |
| gl_version_info_->is_es3 && extensions.Contains("GL_NV_draw_buffers"); |
| - bool have_es2_draw_buffers = !workarounds_.disable_ext_draw_buffers && |
| - IsWebGL1OrES2Context() && |
| - (have_es2_draw_buffers_vendor_agnostic || |
| - can_emulate_es2_draw_buffers_on_es3_nv); |
| + bool have_es2_draw_buffers = |
| + !workarounds_.disable_ext_draw_buffers && |
| + (have_es2_draw_buffers_vendor_agnostic || |
| + can_emulate_es2_draw_buffers_on_es3_nv) && |
| + (context_type_ == CONTEXT_TYPE_OPENGLES2 || |
| + (context_type_ == CONTEXT_TYPE_WEBGL1 && |
| + IsWebGLDrawBuffersSupported(enable_depth_texture, |
| + enable_depth_stencil_texture))); |
| if (have_es2_draw_buffers) { |
| AddExtensionString("GL_EXT_draw_buffers"); |
| feature_flags_.ext_draw_buffers = true; |