summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xgpu/command_buffer/build_gles2_cmd_buffer.py6
-rw-r--r--gpu/command_buffer/client/gles2_implementation_autogen.h6
-rw-r--r--gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h1
-rw-r--r--gpu/command_buffer/service/feature_info.cc12
-rw-r--r--gpu/command_buffer/service/feature_info.h4
-rw-r--r--gpu/command_buffer/service/gl_utils.h4
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc85
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc133
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc18
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h96
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h184
-rw-r--r--gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h1
-rw-r--r--gpu/command_buffer/service/query_manager.cc261
-rw-r--r--gpu/command_buffer/service/query_manager.h115
-rw-r--r--gpu/command_buffer/service/query_manager_unittest.cc165
-rw-r--r--third_party/khronos/GLES2/gl2ext.h9
-rw-r--r--third_party/khronos/README.chromium1
17 files changed, 659 insertions, 442 deletions
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index fbaa67d..59bbde3 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -451,6 +451,7 @@ _ENUM_LISTS = {
'valid': [
'GL_ANY_SAMPLES_PASSED_EXT',
'GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT',
+ 'GL_COMMANDS_ISSUED_CHROMIUM',
],
},
'RenderBufferParameter': {
@@ -795,6 +796,7 @@ _PEPPER_INTERFACES = [
# valid_args: A dictionary of argument indices to args to use in unit tests
# when they can not be automatically determined.
# pepper_interface: The pepper interface that is used for this extension
+# invalid_test: False if no invalid test needed.
_FUNCTION_INFO = {
'ActiveTexture': {
@@ -1594,12 +1596,14 @@ _FUNCTION_INFO = {
'gl_test_func': 'glGenQueriesARB',
'resource_type': 'Query',
'resource_types': 'Queries',
+ 'unit_test': False,
},
'DeleteQueriesEXT': {
'type': 'DELn',
'gl_test_func': 'glDeleteQueriesARB',
'resource_type': 'Query',
'resource_types': 'Queries',
+ 'unit_test': False,
},
'IsQueryEXT': {
'gen_cmd': False,
@@ -2797,7 +2801,7 @@ TEST_F(%(test_name)s, %(name)sValidArgs) {
EXPECT_TRUE(Get%(resource_name)sInfo(kNewClientId) != NULL);
}
"""
- self.WriteValidUnitTest(func, file, valid_test, {
+ self.WriteValidUnitTest(func, file, valid_test, {
'resource_name': func.GetInfo('resource_type'),
})
invalid_test = """
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h
index 6ec6e14..495a913 100644
--- a/gpu/command_buffer/client/gles2_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -1410,8 +1410,7 @@ void TexStorage2DEXT(
}
void GenQueriesEXT(GLsizei n, GLuint* queries) {
- GPU_CLIENT_LOG("[" << this << "] glGenQueriesEXT(" << n << ", "
- << static_cast<const void*>(queries) << ")"); // NOLINT
+ GPU_CLIENT_LOG("[" << this << "] glGenQueriesEXT(" << n << ", " << static_cast<const void*>(queries) << ")"); // NOLINT
if (n < 0) {
SetGLError(GL_INVALID_VALUE, "glGenQueriesEXT: n < 0");
return;
@@ -1429,8 +1428,7 @@ void GenQueriesEXT(GLsizei n, GLuint* queries) {
void DeleteQueriesEXT(GLsizei n, const GLuint* queries) {
GPU_CLIENT_SINGLE_THREAD_CHECK();
- GPU_CLIENT_LOG("[" << this << "] glDeleteQueriesEXT(" << n << ", "
- << static_cast<const void*>(queries) << ")"); // NOLINT
+ GPU_CLIENT_LOG("[" << this << "] glDeleteQueriesEXT(" << n << ", " << static_cast<const void*>(queries) << ")"); // NOLINT
GPU_CLIENT_LOG_CODE_BLOCK({
for (GLsizei i = 0; i < n; ++i) {
GPU_CLIENT_LOG(" " << i << ": " << queries[i]);
diff --git a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
index 26e7bf8..2d725d0 100644
--- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
@@ -941,6 +941,7 @@ std::string GLES2Util::GetStringQueryTarget(uint32 value) {
{ GL_ANY_SAMPLES_PASSED_EXT, "GL_ANY_SAMPLES_PASSED_EXT" },
{ GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
"GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT" },
+ { GL_COMMANDS_ISSUED_CHROMIUM, "GL_COMMANDS_ISSUED_CHROMIUM" },
};
return GLES2Util::GetQualifiedEnumString(
string_table, arraysize(string_table), value);
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc
index b31a5e5..9b83aca 100644
--- a/gpu/command_buffer/service/feature_info.cc
+++ b/gpu/command_buffer/service/feature_info.cc
@@ -118,6 +118,7 @@ void FeatureInfo::AddFeatures(const char* desired_features) {
AddExtensionString("GL_CHROMIUM_rate_limit_offscreen_context");
AddExtensionString("GL_CHROMIUM_set_visibility");
AddExtensionString("GL_CHROMIUM_gpu_memory_manager");
+ AddExtensionString("GL_CHROMIUM_command_buffer_query");
AddExtensionString("GL_ANGLE_translated_shader_source");
if (ext.Have("GL_ANGLE_translated_shader_source")) {
@@ -439,12 +440,15 @@ 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");
if (ext.Desire("GL_EXT_occlusion_query_boolean") &&
- (ext.Have("GL_EXT_occlusion_query_boolean") ||
- ext.Have("GL_ARB_occlusion_query2"))) {
- // TODO(gman): Comment in the next line once this really works.
- // AddExtensionString("GL_EXT_occlusion_query_boolean");
+ (have_ext_occlusion_query_boolean || have_arb_occlusion_query2)) {
+ 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;
}
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 4bac947..71c9b71 100644
--- a/gpu/command_buffer/service/feature_info.h
+++ b/gpu/command_buffer/service/feature_info.h
@@ -33,7 +33,8 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> {
angle_pack_reverse_row_order(false),
arb_texture_rectangle(false),
angle_instanced_arrays(false),
- occlusion_query_boolean(false) {
+ occlusion_query_boolean(false),
+ use_arb_occlusion_query2_for_occlusion_query_boolean(false) {
}
bool chromium_framebuffer_multisample;
@@ -49,6 +50,7 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> {
bool arb_texture_rectangle;
bool angle_instanced_arrays;
bool occlusion_query_boolean;
+ bool use_arb_occlusion_query2_for_occlusion_query_boolean;
};
FeatureInfo();
diff --git a/gpu/command_buffer/service/gl_utils.h b/gpu/command_buffer/service/gl_utils.h
index ce65cb2..64495b3 100644
--- a/gpu/command_buffer/service/gl_utils.h
+++ b/gpu/command_buffer/service/gl_utils.h
@@ -76,6 +76,10 @@
#define GL_QUERY_RESULT_EXT 0x8866
#define GL_QUERY_RESULT_AVAILABLE_EXT 0x8867
+// GL_CHROMIUM_command_buffer_query
+#define GL_COMMANDS_ISSUED_CHROMIUM 0x84F2
+
+
#define GL_GLEXT_PROTOTYPES 1
// Define this for extra GL error debugging (slower).
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 2f4c1e6..3811ac8 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -2023,7 +2023,8 @@ bool GLES2DecoderImpl::Initialize(
vertex_attrib_manager_.reset(new VertexAttribManager());
vertex_attrib_manager_->Initialize(group_->max_vertex_attribs());
- query_manager_.reset(new QueryManager());
+ query_manager_.reset(new QueryManager(this, feature_info_->feature_flags(
+ ).use_arb_occlusion_query2_for_occlusion_query_boolean));
util_.set_num_compressed_texture_formats(
validators_->compressed_texture_format.GetValues().size());
@@ -7931,11 +7932,7 @@ bool GLES2DecoderImpl::GenQueriesEXTHelper(
return false;
}
}
- scoped_array<GLuint> service_ids(new GLuint[n]);
- glGenQueriesARB(n, service_ids.get());
- for (GLsizei ii = 0; ii < n; ++ii) {
- query_manager_->CreateQuery(client_ids[ii], service_ids[ii]);
- }
+ // NOTE: We don't generate Query objects here. Only in BeginQueryEXT
return true;
}
@@ -7947,8 +7944,7 @@ void GLES2DecoderImpl::DeleteQueriesEXTHelper(
if (query == current_query_) {
current_query_ = NULL;
}
- GLuint service_id = query->service_id();
- glDeleteQueriesARB(1, &service_id);
+ query->Destroy(true);
query_manager_->RemoveQuery(client_ids[ii]);
}
}
@@ -7958,7 +7954,7 @@ bool GLES2DecoderImpl::ProcessPendingQueries() {
if (query_manager_.get() == NULL) {
return false;
}
- if (!query_manager_->ProcessPendingQueries(this)) {
+ if (!query_manager_->ProcessPendingQueries()) {
current_decoder_error_ = error::kOutOfBounds;
}
return query_manager_->HavePendingQueries();
@@ -7971,9 +7967,15 @@ error::Error GLES2DecoderImpl::HandleBeginQueryEXT(
int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
- if (!feature_info_->feature_flags().occlusion_query_boolean) {
- SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT: not enabled");
- return error::kNoError;
+ switch (target) {
+ case GL_COMMANDS_ISSUED_CHROMIUM:
+ break;
+ default:
+ if (!feature_info_->feature_flags().occlusion_query_boolean) {
+ SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT: not enabled");
+ return error::kNoError;
+ }
+ break;
}
if (current_query_) {
@@ -7989,31 +7991,28 @@ error::Error GLES2DecoderImpl::HandleBeginQueryEXT(
QueryManager::Query* query = query_manager_->GetQuery(client_id);
if (!query) {
+ // TODO(gman): Decide if we need this check.
+ //
// Checks id was made by glGenQueries
- IdAllocatorInterface* id_allocator =
- group_->GetIdAllocator(id_namespaces::kQueries);
- if (!id_allocator->InUse(client_id)) {
- SetGLError(GL_INVALID_OPERATION,
- "glBeginQueryEXT: id not made by glGenQueriesEXT");
- return error::kNoError;
- }
- // Makes object and assoicates with memory.
- GLuint service_id = 0;
- glGenQueriesARB(1, &service_id);
- DCHECK_NE(0u, service_id);
- query = query_manager_->CreateQuery(client_id, service_id);
- }
-
- QuerySync* sync = GetSharedMemoryAs<QuerySync*>(
- sync_shm_id, sync_shm_offset, sizeof(*sync));
- if (!sync) {
- DLOG(ERROR) << "Invalid shared memory referenced by query";
- return error::kOutOfBounds;
- }
-
- if (!query->IsInitialized()) {
- query->Initialize(target, sync_shm_id, sync_shm_offset);
- } else if (query->target() != target) {
+ //
+ // From the POV of OpenGL ES 2.0 you need to call glGenQueriesEXT
+ // for all Query ids but from the POV of the command buffer service maybe
+ // you don't.
+ //
+ // The client can enforce this. I don't think the service cares.
+ //
+ // IdAllocatorInterface* id_allocator =
+ // group_->GetIdAllocator(id_namespaces::kQueries);
+ // if (!id_allocator->InUse(client_id)) {
+ // SetGLError(GL_INVALID_OPERATION,
+ // "glBeginQueryEXT: id not made by glGenQueriesEXT");
+ // return error::kNoError;
+ // }
+ query = query_manager_->CreateQuery(
+ target, client_id, sync_shm_id, sync_shm_offset);
+ }
+
+ if (query->target() != target) {
SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT: target does not match");
return error::kNoError;
} else if (query->shm_id() != sync_shm_id ||
@@ -8022,11 +8021,11 @@ error::Error GLES2DecoderImpl::HandleBeginQueryEXT(
return error::kInvalidArguments;
}
- query_manager_->RemovePendingQuery(query);
+ if (!query_manager_->BeginQuery(query)) {
+ return error::kOutOfBounds;
+ }
- glBeginQueryARB(target, query->service_id());
current_query_ = query;
-
return error::kNoError;
}
@@ -8044,10 +8043,12 @@ error::Error GLES2DecoderImpl::HandleEndQueryEXT(
"glEndQueryEXT: target does not match active query");
return error::kNoError;
}
- glEndQueryARB(target);
- query_manager_->AddPendingQuery(current_query_, submit_count);
- current_query_ = NULL;
+ if (!query_manager_->EndQuery(current_query_, submit_count)) {
+ return error::kOutOfBounds;
+ }
+
+ current_query_ = NULL;
return error::kNoError;
}
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
index 94f2e95..ca1d5c6 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
@@ -6583,13 +6583,7 @@ TEST_F(GLES2DecoderManualInitTest, BeingEndQueryEXT) {
EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
- // Test a non-generated id fails.
BeginQueryEXT begin_cmd;
- begin_cmd.Init(
- GL_ANY_SAMPLES_PASSED_EXT, kInvalidClientId,
- kSharedMemoryId, kSharedMemoryOffset);
- EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
- EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
// Test id = 0 fails.
begin_cmd.Init(
@@ -6597,22 +6591,12 @@ TEST_F(GLES2DecoderManualInitTest, BeingEndQueryEXT) {
EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
- EXPECT_CALL(*gl_, GenQueriesARB(1, _))
- .WillOnce(SetArgumentPointee<1>(kNewServiceId))
- .RetiresOnSaturation();
GenHelper<GenQueriesEXTImmediate>(kNewClientId);
- // Test bad shared memory fails
- begin_cmd.Init(
- GL_ANY_SAMPLES_PASSED_EXT, kNewClientId,
- kInvalidSharedMemoryId, kSharedMemoryOffset);
- EXPECT_NE(error::kNoError, ExecuteCmd(begin_cmd));
- begin_cmd.Init(
- GL_ANY_SAMPLES_PASSED_EXT, kNewClientId,
- kSharedMemoryId, kInvalidSharedMemoryOffset);
- EXPECT_NE(error::kNoError, ExecuteCmd(begin_cmd));
-
// Test valid parameters work.
+ EXPECT_CALL(*gl_, GenQueriesARB(1, _))
+ .WillOnce(SetArgumentPointee<1>(kNewServiceId))
+ .RetiresOnSaturation();
EXPECT_CALL(*gl_, BeginQueryARB(GL_ANY_SAMPLES_PASSED_EXT, kNewServiceId))
.Times(1)
.RetiresOnSaturation();
@@ -6651,6 +6635,117 @@ TEST_F(GLES2DecoderManualInitTest, BeingEndQueryEXT) {
.RetiresOnSaturation();
}
+static void CheckBeginEndQueryBadMemoryFails(
+ GLES2DecoderTestBase* test,
+ GLuint client_id,
+ GLuint service_id,
+ int32 shm_id,
+ uint32 shm_offset) {
+ ::testing::StrictMock< ::gfx::MockGLInterface>* gl = test->GetGLMock();
+
+ BeginQueryEXT begin_cmd;
+
+ test->GenHelper<GenQueriesEXTImmediate>(client_id);
+
+ EXPECT_CALL(*gl, GenQueriesARB(1, _))
+ .WillOnce(SetArgumentPointee<1>(service_id))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl, BeginQueryARB(GL_ANY_SAMPLES_PASSED_EXT, service_id))
+ .Times(1)
+ .RetiresOnSaturation();
+
+ // Test bad shared memory fails
+ begin_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, client_id, shm_id, shm_offset);
+ error::Error error1 = test->ExecuteCmd(begin_cmd);
+
+ EXPECT_CALL(*gl, EndQueryARB(GL_ANY_SAMPLES_PASSED_EXT))
+ .Times(1)
+ .RetiresOnSaturation();
+
+ EndQueryEXT end_cmd;
+ end_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, 1);
+ error::Error error2 = test->ExecuteCmd(end_cmd);
+
+ EXPECT_CALL(*gl,
+ GetQueryObjectuivARB(service_id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
+ .WillOnce(SetArgumentPointee<2>(1))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl,
+ GetQueryObjectuivARB(service_id, GL_QUERY_RESULT_EXT, _))
+ .WillOnce(SetArgumentPointee<2>(1))
+ .RetiresOnSaturation();
+
+ QueryManager* query_manager = test->GetDecoder()->GetQueryManager();
+ ASSERT_TRUE(query_manager != NULL);
+ bool process_success = query_manager->ProcessPendingQueries();
+
+ EXPECT_TRUE(error1 != error::kNoError ||
+ error2 != error::kNoError ||
+ !process_success);
+
+ EXPECT_CALL(*gl, DeleteQueriesARB(1, _))
+ .Times(1)
+ .RetiresOnSaturation();
+}
+
+TEST_F(GLES2DecoderManualInitTest, BeingEndQueryEXTBadMemoryIdFails) {
+ InitDecoder(
+ "GL_EXT_occlusion_query_boolean", // extensions
+ true, // has alpha
+ false, // has depth
+ false, // has stencil
+ true, // request alpha
+ false, // request depth
+ false, // request stencil
+ true); // bind generates resource
+
+ CheckBeginEndQueryBadMemoryFails(
+ this, kNewClientId, kNewServiceId,
+ kInvalidSharedMemoryId, kSharedMemoryOffset);
+}
+
+TEST_F(GLES2DecoderManualInitTest, BeingEndQueryEXTBadMemoryOffsetFails) {
+ InitDecoder(
+ "GL_EXT_occlusion_query_boolean", // extensions
+ true, // has alpha
+ false, // has depth
+ false, // has stencil
+ true, // request alpha
+ false, // request depth
+ false, // request stencil
+ true); // bind generates resource
+
+ CheckBeginEndQueryBadMemoryFails(
+ this, kNewClientId, kNewServiceId,
+ kSharedMemoryId, kInvalidSharedMemoryOffset);
+}
+
+TEST_F(GLES2DecoderTest, BeingEndQueryEXTCommandsIssuedCHROMIUM) {
+ BeginQueryEXT begin_cmd;
+
+ GenHelper<GenQueriesEXTImmediate>(kNewClientId);
+
+ // Test valid parameters work.
+ begin_cmd.Init(
+ GL_COMMANDS_ISSUED_CHROMIUM, kNewClientId,
+ kSharedMemoryId, kSharedMemoryOffset);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+ QueryManager* query_manager = decoder_->GetQueryManager();
+ ASSERT_TRUE(query_manager != NULL);
+ QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
+ ASSERT_TRUE(query != NULL);
+ EXPECT_FALSE(query->pending());
+
+ // Test end succeeds
+ EndQueryEXT end_cmd;
+ end_cmd.Init(GL_COMMANDS_ISSUED_CHROMIUM, 1);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ EXPECT_FALSE(query->pending());
+}
+
// TODO(gman): Complete this test.
// TEST_F(GLES2DecoderTest, CompressedTexImage2DGLError) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc
index f92a0f6..d9adbfb 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc
@@ -39,17 +39,10 @@ void GLES2DecoderTestBase::SpecializedSetup<GenQueriesEXT, 0>(
// Make the client_query_id_ so that trying to make it again
// will fail.
GetSharedMemoryAs<GLuint*>()[0] = client_query_id_;
- EXPECT_CALL(*gl_, GenQueriesARB(1, _))
- .WillOnce(SetArgumentPointee<1>(kNewServiceId));
GenQueriesEXT cmd;
cmd.Init(1, shared_memory_id_, shared_memory_offset_);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
}
- // In the valid case this deletes the one created in the test. In the invalid
- // case it deleted the one above.
- EXPECT_CALL(*gl_, DeleteQueriesARB(1, _))
- .Times(1)
- .RetiresOnSaturation();
};
template <>
@@ -59,17 +52,10 @@ void GLES2DecoderTestBase::SpecializedSetup<GenQueriesEXTImmediate, 0>(
// Make the client_query_id_ so that trying to make it again
// will fail.
GetSharedMemoryAs<GLuint*>()[0] = client_query_id_;
- EXPECT_CALL(*gl_, GenQueriesARB(1, _))
- .WillOnce(SetArgumentPointee<1>(kNewServiceId));
GenQueriesEXT cmd;
cmd.Init(1, shared_memory_id_, shared_memory_offset_);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
}
- // In the valid case this deletes the one created in the test. In the invalid
- // case it deleted the one above.
- EXPECT_CALL(*gl_, DeleteQueriesARB(1, _))
- .Times(1)
- .RetiresOnSaturation();
};
template <>
@@ -78,8 +64,6 @@ void GLES2DecoderTestBase::SpecializedSetup<DeleteQueriesEXT, 0>(
if (valid) {
// Make the client_query_id_ so that trying to delete it will succeed.
GetSharedMemoryAs<GLuint*>()[0] = client_query_id_;
- EXPECT_CALL(*gl_, GenQueriesARB(1, _))
- .WillOnce(SetArgumentPointee<1>(kServiceQueryId));
GenQueriesEXT cmd;
cmd.Init(1, shared_memory_id_, shared_memory_offset_);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
@@ -92,8 +76,6 @@ void GLES2DecoderTestBase::SpecializedSetup<DeleteQueriesEXTImmediate, 0>(
if (valid) {
// Make the client_query_id_ so that trying to delete it will succeed.
GetSharedMemoryAs<GLuint*>()[0] = client_query_id_;
- EXPECT_CALL(*gl_, GenQueriesARB(1, _))
- .WillOnce(SetArgumentPointee<1>(kServiceQueryId));
GenQueriesEXT cmd;
cmd.Init(1, shared_memory_id_, shared_memory_offset_);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h
index ea1be28..6a62607 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h
@@ -1806,98 +1806,10 @@ TEST_F(GLES2DecoderTest2, ViewportInvalidArgs3_0) {
// TODO(gman): BlitFramebufferEXT
// TODO(gman): RenderbufferStorageMultisampleEXT
// TODO(gman): TexStorage2DEXT
-
-TEST_F(GLES2DecoderTest2, GenQueriesEXTValidArgs) {
- EXPECT_CALL(*gl_, GenQueriesARB(1, _))
- .WillOnce(SetArgumentPointee<1>(kNewServiceId));
- GetSharedMemoryAs<GLuint*>()[0] = kNewClientId;
- SpecializedSetup<GenQueriesEXT, 0>(true);
- GenQueriesEXT cmd;
- cmd.Init(1, shared_memory_id_, shared_memory_offset_);
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(GL_NO_ERROR, GetGLError());
- EXPECT_TRUE(GetQueryInfo(kNewClientId) != NULL);
-}
-
-TEST_F(GLES2DecoderTest2, GenQueriesEXTInvalidArgs) {
- EXPECT_CALL(*gl_, GenQueriesARB(_, _)).Times(0);
- GetSharedMemoryAs<GLuint*>()[0] = client_query_id_;
- SpecializedSetup<GenQueriesEXT, 0>(false);
- GenQueriesEXT cmd;
- cmd.Init(1, shared_memory_id_, shared_memory_offset_);
- EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderTest2, GenQueriesEXTImmediateValidArgs) {
- EXPECT_CALL(*gl_, GenQueriesARB(1, _))
- .WillOnce(SetArgumentPointee<1>(kNewServiceId));
- GenQueriesEXTImmediate* cmd = GetImmediateAs<GenQueriesEXTImmediate>();
- GLuint temp = kNewClientId;
- SpecializedSetup<GenQueriesEXTImmediate, 0>(true);
- cmd->Init(1, &temp);
- EXPECT_EQ(error::kNoError,
- ExecuteImmediateCmd(*cmd, sizeof(temp)));
- EXPECT_EQ(GL_NO_ERROR, GetGLError());
- EXPECT_TRUE(GetQueryInfo(kNewClientId) != NULL);
-}
-
-TEST_F(GLES2DecoderTest2, GenQueriesEXTImmediateInvalidArgs) {
- EXPECT_CALL(*gl_, GenQueriesARB(_, _)).Times(0);
- GenQueriesEXTImmediate* cmd = GetImmediateAs<GenQueriesEXTImmediate>();
- SpecializedSetup<GenQueriesEXTImmediate, 0>(false);
- cmd->Init(1, &client_query_id_);
- EXPECT_EQ(error::kInvalidArguments,
- ExecuteImmediateCmd(*cmd, sizeof(&client_query_id_)));
-}
-
-TEST_F(GLES2DecoderTest2, DeleteQueriesEXTValidArgs) {
- EXPECT_CALL(
- *gl_,
- DeleteQueriesARB(1, Pointee(kServiceQueryId)))
- .Times(1);
- GetSharedMemoryAs<GLuint*>()[0] = client_query_id_;
- SpecializedSetup<DeleteQueriesEXT, 0>(true);
- DeleteQueriesEXT cmd;
- cmd.Init(1, shared_memory_id_, shared_memory_offset_);
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(GL_NO_ERROR, GetGLError());
- EXPECT_TRUE(
- GetQueryInfo(client_query_id_) == NULL);
-}
-
-TEST_F(GLES2DecoderTest2, DeleteQueriesEXTInvalidArgs) {
- GetSharedMemoryAs<GLuint*>()[0] = kInvalidClientId;
- SpecializedSetup<DeleteQueriesEXT, 0>(false);
- DeleteQueriesEXT cmd;
- cmd.Init(1, shared_memory_id_, shared_memory_offset_);
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderTest2, DeleteQueriesEXTImmediateValidArgs) {
- EXPECT_CALL(
- *gl_,
- DeleteQueriesARB(1, Pointee(kServiceQueryId)))
- .Times(1);
- DeleteQueriesEXTImmediate& cmd =
- *GetImmediateAs<DeleteQueriesEXTImmediate>();
- SpecializedSetup<DeleteQueriesEXTImmediate, 0>(true);
- cmd.Init(1, &client_query_id_);
- EXPECT_EQ(error::kNoError,
- ExecuteImmediateCmd(cmd, sizeof(client_query_id_)));
- EXPECT_EQ(GL_NO_ERROR, GetGLError());
- EXPECT_TRUE(
- GetQueryInfo(client_query_id_) == NULL);
-}
-
-TEST_F(GLES2DecoderTest2, DeleteQueriesEXTImmediateInvalidArgs) {
- DeleteQueriesEXTImmediate& cmd =
- *GetImmediateAs<DeleteQueriesEXTImmediate>();
- SpecializedSetup<DeleteQueriesEXTImmediate, 0>(false);
- GLuint temp = kInvalidClientId;
- cmd.Init(1, &temp);
- EXPECT_EQ(error::kNoError,
- ExecuteImmediateCmd(cmd, sizeof(temp)));
-}
+// TODO(gman): GenQueriesEXT
+// TODO(gman): GenQueriesEXTImmediate
+// TODO(gman): DeleteQueriesEXT
+// TODO(gman): DeleteQueriesEXTImmediate
// TODO(gman): BeginQueryEXT
// TODO(gman): EndQueryEXT
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
index 7dcdddb..c73fb0a 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
@@ -30,94 +30,6 @@ class GLES2DecoderTestBase : public testing::Test {
GLES2DecoderTestBase();
virtual ~GLES2DecoderTestBase();
- protected:
- static const GLint kMaxTextureSize = 2048;
- static const GLint kMaxCubeMapTextureSize = 256;
- static const GLint kNumVertexAttribs = 16;
- static const GLint kNumTextureUnits = 8;
- static const GLint kMaxTextureImageUnits = 8;
- static const GLint kMaxVertexTextureImageUnits = 2;
- static const GLint kMaxFragmentUniformVectors = 16;
- static const GLint kMaxVaryingVectors = 8;
- static const GLint kMaxVertexUniformVectors = 128;
-
- static const GLuint kServiceAttrib0BufferId = 801;
- static const GLuint kServiceFixedAttribBufferId = 802;
-
- static const GLuint kServiceBufferId = 301;
- static const GLuint kServiceFramebufferId = 302;
- static const GLuint kServiceRenderbufferId = 303;
- static const GLuint kServiceTextureId = 304;
- static const GLuint kServiceProgramId = 305;
- static const GLuint kServiceShaderId = 306;
- static const GLuint kServiceElementBufferId = 308;
- static const GLuint kServiceQueryId = 309;
-
- static const int32 kSharedMemoryId = 401;
- static const size_t kSharedBufferSize = 2048;
- static const uint32 kSharedMemoryOffset = 132;
- static const int32 kInvalidSharedMemoryId = 402;
- static const uint32 kInvalidSharedMemoryOffset = kSharedBufferSize + 1;
- static const uint32 kInitialResult = 0xBDBDBDBDu;
- static const uint8 kInitialMemoryValue = 0xBDu;
-
- static const uint32 kNewClientId = 501;
- static const uint32 kNewServiceId = 502;
- static const uint32 kInvalidClientId = 601;
-
- static const int kBackBufferWidth = 128;
- static const int kBackBufferHeight = 64;
-
- static const GLuint kServiceVertexShaderId = 321;
- static const GLuint kServiceFragmentShaderId = 322;
-
- static const GLsizei kNumVertices = 100;
- static const GLsizei kNumIndices = 10;
- static const int kValidIndexRangeStart = 1;
- static const int kValidIndexRangeCount = 7;
- static const int kInvalidIndexRangeStart = 0;
- static const int kInvalidIndexRangeCount = 7;
- static const int kOutOfRangeIndexRangeEnd = 10;
- static const GLuint kMaxValidIndex = 7;
-
- static const GLint kMaxAttribLength = 10;
- static const char* kAttrib1Name;
- static const char* kAttrib2Name;
- static const char* kAttrib3Name;
- static const GLint kAttrib1Size = 1;
- static const GLint kAttrib2Size = 1;
- static const GLint kAttrib3Size = 1;
- static const GLint kAttrib1Location = 0;
- static const GLint kAttrib2Location = 1;
- static const GLint kAttrib3Location = 2;
- static const GLenum kAttrib1Type = GL_FLOAT_VEC4;
- static const GLenum kAttrib2Type = GL_FLOAT_VEC2;
- static const GLenum kAttrib3Type = GL_FLOAT_VEC3;
- static const GLint kInvalidAttribLocation = 30;
- static const GLint kBadAttribIndex = kNumVertexAttribs;
-
- static const GLint kMaxUniformLength = 12;
- static const char* kUniform1Name;
- static const char* kUniform2Name;
- static const char* kUniform3Name;
- static const GLint kUniform1Size = 1;
- static const GLint kUniform2Size = 3;
- static const GLint kUniform3Size = 2;
- static const GLint kUniform1RealLocation = 3;
- static const GLint kUniform2RealLocation = 10;
- static const GLint kUniform2ElementRealLocation = 12;
- static const GLint kUniform3RealLocation = 20;
- static const GLint kUniform1FakeLocation = 0; // These are
- static const GLint kUniform2FakeLocation = 1; // hardcoded
- static const GLint kUniform2ElementFakeLocation = 0x10001; // to match
- static const GLint kUniform3FakeLocation = 2; // ProgramManager.
- static const GLenum kUniform1Type = GL_SAMPLER_2D;
- static const GLenum kUniform2Type = GL_INT_VEC2;
- static const GLenum kUniform3Type = GL_FLOAT_VEC3;
- static const GLenum kUniformCubemapType = GL_SAMPLER_CUBE;
- static const GLint kInvalidUniformLocation = 30;
- static const GLint kBadUniformIndex = 1000;
-
// Template to call glGenXXX functions.
template <typename T>
void GenHelper(GLuint client_id) {
@@ -234,6 +146,14 @@ class GLES2DecoderTestBase : public testing::Test {
return *group_.get();
}
+ ::testing::StrictMock< ::gfx::MockGLInterface>* GetGLMock() const {
+ return gl_.get();
+ }
+
+ GLES2Decoder* GetDecoder() const {
+ return decoder_.get();
+ }
+
struct AttribInfo {
const char* name;
GLint size;
@@ -405,6 +325,94 @@ class GLES2DecoderTestBase : public testing::Test {
return isObject;
}
+ protected:
+ static const GLint kMaxTextureSize = 2048;
+ static const GLint kMaxCubeMapTextureSize = 256;
+ static const GLint kNumVertexAttribs = 16;
+ static const GLint kNumTextureUnits = 8;
+ static const GLint kMaxTextureImageUnits = 8;
+ static const GLint kMaxVertexTextureImageUnits = 2;
+ static const GLint kMaxFragmentUniformVectors = 16;
+ static const GLint kMaxVaryingVectors = 8;
+ static const GLint kMaxVertexUniformVectors = 128;
+
+ static const GLuint kServiceAttrib0BufferId = 801;
+ static const GLuint kServiceFixedAttribBufferId = 802;
+
+ static const GLuint kServiceBufferId = 301;
+ static const GLuint kServiceFramebufferId = 302;
+ static const GLuint kServiceRenderbufferId = 303;
+ static const GLuint kServiceTextureId = 304;
+ static const GLuint kServiceProgramId = 305;
+ static const GLuint kServiceShaderId = 306;
+ static const GLuint kServiceElementBufferId = 308;
+ static const GLuint kServiceQueryId = 309;
+
+ static const int32 kSharedMemoryId = 401;
+ static const size_t kSharedBufferSize = 2048;
+ static const uint32 kSharedMemoryOffset = 132;
+ static const int32 kInvalidSharedMemoryId = 402;
+ static const uint32 kInvalidSharedMemoryOffset = kSharedBufferSize + 1;
+ static const uint32 kInitialResult = 0xBDBDBDBDu;
+ static const uint8 kInitialMemoryValue = 0xBDu;
+
+ static const uint32 kNewClientId = 501;
+ static const uint32 kNewServiceId = 502;
+ static const uint32 kInvalidClientId = 601;
+
+ static const int kBackBufferWidth = 128;
+ static const int kBackBufferHeight = 64;
+
+ static const GLuint kServiceVertexShaderId = 321;
+ static const GLuint kServiceFragmentShaderId = 322;
+
+ static const GLsizei kNumVertices = 100;
+ static const GLsizei kNumIndices = 10;
+ static const int kValidIndexRangeStart = 1;
+ static const int kValidIndexRangeCount = 7;
+ static const int kInvalidIndexRangeStart = 0;
+ static const int kInvalidIndexRangeCount = 7;
+ static const int kOutOfRangeIndexRangeEnd = 10;
+ static const GLuint kMaxValidIndex = 7;
+
+ static const GLint kMaxAttribLength = 10;
+ static const char* kAttrib1Name;
+ static const char* kAttrib2Name;
+ static const char* kAttrib3Name;
+ static const GLint kAttrib1Size = 1;
+ static const GLint kAttrib2Size = 1;
+ static const GLint kAttrib3Size = 1;
+ static const GLint kAttrib1Location = 0;
+ static const GLint kAttrib2Location = 1;
+ static const GLint kAttrib3Location = 2;
+ static const GLenum kAttrib1Type = GL_FLOAT_VEC4;
+ static const GLenum kAttrib2Type = GL_FLOAT_VEC2;
+ static const GLenum kAttrib3Type = GL_FLOAT_VEC3;
+ static const GLint kInvalidAttribLocation = 30;
+ static const GLint kBadAttribIndex = kNumVertexAttribs;
+
+ static const GLint kMaxUniformLength = 12;
+ static const char* kUniform1Name;
+ static const char* kUniform2Name;
+ static const char* kUniform3Name;
+ static const GLint kUniform1Size = 1;
+ static const GLint kUniform2Size = 3;
+ static const GLint kUniform3Size = 2;
+ static const GLint kUniform1RealLocation = 3;
+ static const GLint kUniform2RealLocation = 10;
+ static const GLint kUniform2ElementRealLocation = 12;
+ static const GLint kUniform3RealLocation = 20;
+ static const GLint kUniform1FakeLocation = 0; // These are
+ static const GLint kUniform2FakeLocation = 1; // hardcoded
+ static const GLint kUniform2ElementFakeLocation = 0x10001; // to match
+ static const GLint kUniform3FakeLocation = 2; // ProgramManager.
+ static const GLenum kUniform1Type = GL_SAMPLER_2D;
+ static const GLenum kUniform2Type = GL_INT_VEC2;
+ static const GLenum kUniform3Type = GL_FLOAT_VEC3;
+ static const GLenum kUniformCubemapType = GL_SAMPLER_CUBE;
+ static const GLint kInvalidUniformLocation = 30;
+ static const GLint kBadUniformIndex = 1000;
+
// Use StrictMock to make 100% sure we know how GL will be called.
scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_;
scoped_refptr<gfx::GLSurfaceStub> surface_;
diff --git a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
index 8574e53..2d00da9 100644
--- a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
@@ -279,6 +279,7 @@ static GLenum valid_query_parameter_table[] = {
static GLenum valid_query_target_table[] = {
GL_ANY_SAMPLES_PASSED_EXT,
GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
+ GL_COMMANDS_ISSUED_CHROMIUM,
};
static GLenum valid_read_pixel_format_table[] = {
diff --git a/gpu/command_buffer/service/query_manager.cc b/gpu/command_buffer/service/query_manager.cc
index baad7f6..c8f06a3 100644
--- a/gpu/command_buffer/service/query_manager.cc
+++ b/gpu/command_buffer/service/query_manager.cc
@@ -5,14 +5,123 @@
#include "gpu/command_buffer/service/query_manager.h"
#include "base/atomicops.h"
#include "base/logging.h"
+#include "base/time.h"
#include "gpu/command_buffer/common/gles2_cmd_format.h"
#include "gpu/command_buffer/service/common_decoder.h"
namespace gpu {
namespace gles2 {
-QueryManager::QueryManager()
- : query_count_(0) {
+class AllSamplesPassedQuery : public QueryManager::Query {
+ public:
+ AllSamplesPassedQuery(
+ QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset,
+ GLuint service_id);
+ virtual ~AllSamplesPassedQuery();
+ virtual bool Begin() OVERRIDE;
+ virtual bool End(uint32 submit_count) OVERRIDE;
+ virtual bool Process() OVERRIDE;
+ virtual void Destroy(bool have_context) OVERRIDE;
+
+ private:
+ // Service side query id.
+ GLuint service_id_;
+};
+
+AllSamplesPassedQuery::AllSamplesPassedQuery(
+ QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset,
+ GLuint service_id)
+ : Query(manager, target, shm_id, shm_offset),
+ service_id_(service_id) {
+}
+
+AllSamplesPassedQuery::~AllSamplesPassedQuery() {
+}
+
+void AllSamplesPassedQuery::Destroy(bool have_context) {
+ if (have_context && !IsDeleted()) {
+ glDeleteQueriesARB(1, &service_id_);
+ MarkAsDeleted();
+ }
+}
+
+bool AllSamplesPassedQuery::Begin() {
+ BeginQueryHelper(target(), service_id_);
+ return true;
+}
+
+bool AllSamplesPassedQuery::End(uint32 submit_count) {
+ EndQueryHelper(target());
+ return AddToPendingQueue(submit_count);
+}
+
+bool AllSamplesPassedQuery::Process() {
+ GLuint available = 0;
+ glGetQueryObjectuivARB(
+ service_id_, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
+ if (!available) {
+ return true;
+ }
+ GLuint result = 0;
+ glGetQueryObjectuivARB(
+ service_id_, GL_QUERY_RESULT_EXT, &result);
+
+ return MarkAsCompleted(result);
+}
+
+class CommandsIssuedQuery : public QueryManager::Query {
+ public:
+ CommandsIssuedQuery(
+ QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset);
+ virtual ~CommandsIssuedQuery();
+
+ virtual bool Begin() OVERRIDE;
+ virtual bool End(uint32 submit_count) OVERRIDE;
+ virtual bool Process() OVERRIDE;
+ virtual void Destroy(bool have_context) OVERRIDE;
+
+ private:
+ base::TimeTicks begin_time_;
+};
+
+CommandsIssuedQuery::CommandsIssuedQuery(
+ QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset)
+ : Query(manager, target, shm_id, shm_offset) {
+}
+
+CommandsIssuedQuery::~CommandsIssuedQuery() {
+}
+
+bool CommandsIssuedQuery::Process() {
+ NOTREACHED();
+ return true;
+}
+
+bool CommandsIssuedQuery::Begin() {
+ begin_time_ = base::TimeTicks::HighResNow();
+ return true;
+}
+
+bool CommandsIssuedQuery::End(uint32 submit_count) {
+ base::TimeDelta elapsed = base::TimeTicks::HighResNow() - begin_time_;
+ MarkAsPending(submit_count);
+ return MarkAsCompleted(
+ std::min(elapsed.InMicroseconds(), static_cast<int64>(0xFFFFFFFFL)));
+}
+
+void CommandsIssuedQuery::Destroy(bool /* have_context */) {
+ if (!IsDeleted()) {
+ MarkAsDeleted();
+ }
+}
+
+QueryManager::QueryManager(
+ CommonDecoder* decoder,
+ bool use_arb_occlusion_query2_for_occlusion_query_boolean)
+ : decoder_(decoder),
+ use_arb_occlusion_query2_for_occlusion_query_boolean_(
+ use_arb_occlusion_query2_for_occlusion_query_boolean),
+ query_count_(0) {
}
QueryManager::~QueryManager() {
@@ -27,21 +136,27 @@ void QueryManager::Destroy(bool have_context) {
pending_queries_.clear();
while (!queries_.empty()) {
Query* query = queries_.begin()->second;
- if (have_context) {
- if (!query->IsDeleted()) {
- GLuint service_id = query->service_id();
- glDeleteQueriesARB(1, &service_id);
- query->MarkAsDeleted();
- }
- }
+ query->Destroy(have_context);
queries_.erase(queries_.begin());
}
}
QueryManager::Query* QueryManager::CreateQuery(
- GLuint client_id,
- GLuint service_id) {
- Query::Ref query(new Query(this, service_id));
+ GLenum target, GLuint client_id, int32 shm_id, uint32 shm_offset) {
+ Query::Ref query;
+ switch (target) {
+ case GL_COMMANDS_ISSUED_CHROMIUM:
+ query = new CommandsIssuedQuery(this, target, shm_id, shm_offset);
+ break;
+ default: {
+ GLuint service_id = 0;
+ glGenQueriesARB(1, &service_id);
+ DCHECK_NE(0u, service_id);
+ query = new AllSamplesPassedQuery(
+ this, target, shm_id, shm_offset, service_id);
+ break;
+ }
+ }
std::pair<QueryMap::iterator, bool> result =
queries_.insert(std::make_pair(client_id, query));
DCHECK(result.second);
@@ -72,16 +187,33 @@ 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;
+ }
+ 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;
+ }
+ glEndQueryARB(target);
+}
+
QueryManager::Query::Query(
- QueryManager* manager,
- GLuint service_id)
+ QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset)
: manager_(manager),
- service_id_(service_id),
- target_(0),
- shm_id_(0),
- shm_offset_(0),
+ target_(target),
+ shm_id_(shm_id),
+ shm_offset_(shm_offset),
submit_count_(0),
- pending_(false) {
+ pending_(false),
+ deleted_(false) {
DCHECK(manager);
manager_->StartTracking(this);
}
@@ -93,53 +225,33 @@ QueryManager::Query::~Query() {
}
}
-void QueryManager::Query::Initialize(
- GLenum target, int32 shm_id, uint32 shm_offset) {
- DCHECK(!IsInitialized());
- target_ = target;
- shm_id_ = shm_id;
- shm_offset_ = shm_offset;
-}
-
-bool QueryManager::GetClientId(GLuint service_id, GLuint* client_id) const {
- DCHECK(client_id);
- // This doesn't need to be fast. It's only used during slow queries.
- for (QueryMap::const_iterator it = queries_.begin();
- it != queries_.end(); ++it) {
- if (it->second->service_id() == service_id) {
- *client_id = it->first;
- return true;
- }
+bool QueryManager::Query::MarkAsCompleted(GLuint result) {
+ DCHECK(pending_);
+ QuerySync* sync = manager_->decoder_->GetSharedMemoryAs<QuerySync*>(
+ shm_id_, shm_offset_, sizeof(*sync));
+ if (!sync) {
+ return false;
}
- return false;
+
+ pending_ = false;
+ sync->result = result;
+ // Need a MemoryBarrier here so that sync->result is written before
+ // sync->process_count.
+ base::subtle::MemoryBarrier();
+ sync->process_count = submit_count_;
+
+ return true;
}
-bool QueryManager::ProcessPendingQueries(CommonDecoder* decoder) {
- DCHECK(decoder);
+bool QueryManager::ProcessPendingQueries() {
while (!pending_queries_.empty()) {
Query* query = pending_queries_.front().get();
- GLuint available = 0;
- glGetQueryObjectuivARB(
- query->service_id(), GL_QUERY_RESULT_AVAILABLE_EXT, &available);
- if (!available) {
- return true;
- }
- GLuint result = 0;
- glGetQueryObjectuivARB(
- query->service_id(), GL_QUERY_RESULT_EXT, &result);
- QuerySync* sync = decoder->GetSharedMemoryAs<QuerySync*>(
- query->shm_id(), query->shm_offset(), sizeof(*sync));
- if (!sync) {
+ if (!query->Process()) {
return false;
}
-
- sync->result = result;
- // Need a MemoryBarrier here so that sync->result is written before
- // sync->process_count.
- base::subtle::MemoryBarrier();
- sync->process_count = query->submit_count();
-
- query->MarkAsCompleted();
+ if (query->pending()) {
+ return true;
+ }
pending_queries_.pop_front();
}
@@ -150,16 +262,18 @@ bool QueryManager::HavePendingQueries() {
return !pending_queries_.empty();
}
-void QueryManager::AddPendingQuery(Query* query, uint32 submit_count) {
+bool QueryManager::AddPendingQuery(Query* query, uint32 submit_count) {
DCHECK(query);
- DCHECK(query->IsInitialized());
DCHECK(!query->IsDeleted());
- RemovePendingQuery(query);
+ if (!RemovePendingQuery(query)) {
+ return false;
+ }
query->MarkAsPending(submit_count);
pending_queries_.push_back(query);
+ return true;
}
-void QueryManager::RemovePendingQuery(Query* query) {
+bool QueryManager::RemovePendingQuery(Query* query) {
DCHECK(query);
if (query->pending()) {
// TODO(gman): Speed this up if this is a common operation. This would only
@@ -172,8 +286,27 @@ void QueryManager::RemovePendingQuery(Query* query) {
break;
}
}
- query->MarkAsCompleted();
+ if (!query->MarkAsCompleted(0)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool QueryManager::BeginQuery(Query* query) {
+ DCHECK(query);
+ if (!RemovePendingQuery(query)) {
+ return false;
+ }
+ return query->Begin();
+}
+
+bool QueryManager::EndQuery(Query* query, uint32 submit_count) {
+ DCHECK(query);
+ if (!RemovePendingQuery(query)) {
+ return false;
}
+ return query->End(submit_count);
}
} // namespace gles2
diff --git a/gpu/command_buffer/service/query_manager.h b/gpu/command_buffer/service/query_manager.h
index a813ad3..36753e7 100644
--- a/gpu/command_buffer/service/query_manager.h
+++ b/gpu/command_buffer/service/query_manager.h
@@ -28,30 +28,26 @@ class GPU_EXPORT QueryManager {
public:
typedef scoped_refptr<Query> Ref;
- Query(QueryManager* manager, GLuint service_id);
-
- void Initialize(GLenum target, int32 shm_id, uint32 shm_offset);
-
- bool IsInitialized() const {
- return target_ != 0;
- }
-
- GLuint service_id() const {
- return service_id_;
- }
+ Query(
+ QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset);
+ virtual ~Query();
GLenum target() const {
return target_;
}
bool IsDeleted() const {
- return service_id_ == 0;
+ return deleted_;
}
bool IsValid() const {
return target() && !IsDeleted();
}
+ bool pending() const {
+ return pending_;
+ }
+
int32 shm_id() const {
return shm_id_;
}
@@ -60,16 +56,28 @@ class GPU_EXPORT QueryManager {
return shm_offset_;
}
- bool pending() const {
- return pending_;
+ // Returns false if shared memory for sync is invalid.
+ virtual bool Begin() = 0;
+
+ // Returns false if shared memory for sync is invalid.
+ virtual bool End(uint32 submit_count) = 0;
+
+ // Returns false if shared memory for sync is invalid.
+ virtual bool Process() = 0;
+
+ virtual void Destroy(bool have_context) = 0;
+
+ protected:
+ QueryManager* manager() const {
+ return manager_;
}
- private:
- friend class QueryManager;
- friend class QueryManagerTest;
- friend class base::RefCounted<Query>;
+ void MarkAsDeleted() {
+ deleted_ = true;
+ }
- ~Query();
+ // Returns false if shared memory for sync is invalid.
+ bool MarkAsCompleted(GLuint result);
void MarkAsPending(uint32 submit_count) {
DCHECK(!pending_);
@@ -77,25 +85,31 @@ class GPU_EXPORT QueryManager {
submit_count_ = submit_count;
}
- void MarkAsCompleted() {
- DCHECK(pending_);
- pending_ = false;
+ // Returns false if shared memory for sync is invalid.
+ bool AddToPendingQueue(uint32 submit_count) {
+ return manager_->AddPendingQuery(this, submit_count);
}
- uint32 submit_count() const {
- return submit_count_;
+ void BeginQueryHelper(GLenum target, GLuint id) {
+ manager_->BeginQueryHelper(target, id);
}
- void MarkAsDeleted() {
- service_id_ = 0;
+ void EndQueryHelper(GLenum target) {
+ manager_->EndQueryHelper(target);
+ }
+
+ private:
+ friend class QueryManager;
+ friend class QueryManagerTest;
+ friend class base::RefCounted<Query>;
+
+ uint32 submit_count() const {
+ return submit_count_;
}
// The manager that owns this Query.
QueryManager* manager_;
- // Service side query id.
- GLuint service_id_;
-
// The type of query.
GLenum target_;
@@ -106,18 +120,24 @@ class GPU_EXPORT QueryManager {
// Count to set process count do when completed.
uint32 submit_count_;
- // True if in the Queue.
+ // True if in the queue.
bool pending_;
+
+ // True if deleted.
+ bool deleted_;
};
- QueryManager();
+ QueryManager(
+ CommonDecoder* decoder,
+ bool use_arb_occlusion_query2_for_occlusion_query_boolean);
~QueryManager();
// Must call before destruction.
void Destroy(bool have_context);
// Creates a Query for the given query.
- Query* CreateQuery(GLuint client_id, GLuint service_id);
+ Query* CreateQuery(
+ GLenum target, GLuint client_id, int32 shm_id, uint32 shm_offset);
// Gets the query info for the given query.
Query* GetQuery(GLuint client_id);
@@ -125,18 +145,15 @@ class GPU_EXPORT QueryManager {
// Removes a query info for the given query.
void RemoveQuery(GLuint client_id);
- // Gets a client id for a given service id.
- bool GetClientId(GLuint service_id, GLuint* client_id) const;
-
- // Adds to queue of queries waiting for completion.
- void AddPendingQuery(Query* query, uint32 submit_count);
+ // Returns false if any query is pointing to invalid shared memory.
+ bool BeginQuery(Query* query);
- // Removes a query from the queue of pending queries.
- void RemovePendingQuery(Query* query);
+ // Returns false if any query is pointing to invalid shared memory.
+ bool EndQuery(Query* query, uint32 submit_count);
// Processes pending queries. Returns false if any queries are pointing
// to invalid shared memory.
- bool ProcessPendingQueries(CommonDecoder* decoder);
+ bool ProcessPendingQueries();
// True if there are pending queries.
bool HavePendingQueries();
@@ -145,6 +162,24 @@ class GPU_EXPORT QueryManager {
void StartTracking(Query* query);
void StopTracking(Query* query);
+ // Wrappers for BeginQueryARB and EndQueryARB to hide differences between
+ // ARB_occlusion_query2 and EXT_occlusion_query_boolean.
+ void BeginQueryHelper(GLenum target, GLuint id);
+ void EndQueryHelper(GLenum target);
+
+ // Adds to queue of queries waiting for completion.
+ // Returns false if any query is pointing to invalid shared memory.
+ bool AddPendingQuery(Query* query, uint32 submit_count);
+
+ // Removes a query from the queue of pending queries.
+ // Returns false if any query is pointing to invalid shared memory.
+ bool RemovePendingQuery(Query* query);
+
+ // Used to validate shared memory.
+ CommonDecoder* decoder_;
+
+ bool use_arb_occlusion_query2_for_occlusion_query_boolean_;
+
// Counts the number of Queries allocated with 'this' as their manager.
// Allows checking no Query will outlive this.
unsigned query_count_;
diff --git a/gpu/command_buffer/service/query_manager_unittest.cc b/gpu/command_buffer/service/query_manager_unittest.cc
index 17e03ce..38eea14 100644
--- a/gpu/command_buffer/service/query_manager_unittest.cc
+++ b/gpu/command_buffer/service/query_manager_unittest.cc
@@ -48,7 +48,7 @@ class QueryManagerTest : public testing::Test {
engine_.reset(new MockCommandBufferEngine());
decoder_.reset(new MockDecoder());
decoder_->set_engine(engine_.get());
- manager_.reset(new QueryManager());
+ manager_.reset(new QueryManager(decoder_.get(), false));
}
virtual void TearDown() {
@@ -60,6 +60,27 @@ class QueryManagerTest : public testing::Test {
gl_.reset();
}
+ QueryManager::Query* CreateQuery(
+ GLenum target, GLuint client_id, int32 shm_id, uint32 shm_offset,
+ GLuint service_id) {
+ EXPECT_CALL(*gl_, GenQueriesARB(1, _))
+ .WillOnce(SetArgumentPointee<1>(service_id))
+ .RetiresOnSaturation();
+ return manager_->CreateQuery(target, client_id, shm_id, shm_offset);
+ }
+
+ void QueueQuery(
+ QueryManager::Query* query, GLuint service_id, uint32 submit_count) {
+ EXPECT_CALL(*gl_, BeginQueryARB(query->target(), service_id))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, EndQueryARB(query->target()))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_TRUE(manager_->BeginQuery(query));
+ EXPECT_TRUE(manager_->EndQuery(query, submit_count));
+ }
+
// Use StrictMock to make 100% sure we know how GL will be called.
scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_;
scoped_ptr<MockDecoder> decoder_;
@@ -135,15 +156,11 @@ TEST_F(QueryManagerTest, Basic) {
EXPECT_FALSE(manager_->HavePendingQueries());
// Check we can create a Query.
QueryManager::Query::Ref query(
- manager_->CreateQuery(kClient1Id, kService1Id));
+ CreateQuery(GL_ANY_SAMPLES_PASSED_EXT, kClient1Id,
+ kSharedMemoryId, kSharedMemoryOffset, kService1Id));
ASSERT_TRUE(query.get() != NULL);
// Check we can get the same Query.
EXPECT_EQ(query.get(), manager_->GetQuery(kClient1Id));
- // Check we can get the client id.
- GLuint client_id = -1;
- EXPECT_TRUE(manager_->GetClientId(kService1Id, &client_id));
- EXPECT_EQ(kClient1Id, client_id);
- EXPECT_FALSE(manager_->HavePendingQueries());
// Check we get nothing for a non-existent query.
EXPECT_TRUE(manager_->GetQuery(kClient2Id) == NULL);
// Check we can delete the query.
@@ -161,7 +178,8 @@ TEST_F(QueryManagerTest, Destroy) {
// Create Query.
QueryManager::Query::Ref query(
- manager_->CreateQuery(kClient1Id, kService1Id));
+ CreateQuery(GL_ANY_SAMPLES_PASSED_EXT, kClient1Id,
+ kSharedMemoryId, kSharedMemoryOffset, kService1Id));
ASSERT_TRUE(query.get() != NULL);
EXPECT_CALL(*gl_, DeleteQueriesARB(1, ::testing::Pointee(kService1Id)))
.Times(1)
@@ -176,37 +194,20 @@ TEST_F(QueryManagerTest, Destroy) {
TEST_F(QueryManagerTest, QueryBasic) {
const GLuint kClient1Id = 1;
const GLuint kService1Id = 11;
+ const GLenum kTarget = GL_ANY_SAMPLES_PASSED_EXT;
// Create Query.
QueryManager::Query::Ref query(
- manager_->CreateQuery(kClient1Id, kService1Id));
+ CreateQuery(kTarget, kClient1Id,
+ kSharedMemoryId, kSharedMemoryOffset, kService1Id));
ASSERT_TRUE(query.get() != NULL);
- EXPECT_FALSE(query->IsValid());
+ EXPECT_TRUE(query->IsValid());
EXPECT_FALSE(query->IsDeleted());
- EXPECT_FALSE(query->IsInitialized());
EXPECT_FALSE(query->pending());
-}
-
-TEST_F(QueryManagerTest, QueryInitialize) {
- const GLuint kClient1Id = 1;
- const GLuint kService1Id = 11;
- const GLenum kTarget = GL_ANY_SAMPLES_PASSED_EXT;
-
- // Create Query.
- QueryManager::Query::Ref query(
- manager_->CreateQuery(kClient1Id, kService1Id));
- ASSERT_TRUE(query.get() != NULL);
-
- query->Initialize(kTarget, kSharedMemoryId, kSharedMemoryOffset);
EXPECT_EQ(kTarget, query->target());
EXPECT_EQ(kSharedMemoryId, query->shm_id());
EXPECT_EQ(kSharedMemoryOffset, query->shm_offset());
-
- EXPECT_TRUE(query->IsValid());
- EXPECT_FALSE(query->IsDeleted());
- EXPECT_TRUE(query->IsInitialized());
- EXPECT_FALSE(query->pending());
}
TEST_F(QueryManagerTest, ProcessPendingQuery) {
@@ -217,13 +218,13 @@ TEST_F(QueryManagerTest, ProcessPendingQuery) {
const GLuint kResult = 456;
// Check nothing happens if there are no pending queries.
- EXPECT_TRUE(manager_->ProcessPendingQueries(decoder_.get()));
+ EXPECT_TRUE(manager_->ProcessPendingQueries());
// Create Query.
QueryManager::Query::Ref query(
- manager_->CreateQuery(kClient1Id, kService1Id));
+ CreateQuery(kTarget, kClient1Id,
+ kSharedMemoryId, kSharedMemoryOffset, kService1Id));
ASSERT_TRUE(query.get() != NULL);
- query->Initialize(kTarget, kSharedMemoryId, kSharedMemoryOffset);
// Setup shared memory like client would.
QuerySync* sync = decoder_->GetSharedMemoryAs<QuerySync*>(
@@ -232,7 +233,7 @@ TEST_F(QueryManagerTest, ProcessPendingQuery) {
sync->Reset();
// Queue it
- manager_->AddPendingQuery(query.get(), kSubmitCount);
+ QueueQuery(query.get(), kService1Id, kSubmitCount);
EXPECT_TRUE(query->pending());
EXPECT_TRUE(manager_->HavePendingQueries());
@@ -242,7 +243,7 @@ TEST_F(QueryManagerTest, ProcessPendingQuery) {
GetQueryObjectuivARB(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
.WillOnce(SetArgumentPointee<2>(0))
.RetiresOnSaturation();
- EXPECT_TRUE(manager_->ProcessPendingQueries(decoder_.get()));
+ EXPECT_TRUE(manager_->ProcessPendingQueries());
EXPECT_TRUE(query->pending());
EXPECT_EQ(0u, sync->process_count);
EXPECT_EQ(0u, sync->result);
@@ -257,7 +258,7 @@ TEST_F(QueryManagerTest, ProcessPendingQuery) {
GetQueryObjectuivARB(kService1Id, GL_QUERY_RESULT_EXT, _))
.WillOnce(SetArgumentPointee<2>(kResult))
.RetiresOnSaturation();
- EXPECT_TRUE(manager_->ProcessPendingQueries(decoder_.get()));
+ EXPECT_TRUE(manager_->ProcessPendingQueries());
EXPECT_FALSE(query->pending());
EXPECT_EQ(kSubmitCount, sync->process_count);
EXPECT_EQ(kResult, sync->result);
@@ -265,7 +266,7 @@ TEST_F(QueryManagerTest, ProcessPendingQuery) {
// Process with no queries.
// Expect no GL commands/
- EXPECT_TRUE(manager_->ProcessPendingQueries(decoder_.get()));
+ EXPECT_TRUE(manager_->ProcessPendingQueries());
}
TEST_F(QueryManagerTest, ProcessPendingQueries) {
@@ -283,39 +284,39 @@ TEST_F(QueryManagerTest, ProcessPendingQueries) {
const GLuint kResult2 = 457;
const GLuint kResult3 = 458;
+ // Setup shared memory like client would.
+ QuerySync* sync1 = decoder_->GetSharedMemoryAs<QuerySync*>(
+ kSharedMemoryId, kSharedMemoryOffset, sizeof(*sync1) * 3);
+ ASSERT_TRUE(sync1 != NULL);
+ QuerySync* sync2 = sync1 + 1;
+ QuerySync* sync3 = sync2 + 1;
+
// Create Queries.
QueryManager::Query::Ref query1(
- manager_->CreateQuery(kClient1Id, kService1Id));
+ CreateQuery(kTarget, kClient1Id,
+ kSharedMemoryId, kSharedMemoryOffset + sizeof(*sync1) * 0,
+ kService1Id));
QueryManager::Query::Ref query2(
- manager_->CreateQuery(kClient2Id, kService2Id));
+ CreateQuery(kTarget, kClient2Id,
+ kSharedMemoryId, kSharedMemoryOffset + sizeof(*sync1) * 1,
+ kService2Id));
QueryManager::Query::Ref query3(
- manager_->CreateQuery(kClient3Id, kService3Id));
+ CreateQuery(kTarget, kClient3Id,
+ kSharedMemoryId, kSharedMemoryOffset + sizeof(*sync1) * 2,
+ kService3Id));
ASSERT_TRUE(query1.get() != NULL);
ASSERT_TRUE(query2.get() != NULL);
ASSERT_TRUE(query3.get() != NULL);
EXPECT_FALSE(manager_->HavePendingQueries());
- // Setup shared memory like client would.
- QuerySync* sync1 = decoder_->GetSharedMemoryAs<QuerySync*>(
- kSharedMemoryId, kSharedMemoryOffset, sizeof(*sync1) * 3);
- ASSERT_TRUE(sync1 != NULL);
- QuerySync* sync2 = sync1 + 1;
- QuerySync* sync3 = sync2 + 1;
-
sync1->Reset();
sync2->Reset();
sync3->Reset();
- query1->Initialize(kTarget, kSharedMemoryId, kSharedMemoryOffset);
- query2->Initialize(kTarget, kSharedMemoryId,
- kSharedMemoryOffset + sizeof(*sync1));
- query3->Initialize(kTarget, kSharedMemoryId,
- kSharedMemoryOffset + sizeof(*sync1) * 2);
-
// Queue them
- manager_->AddPendingQuery(query1.get(), kSubmitCount1);
- manager_->AddPendingQuery(query2.get(), kSubmitCount2);
- manager_->AddPendingQuery(query3.get(), kSubmitCount3);
+ QueueQuery(query1.get(), kService1Id, kSubmitCount1);
+ QueueQuery(query2.get(), kService2Id, kSubmitCount2);
+ QueueQuery(query3.get(), kService3Id, kSubmitCount3);
EXPECT_TRUE(query1->pending());
EXPECT_TRUE(query2->pending());
EXPECT_TRUE(query3->pending());
@@ -345,7 +346,7 @@ TEST_F(QueryManagerTest, ProcessPendingQueries) {
GetQueryObjectuivARB(kService3Id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
.WillOnce(SetArgumentPointee<2>(0))
.RetiresOnSaturation();
- EXPECT_TRUE(manager_->ProcessPendingQueries(decoder_.get()));
+ EXPECT_TRUE(manager_->ProcessPendingQueries());
}
EXPECT_FALSE(query1->pending());
EXPECT_FALSE(query2->pending());
@@ -364,7 +365,7 @@ TEST_F(QueryManagerTest, ProcessPendingQueries) {
GetQueryObjectuivARB(kService3Id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
.WillOnce(SetArgumentPointee<2>(0))
.RetiresOnSaturation();
- EXPECT_TRUE(manager_->ProcessPendingQueries(decoder_.get()));
+ EXPECT_TRUE(manager_->ProcessPendingQueries());
EXPECT_TRUE(query3->pending());
EXPECT_EQ(0u, sync3->process_count);
EXPECT_EQ(0u, sync3->result);
@@ -380,7 +381,7 @@ TEST_F(QueryManagerTest, ProcessPendingQueries) {
GetQueryObjectuivARB(kService3Id, GL_QUERY_RESULT_EXT, _))
.WillOnce(SetArgumentPointee<2>(kResult3))
.RetiresOnSaturation();
- EXPECT_TRUE(manager_->ProcessPendingQueries(decoder_.get()));
+ EXPECT_TRUE(manager_->ProcessPendingQueries());
EXPECT_FALSE(query3->pending());
EXPECT_EQ(kSubmitCount3, sync3->process_count);
EXPECT_EQ(kResult3, sync3->result);
@@ -396,12 +397,12 @@ TEST_F(QueryManagerTest, ProcessPendingBadSharedMemoryId) {
// Create Query.
QueryManager::Query::Ref query(
- manager_->CreateQuery(kClient1Id, kService1Id));
+ CreateQuery(kTarget, kClient1Id,
+ kInvalidSharedMemoryId, kSharedMemoryOffset, kService1Id));
ASSERT_TRUE(query.get() != NULL);
- query->Initialize(kTarget, kInvalidSharedMemoryId, kSharedMemoryOffset);
// Queue it
- manager_->AddPendingQuery(query.get(), kSubmitCount);
+ QueueQuery(query.get(), kService1Id, kSubmitCount);
// Process with return available.
// Expect 2 GL commands.
@@ -413,7 +414,7 @@ TEST_F(QueryManagerTest, ProcessPendingBadSharedMemoryId) {
GetQueryObjectuivARB(kService1Id, GL_QUERY_RESULT_EXT, _))
.WillOnce(SetArgumentPointee<2>(kResult))
.RetiresOnSaturation();
- EXPECT_FALSE(manager_->ProcessPendingQueries(decoder_.get()));
+ EXPECT_FALSE(manager_->ProcessPendingQueries());
}
TEST_F(QueryManagerTest, ProcessPendingBadSharedMemoryOffset) {
@@ -425,12 +426,12 @@ TEST_F(QueryManagerTest, ProcessPendingBadSharedMemoryOffset) {
// Create Query.
QueryManager::Query::Ref query(
- manager_->CreateQuery(kClient1Id, kService1Id));
+ CreateQuery(kTarget, kClient1Id,
+ kSharedMemoryId, kInvalidSharedMemoryOffset, kService1Id));
ASSERT_TRUE(query.get() != NULL);
- query->Initialize(kTarget, kSharedMemoryId, kInvalidSharedMemoryOffset);
// Queue it
- manager_->AddPendingQuery(query.get(), kSubmitCount);
+ QueueQuery(query.get(), kService1Id, kSubmitCount);
// Process with return available.
// Expect 2 GL commands.
@@ -442,7 +443,7 @@ TEST_F(QueryManagerTest, ProcessPendingBadSharedMemoryOffset) {
GetQueryObjectuivARB(kService1Id, GL_QUERY_RESULT_EXT, _))
.WillOnce(SetArgumentPointee<2>(kResult))
.RetiresOnSaturation();
- EXPECT_FALSE(manager_->ProcessPendingQueries(decoder_.get()));
+ EXPECT_FALSE(manager_->ProcessPendingQueries());
}
TEST_F(QueryManagerTest, ExitWithPendingQuery) {
@@ -453,12 +454,38 @@ TEST_F(QueryManagerTest, ExitWithPendingQuery) {
// Create Query.
QueryManager::Query::Ref query(
- manager_->CreateQuery(kClient1Id, kService1Id));
+ CreateQuery(kTarget, kClient1Id,
+ kSharedMemoryId, kSharedMemoryOffset, kService1Id));
ASSERT_TRUE(query.get() != NULL);
- query->Initialize(kTarget, kSharedMemoryId, kSharedMemoryOffset);
// Queue it
- manager_->AddPendingQuery(query.get(), kSubmitCount);
+ QueueQuery(query.get(), kService1Id, kSubmitCount);
+}
+
+TEST_F(QueryManagerTest, ARBOcclusionQuery2) {
+ const GLuint kClient1Id = 1;
+ const GLuint kService1Id = 11;
+ const GLenum kTarget = GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT;
+ const uint32 kSubmitCount = 123;
+
+ scoped_ptr<QueryManager> manager(new QueryManager(decoder_.get(), true));
+
+ 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_ANY_SAMPLES_PASSED_EXT, kService1Id))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, EndQueryARB(GL_ANY_SAMPLES_PASSED_EXT))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_TRUE(manager->BeginQuery(query));
+ EXPECT_TRUE(manager->EndQuery(query, kSubmitCount));
+ manager->Destroy(false);
}
} // namespace gles2
diff --git a/third_party/khronos/GLES2/gl2ext.h b/third_party/khronos/GLES2/gl2ext.h
index fd39ca3..04fa4e0 100644
--- a/third_party/khronos/GLES2/gl2ext.h
+++ b/third_party/khronos/GLES2/gl2ext.h
@@ -1955,6 +1955,15 @@ typedef void (GL_APIENTRYP PFNGLTEXIMAGEIOSURFACE2DCHROMIUM) (GLenum target, GLs
#endif
#endif
+/* GL_CHROMIUM_command_buffer_query */
+/* Exposes GL_CHROMIUM_command_buffer_query.
+ */
+#ifndef GL_CHROMIUM_command_buffer_query
+#define GL_CHROMIUM_command_buffer_query 1
+// TODO(gman): Get official numbers for these constants.
+#define GL_COMMANDS_ISSUED_CHROMIUM 0x84F2
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/third_party/khronos/README.chromium b/third_party/khronos/README.chromium
index aa2accc..fb7daee 100644
--- a/third_party/khronos/README.chromium
+++ b/third_party/khronos/README.chromium
@@ -20,5 +20,6 @@ GLES2/gl2ext.h
- Added Chromium and Angle extensions.
- Added ANGLE_instanced_arrays
- Added GL_EXT_framebuffer_multisample
+ - Added GL_CHROMIUM_command_buffer_query
EGL/eglplatform.h
- Added EGLNative*Type for Mac.