diff options
author | sievers@chromium.org <sievers@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-15 21:46:18 +0000 |
---|---|---|
committer | sievers@chromium.org <sievers@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-15 21:46:18 +0000 |
commit | f42f05b17630c3c1d5e579e6bac64cb544a2fcd4 (patch) | |
tree | caadfb52f4c343bbddbd741bb7a56af238f206c1 /gpu | |
parent | d6c10da9c1bd55c5878a9c0c7b83794c2ba53675 (diff) | |
download | chromium_src-f42f05b17630c3c1d5e579e6bac64cb544a2fcd4.zip chromium_src-f42f05b17630c3c1d5e579e6bac64cb544a2fcd4.tar.gz chromium_src-f42f05b17630c3c1d5e579e6bac64cb544a2fcd4.tar.bz2 |
gpu: Support ES3 msaa and depth/stencil formats
BUG=314214
R=kbr@chromium.org, piman@chromium.org, skyostil@chromium.org, zmo@chromium.org
Review URL: https://codereview.chromium.org/72173002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@235435 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r-- | gpu/command_buffer/service/feature_info.cc | 48 | ||||
-rw-r--r-- | gpu/command_buffer/service/feature_info.h | 6 | ||||
-rw-r--r-- | gpu/command_buffer/service/feature_info_unittest.cc | 92 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.cc | 141 | ||||
-rw-r--r-- | gpu/command_buffer/service/test_helper.cc | 10 | ||||
-rw-r--r-- | gpu/command_buffer/service/test_helper.h | 3 | ||||
-rw-r--r-- | gpu/config/gpu_driver_bug_list_json.cc | 31 | ||||
-rw-r--r-- | gpu/config/gpu_driver_bug_workaround_type.h | 4 |
8 files changed, 241 insertions, 94 deletions
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc index ad7ebc5..4257b1f 100644 --- a/gpu/command_buffer/service/feature_info.cc +++ b/gpu/command_buffer/service/feature_info.cc @@ -100,11 +100,13 @@ void StringToWorkarounds( FeatureInfo::FeatureFlags::FeatureFlags() : chromium_framebuffer_multisample(false), + use_core_framebuffer_multisample(false), multisampled_render_to_texture(false), use_img_for_multisampled_render_to_texture(false), oes_standard_derivatives(false), oes_egl_image_external(false), oes_depth24(false), + packed_depth24_stencil8(false), npot_ok(false), enable_texture_float_linear(false), enable_texture_half_float_linear(false), @@ -124,7 +126,8 @@ FeatureInfo::FeatureFlags::FeatureFlags() use_async_readpixels(false), map_buffer_range(false), ext_discard_framebuffer(false), - angle_depth_texture(false) { + angle_depth_texture(false), + is_angle(false) { } FeatureInfo::Workarounds::Workarounds() : @@ -206,6 +209,20 @@ void FeatureInfo::InitializeFeatures() { bool npot_ok = false; + const char* renderer_str = + reinterpret_cast<const char*>(glGetString(GL_RENDERER)); + if (renderer_str) { + feature_flags_.is_angle = StartsWithASCII(renderer_str, "ANGLE", true); + } + + bool is_es3 = false; + const char* version_str = + reinterpret_cast<const char*>(glGetString(GL_VERSION)); + if (version_str) { + std::string lstr(StringToLowerASCII(std::string(version_str))); + is_es3 = (lstr.substr(0, 12) == "opengl es 3."); + } + AddExtensionString("GL_ANGLE_translated_shader_source"); AddExtensionString("GL_CHROMIUM_async_pixel_transfers"); AddExtensionString("GL_CHROMIUM_bind_uniform_location"); @@ -313,7 +330,7 @@ void FeatureInfo::InitializeFeatures() { if (!workarounds_.disable_depth_texture && (extensions.Contains("GL_ARB_depth_texture") || extensions.Contains("GL_OES_depth_texture") || - extensions.Contains("GL_ANGLE_depth_texture"))) { + extensions.Contains("GL_ANGLE_depth_texture") || is_es3)) { enable_depth_texture = true; feature_flags_.angle_depth_texture = extensions.Contains("GL_ANGLE_depth_texture"); @@ -331,11 +348,12 @@ void FeatureInfo::InitializeFeatures() { } if (extensions.Contains("GL_EXT_packed_depth_stencil") || - extensions.Contains("GL_OES_packed_depth_stencil")) { + extensions.Contains("GL_OES_packed_depth_stencil") || is_es3) { AddExtensionString("GL_OES_packed_depth_stencil"); + feature_flags_.packed_depth24_stencil8 = true; if (enable_depth_texture) { - texture_format_validators_[GL_DEPTH_STENCIL].AddValue( - GL_UNSIGNED_INT_24_8); + texture_format_validators_[GL_DEPTH_STENCIL] + .AddValue(GL_UNSIGNED_INT_24_8); validators_.texture_internal_format.AddValue(GL_DEPTH_STENCIL); validators_.texture_format.AddValue(GL_DEPTH_STENCIL); validators_.pixel_type.AddValue(GL_UNSIGNED_INT_24_8); @@ -473,13 +491,15 @@ void FeatureInfo::InitializeFeatures() { } // Check for multisample support - if (!disallowed_features_.multisampling) { + if (!disallowed_features_.multisampling && + !workarounds_.disable_framebuffer_multisample) { bool ext_has_multisample = - extensions.Contains("GL_EXT_framebuffer_multisample"); - if (!workarounds_.disable_angle_framebuffer_multisample) { + extensions.Contains("GL_EXT_framebuffer_multisample") || is_es3; + if (feature_flags_.is_angle) { ext_has_multisample |= - extensions.Contains("GL_ANGLE_framebuffer_multisample"); + extensions.Contains("GL_ANGLE_framebuffer_multisample"); } + feature_flags_.use_core_framebuffer_multisample = is_es3; if (ext_has_multisample) { feature_flags_.chromium_framebuffer_multisample = true; validators_.frame_buffer_target.AddValue(GL_READ_FRAMEBUFFER_EXT); @@ -506,7 +526,8 @@ void FeatureInfo::InitializeFeatures() { } } - if (extensions.Contains("GL_OES_depth24") || gfx::HasDesktopGLFeatures()) { + if (extensions.Contains("GL_OES_depth24") || gfx::HasDesktopGLFeatures() || + is_es3) { AddExtensionString("GL_OES_depth24"); feature_flags_.oes_depth24 = true; validators_.render_buffer_format.AddValue(GL_DEPTH_COMPONENT24); @@ -666,13 +687,6 @@ void FeatureInfo::InitializeFeatures() { if (!disallowed_features_.swap_buffer_complete_callback) AddExtensionString("GL_CHROMIUM_swapbuffers_complete_callback"); - bool is_es3 = false; - const char* str = reinterpret_cast<const char*>(glGetString(GL_VERSION)); - if (str) { - std::string lstr(StringToLowerASCII(std::string(str))); - is_es3 = (lstr.substr(0, 12) == "opengl es 3."); - } - bool ui_gl_fence_works = extensions.Contains("GL_NV_fence") || extensions.Contains("GL_ARB_sync") || extensions.Contains("EGL_KHR_fence_sync"); diff --git a/gpu/command_buffer/service/feature_info.h b/gpu/command_buffer/service/feature_info.h index 34a2e6d..5202c26 100644 --- a/gpu/command_buffer/service/feature_info.h +++ b/gpu/command_buffer/service/feature_info.h @@ -27,12 +27,17 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> { FeatureFlags(); bool chromium_framebuffer_multisample; + // Use glBlitFramebuffer() and glRenderbufferStorageMultisample() with + // GL_EXT_framebuffer_multisample-style semantics, since they are exposed + // as core GL functions on this implementation. + bool use_core_framebuffer_multisample; bool multisampled_render_to_texture; // Use the IMG GLenum values and functions rather than EXT. bool use_img_for_multisampled_render_to_texture; bool oes_standard_derivatives; bool oes_egl_image_external; bool oes_depth24; + bool packed_depth24_stencil8; bool npot_ok; bool enable_texture_float_linear; bool enable_texture_half_float_linear; @@ -53,6 +58,7 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> { bool map_buffer_range; bool ext_discard_framebuffer; bool angle_depth_texture; + bool is_angle; }; struct Workarounds { diff --git a/gpu/command_buffer/service/feature_info_unittest.cc b/gpu/command_buffer/service/feature_info_unittest.cc index 041ab36..8164b35 100644 --- a/gpu/command_buffer/service/feature_info_unittest.cc +++ b/gpu/command_buffer/service/feature_info_unittest.cc @@ -32,19 +32,23 @@ using ::testing::StrictMock; namespace gpu { namespace gles2 { +namespace { +const char kGLRendererStringANGLE[] = "ANGLE (some renderer)"; +} // anonymous namespace + class FeatureInfoTest : public testing::Test { public: FeatureInfoTest() { } void SetupInitExpectations(const char* extensions) { - SetupInitExpectationsWithGLVersion(extensions, ""); + SetupInitExpectationsWithGLVersion(extensions, "", ""); } void SetupInitExpectationsWithGLVersion( - const char* extensions, const char* version) { + const char* extensions, const char* renderer, const char* version) { TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion( - gl_.get(), extensions, version); + gl_.get(), extensions, renderer, version); info_ = new FeatureInfo(); info_->Initialize(); } @@ -56,7 +60,7 @@ class FeatureInfoTest : public testing::Test { void SetupInitExpectationsWithCommandLine( const char* extensions, const CommandLine& command_line) { TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion( - gl_.get(), extensions, ""); + gl_.get(), extensions, "", ""); info_ = new FeatureInfo(command_line); info_->Initialize(); } @@ -95,6 +99,7 @@ TEST_F(FeatureInfoTest, Basic) { SetupWithoutInit(); // Test it starts off uninitialized. EXPECT_FALSE(info_->feature_flags().chromium_framebuffer_multisample); + EXPECT_FALSE(info_->feature_flags().use_core_framebuffer_multisample); EXPECT_FALSE(info_->feature_flags().multisampled_render_to_texture); EXPECT_FALSE(info_->feature_flags( ).use_img_for_multisampled_render_to_texture); @@ -103,6 +108,8 @@ TEST_F(FeatureInfoTest, Basic) { EXPECT_FALSE(info_->feature_flags().enable_texture_float_linear); EXPECT_FALSE(info_->feature_flags().enable_texture_half_float_linear); EXPECT_FALSE(info_->feature_flags().oes_egl_image_external); + EXPECT_FALSE(info_->feature_flags().oes_depth24); + EXPECT_FALSE(info_->feature_flags().packed_depth24_stencil8); EXPECT_FALSE(info_->feature_flags().chromium_stream_texture); EXPECT_FALSE(info_->feature_flags().angle_translated_shader_source); EXPECT_FALSE(info_->feature_flags().angle_pack_reverse_row_order); @@ -118,6 +125,7 @@ TEST_F(FeatureInfoTest, Basic) { EXPECT_FALSE(info_->feature_flags().use_async_readpixels); EXPECT_FALSE(info_->feature_flags().ext_discard_framebuffer); EXPECT_FALSE(info_->feature_flags().angle_depth_texture); + EXPECT_FALSE(info_->feature_flags().is_angle); #define GPU_OP(type, name) EXPECT_FALSE(info_->workarounds().name); GPU_DRIVER_BUG_WORKAROUNDS(GPU_OP) @@ -289,6 +297,11 @@ TEST_F(FeatureInfoTest, InitializeNoExtensions) { GL_DEPTH24_STENCIL8_OES)); } +TEST_F(FeatureInfoTest, InitializeWithANGLE) { + SetupInitExpectationsWithGLVersion("", kGLRendererStringANGLE, ""); + EXPECT_TRUE(info_->feature_flags().is_angle); +} + TEST_F(FeatureInfoTest, InitializeNPOTExtensionGLES) { SetupInitExpectations("GL_OES_texture_npot"); EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_texture_npot")); @@ -548,6 +561,44 @@ TEST_F(FeatureInfoTest, InitializeEXT_framebuffer_multisample) { GL_RENDERBUFFER_SAMPLES_EXT)); } +TEST_F(FeatureInfoTest, InitializeANGLE_framebuffer_multisample) { + SetupInitExpectationsWithGLVersion( + "GL_ANGLE_framebuffer_multisample", kGLRendererStringANGLE, ""); + EXPECT_TRUE(info_->feature_flags().chromium_framebuffer_multisample); + EXPECT_THAT(info_->extensions(), + HasSubstr("GL_CHROMIUM_framebuffer_multisample")); + EXPECT_TRUE(info_->validators()->frame_buffer_target.IsValid( + GL_READ_FRAMEBUFFER_EXT)); + EXPECT_TRUE(info_->validators()->frame_buffer_target.IsValid( + GL_DRAW_FRAMEBUFFER_EXT)); + EXPECT_TRUE(info_->validators()->g_l_state.IsValid( + GL_READ_FRAMEBUFFER_BINDING_EXT)); + EXPECT_TRUE(info_->validators()->g_l_state.IsValid( + GL_MAX_SAMPLES_EXT)); + EXPECT_TRUE(info_->validators()->render_buffer_parameter.IsValid( + GL_RENDERBUFFER_SAMPLES_EXT)); +} + +// We don't allow ANGLE_framebuffer_multisample on non-ANGLE implementations, +// because we wouldn't be choosing the right driver entry point and because the +// extension was falsely advertised on some Android devices (crbug.com/165736). +TEST_F(FeatureInfoTest, InitializeANGLE_framebuffer_multisampleWithoutANGLE) { + SetupInitExpectations("GL_ANGLE_framebuffer_multisample"); + EXPECT_FALSE(info_->feature_flags().chromium_framebuffer_multisample); + EXPECT_THAT(info_->extensions(), + Not(HasSubstr("GL_CHROMIUM_framebuffer_multisample"))); + EXPECT_FALSE(info_->validators()->frame_buffer_target.IsValid( + GL_READ_FRAMEBUFFER_EXT)); + EXPECT_FALSE(info_->validators()->frame_buffer_target.IsValid( + GL_DRAW_FRAMEBUFFER_EXT)); + EXPECT_FALSE(info_->validators()->g_l_state.IsValid( + GL_READ_FRAMEBUFFER_BINDING_EXT)); + EXPECT_FALSE(info_->validators()->g_l_state.IsValid( + GL_MAX_SAMPLES_EXT)); + EXPECT_FALSE(info_->validators()->render_buffer_parameter.IsValid( + GL_RENDERBUFFER_SAMPLES_EXT)); +} + TEST_F(FeatureInfoTest, InitializeEXT_multisampled_render_to_texture) { SetupInitExpectations("GL_EXT_multisampled_render_to_texture"); EXPECT_TRUE(info_->feature_flags( @@ -708,6 +759,7 @@ TEST_F(FeatureInfoTest, TEST_F(FeatureInfoTest, InitializeOES_depth24) { SetupInitExpectations("GL_OES_depth24"); + EXPECT_TRUE(info_->feature_flags().oes_depth24); EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_depth24")); EXPECT_TRUE(info_->validators()->render_buffer_format.IsValid( GL_DEPTH_COMPONENT24)); @@ -860,26 +912,50 @@ TEST_F(FeatureInfoTest, InitializeEXT_discard_framebuffer) { } TEST_F(FeatureInfoTest, InitializeSamplersWithARBSamplerObjects) { - SetupInitExpectationsWithGLVersion("GL_ARB_sampler_objects", "OpenGL 3.0"); + SetupInitExpectationsWithGLVersion( + "GL_ARB_sampler_objects", "", "OpenGL 3.0"); EXPECT_TRUE(info_->feature_flags().enable_samplers); } TEST_F(FeatureInfoTest, InitializeWithES3) { - SetupInitExpectationsWithGLVersion("", "OpenGL ES 3.0"); + SetupInitExpectationsWithGLVersion("", "", "OpenGL ES 3.0"); EXPECT_TRUE(info_->feature_flags().enable_samplers); EXPECT_TRUE(info_->feature_flags().map_buffer_range); EXPECT_TRUE(info_->feature_flags().ext_discard_framebuffer); EXPECT_THAT(info_->extensions(), HasSubstr("GL_EXT_discard_framebuffer")); + EXPECT_TRUE(info_->feature_flags().chromium_framebuffer_multisample); + EXPECT_TRUE(info_->feature_flags().use_core_framebuffer_multisample); + EXPECT_THAT(info_->extensions(), + HasSubstr("GL_CHROMIUM_framebuffer_multisample")); EXPECT_FALSE(info_->feature_flags().use_async_readpixels); + EXPECT_TRUE(info_->feature_flags().oes_depth24); + EXPECT_THAT(info_->extensions(), HasSubstr("GL_GOOGLE_depth_texture")); + EXPECT_THAT(info_->extensions(), HasSubstr("GL_CHROMIUM_depth_texture")); + EXPECT_TRUE(info_->validators()->pixel_type.IsValid(GL_UNSIGNED_INT_24_8)); + EXPECT_TRUE(info_->GetTextureFormatValidator(GL_DEPTH_COMPONENT) + .IsValid(GL_UNSIGNED_SHORT)); + EXPECT_TRUE(info_->GetTextureFormatValidator(GL_DEPTH_COMPONENT) + .IsValid(GL_UNSIGNED_INT)); + EXPECT_TRUE(info_->GetTextureFormatValidator(GL_DEPTH_STENCIL) + .IsValid(GL_UNSIGNED_INT_24_8)); + EXPECT_TRUE(info_->feature_flags().packed_depth24_stencil8); + EXPECT_THAT(info_->extensions(), HasSubstr("GL_OES_depth24")); + EXPECT_TRUE( + info_->validators()->render_buffer_format.IsValid(GL_DEPTH_COMPONENT24)); + EXPECT_TRUE( + info_->validators()->render_buffer_format.IsValid(GL_DEPTH24_STENCIL8)); + EXPECT_TRUE( + info_->validators()->texture_internal_format.IsValid(GL_DEPTH_STENCIL)); + EXPECT_TRUE(info_->validators()->texture_format.IsValid(GL_DEPTH_STENCIL)); } TEST_F(FeatureInfoTest, InitializeWithoutSamplers) { - SetupInitExpectationsWithGLVersion("", "OpenGL GL 3.0"); + SetupInitExpectationsWithGLVersion("", "", "OpenGL GL 3.0"); EXPECT_FALSE(info_->feature_flags().enable_samplers); } TEST_F(FeatureInfoTest, InitializeWithES3AndFences) { - SetupInitExpectationsWithGLVersion("EGL_KHR_fence_sync", "OpenGL ES 3.0"); + SetupInitExpectationsWithGLVersion("EGL_KHR_fence_sync", "", "OpenGL ES 3.0"); EXPECT_TRUE(info_->feature_flags().use_async_readpixels); } diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 48142e6..2b79213 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -407,7 +407,10 @@ class BackRenderbuffer { void Create(); // Set the initial size and format of a render buffer or resize it. - bool AllocateStorage(const gfx::Size& size, GLenum format, GLsizei samples); + bool AllocateStorage(const FeatureInfo* feature_info, + const gfx::Size& size, + GLenum format, + GLsizei samples); // Destroy the render buffer. This must be explicitly called before destroying // this object. @@ -627,7 +630,25 @@ class GLES2DecoderImpl : public GLES2Decoder, virtual void OnTextureRefDetachedFromFramebuffer( TextureRef* texture) OVERRIDE; - static bool IsAngle(); + // Helpers to facilitate calling into compatible extensions. + static void RenderbufferStorageMultisampleHelper( + const FeatureInfo* feature_info, + GLenum target, + GLsizei samples, + GLenum internal_format, + GLsizei width, + GLsizei height); + + void BlitFramebufferHelper(GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter); private: friend class ScopedFrameBufferBinder; @@ -1804,13 +1825,16 @@ ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder( const int width = decoder_->offscreen_size_.width(); const int height = decoder_->offscreen_size_.height(); glDisable(GL_SCISSOR_TEST); - if (GLES2DecoderImpl::IsAngle()) { - glBlitFramebufferANGLE(0, 0, width, height, 0, 0, width, height, - GL_COLOR_BUFFER_BIT, GL_NEAREST); - } else { - glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height, - GL_COLOR_BUFFER_BIT, GL_NEAREST); - } + decoder->BlitFramebufferHelper(0, + 0, + width, + height, + 0, + 0, + width, + height, + GL_COLOR_BUFFER_BIT, + GL_NEAREST); glBindFramebufferEXT(GL_FRAMEBUFFER, targetid); } @@ -1962,7 +1986,9 @@ void BackRenderbuffer::Create() { glGenRenderbuffersEXT(1, &id_); } -bool BackRenderbuffer::AllocateStorage(const gfx::Size& size, GLenum format, +bool BackRenderbuffer::AllocateStorage(const FeatureInfo* feature_info, + const gfx::Size& size, + GLenum format, GLsizei samples) { ScopedGLErrorSuppressor suppressor( "BackRenderbuffer::AllocateStorage", state_->GetErrorState()); @@ -1984,19 +2010,12 @@ bool BackRenderbuffer::AllocateStorage(const gfx::Size& size, GLenum format, size.width(), size.height()); } else { - if (GLES2DecoderImpl::IsAngle()) { - glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, - samples, - format, - size.width(), - size.height()); - } else { - glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, - samples, - format, - size.width(), - size.height()); - } + GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(feature_info, + GL_RENDERBUFFER, + samples, + format, + size.width(), + size.height()); } bool success = glGetError() == GL_NO_ERROR; if (success) { @@ -2094,14 +2113,6 @@ GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) { return new GLES2DecoderImpl(group); } -bool GLES2DecoderImpl::IsAngle() { -#if defined(OS_WIN) - return gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2; -#else - return false; -#endif -} - GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group) : GLES2Decoder(), group_(group), @@ -2303,7 +2314,7 @@ bool GLES2DecoderImpl::Initialize( // ANGLE only supports packed depth/stencil formats, so use it if it is // available. const bool depth24_stencil8_supported = - context_->HasExtension("GL_OES_packed_depth_stencil"); + feature_info_->feature_flags().packed_depth24_stencil8; VLOG(1) << "GL_OES_packed_depth_stencil " << (depth24_stencil8_supported ? "" : "not ") << "supported."; if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) && @@ -2326,7 +2337,7 @@ bool GLES2DecoderImpl::Initialize( // it's available, as some desktop GL drivers don't support any non-packed // formats for depth attachments. const bool depth24_stencil8_supported = - context_->HasExtension("GL_EXT_packed_depth_stencil"); + feature_info_->feature_flags().packed_depth24_stencil8; VLOG(1) << "GL_EXT_packed_depth_stencil " << (depth24_stencil8_supported ? "" : "not ") << "supported."; @@ -3321,7 +3332,7 @@ bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) { DCHECK(offscreen_target_color_format_); if (IsOffscreenBufferMultisampled()) { if (!offscreen_target_color_render_buffer_->AllocateStorage( - offscreen_size_, offscreen_target_color_format_, + feature_info_, offscreen_size_, offscreen_target_color_format_, offscreen_target_samples_)) { LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " << "to allocate storage for offscreen target color buffer."; @@ -3337,7 +3348,7 @@ bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) { } if (offscreen_target_depth_format_ && !offscreen_target_depth_render_buffer_->AllocateStorage( - offscreen_size_, offscreen_target_depth_format_, + feature_info_, offscreen_size_, offscreen_target_depth_format_, offscreen_target_samples_)) { LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " << "to allocate storage for offscreen target depth buffer."; @@ -3345,7 +3356,7 @@ bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) { } if (offscreen_target_stencil_format_ && !offscreen_target_stencil_render_buffer_->AllocateStorage( - offscreen_size_, offscreen_target_stencil_format_, + feature_info_, offscreen_size_, offscreen_target_stencil_format_, offscreen_target_samples_)) { LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " << "to allocate storage for offscreen target stencil buffer."; @@ -4997,14 +5008,54 @@ void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM( } glDisable(GL_SCISSOR_TEST); - if (IsAngle()) { + BlitFramebufferHelper( + srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test); +} + +void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper( + const FeatureInfo* feature_info, + GLenum target, + GLsizei samples, + GLenum internal_format, + GLsizei width, + GLsizei height) { + // TODO(sievers): This could be resolved at the GL binding level, but the + // binding process is currently a bit too 'brute force'. + if (feature_info->feature_flags().is_angle) { + glRenderbufferStorageMultisampleANGLE( + target, samples, internal_format, width, height); + } else if (feature_info->feature_flags().use_core_framebuffer_multisample) { + glRenderbufferStorageMultisample( + target, samples, internal_format, width, height); + } else { + glRenderbufferStorageMultisampleEXT( + target, samples, internal_format, width, height); + } +} + +void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter) { + // TODO(sievers): This could be resolved at the GL binding level, but the + // binding process is currently a bit too 'brute force'. + if (feature_info_->feature_flags().is_angle) { glBlitFramebufferANGLE( srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + } else if (feature_info_->feature_flags().use_core_framebuffer_multisample) { + glBlitFramebuffer( + srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); } else { glBlitFramebufferEXT( srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); } - EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test); } bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample( @@ -5074,13 +5125,8 @@ void GLES2DecoderImpl::DoRenderbufferStorageMultisampleCHROMIUM( internalformat); LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER( "glRenderbufferStorageMultisampleCHROMIUM"); - if (IsAngle()) { - glRenderbufferStorageMultisampleANGLE( - target, samples, impl_format, width, height); - } else { - glRenderbufferStorageMultisampleEXT( - target, samples, impl_format, width, height); - } + RenderbufferStorageMultisampleHelper( + feature_info_, target, samples, impl_format, width, height); GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM"); if (error == GL_NO_ERROR) { @@ -5220,7 +5266,8 @@ bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity( glBindFramebufferEXT(GL_READ_FRAMEBUFFER, validation_fbo_multisample_); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, validation_fbo_); - glBlitFramebufferEXT(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST); + BlitFramebufferHelper( + 0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST); // Read a pixel from the buffer. glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_); @@ -8851,7 +8898,7 @@ void GLES2DecoderImpl::DoSwapBuffers() { // Ensure the side effects of the copy are visible to the parent // context. There is no need to do this for ANGLE because it uses a // single D3D device for all contexts. - if (!IsAngle()) + if (!feature_info_->feature_flags().is_angle) glFlush(); } } else { diff --git a/gpu/command_buffer/service/test_helper.cc b/gpu/command_buffer/service/test_helper.cc index ad95353..92c5ec4 100644 --- a/gpu/command_buffer/service/test_helper.cc +++ b/gpu/command_buffer/service/test_helper.cc @@ -278,20 +278,24 @@ void TestHelper::SetupContextGroupInitExpectations( void TestHelper::SetupFeatureInfoInitExpectations( ::gfx::MockGLInterface* gl, const char* extensions) { - SetupFeatureInfoInitExpectationsWithGLVersion(gl, extensions, ""); + SetupFeatureInfoInitExpectationsWithGLVersion(gl, extensions, "", ""); } void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion( ::gfx::MockGLInterface* gl, const char* extensions, - const char* version) { + const char* gl_renderer, + const char* gl_version) { InSequence sequence; EXPECT_CALL(*gl, GetString(GL_EXTENSIONS)) .WillOnce(Return(reinterpret_cast<const uint8*>(extensions))) .RetiresOnSaturation(); + EXPECT_CALL(*gl, GetString(GL_RENDERER)) + .WillOnce(Return(reinterpret_cast<const uint8*>(gl_renderer))) + .RetiresOnSaturation(); EXPECT_CALL(*gl, GetString(GL_VERSION)) - .WillOnce(Return(reinterpret_cast<const uint8*>(version))) + .WillOnce(Return(reinterpret_cast<const uint8*>(gl_version))) .RetiresOnSaturation(); } diff --git a/gpu/command_buffer/service/test_helper.h b/gpu/command_buffer/service/test_helper.h index 11f7004..a619073 100644 --- a/gpu/command_buffer/service/test_helper.h +++ b/gpu/command_buffer/service/test_helper.h @@ -71,7 +71,8 @@ class TestHelper { static void SetupFeatureInfoInitExpectationsWithGLVersion( ::gfx::MockGLInterface* gl, const char* extensions, - const char* version); + const char* gl_renderer, + const char* gl_version); static void SetupTextureManagerInitExpectations( ::gfx::MockGLInterface* gl, const char* extensions); static void SetupTextureManagerDestructionExpectations( diff --git a/gpu/config/gpu_driver_bug_list_json.cc b/gpu/config/gpu_driver_bug_list_json.cc index f5f276d..d6894a2 100644 --- a/gpu/config/gpu_driver_bug_list_json.cc +++ b/gpu/config/gpu_driver_bug_list_json.cc @@ -19,7 +19,7 @@ const char kGpuDriverBugListJson[] = LONG_STRING_CONST( { "name": "gpu driver bug list", // Please update the version number whenever you change this file. - "version": "3.4", + "version": "3.5", "entries": [ { "id": 1, @@ -186,21 +186,6 @@ const char kGpuDriverBugListJson[] = LONG_STRING_CONST( ] }, { - "id": 15, - "description": "Some Android Qualcomm drivers falsely report GL_ANGLE_framebuffer_multisample", - "cr_bugs": [165736], - "os": { - "type": "android" - }, - "gl_vendor": { - "op": "beginwith", - "value": "Qualcomm" - }, - "features": [ - "disable_angle_framebuffer_multisample" - ] - }, - { "id": 16, "description": "Intel drivers on Linux appear to be buggy", "os": { @@ -710,6 +695,20 @@ const char kGpuDriverBugListJson[] = LONG_STRING_CONST( "features": [ "texsubimage2d_faster_than_teximage2d" ] + }, + { + "id": 52, + "description": "ES3 MSAA is broken on Qualcomm.", + "os": { + "type": "android" + }, + "gl_vendor": { + "op": "beginwith", + "value": "Qualcomm" + }, + "features": [ + "disable_framebuffer_multisample" + ] } ] } diff --git a/gpu/config/gpu_driver_bug_workaround_type.h b/gpu/config/gpu_driver_bug_workaround_type.h index 28474bbb..ab5b38f 100644 --- a/gpu/config/gpu_driver_bug_workaround_type.h +++ b/gpu/config/gpu_driver_bug_workaround_type.h @@ -14,8 +14,6 @@ clear_alpha_in_readpixels) \ GPU_OP(CLEAR_UNIFORMS_BEFORE_PROGRAM_USE, \ clear_uniforms_before_program_use) \ - GPU_OP(DISABLE_ANGLE_FRAMEBUFFER_MULTISAMPLE, \ - disable_angle_framebuffer_multisample) \ GPU_OP(DISABLE_ANGLE_INSTANCED_ARRAYS, \ disable_angle_instanced_arrays) \ GPU_OP(DISABLE_ASYNC_READPIXELS, \ @@ -30,6 +28,8 @@ disable_ext_draw_buffers) \ GPU_OP(DISABLE_EXT_OCCLUSION_QUERY, \ disable_ext_occlusion_query) \ + GPU_OP(DISABLE_FRAMEBUFFER_MULTISAMPLE, \ + disable_framebuffer_multisample) \ GPU_OP(DISABLE_MULTIMONITOR_MULTISAMPLING, \ disable_multimonitor_multisampling) \ GPU_OP(DISABLE_OES_STANDARD_DERIVATIVES, \ |