diff options
author | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-14 19:24:13 +0000 |
---|---|---|
committer | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-14 19:24:13 +0000 |
commit | d6ca479b3b921735eb3ce3b5f747e9eb2984da63 (patch) | |
tree | 034d0fa9931702e8fee502840d1ba105d33a0a51 /gpu | |
parent | fa4f854add8a101e64f51cff962bfbb95a848d90 (diff) | |
download | chromium_src-d6ca479b3b921735eb3ce3b5f747e9eb2984da63.zip chromium_src-d6ca479b3b921735eb3ce3b5f747e9eb2984da63.tar.gz chromium_src-d6ca479b3b921735eb3ce3b5f747e9eb2984da63.tar.bz2 |
Implement GL_EXT_occlusion_query_boolean on OSX
Stupid me, I assumed GL_ARB_occlusion_query2 was available
everywhere but it's not. So, if GL_ARB_occlusion_query2 is
not available fallback to GL_ARB_occlusion_query
TEST=unit tests
BUG=126592
Review URL: https://chromiumcodereview.appspot.com/10389107
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@136936 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r-- | gpu/command_buffer/service/feature_info.cc | 10 | ||||
-rw-r--r-- | gpu/command_buffer/service/feature_info.h | 4 | ||||
-rw-r--r-- | gpu/command_buffer/service/feature_info_unittest.cc | 45 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.cc | 3 | ||||
-rw-r--r-- | gpu/command_buffer/service/query_manager.cc | 47 | ||||
-rw-r--r-- | gpu/command_buffer/service/query_manager.h | 10 | ||||
-rw-r--r-- | gpu/command_buffer/service/query_manager_unittest.cc | 61 | ||||
-rw-r--r-- | gpu/command_buffer/tests/occlusion_query_unittests.cc | 5 |
8 files changed, 158 insertions, 27 deletions
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc index fede5a6..011fecc 100644 --- a/gpu/command_buffer/service/feature_info.cc +++ b/gpu/command_buffer/service/feature_info.cc @@ -445,12 +445,18 @@ void FeatureInfo::AddFeatures(const char* desired_features) { bool have_ext_occlusion_query_boolean = ext.Have("GL_EXT_occlusion_query_boolean"); bool have_arb_occlusion_query2 = ext.Have("GL_ARB_occlusion_query2"); + bool have_arb_occlusion_query = ext.Have("GL_ARB_occlusion_query"); if (ext.Desire("GL_EXT_occlusion_query_boolean") && - (have_ext_occlusion_query_boolean || have_arb_occlusion_query2)) { + (have_ext_occlusion_query_boolean || + have_arb_occlusion_query2 || + have_arb_occlusion_query)) { AddExtensionString("GL_EXT_occlusion_query_boolean"); feature_flags_.occlusion_query_boolean = true; feature_flags_.use_arb_occlusion_query2_for_occlusion_query_boolean = - !have_ext_occlusion_query_boolean; + !have_ext_occlusion_query_boolean && have_arb_occlusion_query2; + feature_flags_.use_arb_occlusion_query_for_occlusion_query_boolean = + !have_ext_occlusion_query_boolean && have_arb_occlusion_query && + !have_arb_occlusion_query2; } if (ext.Desire("GL_ANGLE_instanced_arrays") && diff --git a/gpu/command_buffer/service/feature_info.h b/gpu/command_buffer/service/feature_info.h index 71c9b71..53b48f6 100644 --- a/gpu/command_buffer/service/feature_info.h +++ b/gpu/command_buffer/service/feature_info.h @@ -34,7 +34,8 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> { arb_texture_rectangle(false), angle_instanced_arrays(false), occlusion_query_boolean(false), - use_arb_occlusion_query2_for_occlusion_query_boolean(false) { + use_arb_occlusion_query2_for_occlusion_query_boolean(false), + use_arb_occlusion_query_for_occlusion_query_boolean(false) { } bool chromium_framebuffer_multisample; @@ -51,6 +52,7 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> { bool angle_instanced_arrays; bool occlusion_query_boolean; bool use_arb_occlusion_query2_for_occlusion_query_boolean; + bool use_arb_occlusion_query_for_occlusion_query_boolean; }; FeatureInfo(); diff --git a/gpu/command_buffer/service/feature_info_unittest.cc b/gpu/command_buffer/service/feature_info_unittest.cc index 12839e6..609ca48 100644 --- a/gpu/command_buffer/service/feature_info_unittest.cc +++ b/gpu/command_buffer/service/feature_info_unittest.cc @@ -63,6 +63,15 @@ TEST_F(FeatureInfoTest, Basic) { EXPECT_FALSE(info_->feature_flags().chromium_webglsl); EXPECT_FALSE(info_->feature_flags().oes_egl_image_external); 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); + EXPECT_FALSE(info_->feature_flags().arb_texture_rectangle); + EXPECT_FALSE(info_->feature_flags().angle_instanced_arrays); + EXPECT_FALSE(info_->feature_flags().occlusion_query_boolean); + EXPECT_FALSE(info_->feature_flags( + ).use_arb_occlusion_query2_for_occlusion_query_boolean); + EXPECT_FALSE(info_->feature_flags( + ).use_arb_occlusion_query_for_occlusion_query_boolean); } TEST_F(FeatureInfoTest, InitializeNoExtensions) { @@ -446,6 +455,42 @@ TEST_F(FeatureInfoTest, InitializeCHROMIUM_stream_texture) { EXPECT_TRUE(info_->feature_flags().chromium_stream_texture); } +TEST_F(FeatureInfoTest, InitializeEXT_occlusion_query_boolean) { + SetupInitExpectations("GL_EXT_occlusion_query_boolean"); + info_->Initialize(NULL); + EXPECT_THAT(info_->extensions(), + HasSubstr("GL_EXT_occlusion_query_boolean")); + EXPECT_TRUE(info_->feature_flags().occlusion_query_boolean); + EXPECT_FALSE(info_->feature_flags( + ).use_arb_occlusion_query2_for_occlusion_query_boolean); + EXPECT_FALSE(info_->feature_flags( + ).use_arb_occlusion_query_for_occlusion_query_boolean); +} + +TEST_F(FeatureInfoTest, InitializeARB_occlusion_query) { + SetupInitExpectations("GL_ARB_occlusion_query"); + info_->Initialize(NULL); + EXPECT_THAT(info_->extensions(), + HasSubstr("GL_EXT_occlusion_query_boolean")); + EXPECT_TRUE(info_->feature_flags().occlusion_query_boolean); + EXPECT_FALSE(info_->feature_flags( + ).use_arb_occlusion_query2_for_occlusion_query_boolean); + EXPECT_TRUE(info_->feature_flags( + ).use_arb_occlusion_query_for_occlusion_query_boolean); +} + +TEST_F(FeatureInfoTest, InitializeARB_occlusion_query2) { + SetupInitExpectations("GL_ARB_occlusion_query2 GL_ARB_occlusion_query2"); + info_->Initialize(NULL); + EXPECT_THAT(info_->extensions(), + HasSubstr("GL_EXT_occlusion_query_boolean")); + EXPECT_TRUE(info_->feature_flags().occlusion_query_boolean); + EXPECT_TRUE(info_->feature_flags( + ).use_arb_occlusion_query2_for_occlusion_query_boolean); + EXPECT_FALSE(info_->feature_flags( + ).use_arb_occlusion_query_for_occlusion_query_boolean); +} + } // namespace gles2 } // namespace gpu diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 0af984b..4b27218 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -2031,8 +2031,7 @@ bool GLES2DecoderImpl::Initialize( vertex_attrib_manager_.reset(new VertexAttribManager()); vertex_attrib_manager_->Initialize(group_->max_vertex_attribs()); - query_manager_.reset(new QueryManager(this, feature_info_->feature_flags( - ).use_arb_occlusion_query2_for_occlusion_query_boolean)); + query_manager_.reset(new QueryManager(this, feature_info_)); util_.set_num_compressed_texture_formats( validators_->compressed_texture_format.GetValues().size()); diff --git a/gpu/command_buffer/service/query_manager.cc b/gpu/command_buffer/service/query_manager.cc index c8f06a3..81ac83e 100644 --- a/gpu/command_buffer/service/query_manager.cc +++ b/gpu/command_buffer/service/query_manager.cc @@ -8,6 +8,7 @@ #include "base/time.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/service/common_decoder.h" +#include "gpu/command_buffer/service/feature_info.h" namespace gpu { namespace gles2 { @@ -66,7 +67,7 @@ bool AllSamplesPassedQuery::Process() { glGetQueryObjectuivARB( service_id_, GL_QUERY_RESULT_EXT, &result); - return MarkAsCompleted(result); + return MarkAsCompleted(result != 0); } class CommandsIssuedQuery : public QueryManager::Query { @@ -117,11 +118,17 @@ void CommandsIssuedQuery::Destroy(bool /* have_context */) { QueryManager::QueryManager( CommonDecoder* decoder, - bool use_arb_occlusion_query2_for_occlusion_query_boolean) + FeatureInfo* feature_info) : decoder_(decoder), use_arb_occlusion_query2_for_occlusion_query_boolean_( - use_arb_occlusion_query2_for_occlusion_query_boolean), + feature_info->feature_flags( + ).use_arb_occlusion_query2_for_occlusion_query_boolean), + use_arb_occlusion_query_for_occlusion_query_boolean_( + feature_info->feature_flags( + ).use_arb_occlusion_query_for_occlusion_query_boolean), query_count_(0) { + DCHECK(!(use_arb_occlusion_query_for_occlusion_query_boolean_ && + use_arb_occlusion_query2_for_occlusion_query_boolean_)); } QueryManager::~QueryManager() { @@ -187,21 +194,35 @@ void QueryManager::StopTracking(QueryManager::Query* /* query */) { --query_count_; } -void QueryManager::BeginQueryHelper(GLenum target, GLuint id) { - // ARB_occlusion_query2 does not have a GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT - // target. - if (use_arb_occlusion_query2_for_occlusion_query_boolean_) { - target = GL_ANY_SAMPLES_PASSED_EXT; +GLenum QueryManager::AdjustTargetForEmulation(GLenum target) { + switch (target) { + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: + case GL_ANY_SAMPLES_PASSED_EXT: + if (use_arb_occlusion_query2_for_occlusion_query_boolean_) { + // ARB_occlusion_query2 does not have a + // GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT + // target. + target = GL_ANY_SAMPLES_PASSED_EXT; + } else if (use_arb_occlusion_query_for_occlusion_query_boolean_) { + // ARB_occlusion_query does not have a + // GL_ANY_SAMPLES_PASSED_EXT + // target. + target = GL_SAMPLES_PASSED_ARB; + } + break; + default: + break; } + return target; +} + +void QueryManager::BeginQueryHelper(GLenum target, GLuint id) { + target = AdjustTargetForEmulation(target); glBeginQueryARB(target, id); } void QueryManager::EndQueryHelper(GLenum target) { - // ARB_occlusion_query2 does not have a GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT - // target. - if (use_arb_occlusion_query2_for_occlusion_query_boolean_) { - target = GL_ANY_SAMPLES_PASSED_EXT; - } + target = AdjustTargetForEmulation(target); glEndQueryARB(target); } diff --git a/gpu/command_buffer/service/query_manager.h b/gpu/command_buffer/service/query_manager.h index 36753e7..1560a94 100644 --- a/gpu/command_buffer/service/query_manager.h +++ b/gpu/command_buffer/service/query_manager.h @@ -11,6 +11,7 @@ #include "base/logging.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" +#include "gpu/command_buffer/service/feature_info.h" #include "gpu/command_buffer/service/gl_utils.h" #include "gpu/gpu_export.h" @@ -20,6 +21,8 @@ class CommonDecoder; namespace gles2 { +class FeatureInfo; + // This class keeps track of the queries and their state // As Queries are not shared there is one QueryManager per context. class GPU_EXPORT QueryManager { @@ -129,7 +132,7 @@ class GPU_EXPORT QueryManager { QueryManager( CommonDecoder* decoder, - bool use_arb_occlusion_query2_for_occlusion_query_boolean); + FeatureInfo* feature_info); ~QueryManager(); // Must call before destruction. @@ -175,10 +178,15 @@ class GPU_EXPORT QueryManager { // Returns false if any query is pointing to invalid shared memory. bool RemovePendingQuery(Query* query); + // Returns a target used for the underlying GL extension + // used to emulate a query. + GLenum AdjustTargetForEmulation(GLenum target); + // Used to validate shared memory. CommonDecoder* decoder_; bool use_arb_occlusion_query2_for_occlusion_query_boolean_; + bool use_arb_occlusion_query_for_occlusion_query_boolean_; // Counts the number of Queries allocated with 'this' as their manager. // Allows checking no Query will outlive this. diff --git a/gpu/command_buffer/service/query_manager_unittest.cc b/gpu/command_buffer/service/query_manager_unittest.cc index 38eea14..bd2b84f 100644 --- a/gpu/command_buffer/service/query_manager_unittest.cc +++ b/gpu/command_buffer/service/query_manager_unittest.cc @@ -7,6 +7,8 @@ #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/service/cmd_buffer_engine.h" #include "gpu/command_buffer/service/common_decoder.h" +#include "gpu/command_buffer/service/feature_info.h" +#include "gpu/command_buffer/service/test_helper.h" #include "testing/gtest/include/gtest/gtest.h" using ::testing::_; @@ -48,7 +50,12 @@ class QueryManagerTest : public testing::Test { engine_.reset(new MockCommandBufferEngine()); decoder_.reset(new MockDecoder()); decoder_->set_engine(engine_.get()); - manager_.reset(new QueryManager(decoder_.get(), false)); + TestHelper::SetupFeatureInfoInitExpectations( + gl_.get(), + "GL_EXT_occlusion_query_boolean"); + FeatureInfo::Ref feature_info(new FeatureInfo()); + feature_info->Initialize("*"); + manager_.reset(new QueryManager(decoder_.get(), feature_info.get())); } virtual void TearDown() { @@ -215,7 +222,7 @@ TEST_F(QueryManagerTest, ProcessPendingQuery) { const GLuint kService1Id = 11; const GLenum kTarget = GL_ANY_SAMPLES_PASSED_EXT; const uint32 kSubmitCount = 123; - const GLuint kResult = 456; + const GLuint kResult = 1; // Check nothing happens if there are no pending queries. EXPECT_TRUE(manager_->ProcessPendingQueries()); @@ -280,9 +287,9 @@ TEST_F(QueryManagerTest, ProcessPendingQueries) { const uint32 kSubmitCount1 = 123; const uint32 kSubmitCount2 = 123; const uint32 kSubmitCount3 = 123; - const GLuint kResult1 = 456; - const GLuint kResult2 = 457; - const GLuint kResult3 = 458; + const GLuint kResult1 = 1; + const GLuint kResult2 = 1; + const GLuint kResult3 = 1; // Setup shared memory like client would. QuerySync* sync1 = decoder_->GetSharedMemoryAs<QuerySync*>( @@ -393,7 +400,7 @@ TEST_F(QueryManagerTest, ProcessPendingBadSharedMemoryId) { const GLuint kService1Id = 11; const GLenum kTarget = GL_ANY_SAMPLES_PASSED_EXT; const uint32 kSubmitCount = 123; - const GLuint kResult = 456; + const GLuint kResult = 1; // Create Query. QueryManager::Query::Ref query( @@ -422,7 +429,7 @@ TEST_F(QueryManagerTest, ProcessPendingBadSharedMemoryOffset) { const GLuint kService1Id = 11; const GLenum kTarget = GL_ANY_SAMPLES_PASSED_EXT; const uint32 kSubmitCount = 123; - const GLuint kResult = 456; + const GLuint kResult = 1; // Create Query. QueryManager::Query::Ref query( @@ -468,7 +475,13 @@ TEST_F(QueryManagerTest, ARBOcclusionQuery2) { const GLenum kTarget = GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT; const uint32 kSubmitCount = 123; - scoped_ptr<QueryManager> manager(new QueryManager(decoder_.get(), true)); + TestHelper::SetupFeatureInfoInitExpectations( + gl_.get(), + "GL_ARB_occlusion_query2"); + FeatureInfo::Ref feature_info(new FeatureInfo()); + feature_info->Initialize("*"); + scoped_ptr<QueryManager> manager( + new QueryManager(decoder_.get(), feature_info.get())); EXPECT_CALL(*gl_, GenQueriesARB(1, _)) .WillOnce(SetArgumentPointee<1>(kService1Id)) @@ -488,6 +501,38 @@ TEST_F(QueryManagerTest, ARBOcclusionQuery2) { manager->Destroy(false); } +TEST_F(QueryManagerTest, ARBOcclusionQuery) { + const GLuint kClient1Id = 1; + const GLuint kService1Id = 11; + const GLenum kTarget = GL_ANY_SAMPLES_PASSED_EXT; + const uint32 kSubmitCount = 123; + + TestHelper::SetupFeatureInfoInitExpectations( + gl_.get(), + "GL_ARB_occlusion_query"); + FeatureInfo::Ref feature_info(new FeatureInfo()); + feature_info->Initialize("*"); + scoped_ptr<QueryManager> manager( + new QueryManager(decoder_.get(), feature_info.get())); + + EXPECT_CALL(*gl_, GenQueriesARB(1, _)) + .WillOnce(SetArgumentPointee<1>(kService1Id)) + .RetiresOnSaturation(); + QueryManager::Query* query = manager->CreateQuery( + kTarget, kClient1Id, kSharedMemoryId, kSharedMemoryOffset); + ASSERT_TRUE(query != NULL); + + EXPECT_CALL(*gl_, BeginQueryARB(GL_SAMPLES_PASSED_ARB, kService1Id)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, EndQueryARB(GL_SAMPLES_PASSED_ARB)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_TRUE(manager->BeginQuery(query)); + EXPECT_TRUE(manager->EndQuery(query, kSubmitCount)); + manager->Destroy(false); +} + } // namespace gles2 } // namespace gpu diff --git a/gpu/command_buffer/tests/occlusion_query_unittests.cc b/gpu/command_buffer/tests/occlusion_query_unittests.cc index ddf1db9..29ab481 100644 --- a/gpu/command_buffer/tests/occlusion_query_unittests.cc +++ b/gpu/command_buffer/tests/occlusion_query_unittests.cc @@ -66,6 +66,11 @@ void OcclusionQueryTest::DrawRect(float x, float z, float scale, float* color) { } TEST_F(OcclusionQueryTest, Occlusion) { +#ifdef OS_MACOSX + EXPECT_TRUE(GLTestHelper::HasExtension("GL_EXT_occlusion_query_boolean")) + << "GL_EXT_occlusion_query_boolean is required on OSX"; +#endif + if (!GLTestHelper::HasExtension("GL_EXT_occlusion_query_boolean")) { return; } |