summaryrefslogtreecommitdiffstats
path: root/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc')
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc331
1 files changed, 265 insertions, 66 deletions
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
index a76346f..ae525d4 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
@@ -26,6 +26,7 @@
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_mock.h"
#include "ui/gl/gl_surface_stub.h"
+#include "ui/gl/gpu_timing_fake.h"
#if !defined(GL_DEPTH24_STENCIL8)
@@ -562,7 +563,7 @@ TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXT) {
struct QueryType {
GLenum type;
- bool is_gl;
+ bool is_counter;
};
const QueryType kQueryTypes[] = {
@@ -572,112 +573,169 @@ const QueryType kQueryTypes[] = {
{GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, false},
{GL_GET_ERROR_QUERY_CHROMIUM, false},
{GL_COMMANDS_COMPLETED_CHROMIUM, false},
- {GL_ANY_SAMPLES_PASSED_EXT, true},
- {GL_TIME_ELAPSED, true},
+ {GL_ANY_SAMPLES_PASSED_EXT, false},
+ {GL_TIME_ELAPSED, false},
+ {GL_TIMESTAMP, true},
};
+const GLsync kGlSync = reinterpret_cast<GLsync>(0xdeadbeef);
-static void CheckBeginEndQueryBadMemoryFails(GLES2DecoderTestBase* test,
- GLuint client_id,
- GLuint service_id,
- const QueryType& query_type,
- int32 shm_id,
- uint32 shm_offset) {
- // We need to reset the decoder on each iteration, because we lose the
- // context every time.
- GLES2DecoderTestBase::InitState init;
- init.extensions = "GL_EXT_occlusion_query_boolean"
- " GL_ARB_sync"
- " GL_ARB_timer_query";
- init.gl_version = "opengl es 2.0";
- init.has_alpha = true;
- init.request_alpha = true;
- init.bind_generates_resource = true;
- test->InitDecoder(init);
- ::testing::StrictMock< ::gfx::MockGLInterface>* gl = test->GetGLMock();
-
- BeginQueryEXT begin_cmd;
-
+static void ExecuteGenerateQueryCmd(GLES2DecoderTestBase* test,
+ ::gfx::MockGLInterface* gl,
+ GLenum target,
+ GLuint client_id,
+ GLuint service_id) {
test->GenHelper<GenQueriesEXTImmediate>(client_id);
-
- if (query_type.is_gl) {
+ if (GL_ANY_SAMPLES_PASSED_EXT == target) {
EXPECT_CALL(*gl, GenQueries(1, _))
.WillOnce(SetArgPointee<1>(service_id))
.RetiresOnSaturation();
- EXPECT_CALL(*gl, BeginQuery(query_type.type, service_id))
+ }
+}
+
+static error::Error ExecuteBeginQueryCmd(GLES2DecoderTestBase* test,
+ ::gfx::MockGLInterface* gl,
+ ::gfx::GPUTimingFake* timing_queries,
+ GLenum target,
+ GLuint client_id,
+ GLuint service_id,
+ int32 shm_id,
+ uint32 shm_offset) {
+ if (GL_ANY_SAMPLES_PASSED_EXT == target) {
+ EXPECT_CALL(*gl, BeginQuery(target, service_id))
.Times(1)
.RetiresOnSaturation();
+ } else if (GL_TIME_ELAPSED == target) {
+ timing_queries->ExpectGPUTimerQuery(*gl, true);
}
- // Test bad shared memory fails
- begin_cmd.Init(query_type.type, client_id, shm_id, shm_offset);
- error::Error error1 = test->ExecuteCmd(begin_cmd);
+ BeginQueryEXT begin_cmd;
+ begin_cmd.Init(target, client_id, shm_id, shm_offset);
+ return test->ExecuteCmd(begin_cmd);
+}
- if (query_type.is_gl) {
- EXPECT_CALL(*gl, EndQuery(query_type.type))
+static error::Error ExecuteEndQueryCmd(GLES2DecoderTestBase* test,
+ ::gfx::MockGLInterface* gl,
+ GLenum target,
+ uint32_t submit_count) {
+ if (GL_ANY_SAMPLES_PASSED_EXT == target) {
+ EXPECT_CALL(*gl, EndQuery(target))
.Times(1)
.RetiresOnSaturation();
- }
- if (query_type.type == GL_GET_ERROR_QUERY_CHROMIUM) {
+ } else if (GL_GET_ERROR_QUERY_CHROMIUM == target) {
EXPECT_CALL(*gl, GetError())
.WillOnce(Return(GL_NO_ERROR))
.RetiresOnSaturation();
- }
- GLsync kGlSync = reinterpret_cast<GLsync>(0xdeadbeef);
- if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM) {
+ } else if (GL_COMMANDS_COMPLETED_CHROMIUM == target) {
EXPECT_CALL(*gl, Flush()).RetiresOnSaturation();
EXPECT_CALL(*gl, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0))
.WillOnce(Return(kGlSync))
.RetiresOnSaturation();
#if DCHECK_IS_ON()
EXPECT_CALL(*gl, IsSync(kGlSync))
- .WillOnce(Return(GL_TRUE))
- .RetiresOnSaturation();
+ .WillRepeatedly(Return(GL_TRUE));
#endif
}
EndQueryEXT end_cmd;
- end_cmd.Init(query_type.type, 1);
- error::Error error2 = test->ExecuteCmd(end_cmd);
+ end_cmd.Init(target, submit_count);
+ return test->ExecuteCmd(end_cmd);
+}
+
+static error::Error ExecuteQueryCounterCmd(GLES2DecoderTestBase* test,
+ ::gfx::MockGLInterface* gl,
+ ::gfx::GPUTimingFake* timing_queries,
+ GLenum target,
+ GLuint client_id,
+ GLuint service_id,
+ int32 shm_id,
+ uint32 shm_offset,
+ uint32_t submit_count) {
+ if (GL_TIMESTAMP == target) {
+ timing_queries->ExpectGPUTimeStampQuery(*gl, false);
+ }
+
+ QueryCounterEXT query_counter_cmd;
+ query_counter_cmd.Init(client_id,
+ target,
+ shm_id,
+ shm_offset,
+ submit_count);
+ return test->ExecuteCmd(query_counter_cmd);
+}
- if (query_type.is_gl) {
+static bool ProcessQuery(GLES2DecoderTestBase* test,
+ ::gfx::MockGLInterface* gl,
+ GLenum target,
+ GLuint service_id) {
+ if (GL_ANY_SAMPLES_PASSED_EXT == target) {
EXPECT_CALL(
*gl, GetQueryObjectuiv(service_id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
.WillOnce(SetArgPointee<2>(1))
.RetiresOnSaturation();
- if (query_type.type == GL_TIME_ELAPSED) {
- EXPECT_CALL(*gl, GetQueryObjectui64v(service_id, GL_QUERY_RESULT_EXT, _))
- .WillOnce(SetArgPointee<2>(1))
- .RetiresOnSaturation();
- } else {
- EXPECT_CALL(*gl, GetQueryObjectuiv(service_id, GL_QUERY_RESULT_EXT, _))
- .WillOnce(SetArgPointee<2>(1))
- .RetiresOnSaturation();
- }
- EXPECT_CALL(*gl, DeleteQueries(1, _)).Times(1).RetiresOnSaturation();
- }
- if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM) {
-#if DCHECK_IS_ON()
- EXPECT_CALL(*gl, IsSync(kGlSync))
- .WillOnce(Return(GL_TRUE))
+ EXPECT_CALL(*gl, GetQueryObjectuiv(service_id, GL_QUERY_RESULT_EXT, _))
+ .WillOnce(SetArgPointee<2>(1))
.RetiresOnSaturation();
-#endif
+ } else if (GL_COMMANDS_COMPLETED_CHROMIUM == target) {
EXPECT_CALL(*gl, ClientWaitSync(kGlSync, _, _))
.WillOnce(Return(GL_ALREADY_SIGNALED))
.RetiresOnSaturation();
-#if DCHECK_IS_ON()
- EXPECT_CALL(*gl, IsSync(kGlSync))
- .WillOnce(Return(GL_TRUE))
- .RetiresOnSaturation();
-#endif
EXPECT_CALL(*gl, DeleteSync(kGlSync)).Times(1).RetiresOnSaturation();
}
QueryManager* query_manager = test->GetDecoder()->GetQueryManager();
- ASSERT_TRUE(query_manager != NULL);
- bool process_success = query_manager->ProcessPendingQueries(false);
+ EXPECT_TRUE(nullptr != query_manager);
+ if (!query_manager)
+ return false;
+
+ return query_manager->ProcessPendingQueries(false);
+}
+
+static void CheckBeginEndQueryBadMemoryFails(GLES2DecoderTestBase* test,
+ GLuint client_id,
+ GLuint service_id,
+ const QueryType& query_type,
+ int32 shm_id,
+ uint32 shm_offset) {
+ // We need to reset the decoder on each iteration, because we lose the
+ // context every time.
+ GLES2DecoderTestBase::InitState init;
+ init.extensions = "GL_EXT_occlusion_query_boolean"
+ " GL_ARB_sync"
+ " GL_ARB_timer_query";
+ init.gl_version = "opengl es 3.0";
+ init.has_alpha = true;
+ init.request_alpha = true;
+ init.bind_generates_resource = true;
+ test->InitDecoder(init);
+ ::testing::StrictMock< ::gfx::MockGLInterface>* gl = test->GetGLMock();
+ ::gfx::GPUTimingFake gpu_timing_queries;
+
+ ExecuteGenerateQueryCmd(test, gl, query_type.type,
+ client_id, service_id);
+
+ // Test bad shared memory fails
+ error::Error error1 = error::kNoError;
+ error::Error error2 = error::kNoError;
+ if (query_type.is_counter) {
+ error1 = ExecuteQueryCounterCmd(test, gl, &gpu_timing_queries,
+ query_type.type,
+ client_id, service_id,
+ shm_id, shm_offset, 1);
+ } else {
+ error1 = ExecuteBeginQueryCmd(test, gl, &gpu_timing_queries,
+ query_type.type,
+ client_id, service_id,
+ shm_id, shm_offset);
+ error2 = ExecuteEndQueryCmd(test, gl, query_type.type, 1);
+ }
+
+ bool process_success = ProcessQuery(test, gl, query_type.type, service_id);
EXPECT_TRUE(error1 != error::kNoError || error2 != error::kNoError ||
!process_success);
+
+ if (GL_ANY_SAMPLES_PASSED_EXT == query_type.type)
+ EXPECT_CALL(*gl, DeleteQueries(1, _)).Times(1).RetiresOnSaturation();
test->ResetDecoder();
}
@@ -711,6 +769,79 @@ TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTBadMemoryOffsetFails) {
}
}
+TEST_P(GLES2DecoderManualInitTest, QueryReuseTest) {
+ for (size_t i = 0; i < arraysize(kQueryTypes); ++i) {
+ const QueryType& query_type = kQueryTypes[i];
+
+ GLES2DecoderTestBase::InitState init;
+ init.extensions = "GL_EXT_occlusion_query_boolean"
+ " GL_ARB_sync"
+ " GL_ARB_timer_query";
+ init.gl_version = "opengl es 3.0";
+ init.has_alpha = true;
+ init.request_alpha = true;
+ init.bind_generates_resource = true;
+ InitDecoder(init);
+ ::testing::StrictMock< ::gfx::MockGLInterface>* gl = GetGLMock();
+ ::gfx::GPUTimingFake gpu_timing_queries;
+
+ ExecuteGenerateQueryCmd(this, gl, query_type.type,
+ kNewClientId, kNewServiceId);
+
+ // Query once.
+ if (query_type.is_counter) {
+ EXPECT_EQ(error::kNoError, ExecuteQueryCounterCmd(this, gl,
+ &gpu_timing_queries,
+ query_type.type,
+ kNewClientId,
+ kNewServiceId,
+ kSharedMemoryId,
+ kSharedMemoryOffset,
+ 1));
+ } else {
+ EXPECT_EQ(error::kNoError, ExecuteBeginQueryCmd(this, gl,
+ &gpu_timing_queries,
+ query_type.type,
+ kNewClientId,
+ kNewServiceId,
+ kSharedMemoryId,
+ kSharedMemoryOffset));
+ EXPECT_EQ(error::kNoError, ExecuteEndQueryCmd(this, gl,
+ query_type.type, 1));
+ }
+
+ EXPECT_TRUE(ProcessQuery(this, gl, query_type.type, kNewServiceId));
+
+ // Reuse query.
+ if (query_type.is_counter) {
+ EXPECT_EQ(error::kNoError, ExecuteQueryCounterCmd(this, gl,
+ &gpu_timing_queries,
+ query_type.type,
+ kNewClientId,
+ kNewServiceId,
+ kSharedMemoryId,
+ kSharedMemoryOffset,
+ 2));
+ } else {
+ EXPECT_EQ(error::kNoError, ExecuteBeginQueryCmd(this, gl,
+ &gpu_timing_queries,
+ query_type.type,
+ kNewClientId,
+ kNewServiceId,
+ kSharedMemoryId,
+ kSharedMemoryOffset));
+ EXPECT_EQ(error::kNoError, ExecuteEndQueryCmd(this, gl,
+ query_type.type, 2));
+ }
+
+ EXPECT_TRUE(ProcessQuery(this, gl, query_type.type, kNewServiceId));
+
+ if (GL_ANY_SAMPLES_PASSED_EXT == query_type.type)
+ EXPECT_CALL(*gl, DeleteQueries(1, _)).Times(1).RetiresOnSaturation();
+ ResetDecoder();
+ }
+}
+
TEST_P(GLES2DecoderTest, BeginEndQueryEXTCommandsIssuedCHROMIUM) {
BeginQueryEXT begin_cmd;
@@ -798,7 +929,6 @@ TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTCommandsCompletedCHROMIUM) {
ASSERT_TRUE(query != NULL);
EXPECT_FALSE(query->pending());
- GLsync kGlSync = reinterpret_cast<GLsync>(0xdeadbeef);
EXPECT_CALL(*gl_, Flush()).RetiresOnSaturation();
EXPECT_CALL(*gl_, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0))
.WillOnce(Return(kGlSync))
@@ -883,12 +1013,81 @@ TEST_P(GLES2DecoderManualInitTest, BeginInvalidTargetQueryFails) {
EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+ begin_cmd.Init(GL_TIME_ELAPSED,
+ kNewClientId,
+ kSharedMemoryId,
+ kSharedMemoryOffset);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+
begin_cmd.Init(0xdeadbeef,
kNewClientId,
kSharedMemoryId,
kSharedMemoryOffset);
EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
+ EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+}
+
+TEST_P(GLES2DecoderManualInitTest, QueryCounterEXTTimeStamp) {
+ InitState init;
+ init.extensions = "GL_ARB_timer_query";
+ init.gl_version = "opengl 2.0";
+ init.has_alpha = true;
+ init.request_alpha = true;
+ init.bind_generates_resource = true;
+ InitDecoder(init);
+
+ GenHelper<GenQueriesEXTImmediate>(kNewClientId);
+
+ EXPECT_CALL(*gl_, GenQueries(1, _))
+ .WillOnce(SetArgPointee<1>(kNewServiceId))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, QueryCounter(kNewServiceId, GL_TIMESTAMP))
+ .Times(1)
+ .RetiresOnSaturation();
+ QueryCounterEXT query_counter_cmd;
+ query_counter_cmd.Init(kNewClientId,
+ GL_TIMESTAMP,
+ kSharedMemoryId,
+ kSharedMemoryOffset,
+ 1);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(query_counter_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_TRUE(query->pending());
+}
+
+TEST_P(GLES2DecoderManualInitTest, InvalidTargetQueryCounterFails) {
+ InitState init;
+ init.extensions = "";
+ init.gl_version = "opengl es 2.0";
+ init.has_alpha = true;
+ init.request_alpha = true;
+ init.bind_generates_resource = true;
+ InitDecoder(init);
+
+ GenHelper<GenQueriesEXTImmediate>(kNewClientId);
+
+ QueryCounterEXT query_counter_cmd;
+ query_counter_cmd.Init(kNewClientId,
+ GL_TIMESTAMP,
+ kSharedMemoryId,
+ kSharedMemoryOffset,
+ 1);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(query_counter_cmd));
EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+
+ query_counter_cmd.Init(kNewClientId,
+ 0xdeadbeef,
+ kSharedMemoryId,
+ kSharedMemoryOffset,
+ 1);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(query_counter_cmd));
+ EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
}
TEST_P(GLES2DecoderTest, IsEnabledReturnsCachedValue) {