| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "gpu/command_buffer/service/feature_info.h" | 5 #include "gpu/command_buffer/service/feature_info.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <set> | 9 #include <set> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 ~ScopedPixelUnpackBufferOverride() { | 99 ~ScopedPixelUnpackBufferOverride() { |
| 100 if (orig_binding_ != -1) { | 100 if (orig_binding_ != -1) { |
| 101 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, static_cast<GLuint>(orig_binding_)); | 101 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, static_cast<GLuint>(orig_binding_)); |
| 102 } | 102 } |
| 103 } | 103 } |
| 104 | 104 |
| 105 private: | 105 private: |
| 106 GLint orig_binding_; | 106 GLint orig_binding_; |
| 107 }; | 107 }; |
| 108 | 108 |
| 109 bool IsWebGLDrawBuffersSupported(GLenum depth_texture_internal_format, |
| 110 GLenum depth_stencil_texture_internal_format) { |
| 111 // This is called after we make sure GL_EXT_draw_buffers is supported. |
| 112 GLint max_draw_buffers = 0; |
| 113 GLint max_color_attachments = 0; |
| 114 glGetIntegerv(GL_MAX_DRAW_BUFFERS, &max_draw_buffers); |
| 115 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments); |
| 116 if (max_draw_buffers < 4 || max_color_attachments < 4) { |
| 117 return false; |
| 118 } |
| 119 |
| 120 GLint fb_binding = 0; |
| 121 GLint tex_binding = 0; |
| 122 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fb_binding); |
| 123 glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex_binding); |
| 124 |
| 125 GLuint fbo; |
| 126 glGenFramebuffersEXT(1, &fbo); |
| 127 glBindFramebufferEXT(GL_FRAMEBUFFER, fbo); |
| 128 |
| 129 GLuint depth_stencil_texture = 0; |
| 130 if (depth_stencil_texture_internal_format != GL_NONE) { |
| 131 glGenTextures(1, &depth_stencil_texture); |
| 132 glBindTexture(GL_TEXTURE_2D, depth_stencil_texture); |
| 133 glTexImage2D(GL_TEXTURE_2D, 0, depth_stencil_texture_internal_format, 1, 1, |
| 134 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr); |
| 135 } |
| 136 |
| 137 GLuint depth_texture = 0; |
| 138 if (depth_texture_internal_format != GL_NONE) { |
| 139 glGenTextures(1, &depth_texture); |
| 140 glBindTexture(GL_TEXTURE_2D, depth_texture); |
| 141 glTexImage2D(GL_TEXTURE_2D, 0, depth_texture_internal_format, 1, 1, 0, |
| 142 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); |
| 143 } |
| 144 |
| 145 GLint max_allowed_buffers = std::min(max_draw_buffers, max_color_attachments); |
| 146 std::vector<GLuint> colors(max_allowed_buffers, 0); |
| 147 glGenTextures(max_allowed_buffers, colors.data()); |
| 148 |
| 149 bool result = true; |
| 150 for (GLint i = 0; i < max_allowed_buffers; ++i) { |
| 151 GLint color = colors[i]; |
| 152 glBindTexture(GL_TEXTURE_2D, color); |
| 153 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, |
| 154 nullptr); |
| 155 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, |
| 156 GL_TEXTURE_2D, color, 0); |
| 157 if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) != |
| 158 GL_FRAMEBUFFER_COMPLETE) { |
| 159 result = false; |
| 160 break; |
| 161 } |
| 162 if (depth_texture != 0) { |
| 163 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, |
| 164 GL_TEXTURE_2D, depth_texture, 0); |
| 165 if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) != |
| 166 GL_FRAMEBUFFER_COMPLETE) { |
| 167 result = false; |
| 168 break; |
| 169 } |
| 170 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, |
| 171 GL_TEXTURE_2D, 0, 0); |
| 172 } |
| 173 if (depth_stencil_texture != 0) { |
| 174 // For ES 2.0 contexts DEPTH_STENCIL is not available natively, so we |
| 175 // emulate it at the command buffer level for WebGL contexts. |
| 176 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, |
| 177 GL_TEXTURE_2D, depth_stencil_texture, 0); |
| 178 if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) != |
| 179 GL_FRAMEBUFFER_COMPLETE) { |
| 180 result = false; |
| 181 break; |
| 182 } |
| 183 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, |
| 184 GL_TEXTURE_2D, 0, 0); |
| 185 } |
| 186 } |
| 187 |
| 188 glBindFramebufferEXT(GL_FRAMEBUFFER, static_cast<GLuint>(fb_binding)); |
| 189 glDeleteFramebuffersEXT(1, &fbo); |
| 190 |
| 191 glBindTexture(GL_TEXTURE_2D, static_cast<GLuint>(tex_binding)); |
| 192 glDeleteTextures(1, &depth_texture); |
| 193 glDeleteTextures(1, &depth_stencil_texture); |
| 194 glDeleteTextures(colors.size(), colors.data()); |
| 195 |
| 196 DCHECK(glGetError() == GL_NO_ERROR); |
| 197 |
| 198 return result; |
| 199 } |
| 200 |
| 109 } // anonymous namespace. | 201 } // anonymous namespace. |
| 110 | 202 |
| 111 FeatureInfo::FeatureFlags::FeatureFlags() {} | 203 FeatureInfo::FeatureFlags::FeatureFlags() {} |
| 112 | 204 |
| 113 FeatureInfo::FeatureInfo() { | 205 FeatureInfo::FeatureInfo() { |
| 114 InitializeBasicState(base::CommandLine::InitializedForCurrentProcess() | 206 InitializeBasicState(base::CommandLine::InitializedForCurrentProcess() |
| 115 ? base::CommandLine::ForCurrentProcess() | 207 ? base::CommandLine::ForCurrentProcess() |
| 116 : nullptr); | 208 : nullptr); |
| 117 } | 209 } |
| 118 | 210 |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 // NOTE: GL_OES_depth_texture requires support for depth cubemaps. | 528 // NOTE: GL_OES_depth_texture requires support for depth cubemaps. |
| 437 // GL_ARB_depth_texture requires other features that | 529 // GL_ARB_depth_texture requires other features that |
| 438 // GL_OES_packed_depth_stencil does not provide. | 530 // GL_OES_packed_depth_stencil does not provide. |
| 439 // | 531 // |
| 440 // Therefore we made up GL_GOOGLE_depth_texture / GL_CHROMIUM_depth_texture. | 532 // Therefore we made up GL_GOOGLE_depth_texture / GL_CHROMIUM_depth_texture. |
| 441 // | 533 // |
| 442 // GL_GOOGLE_depth_texture is legacy. As we exposed it into NaCl we can't | 534 // GL_GOOGLE_depth_texture is legacy. As we exposed it into NaCl we can't |
| 443 // get rid of it. | 535 // get rid of it. |
| 444 // | 536 // |
| 445 bool enable_depth_texture = false; | 537 bool enable_depth_texture = false; |
| 538 GLenum depth_texture_format = GL_NONE; |
| 446 if (!workarounds_.disable_depth_texture && | 539 if (!workarounds_.disable_depth_texture && |
| 447 (extensions.Contains("GL_ARB_depth_texture") || | 540 (extensions.Contains("GL_ARB_depth_texture") || |
| 448 extensions.Contains("GL_OES_depth_texture") || | 541 extensions.Contains("GL_OES_depth_texture") || |
| 449 extensions.Contains("GL_ANGLE_depth_texture") || | 542 extensions.Contains("GL_ANGLE_depth_texture") || |
| 450 gl_version_info_->is_desktop_core_profile)) { | 543 gl_version_info_->is_desktop_core_profile)) { |
| 451 // Note that we don't expose depth_texture extenion on top of ES3 if | 544 // Note that we don't expose depth_texture extenion on top of ES3 if |
| 452 // the depth_texture extension isn't exposed by the ES3 driver. | 545 // the depth_texture extension isn't exposed by the ES3 driver. |
| 453 // This is because depth textures are filterable under linear mode in | 546 // This is because depth textures are filterable under linear mode in |
| 454 // ES2 + extension, but not in core ES3. | 547 // ES2 + extension, but not in core ES3. |
| 455 enable_depth_texture = true; | 548 enable_depth_texture = true; |
| 549 depth_texture_format = GL_DEPTH_COMPONENT; |
| 456 feature_flags_.angle_depth_texture = | 550 feature_flags_.angle_depth_texture = |
| 457 extensions.Contains("GL_ANGLE_depth_texture"); | 551 extensions.Contains("GL_ANGLE_depth_texture"); |
| 458 } | 552 } |
| 459 | 553 |
| 460 if (enable_depth_texture) { | 554 if (enable_depth_texture) { |
| 461 AddExtensionString("GL_CHROMIUM_depth_texture"); | 555 AddExtensionString("GL_CHROMIUM_depth_texture"); |
| 462 AddExtensionString("GL_GOOGLE_depth_texture"); | 556 AddExtensionString("GL_GOOGLE_depth_texture"); |
| 463 validators_.texture_internal_format.AddValue(GL_DEPTH_COMPONENT); | 557 validators_.texture_internal_format.AddValue(GL_DEPTH_COMPONENT); |
| 464 validators_.texture_format.AddValue(GL_DEPTH_COMPONENT); | 558 validators_.texture_format.AddValue(GL_DEPTH_COMPONENT); |
| 465 validators_.pixel_type.AddValue(GL_UNSIGNED_SHORT); | 559 validators_.pixel_type.AddValue(GL_UNSIGNED_SHORT); |
| 466 validators_.pixel_type.AddValue(GL_UNSIGNED_INT); | 560 validators_.pixel_type.AddValue(GL_UNSIGNED_INT); |
| 467 validators_.texture_depth_renderable_internal_format.AddValue( | 561 validators_.texture_depth_renderable_internal_format.AddValue( |
| 468 GL_DEPTH_COMPONENT); | 562 GL_DEPTH_COMPONENT); |
| 469 } | 563 } |
| 470 | 564 |
| 565 GLenum depth_stencil_texture_format = GL_NONE; |
| 471 if (extensions.Contains("GL_EXT_packed_depth_stencil") || | 566 if (extensions.Contains("GL_EXT_packed_depth_stencil") || |
| 472 extensions.Contains("GL_OES_packed_depth_stencil") || | 567 extensions.Contains("GL_OES_packed_depth_stencil") || |
| 473 gl_version_info_->is_es3 || | 568 gl_version_info_->is_es3 || |
| 474 gl_version_info_->is_desktop_core_profile) { | 569 gl_version_info_->is_desktop_core_profile) { |
| 475 AddExtensionString("GL_OES_packed_depth_stencil"); | 570 AddExtensionString("GL_OES_packed_depth_stencil"); |
| 476 feature_flags_.packed_depth24_stencil8 = true; | 571 feature_flags_.packed_depth24_stencil8 = true; |
| 477 if (enable_depth_texture) { | 572 if (enable_depth_texture) { |
| 573 if (gl_version_info_->is_es3) { |
| 574 depth_stencil_texture_format = GL_DEPTH24_STENCIL8; |
| 575 } else { |
| 576 depth_stencil_texture_format = GL_DEPTH_STENCIL; |
| 577 } |
| 478 validators_.texture_internal_format.AddValue(GL_DEPTH_STENCIL); | 578 validators_.texture_internal_format.AddValue(GL_DEPTH_STENCIL); |
| 479 validators_.texture_format.AddValue(GL_DEPTH_STENCIL); | 579 validators_.texture_format.AddValue(GL_DEPTH_STENCIL); |
| 480 validators_.pixel_type.AddValue(GL_UNSIGNED_INT_24_8); | 580 validators_.pixel_type.AddValue(GL_UNSIGNED_INT_24_8); |
| 481 validators_.texture_depth_renderable_internal_format.AddValue( | 581 validators_.texture_depth_renderable_internal_format.AddValue( |
| 482 GL_DEPTH_STENCIL); | 582 GL_DEPTH_STENCIL); |
| 483 validators_.texture_stencil_renderable_internal_format.AddValue( | 583 validators_.texture_stencil_renderable_internal_format.AddValue( |
| 484 GL_DEPTH_STENCIL); | 584 GL_DEPTH_STENCIL); |
| 485 } | 585 } |
| 486 validators_.render_buffer_format.AddValue(GL_DEPTH24_STENCIL8); | 586 validators_.render_buffer_format.AddValue(GL_DEPTH24_STENCIL8); |
| 487 if (context_type_ == CONTEXT_TYPE_WEBGL1) { | 587 if (context_type_ == CONTEXT_TYPE_WEBGL1) { |
| (...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1154 feature_flags_.angle_instanced_arrays = true; | 1254 feature_flags_.angle_instanced_arrays = true; |
| 1155 validators_.vertex_attribute.AddValue(GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE); | 1255 validators_.vertex_attribute.AddValue(GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE); |
| 1156 } | 1256 } |
| 1157 | 1257 |
| 1158 bool have_es2_draw_buffers_vendor_agnostic = | 1258 bool have_es2_draw_buffers_vendor_agnostic = |
| 1159 gl_version_info_->is_desktop_core_profile || | 1259 gl_version_info_->is_desktop_core_profile || |
| 1160 extensions.Contains("GL_ARB_draw_buffers") || | 1260 extensions.Contains("GL_ARB_draw_buffers") || |
| 1161 extensions.Contains("GL_EXT_draw_buffers"); | 1261 extensions.Contains("GL_EXT_draw_buffers"); |
| 1162 bool can_emulate_es2_draw_buffers_on_es3_nv = | 1262 bool can_emulate_es2_draw_buffers_on_es3_nv = |
| 1163 gl_version_info_->is_es3 && extensions.Contains("GL_NV_draw_buffers"); | 1263 gl_version_info_->is_es3 && extensions.Contains("GL_NV_draw_buffers"); |
| 1164 bool have_es2_draw_buffers = !workarounds_.disable_ext_draw_buffers && | 1264 bool have_es2_draw_buffers = |
| 1165 IsWebGL1OrES2Context() && | 1265 !workarounds_.disable_ext_draw_buffers && |
| 1166 (have_es2_draw_buffers_vendor_agnostic || | 1266 (have_es2_draw_buffers_vendor_agnostic || |
| 1167 can_emulate_es2_draw_buffers_on_es3_nv); | 1267 can_emulate_es2_draw_buffers_on_es3_nv) && |
| 1268 (context_type_ == CONTEXT_TYPE_OPENGLES2 || |
| 1269 (context_type_ == CONTEXT_TYPE_WEBGL1 && |
| 1270 IsWebGLDrawBuffersSupported(depth_texture_format, |
| 1271 depth_stencil_texture_format))); |
| 1168 if (have_es2_draw_buffers) { | 1272 if (have_es2_draw_buffers) { |
| 1169 AddExtensionString("GL_EXT_draw_buffers"); | 1273 AddExtensionString("GL_EXT_draw_buffers"); |
| 1170 feature_flags_.ext_draw_buffers = true; | 1274 feature_flags_.ext_draw_buffers = true; |
| 1171 | 1275 |
| 1172 // This flag is set to enable emulation of EXT_draw_buffers when we're | 1276 // This flag is set to enable emulation of EXT_draw_buffers when we're |
| 1173 // running on GLES 3.0+, NV_draw_buffers extension is supported and | 1277 // running on GLES 3.0+, NV_draw_buffers extension is supported and |
| 1174 // glDrawBuffers from GLES 3.0 core has been bound. It toggles using the | 1278 // glDrawBuffers from GLES 3.0 core has been bound. It toggles using the |
| 1175 // NV_draw_buffers extension directive instead of EXT_draw_buffers extension | 1279 // NV_draw_buffers extension directive instead of EXT_draw_buffers extension |
| 1176 // directive in ESSL 100 shaders translated by ANGLE, enabling them to write | 1280 // directive in ESSL 100 shaders translated by ANGLE, enabling them to write |
| 1177 // into multiple gl_FragData values, which is not by default possible in | 1281 // into multiple gl_FragData values, which is not by default possible in |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1528 if (pos == std::string::npos) { | 1632 if (pos == std::string::npos) { |
| 1529 extensions_ += (extensions_.empty() ? "" : " ") + str; | 1633 extensions_ += (extensions_.empty() ? "" : " ") + str; |
| 1530 } | 1634 } |
| 1531 } | 1635 } |
| 1532 | 1636 |
| 1533 FeatureInfo::~FeatureInfo() { | 1637 FeatureInfo::~FeatureInfo() { |
| 1534 } | 1638 } |
| 1535 | 1639 |
| 1536 } // namespace gles2 | 1640 } // namespace gles2 |
| 1537 } // namespace gpu | 1641 } // namespace gpu |
| OLD | NEW |