summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorgman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-14 19:24:13 +0000
committergman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-14 19:24:13 +0000
commitd6ca479b3b921735eb3ce3b5f747e9eb2984da63 (patch)
tree034d0fa9931702e8fee502840d1ba105d33a0a51 /gpu
parentfa4f854add8a101e64f51cff962bfbb95a848d90 (diff)
downloadchromium_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.cc10
-rw-r--r--gpu/command_buffer/service/feature_info.h4
-rw-r--r--gpu/command_buffer/service/feature_info_unittest.cc45
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc3
-rw-r--r--gpu/command_buffer/service/query_manager.cc47
-rw-r--r--gpu/command_buffer/service/query_manager.h10
-rw-r--r--gpu/command_buffer/service/query_manager_unittest.cc61
-rw-r--r--gpu/command_buffer/tests/occlusion_query_unittests.cc5
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;
}