diff options
author | kbr <kbr@chromium.org> | 2015-03-31 12:49:12 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-03-31 19:50:00 +0000 |
commit | c9f0e10c369408bdc80c158a882949f5121f3a7a (patch) | |
tree | 199653659aebd5cb137eae8a20fd5cee73abc207 /gpu | |
parent | e0fd6c1d6106a5720fdd97dcefb7dcfd6b4743af (diff) | |
download | chromium_src-c9f0e10c369408bdc80c158a882949f5121f3a7a.zip chromium_src-c9f0e10c369408bdc80c158a882949f5121f3a7a.tar.gz chromium_src-c9f0e10c369408bdc80c158a882949f5121f3a7a.tar.bz2 |
Added support for desktop OpenGL's Core Profile on Mac OS X.
Joint work with ccameron@, thanks to whom for the ImageTransportSurface
changes and some of the others.
When --enable-unsafe-es3-apis is specified, use the core profile rather
than the compatibility profile for all OpenGL contexts on Mac OS X. This CL
adds the core profile as another known GLImplementation which behaves
mostly like OpenGL ES, but partly like desktop GL, and has some differences
compared to both.
It is likely that Chrome will upgrade to the Core Profile on all platforms
using desktop OpenGL, and that support for the compatibility profile will
be dropped.
Tested with both regular and WebGL content, with all combinations of
--enable-unsafe-es3-apis and --disable-remote-core-animation.
BUG=470396
Review URL: https://codereview.chromium.org/1038763004
Cr-Commit-Position: refs/heads/master@{#323091}
Diffstat (limited to 'gpu')
17 files changed, 386 insertions, 146 deletions
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index aa7be79..0407033 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -386,7 +386,8 @@ _STATES = { 'name': 'hint_generate_mipmap', 'type': 'GLenum', 'enum': 'GL_GENERATE_MIPMAP_HINT', - 'default': 'GL_DONT_CARE' + 'default': 'GL_DONT_CARE', + 'gl_version_flag': '!is_desktop_core_profile' }, { 'name': 'hint_fragment_shader_derivative', @@ -9652,11 +9653,21 @@ void ContextState::InitState(const ContextState *prev_state) const { else: file.Write(" if (prev_state->%s != %s) {\n " % (item_name, item_name)) + if 'gl_version_flag' in item: + item_name = item['gl_version_flag'] + inverted = '' + if item_name[0] == '!': + inverted = '!' + item_name = item_name[1:] + file.Write(" if (%sfeature_info_->gl_version_info().%s) {\n" % + (inverted, item_name)) file.Write(" gl%s(%s, %s);\n" % (state['func'], (item['enum_set'] if 'enum_set' in item else item['enum']), item['name'])) + if 'gl_version_flag' in item: + file.Write(" }\n") if test_prev: if 'extension_flag' in item: file.Write(" ") diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager_mac.cc b/gpu/command_buffer/service/async_pixel_transfer_manager_mac.cc index dcc7e18..6d8562f 100644 --- a/gpu/command_buffer/service/async_pixel_transfer_manager_mac.cc +++ b/gpu/command_buffer/service/async_pixel_transfer_manager_mac.cc @@ -17,6 +17,7 @@ AsyncPixelTransferManager* AsyncPixelTransferManager::Create( switch (gfx::GetGLImplementation()) { case gfx::kGLImplementationOSMesaGL: case gfx::kGLImplementationDesktopGL: + case gfx::kGLImplementationDesktopGLCoreProfile: case gfx::kGLImplementationAppleGL: return new AsyncPixelTransferManagerIdle(true); case gfx::kGLImplementationMockGL: diff --git a/gpu/command_buffer/service/context_group.cc b/gpu/command_buffer/service/context_group.cc index d918526..17871b9 100644 --- a/gpu/command_buffer/service/context_group.cc +++ b/gpu/command_buffer/service/context_group.cc @@ -97,7 +97,8 @@ bool ContextGroup::Initialize( GL_MAX_RENDERBUFFER_SIZE, kMinRenderbufferSize, &max_renderbuffer_size)) { LOG(ERROR) << "ContextGroup::Initialize failed because maximum " - << "renderbuffer size too small."; + << "renderbuffer size too small (" << max_renderbuffer_size + << ", should be " << kMinRenderbufferSize << ")."; return false; } GLint max_samples = 0; @@ -121,15 +122,13 @@ bool ContextGroup::Initialize( draw_buffer_ = GL_BACK; } - const bool depth24_supported = feature_info_->feature_flags().oes_depth24; - buffer_manager_.reset( new BufferManager(memory_tracker_.get(), feature_info_.get())); framebuffer_manager_.reset( new FramebufferManager(max_draw_buffers_, max_color_attachments_)); renderbuffer_manager_.reset(new RenderbufferManager( memory_tracker_.get(), max_renderbuffer_size, max_samples, - depth24_supported)); + feature_info_.get())); shader_manager_.reset(new ShaderManager()); valuebuffer_manager_.reset( new ValuebufferManager(subscription_ref_set_.get(), @@ -213,7 +212,7 @@ bool ContextGroup::Initialize( return false; } - if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) { + if (feature_info_->gl_version_info().BehavesLikeGLES()) { GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &max_fragment_uniform_vectors_); GetIntegerv(GL_MAX_VARYING_VECTORS, &max_varying_vectors_); diff --git a/gpu/command_buffer/service/context_state_impl_autogen.h b/gpu/command_buffer/service/context_state_impl_autogen.h index 467f1ce..e6c63a6 100644 --- a/gpu/command_buffer/service/context_state_impl_autogen.h +++ b/gpu/command_buffer/service/context_state_impl_autogen.h @@ -242,7 +242,9 @@ void ContextState::InitState(const ContextState* prev_state) const { if ((front_face != prev_state->front_face)) glFrontFace(front_face); if (prev_state->hint_generate_mipmap != hint_generate_mipmap) { - glHint(GL_GENERATE_MIPMAP_HINT, hint_generate_mipmap); + if (!feature_info_->gl_version_info().is_desktop_core_profile) { + glHint(GL_GENERATE_MIPMAP_HINT, hint_generate_mipmap); + } } if (feature_info_->feature_flags().oes_standard_derivatives) { if (prev_state->hint_fragment_shader_derivative != @@ -330,7 +332,9 @@ void ContextState::InitState(const ContextState* prev_state) const { glDepthMask(cached_depth_mask); glDepthRange(z_near, z_far); glFrontFace(front_face); - glHint(GL_GENERATE_MIPMAP_HINT, hint_generate_mipmap); + if (!feature_info_->gl_version_info().is_desktop_core_profile) { + glHint(GL_GENERATE_MIPMAP_HINT, hint_generate_mipmap); + } if (feature_info_->feature_flags().oes_standard_derivatives) { glHint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES, hint_fragment_shader_derivative); diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc index 6675ba7..0ff5be1 100644 --- a/gpu/command_buffer/service/feature_info.cc +++ b/gpu/command_buffer/service/feature_info.cc @@ -44,6 +44,10 @@ class StringSet { Init(str); } + StringSet(const std::vector<std::string>& strs) { + string_set_.insert(strs.begin(), strs.end()); + } + void Init(const char* s) { std::string str(s ? s : ""); Init(str); @@ -63,6 +67,10 @@ class StringSet { return string_set_.find(s) != string_set_.end(); } + const std::set<std::string>& GetImpl() { + return string_set_; + } + private: std::set<std::string> string_set_; }; @@ -272,15 +280,35 @@ bool IsGL_REDSupportedOnFBOs() { void FeatureInfo::InitializeFeatures() { // Figure out what extensions to turn on. - StringSet extensions( - reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))); + StringSet extensions; + // We need to figure out how to query the extension string before we + // have a GLVersionInfo available. + const char* version_str = + reinterpret_cast<const char*>(glGetString(GL_VERSION)); + unsigned major_version, minor_version; + bool is_es, is_es3; + gfx::GLVersionInfo::ParseVersionString( + version_str, &major_version, &minor_version, &is_es, &is_es3); + if (!is_es && major_version >= 3) { + std::vector<std::string> exts; + GLint num_extensions = 0; + glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions); + for (GLint i = 0; i < num_extensions; ++i) { + const char* extension = reinterpret_cast<const char*>( + glGetStringi(GL_EXTENSIONS, i)); + DCHECK(extension != NULL); + exts.push_back(extension); + } + extensions = exts; + } else { + extensions = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)); + } const char* renderer_str = reinterpret_cast<const char*>(glGetString(GL_RENDERER)); - const char* version_str = - reinterpret_cast<const char*>(glGetString(GL_VERSION)); - gl_version_info_.reset(new gfx::GLVersionInfo(version_str, renderer_str)); + gl_version_info_.reset(new gfx::GLVersionInfo( + version_str, renderer_str, extensions.GetImpl())); AddExtensionString("GL_ANGLE_translated_shader_source"); AddExtensionString("GL_CHROMIUM_async_pixel_transfers"); @@ -402,7 +430,8 @@ void FeatureInfo::InitializeFeatures() { (extensions.Contains("GL_ARB_depth_texture") || extensions.Contains("GL_OES_depth_texture") || extensions.Contains("GL_ANGLE_depth_texture") || - gl_version_info_->is_es3)) { + gl_version_info_->is_es3 || + gl_version_info_->is_desktop_core_profile)) { enable_depth_texture = true; feature_flags_.angle_depth_texture = extensions.Contains("GL_ANGLE_depth_texture"); @@ -421,7 +450,8 @@ void FeatureInfo::InitializeFeatures() { if (extensions.Contains("GL_EXT_packed_depth_stencil") || extensions.Contains("GL_OES_packed_depth_stencil") || - gl_version_info_->is_es3) { + gl_version_info_->is_es3 || + gl_version_info_->is_desktop_core_profile) { AddExtensionString("GL_OES_packed_depth_stencil"); feature_flags_.packed_depth24_stencil8 = true; if (enable_depth_texture) { @@ -435,6 +465,7 @@ void FeatureInfo::InitializeFeatures() { } if (gl_version_info_->is_es3 || + gl_version_info_->is_desktop_core_profile || extensions.Contains("GL_OES_vertex_array_object") || extensions.Contains("GL_ARB_vertex_array_object") || extensions.Contains("GL_APPLE_vertex_array_object")) { @@ -526,6 +557,7 @@ void FeatureInfo::InitializeFeatures() { // Check if we should allow GL_OES_texture_npot if (gl_version_info_->is_es3 || + gl_version_info_->is_desktop_core_profile || extensions.Contains("GL_ARB_texture_non_power_of_two") || extensions.Contains("GL_OES_texture_npot")) { AddExtensionString("GL_OES_texture_npot"); @@ -541,7 +573,8 @@ void FeatureInfo::InitializeFeatures() { bool may_enable_chromium_color_buffer_float = false; - if (extensions.Contains("GL_ARB_texture_float")) { + if (extensions.Contains("GL_ARB_texture_float") || + gl_version_info_->is_desktop_core_profile) { enable_texture_float = true; enable_texture_float_linear = true; enable_texture_half_float = true; @@ -663,12 +696,14 @@ void FeatureInfo::InitializeFeatures() { if (!workarounds_.disable_multisampling) { bool ext_has_multisample = extensions.Contains("GL_EXT_framebuffer_multisample") || - gl_version_info_->is_es3; + gl_version_info_->is_es3 || + gl_version_info_->is_desktop_core_profile; if (gl_version_info_->is_angle) { ext_has_multisample |= extensions.Contains("GL_ANGLE_framebuffer_multisample"); } - feature_flags_.use_core_framebuffer_multisample = gl_version_info_->is_es3; + feature_flags_.use_core_framebuffer_multisample = + gl_version_info_->is_es3 || gl_version_info_->is_desktop_core_profile; if (ext_has_multisample) { feature_flags_.chromium_framebuffer_multisample = true; validators_.frame_buffer_target.AddValue(GL_READ_FRAMEBUFFER_EXT); @@ -753,7 +788,8 @@ void FeatureInfo::InitializeFeatures() { // applications to start using it; they should use ordinary non- // power-of-two textures. However, for unit testing purposes we // expose it on all supported platforms. - if (extensions.Contains("GL_ARB_texture_rectangle")) { + if (extensions.Contains("GL_ARB_texture_rectangle") || + gl_version_info_->is_desktop_core_profile) { AddExtensionString("GL_ARB_texture_rectangle"); feature_flags_.arb_texture_rectangle = true; validators_.texture_bind_target.AddValue(GL_TEXTURE_RECTANGLE_ARB); @@ -803,7 +839,8 @@ void FeatureInfo::InitializeFeatures() { !enable_texture_format_bgra8888); if (extensions.Contains("GL_EXT_texture_storage") || extensions.Contains("GL_ARB_texture_storage") || - support_texture_storage_on_es3) { + support_texture_storage_on_es3 || + gl_version_info_->is_desktop_core_profile) { feature_flags_.ext_texture_storage = true; AddExtensionString("GL_EXT_texture_storage"); validators_.texture_parameter.AddValue(GL_TEXTURE_IMMUTABLE_FORMAT_EXT); @@ -865,7 +902,8 @@ void FeatureInfo::InitializeFeatures() { if (!workarounds_.disable_ext_draw_buffers && (vendor_agnostic_draw_buffers || (extensions.Contains("GL_NV_draw_buffers") && - gl_version_info_->is_es3))) { + gl_version_info_->is_es3) || + gl_version_info_->is_desktop_core_profile)) { AddExtensionString("GL_EXT_draw_buffers"); feature_flags_.ext_draw_buffers = true; @@ -937,6 +975,7 @@ void FeatureInfo::InitializeFeatures() { feature_flags_.map_buffer_range = gl_version_info_->is_es3 || + gl_version_info_->is_desktop_core_profile || extensions.Contains("GL_ARB_map_buffer_range") || extensions.Contains("GL_EXT_map_buffer_range"); @@ -944,6 +983,7 @@ void FeatureInfo::InitializeFeatures() { // extension is still advertised. bool has_pixel_buffers = gl_version_info_->is_es3 || + gl_version_info_->is_desktop_core_profile || extensions.Contains("GL_ARB_pixel_buffer_object") || extensions.Contains("GL_NV_pixel_buffer_object"); @@ -1017,7 +1057,8 @@ void FeatureInfo::InitializeFeatures() { } } - if ((gl_version_info_->is_es3 || extensions.Contains("GL_EXT_texture_rg") || + if ((gl_version_info_->is_es3 || gl_version_info_->is_desktop_core_profile || + extensions.Contains("GL_EXT_texture_rg") || extensions.Contains("GL_ARB_texture_rg")) && IsGL_REDSupportedOnFBOs()) { feature_flags_.ext_texture_rg = true; diff --git a/gpu/command_buffer/service/feature_info_unittest.cc b/gpu/command_buffer/service/feature_info_unittest.cc index 177ef10..f4b2dac 100644 --- a/gpu/command_buffer/service/feature_info_unittest.cc +++ b/gpu/command_buffer/service/feature_info_unittest.cc @@ -42,7 +42,13 @@ class FeatureInfoTest : public GpuServiceTest { } void SetupInitExpectations(const char* extensions) { - SetupInitExpectationsWithGLVersion(extensions, "", "3.0"); + std::string extensions_str = extensions; + // Most of the tests' expectations currently assume the desktop + // OpenGL compatibility profile. + if (extensions_str.find("GL_ARB_compatibility") == std::string::npos) { + extensions_str += " GL_ARB_compatibility"; + } + SetupInitExpectationsWithGLVersion(extensions_str.c_str(), "", "3.0"); } void SetupInitExpectationsWithGLVersion( @@ -1382,7 +1388,8 @@ TEST_F(FeatureInfoTest, ARBSyncDisabled) { TEST_F(FeatureInfoTest, InitializeCHROMIUM_path_rendering) { SetupInitExpectationsWithGLVersion( - "GL_NV_path_rendering GL_EXT_direct_state_access", "", "4.3"); + "GL_ARB_compatibility GL_NV_path_rendering GL_EXT_direct_state_access", + "", "4.3"); EXPECT_TRUE(info_->feature_flags().chromium_path_rendering); EXPECT_THAT(info_->extensions(), HasSubstr("GL_CHROMIUM_path_rendering")); } @@ -1395,21 +1402,22 @@ TEST_F(FeatureInfoTest, InitializeCHROMIUM_path_rendering2) { } TEST_F(FeatureInfoTest, InitializeNoCHROMIUM_path_rendering) { - SetupInitExpectationsWithGLVersion("", "", "4.3"); + SetupInitExpectationsWithGLVersion("GL_ARB_compatibility", "", "4.3"); EXPECT_FALSE(info_->feature_flags().chromium_path_rendering); EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_CHROMIUM_path_rendering"))); } TEST_F(FeatureInfoTest, InitializeNoCHROMIUM_path_rendering2) { - SetupInitExpectationsWithGLVersion("GL_NV_path_rendering", "", "4.3"); + SetupInitExpectationsWithGLVersion( + "GL_ARB_compatibility GL_NV_path_rendering", "", "4.3"); EXPECT_FALSE(info_->feature_flags().chromium_path_rendering); EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_CHROMIUM_path_rendering"))); } TEST_F(FeatureInfoTest, InitializeNoKHR_blend_equation_advanced) { - SetupInitExpectationsWithGLVersion("", "", "4.3"); + SetupInitExpectationsWithGLVersion("GL_ARB_compatibility", "", "4.3"); EXPECT_FALSE(info_->feature_flags().blend_equation_advanced); EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_KHR_blend_equation_advanced"))); @@ -1428,7 +1436,7 @@ TEST_F(FeatureInfoTest, InitializeNV_blend_equations_advanced) { } TEST_F(FeatureInfoTest, InitializeNoKHR_blend_equation_advanced_coherent) { - SetupInitExpectationsWithGLVersion("", "", "4.3"); + SetupInitExpectationsWithGLVersion("GL_ARB_compatibility ", "", "4.3"); EXPECT_FALSE(info_->feature_flags().blend_equation_advanced_coherent); EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_KHR_blend_equation_advanced_coherent"))); diff --git a/gpu/command_buffer/service/framebuffer_manager_unittest.cc b/gpu/command_buffer/service/framebuffer_manager_unittest.cc index ddd3739..66fb260 100644 --- a/gpu/command_buffer/service/framebuffer_manager_unittest.cc +++ b/gpu/command_buffer/service/framebuffer_manager_unittest.cc @@ -26,7 +26,6 @@ const GLint kMaxRenderbufferSize = 64; const GLint kMaxSamples = 4; const uint32 kMaxDrawBuffers = 16; const uint32 kMaxColorAttachments = 16; -const bool kDepth24Supported = false; const bool kUseDefaultTextures = false; } // namespace @@ -35,27 +34,30 @@ class FramebufferManagerTest : public GpuServiceTest { public: FramebufferManagerTest() : manager_(1, 1), - texture_manager_(NULL, - new FeatureInfo(), - kMaxTextureSize, - kMaxCubemapSize, - kMaxRectangleTextureSize, - kUseDefaultTextures), - renderbuffer_manager_(NULL, - kMaxRenderbufferSize, - kMaxSamples, - kDepth24Supported) {} + feature_info_(new FeatureInfo()) { + texture_manager_.reset(new TextureManager(NULL, + feature_info_.get(), + kMaxTextureSize, + kMaxCubemapSize, + kMaxRectangleTextureSize, + kUseDefaultTextures)); + renderbuffer_manager_.reset(new RenderbufferManager(NULL, + kMaxRenderbufferSize, + kMaxSamples, + feature_info_.get())); + } ~FramebufferManagerTest() override { manager_.Destroy(false); - texture_manager_.Destroy(false); - renderbuffer_manager_.Destroy(false); + texture_manager_->Destroy(false); + renderbuffer_manager_->Destroy(false); } protected: FramebufferManager manager_; - TextureManager texture_manager_; - RenderbufferManager renderbuffer_manager_; + scoped_refptr<FeatureInfo> feature_info_; + scoped_ptr<TextureManager> texture_manager_; + scoped_ptr<RenderbufferManager> renderbuffer_manager_; }; TEST_F(FramebufferManagerTest, Basic) { @@ -109,20 +111,22 @@ class FramebufferInfoTest : public GpuServiceTest { FramebufferInfoTest() : manager_(kMaxDrawBuffers, kMaxColorAttachments), - feature_info_(new FeatureInfo()), - renderbuffer_manager_(NULL, kMaxRenderbufferSize, kMaxSamples, - kDepth24Supported) { + feature_info_(new FeatureInfo()) { texture_manager_.reset(new TextureManager(NULL, feature_info_.get(), kMaxTextureSize, kMaxCubemapSize, kMaxRectangleTextureSize, kUseDefaultTextures)); + renderbuffer_manager_.reset(new RenderbufferManager(NULL, + kMaxRenderbufferSize, + kMaxSamples, + feature_info_.get())); } ~FramebufferInfoTest() override { manager_.Destroy(false); texture_manager_->Destroy(false); - renderbuffer_manager_.Destroy(false); + renderbuffer_manager_->Destroy(false); } protected: @@ -145,7 +149,7 @@ class FramebufferInfoTest : public GpuServiceTest { Framebuffer* framebuffer_; scoped_refptr<FeatureInfo> feature_info_; scoped_ptr<TextureManager> texture_manager_; - RenderbufferManager renderbuffer_manager_; + scoped_ptr<RenderbufferManager> renderbuffer_manager_; scoped_ptr<MockErrorState> error_state_; }; @@ -205,10 +209,10 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) { EXPECT_FALSE( framebuffer_->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)); - renderbuffer_manager_.CreateRenderbuffer( + renderbuffer_manager_->CreateRenderbuffer( kRenderbufferClient1Id, kRenderbufferService1Id); Renderbuffer* renderbuffer1 = - renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id); + renderbuffer_manager_->GetRenderbuffer(kRenderbufferClient1Id); ASSERT_TRUE(renderbuffer1 != NULL); // check adding one attachment @@ -224,13 +228,13 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) { EXPECT_TRUE(framebuffer_->IsCleared()); // Try a format that's not good for COLOR_ATTACHMENT0. - renderbuffer_manager_.SetInfo( + renderbuffer_manager_->SetInfo( renderbuffer1, kSamples1, kBadFormat1, kWidth1, kHeight1); EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT), framebuffer_->IsPossiblyComplete()); // Try a good format. - renderbuffer_manager_.SetInfo( + renderbuffer_manager_->SetInfo( renderbuffer1, kSamples1, kFormat1, kWidth1, kHeight1); EXPECT_EQ(static_cast<GLenum>(kFormat1), framebuffer_->GetColorAttachmentFormat()); @@ -241,10 +245,10 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) { EXPECT_FALSE(framebuffer_->IsCleared()); // check adding another - renderbuffer_manager_.CreateRenderbuffer( + renderbuffer_manager_->CreateRenderbuffer( kRenderbufferClient2Id, kRenderbufferService2Id); Renderbuffer* renderbuffer2 = - renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient2Id); + renderbuffer_manager_->GetRenderbuffer(kRenderbufferClient2Id); ASSERT_TRUE(renderbuffer2 != NULL); framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, renderbuffer2); EXPECT_TRUE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)); @@ -263,7 +267,7 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) { status == GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT); EXPECT_FALSE(framebuffer_->IsCleared()); - renderbuffer_manager_.SetInfo( + renderbuffer_manager_->SetInfo( renderbuffer2, kSamples2, kFormat2, kWidth2, kHeight2); EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), framebuffer_->IsPossiblyComplete()); @@ -272,7 +276,7 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) { // check marking them as cleared. manager_.MarkAttachmentsAsCleared( - framebuffer_, &renderbuffer_manager_, texture_manager_.get()); + framebuffer_, renderbuffer_manager_.get(), texture_manager_.get()); EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)); EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT)); EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), @@ -280,14 +284,14 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) { EXPECT_TRUE(framebuffer_->IsCleared()); // Check adding one that is already cleared. - renderbuffer_manager_.CreateRenderbuffer( + renderbuffer_manager_->CreateRenderbuffer( kRenderbufferClient3Id, kRenderbufferService3Id); Renderbuffer* renderbuffer3 = - renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient3Id); + renderbuffer_manager_->GetRenderbuffer(kRenderbufferClient3Id); ASSERT_TRUE(renderbuffer3 != NULL); - renderbuffer_manager_.SetInfo( + renderbuffer_manager_->SetInfo( renderbuffer3, kSamples3, kFormat3, kWidth3, kHeight3); - renderbuffer_manager_.SetCleared(renderbuffer3, true); + renderbuffer_manager_->SetCleared(renderbuffer3, true); framebuffer_->AttachRenderbuffer(GL_STENCIL_ATTACHMENT, renderbuffer3); EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT)); @@ -300,7 +304,7 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) { EXPECT_TRUE(framebuffer_->IsCleared()); // Check marking the renderbuffer as unclared. - renderbuffer_manager_.SetInfo( + renderbuffer_manager_->SetInfo( renderbuffer1, kSamples1, kFormat1, kWidth1, kHeight1); EXPECT_EQ(static_cast<GLenum>(kFormat1), framebuffer_->GetColorAttachmentFormat()); @@ -323,17 +327,17 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) { // Clear it. manager_.MarkAttachmentsAsCleared( - framebuffer_, &renderbuffer_manager_, texture_manager_.get()); + framebuffer_, renderbuffer_manager_.get(), texture_manager_.get()); EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)); EXPECT_TRUE(framebuffer_->IsCleared()); // Check replacing an attachment - renderbuffer_manager_.CreateRenderbuffer( + renderbuffer_manager_->CreateRenderbuffer( kRenderbufferClient4Id, kRenderbufferService4Id); Renderbuffer* renderbuffer4 = - renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient4Id); + renderbuffer_manager_->GetRenderbuffer(kRenderbufferClient4Id); ASSERT_TRUE(renderbuffer4 != NULL); - renderbuffer_manager_.SetInfo( + renderbuffer_manager_->SetInfo( renderbuffer4, kSamples4, kFormat4, kWidth4, kHeight4); framebuffer_->AttachRenderbuffer(GL_STENCIL_ATTACHMENT, renderbuffer4); @@ -351,7 +355,7 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) { framebuffer_->IsPossiblyComplete()); // Check changing an attachment. - renderbuffer_manager_.SetInfo( + renderbuffer_manager_->SetInfo( renderbuffer4, kSamples4, kFormat4, kWidth4 + 1, kHeight4); attachment = framebuffer_->GetAttachment(GL_STENCIL_ATTACHMENT); @@ -379,7 +383,7 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) { // Remove depth, Set color to 0 size. framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, NULL); - renderbuffer_manager_.SetInfo(renderbuffer1, kSamples1, kFormat1, 0, 0); + renderbuffer_manager_->SetInfo(renderbuffer1, kSamples1, kFormat1, 0, 0); EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT), framebuffer_->IsPossiblyComplete()); @@ -735,15 +739,15 @@ TEST_F(FramebufferInfoTest, UnbindRenderbuffer) { const GLuint kRenderbufferClient2Id = 34; const GLuint kRenderbufferService2Id = 334; - renderbuffer_manager_.CreateRenderbuffer( + renderbuffer_manager_->CreateRenderbuffer( kRenderbufferClient1Id, kRenderbufferService1Id); Renderbuffer* renderbuffer1 = - renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id); + renderbuffer_manager_->GetRenderbuffer(kRenderbufferClient1Id); ASSERT_TRUE(renderbuffer1 != NULL); - renderbuffer_manager_.CreateRenderbuffer( + renderbuffer_manager_->CreateRenderbuffer( kRenderbufferClient2Id, kRenderbufferService2Id); Renderbuffer* renderbuffer2 = - renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient2Id); + renderbuffer_manager_->GetRenderbuffer(kRenderbufferClient2Id); ASSERT_TRUE(renderbuffer2 != NULL); // Attach to 2 attachment points. @@ -811,10 +815,10 @@ TEST_F(FramebufferInfoTest, IsCompleteMarkAsComplete) { const GLint kLevel1 = 0; const GLint kSamples1 = 0; - renderbuffer_manager_.CreateRenderbuffer( + renderbuffer_manager_->CreateRenderbuffer( kRenderbufferClient1Id, kRenderbufferService1Id); Renderbuffer* renderbuffer1 = - renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id); + renderbuffer_manager_->GetRenderbuffer(kRenderbufferClient1Id); ASSERT_TRUE(renderbuffer1 != NULL); texture_manager_->CreateTexture(kTextureClient2Id, kTextureService2Id); scoped_refptr<TextureRef> texture2( @@ -836,7 +840,7 @@ TEST_F(FramebufferInfoTest, IsCompleteMarkAsComplete) { // Check MarkAttachmentsAsCleared marks as complete. manager_.MarkAttachmentsAsCleared( - framebuffer_, &renderbuffer_manager_, texture_manager_.get()); + framebuffer_, renderbuffer_manager_.get(), texture_manager_.get()); EXPECT_TRUE(manager_.IsComplete(framebuffer_)); // Check Unbind marks as not complete. @@ -857,10 +861,10 @@ TEST_F(FramebufferInfoTest, GetStatus) { const GLint kLevel1 = 0; const GLint kSamples1 = 0; - renderbuffer_manager_.CreateRenderbuffer( + renderbuffer_manager_->CreateRenderbuffer( kRenderbufferClient1Id, kRenderbufferService1Id); Renderbuffer* renderbuffer1 = - renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id); + renderbuffer_manager_->GetRenderbuffer(kRenderbufferClient1Id); ASSERT_TRUE(renderbuffer1 != NULL); texture_manager_->CreateTexture(kTextureClient2Id, kTextureService2Id); scoped_refptr<TextureRef> texture2( diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 3abe199..d402c93 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -2733,17 +2733,39 @@ bool GLES2DecoderImpl::Initialize( // can't do anything about that. if (!surfaceless_) { - GLint v = 0; - glGetIntegerv(GL_ALPHA_BITS, &v); + GLint alpha_bits = 0; + GLint depth_bits = 0; + GLint stencil_bits = 0; + + bool default_fb = (GetBackbufferServiceId() == 0); + + if (feature_info_->gl_version_info().is_desktop_core_profile) { + glGetFramebufferAttachmentParameterivEXT( + GL_FRAMEBUFFER, + default_fb ? GL_BACK_LEFT : GL_COLOR_ATTACHMENT0, + GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, &alpha_bits); + glGetFramebufferAttachmentParameterivEXT( + GL_FRAMEBUFFER, + default_fb ? GL_DEPTH : GL_DEPTH_ATTACHMENT, + GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &depth_bits); + glGetFramebufferAttachmentParameterivEXT( + GL_FRAMEBUFFER, + default_fb ? GL_STENCIL : GL_STENCIL_ATTACHMENT, + GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &stencil_bits); + } else { + glGetIntegerv(GL_ALPHA_BITS, &alpha_bits); + glGetIntegerv(GL_DEPTH_BITS, &depth_bits); + glGetIntegerv(GL_STENCIL_BITS, &stencil_bits); + } + // This checks if the user requested RGBA and we have RGBA then RGBA. If // the user requested RGB then RGB. If the user did not specify a // preference than use whatever we were given. Same for DEPTH and STENCIL. back_buffer_color_format_ = - (attrib_parser.alpha_size != 0 && v > 0) ? GL_RGBA : GL_RGB; - glGetIntegerv(GL_DEPTH_BITS, &v); - back_buffer_has_depth_ = attrib_parser.depth_size != 0 && v > 0; - glGetIntegerv(GL_STENCIL_BITS, &v); - back_buffer_has_stencil_ = attrib_parser.stencil_size != 0 && v > 0; + (attrib_parser.alpha_size != 0 && alpha_bits > 0) ? GL_RGBA : GL_RGB; + back_buffer_has_depth_ = attrib_parser.depth_size != 0 && depth_bits > 0; + back_buffer_has_stencil_ = + attrib_parser.stencil_size != 0 && stencil_bits > 0; } state_.viewport_width = surface->GetSize().width(); @@ -2756,7 +2778,7 @@ bool GLES2DecoderImpl::Initialize( // mailing list archives. It also implicitly enables the desktop GL // capability GL_POINT_SPRITE to provide access to the gl_PointCoord // variable in fragment shaders. - if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { + if (!feature_info_->gl_version_info().BehavesLikeGLES()) { glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); glEnable(GL_POINT_SPRITE); } @@ -4749,23 +4771,93 @@ bool GLES2DecoderImpl::GetHelper( *num_written = 1; if (params) { GLint v = 0; - glGetIntegerv(GL_ALPHA_BITS, &v); - params[0] = BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0; + if (feature_info_->gl_version_info().is_desktop_core_profile) { + Framebuffer* framebuffer = + GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); + if (framebuffer) { + glGetFramebufferAttachmentParameterivEXT( + GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, &v); + } else { + v = (back_buffer_color_format_ == GL_RGBA ? 8 : 0); + } + } else { + glGetIntegerv(GL_ALPHA_BITS, &v); + } + params[0] = + BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0; } return true; case GL_DEPTH_BITS: *num_written = 1; if (params) { GLint v = 0; - glGetIntegerv(GL_DEPTH_BITS, &v); + if (feature_info_->gl_version_info().is_desktop_core_profile) { + Framebuffer* framebuffer = + GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); + if (framebuffer) { + glGetFramebufferAttachmentParameterivEXT( + GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &v); + } else { + v = (back_buffer_has_depth_ ? 24 : 0); + } + } else { + glGetIntegerv(GL_DEPTH_BITS, &v); + } params[0] = BoundFramebufferHasDepthAttachment() ? v : 0; } return true; + case GL_RED_BITS: + case GL_GREEN_BITS: + case GL_BLUE_BITS: + *num_written = 1; + if (params) { + GLint v = 0; + if (feature_info_->gl_version_info().is_desktop_core_profile) { + Framebuffer* framebuffer = + GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); + if (framebuffer) { + GLenum framebuffer_enum = 0; + switch (pname) { + case GL_RED_BITS: + framebuffer_enum = GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE; + break; + case GL_GREEN_BITS: + framebuffer_enum = GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE; + break; + case GL_BLUE_BITS: + framebuffer_enum = GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE; + break; + } + glGetFramebufferAttachmentParameterivEXT( + GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, framebuffer_enum, &v); + } else { + v = 8; + } + } else { + glGetIntegerv(pname, &v); + } + params[0] = v; + } + return true; case GL_STENCIL_BITS: *num_written = 1; if (params) { GLint v = 0; - glGetIntegerv(GL_STENCIL_BITS, &v); + if (feature_info_->gl_version_info().is_desktop_core_profile) { + Framebuffer* framebuffer = + GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); + if (framebuffer) { + glGetFramebufferAttachmentParameterivEXT( + GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, + GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &v); + } else { + v = (back_buffer_has_stencil_ ? 8 : 0); + } + } else { + glGetIntegerv(GL_STENCIL_BITS, &v); + } params[0] = BoundFramebufferHasStencilAttachment() ? v : 0; } return true; @@ -6612,7 +6704,7 @@ bool GLES2DecoderImpl::SimulateAttrib0( DCHECK(simulated); *simulated = false; - if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) + if (feature_info_->gl_version_info().BehavesLikeGLES()) return true; const VertexAttrib* attrib = @@ -8358,7 +8450,8 @@ error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size, LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name"); return error::kNoError; } - const char* str = reinterpret_cast<const char*>(glGetString(name)); + + const char* str = nullptr; std::string extensions; switch (name) { case GL_VERSION: @@ -8373,6 +8466,8 @@ error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size, // They are used by WEBGL_debug_renderer_info. if (!force_webgl_glsl_validation_) str = "Chromium"; + else + str = reinterpret_cast<const char*>(glGetString(name)); break; case GL_EXTENSIONS: { @@ -8418,6 +8513,7 @@ error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size, } break; default: + str = reinterpret_cast<const char*>(glGetString(name)); break; } Bucket* bucket = CreateBucket(c.bucket_id); diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc index 119096bb..8648134 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc @@ -126,6 +126,7 @@ void GLES2DecoderTestBase::SetUp() { // Autogenerated tests do not overwrite version or extension string, // so we have to pick something that supports everything here. init.gl_version = "4.4"; + init.extensions += " GL_ARB_compatibility"; init.has_alpha = true; init.has_depth = true; init.request_alpha = true; @@ -321,13 +322,15 @@ void GLES2DecoderTestBase::InitDecoderWithCommandLine( .WillOnce(SetArgumentPointee<1>(normalized_init.has_stencil ? 8 : 0)) .RetiresOnSaturation(); - EXPECT_CALL(*gl_, Enable(GL_VERTEX_PROGRAM_POINT_SIZE)) - .Times(1) - .RetiresOnSaturation(); + if (!group_->feature_info()->gl_version_info().BehavesLikeGLES()) { + EXPECT_CALL(*gl_, Enable(GL_VERTEX_PROGRAM_POINT_SIZE)) + .Times(1) + .RetiresOnSaturation(); - EXPECT_CALL(*gl_, Enable(GL_POINT_SPRITE)) - .Times(1) - .RetiresOnSaturation(); + EXPECT_CALL(*gl_, Enable(GL_POINT_SPRITE)) + .Times(1) + .RetiresOnSaturation(); + } static GLint max_viewport_dims[] = { kMaxViewportWidth, @@ -1684,7 +1687,7 @@ void GLES2DecoderTestBase::DeleteIndexBuffer() { void GLES2DecoderTestBase::AddExpectationsForSimulatedAttrib0WithError( GLsizei num_vertices, GLuint buffer_id, GLenum error) { - if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) { + if (group_->feature_info()->gl_version_info().BehavesLikeGLES()) { return; } diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc index 957b53b..fc5e2de 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc @@ -60,7 +60,10 @@ class GLES2DecoderGeometryInstancingTest : public GLES2DecoderWithShaderTest { void SetUp() override { InitState init; init.extensions = "GL_ANGLE_instanced_arrays"; - init.gl_version = "opengl es 2.0"; + // Most of the tests in this file assume they're running on + // desktop OpenGL, and large portions of the tests will become + // no-ops if they aren't. + init.gl_version = "opengl 2.1"; init.has_alpha = true; init.has_depth = true; init.request_alpha = true; diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc index 21526b1..4255ffa 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc @@ -1543,7 +1543,7 @@ class GLES2DecoderMultisampledRenderToTextureTest *gl_, RenderbufferStorageMultisampleIMG(GL_RENDERBUFFER, TestHelper::kMaxSamples, - GL_RGBA, + GL_RGBA4, TestHelper::kMaxRenderbufferSize, 1)) .Times(1) @@ -1553,7 +1553,7 @@ class GLES2DecoderMultisampledRenderToTextureTest *gl_, RenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, TestHelper::kMaxSamples, - GL_RGBA, + GL_RGBA4, TestHelper::kMaxRenderbufferSize, 1)) .Times(1) diff --git a/gpu/command_buffer/service/renderbuffer_manager.cc b/gpu/command_buffer/service/renderbuffer_manager.cc index 4b4337e..2af22de 100644 --- a/gpu/command_buffer/service/renderbuffer_manager.cc +++ b/gpu/command_buffer/service/renderbuffer_manager.cc @@ -8,6 +8,7 @@ #include "base/strings/stringprintf.h" #include "base/trace_event/trace_event.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" +#include "gpu/command_buffer/service/feature_info.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" #include "gpu/command_buffer/service/memory_tracking.h" #include "ui/gl/gl_implementation.h" @@ -43,12 +44,12 @@ RenderbufferManager::RenderbufferManager( MemoryTracker* memory_tracker, GLint max_renderbuffer_size, GLint max_samples, - bool depth24_supported) + FeatureInfo* feature_info) : memory_tracker_( new MemoryTypeTracker(memory_tracker, MemoryTracker::kUnmanaged)), max_renderbuffer_size_(max_renderbuffer_size), max_samples_(max_samples), - depth24_supported_(depth24_supported), + feature_info_(feature_info), num_uncleared_renderbuffers_(0), renderbuffer_count_(0), have_context_(true) { @@ -210,7 +211,7 @@ bool RenderbufferManager::ComputeEstimatedRenderbufferSize(int width, GLenum RenderbufferManager::InternalRenderbufferFormatToImplFormat( GLenum impl_format) const { - if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { + if (!feature_info_->gl_version_info().BehavesLikeGLES()) { switch (impl_format) { case GL_DEPTH_COMPONENT16: return GL_DEPTH_COMPONENT; @@ -222,7 +223,8 @@ GLenum RenderbufferManager::InternalRenderbufferFormatToImplFormat( } } else { // Upgrade 16-bit depth to 24-bit if possible. - if (impl_format == GL_DEPTH_COMPONENT16 && depth24_supported_) + if (impl_format == GL_DEPTH_COMPONENT16 && + feature_info_->feature_flags().oes_depth24) return GL_DEPTH_COMPONENT24; } return impl_format; diff --git a/gpu/command_buffer/service/renderbuffer_manager.h b/gpu/command_buffer/service/renderbuffer_manager.h index 71f830a..be4cc09 100644 --- a/gpu/command_buffer/service/renderbuffer_manager.h +++ b/gpu/command_buffer/service/renderbuffer_manager.h @@ -17,6 +17,7 @@ namespace gpu { namespace gles2 { +class FeatureInfo; class RenderbufferManager; // Info about a Renderbuffer. @@ -128,7 +129,7 @@ class GPU_EXPORT RenderbufferManager { RenderbufferManager(MemoryTracker* memory_tracker, GLint max_renderbuffer_size, GLint max_samples, - bool depth24_supported); + FeatureInfo* feature_info); ~RenderbufferManager(); GLint max_renderbuffer_size() const { @@ -182,7 +183,8 @@ class GPU_EXPORT RenderbufferManager { GLint max_renderbuffer_size_; GLint max_samples_; - bool depth24_supported_; + + scoped_refptr<FeatureInfo> feature_info_; int num_uncleared_renderbuffers_; diff --git a/gpu/command_buffer/service/renderbuffer_manager_unittest.cc b/gpu/command_buffer/service/renderbuffer_manager_unittest.cc index 7c625e6..7633f68 100644 --- a/gpu/command_buffer/service/renderbuffer_manager_unittest.cc +++ b/gpu/command_buffer/service/renderbuffer_manager_unittest.cc @@ -6,8 +6,10 @@ #include <set> #include "gpu/command_buffer/common/gles2_cmd_utils.h" +#include "gpu/command_buffer/service/feature_info.h" #include "gpu/command_buffer/service/gpu_service_test.h" #include "gpu/command_buffer/service/mocks.h" +#include "gpu/command_buffer/service/test_helper.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gl/gl_implementation.h" #include "ui/gl/gl_mock.h" @@ -23,10 +25,19 @@ class RenderbufferManagerTestBase : public GpuServiceTest { static const GLint kMaxSamples = 4; protected: - void SetUpBase(MemoryTracker* memory_tracker, bool depth24_supported) { + void SetUpBase(MemoryTracker* memory_tracker, + bool depth24_supported, + bool use_gles) { GpuServiceTest::SetUp(); + feature_info_ = new FeatureInfo(); + TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion( + gl_.get(), + depth24_supported ? "GL_OES_depth24" : "", + "", + use_gles ? "OpenGL ES 2.0" : "OpenGL 2.1"); + feature_info_->Initialize(); manager_.reset(new RenderbufferManager( - memory_tracker, kMaxSize, kMaxSamples, depth24_supported)); + memory_tracker, kMaxSize, kMaxSamples, feature_info_.get())); } void TearDown() override { @@ -35,6 +46,7 @@ class RenderbufferManagerTestBase : public GpuServiceTest { GpuServiceTest::TearDown(); } + scoped_refptr<FeatureInfo> feature_info_; scoped_ptr<RenderbufferManager> manager_; }; @@ -42,7 +54,8 @@ class RenderbufferManagerTest : public RenderbufferManagerTestBase { protected: void SetUp() override { bool depth24_supported = false; - SetUpBase(NULL, depth24_supported); + bool use_gles = false; + SetUpBase(NULL, depth24_supported, use_gles); } }; @@ -52,7 +65,8 @@ class RenderbufferManagerMemoryTrackerTest void SetUp() override { mock_memory_tracker_ = new StrictMock<MockMemoryTracker>(); bool depth24_supported = false; - SetUpBase(mock_memory_tracker_.get(), depth24_supported); + bool use_gles = false; + SetUpBase(mock_memory_tracker_.get(), depth24_supported, use_gles); } scoped_refptr<MockMemoryTracker> mock_memory_tracker_; @@ -291,29 +305,34 @@ TEST_F(RenderbufferManagerTest, AddToSignature) { .RetiresOnSaturation(); } -class RenderbufferManagerFormatTest : public RenderbufferManagerTestBase { +class RenderbufferManagerFormatGLESTest : public RenderbufferManagerTestBase { protected: void SetUp() override { bool depth24_supported = true; - SetUpBase(NULL, depth24_supported); + bool use_gles = true; + SetUpBase(NULL, depth24_supported, use_gles); } }; -TEST_F(RenderbufferManagerFormatTest, UpgradeDepthFormatOnGLES) { - gfx::GLImplementation prev_impl = gfx::GetGLImplementation(); - gfx::SetGLImplementation(gfx::kGLImplementationEGLGLES2); +TEST_F(RenderbufferManagerFormatGLESTest, UpgradeDepthFormatOnGLES) { GLenum impl_format = manager_->InternalRenderbufferFormatToImplFormat(GL_DEPTH_COMPONENT16); - gfx::SetGLImplementation(prev_impl); EXPECT_EQ(static_cast<GLenum>(GL_DEPTH_COMPONENT24), impl_format); } -TEST_F(RenderbufferManagerFormatTest, UseUnsizedDepthFormatOnNonGLES) { - gfx::GLImplementation prev_impl = gfx::GetGLImplementation(); - gfx::SetGLImplementation(gfx::kGLImplementationDesktopGL); +class RenderbufferManagerFormatNonGLESTest : + public RenderbufferManagerTestBase { + protected: + void SetUp() override { + bool depth24_supported = true; + bool use_gles = false; + SetUpBase(NULL, depth24_supported, use_gles); + } +}; + +TEST_F(RenderbufferManagerFormatNonGLESTest, UseUnsizedDepthFormatOnNonGLES) { GLenum impl_format = manager_->InternalRenderbufferFormatToImplFormat(GL_DEPTH_COMPONENT16); - gfx::SetGLImplementation(prev_impl); EXPECT_EQ(static_cast<GLenum>(GL_DEPTH_COMPONENT), impl_format); } diff --git a/gpu/command_buffer/service/shader_translator.cc b/gpu/command_buffer/service/shader_translator.cc index c0904c7b..b4a94fc 100644 --- a/gpu/command_buffer/service/shader_translator.cc +++ b/gpu/command_buffer/service/shader_translator.cc @@ -15,6 +15,7 @@ #include "base/strings/string_number_conversions.h" #include "base/trace_event/trace_event.h" #include "gpu/command_buffer/service/gpu_switches.h" +#include "ui/gl/gl_implementation.h" namespace gpu { namespace gles2 { @@ -120,8 +121,15 @@ bool ShaderTranslator::Init( if (glsl_implementation_type == kGlslES) { shader_output = SH_ESSL_OUTPUT; } else { - shader_output = (shader_spec == SH_WEBGL2_SPEC) ? SH_GLSL_CORE_OUTPUT : - SH_GLSL_COMPATIBILITY_OUTPUT; + // TODO(kbr): clean up the tests of shader_spec and + // gfx::GetGLImplementation(). crbug.com/471960 + if (shader_spec == SH_WEBGL2_SPEC || + gfx::GetGLImplementation() == + gfx::kGLImplementationDesktopGLCoreProfile) { + shader_output = SH_GLSL_CORE_OUTPUT; + } else { + shader_output = SH_GLSL_COMPATIBILITY_OUTPUT; + } } { diff --git a/gpu/command_buffer/service/test_helper.cc b/gpu/command_buffer/service/test_helper.cc index 096a60c..2104ddb 100644 --- a/gpu/command_buffer/service/test_helper.cc +++ b/gpu/command_buffer/service/test_helper.cc @@ -18,6 +18,7 @@ #include "gpu/command_buffer/service/texture_manager.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gl/gl_mock.h" +#include "ui/gl/gl_version_info.h" using ::testing::_; using ::testing::DoAll; @@ -80,6 +81,8 @@ const GLint TestHelper::kMaxVertexUniformVectors; const GLint TestHelper::kMaxVertexUniformComponents; #endif +std::vector<std::string> TestHelper::split_extensions_; + void TestHelper::SetupTextureInitializationExpectations( ::gfx::MockGLInterface* gl, GLenum target, @@ -270,14 +273,14 @@ void TestHelper::SetupContextGroupInitExpectations( SetupFeatureInfoInitExpectationsWithGLVersion(gl, extensions, "", gl_version); - std::string l_version(base::StringToLowerASCII(std::string(gl_version))); - bool is_es3 = (l_version.substr(0, 12) == "opengl es 3."); + gfx::GLVersionInfo gl_info(gl_version, "", extensions); EXPECT_CALL(*gl, GetIntegerv(GL_MAX_RENDERBUFFER_SIZE, _)) .WillOnce(SetArgumentPointee<1>(kMaxRenderbufferSize)) .RetiresOnSaturation(); if (strstr(extensions, "GL_EXT_framebuffer_multisample") || - strstr(extensions, "GL_EXT_multisampled_render_to_texture") || is_es3) { + strstr(extensions, "GL_EXT_multisampled_render_to_texture") || + gl_info.is_es3) { EXPECT_CALL(*gl, GetIntegerv(GL_MAX_SAMPLES, _)) .WillOnce(SetArgumentPointee<1>(kMaxSamples)) .RetiresOnSaturation(); @@ -309,15 +312,28 @@ void TestHelper::SetupContextGroupInitExpectations( EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, _)) .WillOnce(SetArgumentPointee<1>(kMaxVertexTextureImageUnits)) .RetiresOnSaturation(); - EXPECT_CALL(*gl, GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, _)) - .WillOnce(SetArgumentPointee<1>(kMaxFragmentUniformComponents)) - .RetiresOnSaturation(); - EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VARYING_FLOATS, _)) - .WillOnce(SetArgumentPointee<1>(kMaxVaryingFloats)) - .RetiresOnSaturation(); - EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, _)) - .WillOnce(SetArgumentPointee<1>(kMaxVertexUniformComponents)) - .RetiresOnSaturation(); + + if (gl_info.is_es) { + EXPECT_CALL(*gl, GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, _)) + .WillOnce(SetArgumentPointee<1>(kMaxFragmentUniformVectors)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VARYING_VECTORS, _)) + .WillOnce(SetArgumentPointee<1>(kMaxVaryingVectors)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, _)) + .WillOnce(SetArgumentPointee<1>(kMaxVertexUniformVectors)) + .RetiresOnSaturation(); + } else { + EXPECT_CALL(*gl, GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, _)) + .WillOnce(SetArgumentPointee<1>(kMaxFragmentUniformComponents)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VARYING_FLOATS, _)) + .WillOnce(SetArgumentPointee<1>(kMaxVaryingFloats)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, _)) + .WillOnce(SetArgumentPointee<1>(kMaxVertexUniformComponents)) + .RetiresOnSaturation(); + } bool use_default_textures = bind_generates_resource; SetupTextureManagerInitExpectations(gl, extensions, use_default_textures); @@ -335,21 +351,39 @@ void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion( 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*>(gl_version))) .RetiresOnSaturation(); - std::string l_version(base::StringToLowerASCII(std::string(gl_version))); - bool is_es3 = (l_version.substr(0, 12) == "opengl es 3."); + // Persistent storage is needed for the split extension string. + split_extensions_.clear(); + if (extensions) { + Tokenize(extensions, " ", &split_extensions_); + } + + gfx::GLVersionInfo gl_info(gl_version, gl_renderer, extensions); + if (!gl_info.is_es && gl_info.major_version >= 3) { + EXPECT_CALL(*gl, GetIntegerv(GL_NUM_EXTENSIONS, _)) + .WillOnce(SetArgumentPointee<1>(split_extensions_.size())) + .RetiresOnSaturation(); + for (size_t ii = 0; ii < split_extensions_.size(); ++ii) { + EXPECT_CALL(*gl, GetStringi(GL_EXTENSIONS, ii)) + .WillOnce(Return(reinterpret_cast<const uint8*>( + split_extensions_[ii].c_str()))) + .RetiresOnSaturation(); + } + } else { + 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(); if (strstr(extensions, "GL_ARB_texture_float") || - (is_es3 && strstr(extensions, "GL_EXT_color_buffer_float"))) { + (gl_info.is_es3 && strstr(extensions, "GL_EXT_color_buffer_float"))) { static const GLuint tx_ids[] = {101, 102}; static const GLuint fb_ids[] = {103, 104}; const GLsizei width = 16; @@ -390,7 +424,7 @@ void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion( GL_RGB, GL_FLOAT, _)) .Times(1) .RetiresOnSaturation(); - if (is_es3) { + if (gl_info.is_es3) { EXPECT_CALL(*gl, CheckFramebufferStatusEXT(GL_FRAMEBUFFER)) .WillOnce(Return(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)) .RetiresOnSaturation(); @@ -420,7 +454,7 @@ void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion( if (strstr(extensions, "GL_EXT_draw_buffers") || strstr(extensions, "GL_ARB_draw_buffers") || - (is_es3 && strstr(extensions, "GL_NV_draw_buffers"))) { + (gl_info.is_es3 && strstr(extensions, "GL_NV_draw_buffers"))) { EXPECT_CALL(*gl, GetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, _)) .WillOnce(SetArgumentPointee<1>(8)) .RetiresOnSaturation(); @@ -429,7 +463,7 @@ void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion( .RetiresOnSaturation(); } - if (is_es3 || strstr(extensions, "GL_EXT_texture_rg") || + if (gl_info.is_es3 || strstr(extensions, "GL_EXT_texture_rg") || (strstr(extensions, "GL_ARB_texture_rg"))) { static const GLuint tx_ids[] = {101, 102}; static const GLuint fb_ids[] = {103, 104}; diff --git a/gpu/command_buffer/service/test_helper.h b/gpu/command_buffer/service/test_helper.h index a536cce..2cf3f96 100644 --- a/gpu/command_buffer/service/test_helper.h +++ b/gpu/command_buffer/service/test_helper.h @@ -5,6 +5,9 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_TEST_HELPER_H_ #define GPU_COMMAND_BUFFER_SERVICE_TEST_HELPER_H_ +#include <string> +#include <vector> + #include "gpu/command_buffer/service/shader_translator.h" #include "ui/gl/gl_implementation.h" #include "ui/gl/gl_mock.h" @@ -140,6 +143,8 @@ class TestHelper { static void SetupTextureDestructionExpectations(::gfx::MockGLInterface* gl, GLenum target, bool use_default_textures); + + static std::vector<std::string> split_extensions_; }; // This object temporaritly Sets what gfx::GetGLImplementation returns. During |