Supervised user import: Listen for profile creation/deletion
[chromium-blink-merge.git] / gpu / command_buffer / service / gles2_cmd_decoder_unittest.cc
blobda06fbdbaca6d2b23dcb35e9e4add6d4b186dd53
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h"
7 #include "base/command_line.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "gpu/command_buffer/common/gles2_cmd_format.h"
10 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
11 #include "gpu/command_buffer/service/async_pixel_transfer_delegate_mock.h"
12 #include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
13 #include "gpu/command_buffer/service/async_pixel_transfer_manager_mock.h"
14 #include "gpu/command_buffer/service/cmd_buffer_engine.h"
15 #include "gpu/command_buffer/service/context_group.h"
16 #include "gpu/command_buffer/service/context_state.h"
17 #include "gpu/command_buffer/service/gl_surface_mock.h"
18 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
19 #include "gpu/command_buffer/service/image_manager.h"
20 #include "gpu/command_buffer/service/mailbox_manager.h"
21 #include "gpu/command_buffer/service/mocks.h"
22 #include "gpu/command_buffer/service/program_manager.h"
23 #include "gpu/command_buffer/service/test_helper.h"
24 #include "gpu/config/gpu_switches.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 #include "ui/gl/gl_implementation.h"
27 #include "ui/gl/gl_mock.h"
28 #include "ui/gl/gl_surface_stub.h"
31 #if !defined(GL_DEPTH24_STENCIL8)
32 #define GL_DEPTH24_STENCIL8 0x88F0
33 #endif
35 using ::gfx::MockGLInterface;
36 using ::testing::_;
37 using ::testing::AtLeast;
38 using ::testing::DoAll;
39 using ::testing::InSequence;
40 using ::testing::Invoke;
41 using ::testing::MatcherCast;
42 using ::testing::Mock;
43 using ::testing::Pointee;
44 using ::testing::Return;
45 using ::testing::SaveArg;
46 using ::testing::SetArrayArgument;
47 using ::testing::SetArgumentPointee;
48 using ::testing::SetArgPointee;
49 using ::testing::StrEq;
50 using ::testing::StrictMock;
52 namespace gpu {
53 namespace gles2 {
55 using namespace cmds;
57 void GLES2DecoderRGBBackbufferTest::SetUp() {
58 // Test codepath with workaround clear_alpha_in_readpixels because
59 // ReadPixelsEmulator emulates the incorrect driver behavior.
60 base::CommandLine command_line(0, NULL);
61 command_line.AppendSwitchASCII(
62 switches::kGpuDriverBugWorkarounds,
63 base::IntToString(gpu::CLEAR_ALPHA_IN_READPIXELS));
64 InitState init;
65 init.bind_generates_resource = true;
66 InitDecoderWithCommandLine(init, &command_line);
67 SetupDefaultProgram();
70 // Override default setup so nothing gets setup.
71 void GLES2DecoderManualInitTest::SetUp() {
74 void GLES2DecoderManualInitTest::EnableDisableTest(GLenum cap,
75 bool enable,
76 bool expect_set) {
77 if (expect_set) {
78 SetupExpectationsForEnableDisable(cap, enable);
80 if (enable) {
81 Enable cmd;
82 cmd.Init(cap);
83 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
84 EXPECT_EQ(GL_NO_ERROR, GetGLError());
85 } else {
86 Disable cmd;
87 cmd.Init(cap);
88 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
89 EXPECT_EQ(GL_NO_ERROR, GetGLError());
93 void GLES3DecoderTest::SetUp() {
94 // Test codepath with workaround clear_alpha_in_readpixels because
95 // ReadPixelsEmulator emulates the incorrect driver behavior.
96 base::CommandLine command_line(0, NULL);
97 command_line.AppendSwitch(switches::kEnableUnsafeES3APIs);
98 InitState init;
99 init.gl_version = "4.4";
100 init.bind_generates_resource = true;
101 InitDecoderWithCommandLine(init, &command_line);
105 TEST_P(GLES2DecoderTest, GetIntegervCached) {
106 struct TestInfo {
107 GLenum pname;
108 GLint expected;
110 TestInfo tests[] = {
112 GL_MAX_TEXTURE_SIZE, TestHelper::kMaxTextureSize,
115 GL_MAX_CUBE_MAP_TEXTURE_SIZE, TestHelper::kMaxCubeMapTextureSize,
118 GL_MAX_RENDERBUFFER_SIZE, TestHelper::kMaxRenderbufferSize,
121 typedef GetIntegerv::Result Result;
122 for (size_t ii = 0; ii < sizeof(tests) / sizeof(tests[0]); ++ii) {
123 const TestInfo& test = tests[ii];
124 Result* result = static_cast<Result*>(shared_memory_address_);
125 EXPECT_CALL(*gl_, GetError())
126 .WillOnce(Return(GL_NO_ERROR))
127 .WillOnce(Return(GL_NO_ERROR))
128 .RetiresOnSaturation();
129 EXPECT_CALL(*gl_, GetIntegerv(test.pname, _)).Times(0);
130 result->size = 0;
131 GetIntegerv cmd2;
132 cmd2.Init(test.pname, shared_memory_id_, shared_memory_offset_);
133 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
134 EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(test.pname),
135 result->GetNumResults());
136 EXPECT_EQ(GL_NO_ERROR, GetGLError());
137 EXPECT_EQ(test.expected, result->GetData()[0]);
141 TEST_P(GLES2DecoderWithShaderTest, GetMaxValueInBufferCHROMIUM) {
142 SetupIndexBuffer();
143 GetMaxValueInBufferCHROMIUM::Result* result =
144 static_cast<GetMaxValueInBufferCHROMIUM::Result*>(shared_memory_address_);
145 *result = 0;
147 GetMaxValueInBufferCHROMIUM cmd;
148 cmd.Init(client_element_buffer_id_,
149 kValidIndexRangeCount,
150 GL_UNSIGNED_SHORT,
151 kValidIndexRangeStart * 2,
152 kSharedMemoryId,
153 kSharedMemoryOffset);
154 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
155 EXPECT_EQ(7u, *result);
156 EXPECT_EQ(GL_NO_ERROR, GetGLError());
157 cmd.Init(client_element_buffer_id_,
158 kValidIndexRangeCount + 1,
159 GL_UNSIGNED_SHORT,
160 kValidIndexRangeStart * 2,
161 kSharedMemoryId,
162 kSharedMemoryOffset);
163 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
164 EXPECT_EQ(100u, *result);
165 EXPECT_EQ(GL_NO_ERROR, GetGLError());
167 cmd.Init(kInvalidClientId,
168 kValidIndexRangeCount,
169 GL_UNSIGNED_SHORT,
170 kValidIndexRangeStart * 2,
171 kSharedMemoryId,
172 kSharedMemoryOffset);
173 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
174 EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
175 cmd.Init(client_element_buffer_id_,
176 kOutOfRangeIndexRangeEnd,
177 GL_UNSIGNED_SHORT,
178 kValidIndexRangeStart * 2,
179 kSharedMemoryId,
180 kSharedMemoryOffset);
181 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
182 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
183 cmd.Init(client_element_buffer_id_,
184 kValidIndexRangeCount + 1,
185 GL_UNSIGNED_SHORT,
186 kOutOfRangeIndexRangeEnd * 2,
187 kSharedMemoryId,
188 kSharedMemoryOffset);
189 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
190 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
191 cmd.Init(client_element_buffer_id_,
192 kValidIndexRangeCount + 1,
193 GL_UNSIGNED_SHORT,
194 kValidIndexRangeStart * 2,
195 kSharedMemoryId,
196 kSharedMemoryOffset);
197 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
198 cmd.Init(client_buffer_id_,
199 kValidIndexRangeCount + 1,
200 GL_UNSIGNED_SHORT,
201 kValidIndexRangeStart * 2,
202 kSharedMemoryId,
203 kSharedMemoryOffset);
204 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
205 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
206 cmd.Init(client_element_buffer_id_,
207 kValidIndexRangeCount + 1,
208 GL_UNSIGNED_SHORT,
209 kValidIndexRangeStart * 2,
210 kInvalidSharedMemoryId,
211 kSharedMemoryOffset);
212 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
213 cmd.Init(client_element_buffer_id_,
214 kValidIndexRangeCount + 1,
215 GL_UNSIGNED_SHORT,
216 kValidIndexRangeStart * 2,
217 kSharedMemoryId,
218 kInvalidSharedMemoryOffset);
219 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
222 TEST_P(GLES2DecoderTest, IsBuffer) {
223 EXPECT_FALSE(DoIsBuffer(client_buffer_id_));
224 DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
225 EXPECT_TRUE(DoIsBuffer(client_buffer_id_));
226 DoDeleteBuffer(client_buffer_id_, kServiceBufferId);
227 EXPECT_FALSE(DoIsBuffer(client_buffer_id_));
230 TEST_P(GLES2DecoderTest, IsFramebuffer) {
231 EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_));
232 DoBindFramebuffer(
233 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
234 EXPECT_TRUE(DoIsFramebuffer(client_framebuffer_id_));
235 DoDeleteFramebuffer(client_framebuffer_id_,
236 kServiceFramebufferId,
237 true,
238 GL_FRAMEBUFFER,
240 true,
241 GL_FRAMEBUFFER,
243 EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_));
246 TEST_P(GLES2DecoderTest, IsProgram) {
247 // IsProgram is true as soon as the program is created.
248 EXPECT_TRUE(DoIsProgram(client_program_id_));
249 EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId))
250 .Times(1)
251 .RetiresOnSaturation();
252 DoDeleteProgram(client_program_id_, kServiceProgramId);
253 EXPECT_FALSE(DoIsProgram(client_program_id_));
256 TEST_P(GLES2DecoderTest, IsRenderbuffer) {
257 EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_));
258 DoBindRenderbuffer(
259 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
260 EXPECT_TRUE(DoIsRenderbuffer(client_renderbuffer_id_));
261 DoDeleteRenderbuffer(client_renderbuffer_id_, kServiceRenderbufferId);
262 EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_));
265 TEST_P(GLES2DecoderTest, IsShader) {
266 // IsShader is true as soon as the program is created.
267 EXPECT_TRUE(DoIsShader(client_shader_id_));
268 DoDeleteShader(client_shader_id_, kServiceShaderId);
269 EXPECT_FALSE(DoIsShader(client_shader_id_));
272 TEST_P(GLES2DecoderTest, IsTexture) {
273 EXPECT_FALSE(DoIsTexture(client_texture_id_));
274 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
275 EXPECT_TRUE(DoIsTexture(client_texture_id_));
276 DoDeleteTexture(client_texture_id_, kServiceTextureId);
277 EXPECT_FALSE(DoIsTexture(client_texture_id_));
280 TEST_P(GLES2DecoderTest, ClientWaitSyncValid) {
281 typedef cmds::ClientWaitSync::Result Result;
282 Result* result = static_cast<Result*>(shared_memory_address_);
283 cmds::ClientWaitSync cmd;
284 uint32_t v32_0 = 0, v32_1 = 0;
285 GLES2Util::MapUint64ToTwoUint32(0, &v32_0, &v32_1);
286 cmd.Init(client_sync_id_, GL_SYNC_FLUSH_COMMANDS_BIT, v32_0, v32_1,
287 shared_memory_id_, shared_memory_offset_);
288 EXPECT_CALL(*gl_,
289 ClientWaitSync(reinterpret_cast<GLsync>(kServiceSyncId),
290 GL_SYNC_FLUSH_COMMANDS_BIT, 0))
291 .WillOnce(Return(GL_CONDITION_SATISFIED))
292 .RetiresOnSaturation();
293 *result = GL_WAIT_FAILED;
294 decoder_->set_unsafe_es3_apis_enabled(true);
295 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
296 EXPECT_EQ(static_cast<GLenum>(GL_CONDITION_SATISFIED), *result);
297 EXPECT_EQ(GL_NO_ERROR, GetGLError());
298 decoder_->set_unsafe_es3_apis_enabled(false);
299 EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
302 TEST_P(GLES2DecoderTest, ClientWaitSyncNonZeroTimeoutValid) {
303 typedef cmds::ClientWaitSync::Result Result;
304 Result* result = static_cast<Result*>(shared_memory_address_);
305 cmds::ClientWaitSync cmd;
306 const GLuint64 kTimeout = 0xABCDEF0123456789;
307 uint32_t v32_0 = 0, v32_1 = 0;
308 GLES2Util::MapUint64ToTwoUint32(kTimeout, &v32_0, &v32_1);
309 cmd.Init(client_sync_id_, GL_SYNC_FLUSH_COMMANDS_BIT, v32_0, v32_1,
310 shared_memory_id_, shared_memory_offset_);
311 EXPECT_CALL(*gl_,
312 ClientWaitSync(reinterpret_cast<GLsync>(kServiceSyncId),
313 GL_SYNC_FLUSH_COMMANDS_BIT, kTimeout))
314 .WillOnce(Return(GL_CONDITION_SATISFIED))
315 .RetiresOnSaturation();
316 *result = GL_WAIT_FAILED;
317 decoder_->set_unsafe_es3_apis_enabled(true);
318 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
319 EXPECT_EQ(static_cast<GLenum>(GL_CONDITION_SATISFIED), *result);
320 EXPECT_EQ(GL_NO_ERROR, GetGLError());
321 decoder_->set_unsafe_es3_apis_enabled(false);
322 EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
325 TEST_P(GLES2DecoderTest, ClientWaitSyncInvalidSyncFails) {
326 typedef cmds::ClientWaitSync::Result Result;
327 Result* result = static_cast<Result*>(shared_memory_address_);
328 cmds::ClientWaitSync cmd;
329 uint32_t v32_0 = 0, v32_1 = 0;
330 GLES2Util::MapUint64ToTwoUint32(0, &v32_0, &v32_1);
331 decoder_->set_unsafe_es3_apis_enabled(true);
332 cmd.Init(kInvalidClientId, GL_SYNC_FLUSH_COMMANDS_BIT, v32_0, v32_1,
333 shared_memory_id_, shared_memory_offset_);
334 *result = GL_WAIT_FAILED;
335 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
336 EXPECT_EQ(static_cast<GLenum>(GL_WAIT_FAILED), *result);
337 EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
340 TEST_P(GLES2DecoderTest, ClientWaitSyncResultNotInitFails) {
341 typedef cmds::ClientWaitSync::Result Result;
342 Result* result = static_cast<Result*>(shared_memory_address_);
343 cmds::ClientWaitSync cmd;
344 uint32_t v32_0 = 0, v32_1 = 0;
345 GLES2Util::MapUint64ToTwoUint32(0, &v32_0, &v32_1);
346 decoder_->set_unsafe_es3_apis_enabled(true);
347 cmd.Init(client_sync_id_, GL_SYNC_FLUSH_COMMANDS_BIT, v32_0, v32_1,
348 shared_memory_id_, shared_memory_offset_);
349 *result = 1; // Any value other than GL_WAIT_FAILED
350 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
353 TEST_P(GLES2DecoderTest, ClientWaitSyncBadSharedMemoryFails) {
354 typedef cmds::ClientWaitSync::Result Result;
355 Result* result = static_cast<Result*>(shared_memory_address_);
356 cmds::ClientWaitSync cmd;
357 uint32_t v32_0 = 0, v32_1 = 0;
358 GLES2Util::MapUint64ToTwoUint32(0, &v32_0, &v32_1);
359 decoder_->set_unsafe_es3_apis_enabled(true);
360 *result = GL_WAIT_FAILED;
361 cmd.Init(client_sync_id_, GL_SYNC_FLUSH_COMMANDS_BIT, v32_0, v32_1,
362 kInvalidSharedMemoryId, shared_memory_offset_);
363 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
365 *result = GL_WAIT_FAILED;
366 cmd.Init(client_sync_id_, GL_SYNC_FLUSH_COMMANDS_BIT, v32_0, v32_1,
367 shared_memory_id_, kInvalidSharedMemoryOffset);
368 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
371 TEST_P(GLES2DecoderTest, WaitSyncValidArgs) {
372 const GLuint64 kTimeout = GL_TIMEOUT_IGNORED;
373 EXPECT_CALL(*gl_, WaitSync(reinterpret_cast<GLsync>(kServiceSyncId),
374 0, kTimeout))
375 .Times(1)
376 .RetiresOnSaturation();
378 uint32_t v32_0 = 0, v32_1 = 0;
379 GLES2Util::MapUint64ToTwoUint32(kTimeout, &v32_0, &v32_1);
380 cmds::WaitSync cmd;
381 cmd.Init(client_sync_id_, 0, v32_0, v32_1);
382 decoder_->set_unsafe_es3_apis_enabled(true);
383 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
384 EXPECT_EQ(GL_NO_ERROR, GetGLError());
385 decoder_->set_unsafe_es3_apis_enabled(false);
386 EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
389 TEST_P(GLES2DecoderManualInitTest, BindGeneratesResourceFalse) {
390 InitState init;
391 InitDecoder(init);
393 BindTexture cmd1;
394 cmd1.Init(GL_TEXTURE_2D, kInvalidClientId);
395 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
396 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
398 BindBuffer cmd2;
399 cmd2.Init(GL_ARRAY_BUFFER, kInvalidClientId);
400 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
401 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
403 BindFramebuffer cmd3;
404 cmd3.Init(GL_FRAMEBUFFER, kInvalidClientId);
405 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd3));
406 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
408 BindRenderbuffer cmd4;
409 cmd4.Init(GL_RENDERBUFFER, kInvalidClientId);
410 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd4));
411 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
414 TEST_P(GLES2DecoderTest, EnableFeatureCHROMIUMBadBucket) {
415 const uint32 kBadBucketId = 123;
416 EnableFeatureCHROMIUM cmd;
417 cmd.Init(kBadBucketId, shared_memory_id_, shared_memory_offset_);
418 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
421 TEST_P(GLES2DecoderTest, RequestExtensionCHROMIUMBadBucket) {
422 const uint32 kBadBucketId = 123;
423 RequestExtensionCHROMIUM cmd;
424 cmd.Init(kBadBucketId);
425 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
428 TEST_P(GLES2DecoderTest, BeginQueryEXTDisabled) {
429 // Test something fails if off.
432 TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXT) {
433 InitState init;
434 init.extensions = "GL_EXT_occlusion_query_boolean";
435 init.gl_version = "opengl es 2.0";
436 init.has_alpha = true;
437 init.request_alpha = true;
438 init.bind_generates_resource = true;
439 InitDecoder(init);
441 // Test end fails if no begin.
442 EndQueryEXT end_cmd;
443 end_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, 1);
444 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
445 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
447 BeginQueryEXT begin_cmd;
449 // Test id = 0 fails.
450 begin_cmd.Init(
451 GL_ANY_SAMPLES_PASSED_EXT, 0, kSharedMemoryId, kSharedMemoryOffset);
452 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
453 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
455 GenHelper<GenQueriesEXTImmediate>(kNewClientId);
457 // Test valid parameters work.
458 EXPECT_CALL(*gl_, GenQueries(1, _))
459 .WillOnce(SetArgumentPointee<1>(kNewServiceId))
460 .RetiresOnSaturation();
461 EXPECT_CALL(*gl_, BeginQuery(GL_ANY_SAMPLES_PASSED_EXT, kNewServiceId))
462 .Times(1)
463 .RetiresOnSaturation();
465 // Query object should not be created untill BeginQueriesEXT.
466 QueryManager* query_manager = decoder_->GetQueryManager();
467 ASSERT_TRUE(query_manager != NULL);
468 QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
469 EXPECT_TRUE(query == NULL);
471 // BeginQueryEXT should fail if id is not generated from GenQueriesEXT.
472 begin_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT,
473 kInvalidClientId,
474 kSharedMemoryId,
475 kSharedMemoryOffset);
476 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
477 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
479 begin_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT,
480 kNewClientId,
481 kSharedMemoryId,
482 kSharedMemoryOffset);
483 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
484 EXPECT_EQ(GL_NO_ERROR, GetGLError());
486 // After BeginQueriesEXT id name should have query object associated with it.
487 query = query_manager->GetQuery(kNewClientId);
488 ASSERT_TRUE(query != NULL);
489 EXPECT_FALSE(query->pending());
491 // Test trying begin again fails
492 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
493 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
495 // Test end fails with different target
496 end_cmd.Init(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, 1);
497 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
498 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
500 // Test end succeeds
501 EXPECT_CALL(*gl_, EndQuery(GL_ANY_SAMPLES_PASSED_EXT))
502 .Times(1)
503 .RetiresOnSaturation();
504 end_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, 1);
505 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
506 EXPECT_EQ(GL_NO_ERROR, GetGLError());
507 EXPECT_TRUE(query->pending());
509 EXPECT_CALL(*gl_, DeleteQueries(1, _)).Times(1).RetiresOnSaturation();
512 struct QueryType {
513 GLenum type;
514 bool is_gl;
517 const QueryType kQueryTypes[] = {
518 {GL_COMMANDS_ISSUED_CHROMIUM, false},
519 {GL_LATENCY_QUERY_CHROMIUM, false},
520 {GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM, false},
521 {GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, false},
522 {GL_GET_ERROR_QUERY_CHROMIUM, false},
523 {GL_COMMANDS_COMPLETED_CHROMIUM, false},
524 {GL_ANY_SAMPLES_PASSED_EXT, true},
527 static void CheckBeginEndQueryBadMemoryFails(GLES2DecoderTestBase* test,
528 GLuint client_id,
529 GLuint service_id,
530 const QueryType& query_type,
531 int32 shm_id,
532 uint32 shm_offset) {
533 // We need to reset the decoder on each iteration, because we lose the
534 // context every time.
535 GLES2DecoderTestBase::InitState init;
536 init.extensions = "GL_EXT_occlusion_query_boolean GL_ARB_sync";
537 init.gl_version = "opengl es 2.0";
538 init.has_alpha = true;
539 init.request_alpha = true;
540 init.bind_generates_resource = true;
541 test->InitDecoder(init);
542 ::testing::StrictMock< ::gfx::MockGLInterface>* gl = test->GetGLMock();
544 BeginQueryEXT begin_cmd;
546 test->GenHelper<GenQueriesEXTImmediate>(client_id);
548 if (query_type.is_gl) {
549 EXPECT_CALL(*gl, GenQueries(1, _))
550 .WillOnce(SetArgumentPointee<1>(service_id))
551 .RetiresOnSaturation();
552 EXPECT_CALL(*gl, BeginQuery(query_type.type, service_id))
553 .Times(1)
554 .RetiresOnSaturation();
557 // Test bad shared memory fails
558 begin_cmd.Init(query_type.type, client_id, shm_id, shm_offset);
559 error::Error error1 = test->ExecuteCmd(begin_cmd);
561 if (query_type.is_gl) {
562 EXPECT_CALL(*gl, EndQuery(query_type.type))
563 .Times(1)
564 .RetiresOnSaturation();
566 if (query_type.type == GL_GET_ERROR_QUERY_CHROMIUM) {
567 EXPECT_CALL(*gl, GetError())
568 .WillOnce(Return(GL_NO_ERROR))
569 .RetiresOnSaturation();
571 GLsync kGlSync = reinterpret_cast<GLsync>(0xdeadbeef);
572 if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM) {
573 EXPECT_CALL(*gl, Flush()).RetiresOnSaturation();
574 EXPECT_CALL(*gl, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0))
575 .WillOnce(Return(kGlSync))
576 .RetiresOnSaturation();
577 #if DCHECK_IS_ON()
578 EXPECT_CALL(*gl, IsSync(kGlSync))
579 .WillOnce(Return(GL_TRUE))
580 .RetiresOnSaturation();
581 #endif
584 EndQueryEXT end_cmd;
585 end_cmd.Init(query_type.type, 1);
586 error::Error error2 = test->ExecuteCmd(end_cmd);
588 if (query_type.is_gl) {
589 EXPECT_CALL(
590 *gl, GetQueryObjectuiv(service_id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
591 .WillOnce(SetArgumentPointee<2>(1))
592 .RetiresOnSaturation();
593 EXPECT_CALL(*gl, GetQueryObjectuiv(service_id, GL_QUERY_RESULT_EXT, _))
594 .WillOnce(SetArgumentPointee<2>(1))
595 .RetiresOnSaturation();
597 if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM) {
598 #if DCHECK_IS_ON()
599 EXPECT_CALL(*gl, IsSync(kGlSync))
600 .WillOnce(Return(GL_TRUE))
601 .RetiresOnSaturation();
602 #endif
603 EXPECT_CALL(*gl, ClientWaitSync(kGlSync, _, _))
604 .WillOnce(Return(GL_ALREADY_SIGNALED))
605 .RetiresOnSaturation();
608 QueryManager* query_manager = test->GetDecoder()->GetQueryManager();
609 ASSERT_TRUE(query_manager != NULL);
610 bool process_success = query_manager->ProcessPendingQueries(false);
612 EXPECT_TRUE(error1 != error::kNoError || error2 != error::kNoError ||
613 !process_success);
615 if (query_type.is_gl) {
616 EXPECT_CALL(*gl, DeleteQueries(1, _)).Times(1).RetiresOnSaturation();
618 if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM) {
619 #if DCHECK_IS_ON()
620 EXPECT_CALL(*gl, IsSync(kGlSync))
621 .WillOnce(Return(GL_TRUE))
622 .RetiresOnSaturation();
623 #endif
624 EXPECT_CALL(*gl, DeleteSync(kGlSync)).Times(1).RetiresOnSaturation();
626 test->ResetDecoder();
629 TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTBadMemoryIdFails) {
630 for (size_t i = 0; i < arraysize(kQueryTypes); ++i) {
631 CheckBeginEndQueryBadMemoryFails(this,
632 kNewClientId,
633 kNewServiceId,
634 kQueryTypes[i],
635 kInvalidSharedMemoryId,
636 kSharedMemoryOffset);
640 TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTBadMemoryOffsetFails) {
641 for (size_t i = 0; i < arraysize(kQueryTypes); ++i) {
642 // Out-of-bounds.
643 CheckBeginEndQueryBadMemoryFails(this,
644 kNewClientId,
645 kNewServiceId,
646 kQueryTypes[i],
647 kSharedMemoryId,
648 kInvalidSharedMemoryOffset);
649 // Overflow.
650 CheckBeginEndQueryBadMemoryFails(this,
651 kNewClientId,
652 kNewServiceId,
653 kQueryTypes[i],
654 kSharedMemoryId,
655 0xfffffffcu);
659 TEST_P(GLES2DecoderTest, BeginEndQueryEXTCommandsIssuedCHROMIUM) {
660 BeginQueryEXT begin_cmd;
662 GenHelper<GenQueriesEXTImmediate>(kNewClientId);
664 // Test valid parameters work.
665 begin_cmd.Init(GL_COMMANDS_ISSUED_CHROMIUM,
666 kNewClientId,
667 kSharedMemoryId,
668 kSharedMemoryOffset);
669 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
670 EXPECT_EQ(GL_NO_ERROR, GetGLError());
672 QueryManager* query_manager = decoder_->GetQueryManager();
673 ASSERT_TRUE(query_manager != NULL);
674 QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
675 ASSERT_TRUE(query != NULL);
676 EXPECT_FALSE(query->pending());
678 // Test end succeeds
679 EndQueryEXT end_cmd;
680 end_cmd.Init(GL_COMMANDS_ISSUED_CHROMIUM, 1);
681 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
682 EXPECT_EQ(GL_NO_ERROR, GetGLError());
683 EXPECT_FALSE(query->pending());
686 TEST_P(GLES2DecoderTest, BeginEndQueryEXTGetErrorQueryCHROMIUM) {
687 BeginQueryEXT begin_cmd;
689 GenHelper<GenQueriesEXTImmediate>(kNewClientId);
691 // Test valid parameters work.
692 begin_cmd.Init(GL_GET_ERROR_QUERY_CHROMIUM,
693 kNewClientId,
694 kSharedMemoryId,
695 kSharedMemoryOffset);
696 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
697 EXPECT_EQ(GL_NO_ERROR, GetGLError());
699 QueryManager* query_manager = decoder_->GetQueryManager();
700 ASSERT_TRUE(query_manager != NULL);
701 QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
702 ASSERT_TRUE(query != NULL);
703 EXPECT_FALSE(query->pending());
705 // Test end succeeds
706 QuerySync* sync = static_cast<QuerySync*>(shared_memory_address_);
708 EXPECT_CALL(*gl_, GetError())
709 .WillOnce(Return(GL_INVALID_VALUE))
710 .RetiresOnSaturation();
712 EndQueryEXT end_cmd;
713 end_cmd.Init(GL_GET_ERROR_QUERY_CHROMIUM, 1);
714 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
715 EXPECT_EQ(GL_NO_ERROR, GetGLError());
716 EXPECT_FALSE(query->pending());
717 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE),
718 static_cast<GLenum>(sync->result));
721 TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTCommandsCompletedCHROMIUM) {
722 InitState init;
723 init.extensions = "GL_EXT_occlusion_query_boolean GL_ARB_sync";
724 init.gl_version = "opengl es 2.0";
725 init.has_alpha = true;
726 init.request_alpha = true;
727 init.bind_generates_resource = true;
728 InitDecoder(init);
730 GenHelper<GenQueriesEXTImmediate>(kNewClientId);
732 BeginQueryEXT begin_cmd;
733 begin_cmd.Init(GL_COMMANDS_COMPLETED_CHROMIUM,
734 kNewClientId,
735 kSharedMemoryId,
736 kSharedMemoryOffset);
737 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
738 EXPECT_EQ(GL_NO_ERROR, GetGLError());
740 QueryManager* query_manager = decoder_->GetQueryManager();
741 ASSERT_TRUE(query_manager != NULL);
742 QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
743 ASSERT_TRUE(query != NULL);
744 EXPECT_FALSE(query->pending());
746 GLsync kGlSync = reinterpret_cast<GLsync>(0xdeadbeef);
747 EXPECT_CALL(*gl_, Flush()).RetiresOnSaturation();
748 EXPECT_CALL(*gl_, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0))
749 .WillOnce(Return(kGlSync))
750 .RetiresOnSaturation();
751 #if DCHECK_IS_ON()
752 EXPECT_CALL(*gl_, IsSync(kGlSync))
753 .WillOnce(Return(GL_TRUE))
754 .RetiresOnSaturation();
755 #endif
757 EndQueryEXT end_cmd;
758 end_cmd.Init(GL_COMMANDS_COMPLETED_CHROMIUM, 1);
759 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
760 EXPECT_EQ(GL_NO_ERROR, GetGLError());
761 EXPECT_TRUE(query->pending());
763 #if DCHECK_IS_ON()
764 EXPECT_CALL(*gl_, IsSync(kGlSync))
765 .WillOnce(Return(GL_TRUE))
766 .RetiresOnSaturation();
767 #endif
768 EXPECT_CALL(*gl_, ClientWaitSync(kGlSync, _, _))
769 .WillOnce(Return(GL_TIMEOUT_EXPIRED))
770 .RetiresOnSaturation();
771 bool process_success = query_manager->ProcessPendingQueries(false);
773 EXPECT_TRUE(process_success);
774 EXPECT_TRUE(query->pending());
776 #if DCHECK_IS_ON()
777 EXPECT_CALL(*gl_, IsSync(kGlSync))
778 .WillOnce(Return(GL_TRUE))
779 .RetiresOnSaturation();
780 #endif
781 EXPECT_CALL(*gl_, ClientWaitSync(kGlSync, _, _))
782 .WillOnce(Return(GL_ALREADY_SIGNALED))
783 .RetiresOnSaturation();
784 process_success = query_manager->ProcessPendingQueries(false);
786 EXPECT_TRUE(process_success);
787 EXPECT_FALSE(query->pending());
789 #if DCHECK_IS_ON()
790 EXPECT_CALL(*gl_, IsSync(kGlSync))
791 .WillOnce(Return(GL_TRUE))
792 .RetiresOnSaturation();
793 #endif
794 EXPECT_CALL(*gl_, DeleteSync(kGlSync)).Times(1).RetiresOnSaturation();
795 ResetDecoder();
798 TEST_P(GLES2DecoderTest, IsEnabledReturnsCachedValue) {
799 // NOTE: There are no expectations because no GL functions should be
800 // called for DEPTH_TEST or STENCIL_TEST
801 static const GLenum kStates[] = {
802 GL_DEPTH_TEST, GL_STENCIL_TEST,
804 for (size_t ii = 0; ii < arraysize(kStates); ++ii) {
805 Enable enable_cmd;
806 GLenum state = kStates[ii];
807 enable_cmd.Init(state);
808 EXPECT_EQ(error::kNoError, ExecuteCmd(enable_cmd));
809 IsEnabled::Result* result =
810 static_cast<IsEnabled::Result*>(shared_memory_address_);
811 IsEnabled is_enabled_cmd;
812 is_enabled_cmd.Init(state, shared_memory_id_, shared_memory_offset_);
813 EXPECT_EQ(error::kNoError, ExecuteCmd(is_enabled_cmd));
814 EXPECT_NE(0u, *result);
815 Disable disable_cmd;
816 disable_cmd.Init(state);
817 EXPECT_EQ(error::kNoError, ExecuteCmd(disable_cmd));
818 EXPECT_EQ(error::kNoError, ExecuteCmd(is_enabled_cmd));
819 EXPECT_EQ(0u, *result);
823 TEST_P(GLES2DecoderManualInitTest, GpuMemoryManagerCHROMIUM) {
824 InitState init;
825 init.extensions = "GL_ARB_texture_rectangle";
826 init.bind_generates_resource = true;
827 InitDecoder(init);
829 Texture* texture = GetTexture(client_texture_id_)->texture();
830 EXPECT_TRUE(texture != NULL);
831 EXPECT_TRUE(texture->pool() == GL_TEXTURE_POOL_UNMANAGED_CHROMIUM);
833 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
835 TexParameteri cmd;
836 cmd.Init(GL_TEXTURE_2D,
837 GL_TEXTURE_POOL_CHROMIUM,
838 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM);
839 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
840 EXPECT_EQ(GL_NO_ERROR, GetGLError());
842 cmd.Init(GL_TEXTURE_2D,
843 GL_TEXTURE_POOL_CHROMIUM,
844 GL_TEXTURE_POOL_MANAGED_CHROMIUM);
845 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
846 EXPECT_EQ(GL_NO_ERROR, GetGLError());
848 EXPECT_TRUE(texture->pool() == GL_TEXTURE_POOL_MANAGED_CHROMIUM);
850 cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_POOL_CHROMIUM, GL_NONE);
851 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
852 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
855 namespace {
857 class SizeOnlyMemoryTracker : public MemoryTracker {
858 public:
859 SizeOnlyMemoryTracker() {
860 // These are the default textures. 1 for TEXTURE_2D and 6 faces for
861 // TEXTURE_CUBE_MAP.
862 const size_t kInitialUnmanagedPoolSize = 7 * 4;
863 const size_t kInitialManagedPoolSize = 0;
864 pool_infos_[MemoryTracker::kUnmanaged].initial_size =
865 kInitialUnmanagedPoolSize;
866 pool_infos_[MemoryTracker::kManaged].initial_size = kInitialManagedPoolSize;
869 // Ensure a certain amount of GPU memory is free. Returns true on success.
870 MOCK_METHOD1(EnsureGPUMemoryAvailable, bool(size_t size_needed));
872 virtual void TrackMemoryAllocatedChange(size_t old_size,
873 size_t new_size,
874 Pool pool) {
875 PoolInfo& info = pool_infos_[pool];
876 info.size += new_size - old_size;
879 size_t GetPoolSize(Pool pool) {
880 const PoolInfo& info = pool_infos_[pool];
881 return info.size - info.initial_size;
884 private:
885 virtual ~SizeOnlyMemoryTracker() {}
886 struct PoolInfo {
887 PoolInfo() : initial_size(0), size(0) {}
888 size_t initial_size;
889 size_t size;
891 std::map<Pool, PoolInfo> pool_infos_;
894 } // anonymous namespace.
896 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerInitialSize) {
897 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
898 new SizeOnlyMemoryTracker();
899 set_memory_tracker(memory_tracker.get());
900 InitState init;
901 init.bind_generates_resource = true;
902 InitDecoder(init);
903 // Expect that initial size - size is 0.
904 EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
905 EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kManaged));
908 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerTexImage2D) {
909 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
910 new SizeOnlyMemoryTracker();
911 set_memory_tracker(memory_tracker.get());
912 InitState init;
913 init.bind_generates_resource = true;
914 InitDecoder(init);
915 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
916 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
917 .WillOnce(Return(true))
918 .RetiresOnSaturation();
919 DoTexImage2D(GL_TEXTURE_2D,
921 GL_RGBA,
925 GL_RGBA,
926 GL_UNSIGNED_BYTE,
927 kSharedMemoryId,
928 kSharedMemoryOffset);
929 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
930 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(64))
931 .WillOnce(Return(true))
932 .RetiresOnSaturation();
933 DoTexImage2D(GL_TEXTURE_2D,
935 GL_RGBA,
939 GL_RGBA,
940 GL_UNSIGNED_BYTE,
941 kSharedMemoryId,
942 kSharedMemoryOffset);
943 EXPECT_EQ(64u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
944 EXPECT_EQ(GL_NO_ERROR, GetGLError());
945 // Check we get out of memory and no call to glTexImage2D if Ensure fails.
946 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(64))
947 .WillOnce(Return(false))
948 .RetiresOnSaturation();
949 TexImage2D cmd;
950 cmd.Init(GL_TEXTURE_2D,
952 GL_RGBA,
955 GL_RGBA,
956 GL_UNSIGNED_BYTE,
957 kSharedMemoryId,
958 kSharedMemoryOffset);
959 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
960 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
961 EXPECT_EQ(64u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
964 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerTexStorage2DEXT) {
965 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
966 new SizeOnlyMemoryTracker();
967 set_memory_tracker(memory_tracker.get());
968 InitState init;
969 init.bind_generates_resource = true;
970 InitDecoder(init);
971 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
972 // Check we get out of memory and no call to glTexStorage2DEXT
973 // if Ensure fails.
974 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
975 .WillOnce(Return(false))
976 .RetiresOnSaturation();
977 TexStorage2DEXT cmd;
978 cmd.Init(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 4);
979 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
980 EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
981 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
984 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerCopyTexImage2D) {
985 GLenum target = GL_TEXTURE_2D;
986 GLint level = 0;
987 GLenum internal_format = GL_RGBA;
988 GLsizei width = 4;
989 GLsizei height = 8;
990 GLint border = 0;
991 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
992 new SizeOnlyMemoryTracker();
993 set_memory_tracker(memory_tracker.get());
994 InitState init;
995 init.has_alpha = true;
996 init.request_alpha = true;
997 init.bind_generates_resource = true;
998 InitDecoder(init);
999 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
1000 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1001 .WillOnce(Return(true))
1002 .RetiresOnSaturation();
1003 EXPECT_CALL(*gl_, GetError())
1004 .WillOnce(Return(GL_NO_ERROR))
1005 .WillOnce(Return(GL_NO_ERROR))
1006 .RetiresOnSaturation();
1007 EXPECT_CALL(*gl_,
1008 CopyTexImage2D(
1009 target, level, internal_format, 0, 0, width, height, border))
1010 .Times(1)
1011 .RetiresOnSaturation();
1012 CopyTexImage2D cmd;
1013 cmd.Init(target, level, internal_format, 0, 0, width, height);
1014 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1015 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1016 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1017 // Check we get out of memory and no call to glCopyTexImage2D if Ensure fails.
1018 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1019 .WillOnce(Return(false))
1020 .RetiresOnSaturation();
1021 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1022 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
1023 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1026 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerRenderbufferStorage) {
1027 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
1028 new SizeOnlyMemoryTracker();
1029 set_memory_tracker(memory_tracker.get());
1030 InitState init;
1031 init.bind_generates_resource = true;
1032 InitDecoder(init);
1033 DoBindRenderbuffer(
1034 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
1035 EnsureRenderbufferBound(false);
1036 EXPECT_CALL(*gl_, GetError())
1037 .WillOnce(Return(GL_NO_ERROR))
1038 .WillOnce(Return(GL_NO_ERROR))
1039 .RetiresOnSaturation();
1040 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1041 .WillOnce(Return(true))
1042 .RetiresOnSaturation();
1043 EXPECT_CALL(*gl_, RenderbufferStorageEXT(GL_RENDERBUFFER, GL_RGBA, 8, 4))
1044 .Times(1)
1045 .RetiresOnSaturation();
1046 RenderbufferStorage cmd;
1047 cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 8, 4);
1048 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1049 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1050 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1051 // Check we get out of memory and no call to glRenderbufferStorage if Ensure
1052 // fails.
1053 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1054 .WillOnce(Return(false))
1055 .RetiresOnSaturation();
1056 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1057 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
1058 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1061 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerBufferData) {
1062 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
1063 new SizeOnlyMemoryTracker();
1064 set_memory_tracker(memory_tracker.get());
1065 InitState init;
1066 init.bind_generates_resource = true;
1067 InitDecoder(init);
1068 DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
1069 EXPECT_CALL(*gl_, GetError())
1070 .WillOnce(Return(GL_NO_ERROR))
1071 .WillOnce(Return(GL_NO_ERROR))
1072 .RetiresOnSaturation();
1073 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1074 .WillOnce(Return(true))
1075 .RetiresOnSaturation();
1076 EXPECT_CALL(*gl_, BufferData(GL_ARRAY_BUFFER, 128, _, GL_STREAM_DRAW))
1077 .Times(1)
1078 .RetiresOnSaturation();
1079 BufferData cmd;
1080 cmd.Init(GL_ARRAY_BUFFER, 128, 0, 0, GL_STREAM_DRAW);
1081 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1082 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1083 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kManaged));
1084 // Check we get out of memory and no call to glBufferData if Ensure
1085 // fails.
1086 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1087 .WillOnce(Return(false))
1088 .RetiresOnSaturation();
1089 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1090 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
1091 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kManaged));
1094 TEST_P(GLES2DecoderManualInitTest, ImmutableCopyTexImage2D) {
1095 const GLenum kTarget = GL_TEXTURE_2D;
1096 const GLint kLevel = 0;
1097 const GLenum kInternalFormat = GL_RGBA;
1098 const GLenum kSizedInternalFormat = GL_RGBA8;
1099 const GLsizei kWidth = 4;
1100 const GLsizei kHeight = 8;
1101 const GLint kBorder = 0;
1102 InitState init;
1103 init.extensions = "GL_EXT_texture_storage";
1104 init.has_alpha = true;
1105 init.request_alpha = true;
1106 init.bind_generates_resource = true;
1107 InitDecoder(init);
1108 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
1110 // CopyTexImage2D will call arbitrary amount of GetErrors.
1111 EXPECT_CALL(*gl_, GetError())
1112 .Times(AtLeast(1));
1114 EXPECT_CALL(*gl_,
1115 CopyTexImage2D(
1116 kTarget, kLevel, kInternalFormat, 0, 0, kWidth, kHeight,
1117 kBorder))
1118 .Times(1);
1120 EXPECT_CALL(*gl_,
1121 TexStorage2DEXT(
1122 kTarget, kLevel, kSizedInternalFormat, kWidth, kHeight))
1123 .Times(1);
1124 CopyTexImage2D copy_cmd;
1125 copy_cmd.Init(kTarget, kLevel, kInternalFormat, 0, 0, kWidth, kHeight);
1126 EXPECT_EQ(error::kNoError, ExecuteCmd(copy_cmd));
1127 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1129 TexStorage2DEXT storage_cmd;
1130 storage_cmd.Init(kTarget, kLevel, kSizedInternalFormat, kWidth, kHeight);
1131 EXPECT_EQ(error::kNoError, ExecuteCmd(storage_cmd));
1132 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1134 // This should not invoke CopyTexImage2D.
1135 copy_cmd.Init(kTarget, kLevel, kInternalFormat, 0, 0, kWidth, kHeight);
1136 EXPECT_EQ(error::kNoError, ExecuteCmd(copy_cmd));
1137 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
1140 TEST_P(GLES2DecoderTest, LoseContextCHROMIUMGuilty) {
1141 EXPECT_CALL(*mock_decoder_, MarkContextLost(error::kInnocent))
1142 .Times(1);
1143 cmds::LoseContextCHROMIUM cmd;
1144 cmd.Init(GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
1145 EXPECT_EQ(error::kLostContext, ExecuteCmd(cmd));
1146 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1147 EXPECT_TRUE(decoder_->WasContextLost());
1148 EXPECT_TRUE(decoder_->WasContextLostByRobustnessExtension());
1151 TEST_P(GLES2DecoderTest, LoseContextCHROMIUMUnkown) {
1152 EXPECT_CALL(*mock_decoder_, MarkContextLost(error::kUnknown))
1153 .Times(1);
1154 cmds::LoseContextCHROMIUM cmd;
1155 cmd.Init(GL_UNKNOWN_CONTEXT_RESET_ARB, GL_UNKNOWN_CONTEXT_RESET_ARB);
1156 EXPECT_EQ(error::kLostContext, ExecuteCmd(cmd));
1157 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1158 EXPECT_TRUE(decoder_->WasContextLost());
1159 EXPECT_TRUE(decoder_->WasContextLostByRobustnessExtension());
1162 TEST_P(GLES2DecoderTest, LoseContextCHROMIUMInvalidArgs0_0) {
1163 EXPECT_CALL(*mock_decoder_, MarkContextLost(_))
1164 .Times(0);
1165 cmds::LoseContextCHROMIUM cmd;
1166 cmd.Init(GL_NONE, GL_GUILTY_CONTEXT_RESET_ARB);
1167 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1168 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
1171 TEST_P(GLES2DecoderTest, LoseContextCHROMIUMInvalidArgs1_0) {
1172 EXPECT_CALL(*mock_decoder_, MarkContextLost(_))
1173 .Times(0);
1174 cmds::LoseContextCHROMIUM cmd;
1175 cmd.Init(GL_GUILTY_CONTEXT_RESET_ARB, GL_NONE);
1176 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1177 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
1180 class GLES2DecoderDoCommandsTest : public GLES2DecoderTest {
1181 public:
1182 GLES2DecoderDoCommandsTest() {
1183 for (int i = 0; i < 3; i++) {
1184 cmds_[i].Init(GL_BLEND);
1186 entries_per_cmd_ = ComputeNumEntries(cmds_[0].ComputeSize());
1189 void SetExpectationsForNCommands(int num_commands) {
1190 for (int i = 0; i < num_commands; i++)
1191 SetupExpectationsForEnableDisable(GL_BLEND, true);
1194 protected:
1195 Enable cmds_[3];
1196 int entries_per_cmd_;
1199 // Test that processing with 0 entries does nothing.
1200 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsOneOfZero) {
1201 int num_processed = -1;
1202 SetExpectationsForNCommands(0);
1203 EXPECT_EQ(
1204 error::kNoError,
1205 decoder_->DoCommands(1, &cmds_, entries_per_cmd_ * 0, &num_processed));
1206 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1207 EXPECT_EQ(0, num_processed);
1210 // Test processing at granularity of single commands.
1211 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsOneOfOne) {
1212 int num_processed = -1;
1213 SetExpectationsForNCommands(1);
1214 EXPECT_EQ(
1215 error::kNoError,
1216 decoder_->DoCommands(1, &cmds_, entries_per_cmd_ * 1, &num_processed));
1217 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1218 EXPECT_EQ(entries_per_cmd_, num_processed);
1221 // Test processing at granularity of multiple commands.
1222 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsThreeOfThree) {
1223 int num_processed = -1;
1224 SetExpectationsForNCommands(3);
1225 EXPECT_EQ(
1226 error::kNoError,
1227 decoder_->DoCommands(3, &cmds_, entries_per_cmd_ * 3, &num_processed));
1228 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1229 EXPECT_EQ(entries_per_cmd_ * 3, num_processed);
1232 // Test processing a request smaller than available entries.
1233 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsTwoOfThree) {
1234 int num_processed = -1;
1235 SetExpectationsForNCommands(2);
1236 EXPECT_EQ(
1237 error::kNoError,
1238 decoder_->DoCommands(2, &cmds_, entries_per_cmd_ * 3, &num_processed));
1239 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1240 EXPECT_EQ(entries_per_cmd_ * 2, num_processed);
1243 // Test that processing stops on a command with size 0.
1244 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsZeroCmdSize) {
1245 cmds_[1].header.size = 0;
1246 int num_processed = -1;
1247 SetExpectationsForNCommands(1);
1248 EXPECT_EQ(
1249 error::kInvalidSize,
1250 decoder_->DoCommands(2, &cmds_, entries_per_cmd_ * 2, &num_processed));
1251 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1252 EXPECT_EQ(entries_per_cmd_, num_processed);
1255 // Test that processing stops on a command with size greater than available.
1256 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsOutOfBounds) {
1257 int num_processed = -1;
1258 SetExpectationsForNCommands(1);
1259 EXPECT_EQ(error::kOutOfBounds,
1260 decoder_->DoCommands(
1261 2, &cmds_, entries_per_cmd_ * 2 - 1, &num_processed));
1262 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1263 EXPECT_EQ(entries_per_cmd_, num_processed);
1266 // Test that commands with bad argument size are skipped without processing.
1267 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsBadArgSize) {
1268 cmds_[1].header.size += 1;
1269 int num_processed = -1;
1270 SetExpectationsForNCommands(1);
1271 EXPECT_EQ(error::kInvalidArguments,
1272 decoder_->DoCommands(
1273 2, &cmds_, entries_per_cmd_ * 2 + 1, &num_processed));
1274 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1275 EXPECT_EQ(entries_per_cmd_ + cmds_[1].header.size, num_processed);
1278 INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderTest, ::testing::Bool());
1280 INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderWithShaderTest, ::testing::Bool());
1282 INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderManualInitTest, ::testing::Bool());
1284 INSTANTIATE_TEST_CASE_P(Service,
1285 GLES2DecoderRGBBackbufferTest,
1286 ::testing::Bool());
1288 INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderDoCommandsTest, ::testing::Bool());
1290 } // namespace gles2
1291 } // namespace gpu