Don't add an aura tooltip to bubble close buttons on Windows.
[chromium-blink-merge.git] / gpu / command_buffer / service / gles2_cmd_decoder_unittest.cc
blobcae6c006b75b3b621bd50fa5daeedbf30c47988c
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/gpu_switches.h"
20 #include "gpu/command_buffer/service/image_manager.h"
21 #include "gpu/command_buffer/service/mailbox_manager.h"
22 #include "gpu/command_buffer/service/mocks.h"
23 #include "gpu/command_buffer/service/program_manager.h"
24 #include "gpu/command_buffer/service/test_helper.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 TEST_P(GLES2DecoderTest, GetIntegervCached) {
94 struct TestInfo {
95 GLenum pname;
96 GLint expected;
98 TestInfo tests[] = {
100 GL_MAX_TEXTURE_SIZE, TestHelper::kMaxTextureSize,
103 GL_MAX_CUBE_MAP_TEXTURE_SIZE, TestHelper::kMaxCubeMapTextureSize,
106 GL_MAX_RENDERBUFFER_SIZE, TestHelper::kMaxRenderbufferSize,
109 typedef GetIntegerv::Result Result;
110 for (size_t ii = 0; ii < sizeof(tests) / sizeof(tests[0]); ++ii) {
111 const TestInfo& test = tests[ii];
112 Result* result = static_cast<Result*>(shared_memory_address_);
113 EXPECT_CALL(*gl_, GetError())
114 .WillOnce(Return(GL_NO_ERROR))
115 .WillOnce(Return(GL_NO_ERROR))
116 .RetiresOnSaturation();
117 EXPECT_CALL(*gl_, GetIntegerv(test.pname, _)).Times(0);
118 result->size = 0;
119 GetIntegerv cmd2;
120 cmd2.Init(test.pname, shared_memory_id_, shared_memory_offset_);
121 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
122 EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(test.pname),
123 result->GetNumResults());
124 EXPECT_EQ(GL_NO_ERROR, GetGLError());
125 EXPECT_EQ(test.expected, result->GetData()[0]);
129 TEST_P(GLES2DecoderWithShaderTest, GetMaxValueInBufferCHROMIUM) {
130 SetupIndexBuffer();
131 GetMaxValueInBufferCHROMIUM::Result* result =
132 static_cast<GetMaxValueInBufferCHROMIUM::Result*>(shared_memory_address_);
133 *result = 0;
135 GetMaxValueInBufferCHROMIUM cmd;
136 cmd.Init(client_element_buffer_id_,
137 kValidIndexRangeCount,
138 GL_UNSIGNED_SHORT,
139 kValidIndexRangeStart * 2,
140 kSharedMemoryId,
141 kSharedMemoryOffset);
142 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
143 EXPECT_EQ(7u, *result);
144 EXPECT_EQ(GL_NO_ERROR, GetGLError());
145 cmd.Init(client_element_buffer_id_,
146 kValidIndexRangeCount + 1,
147 GL_UNSIGNED_SHORT,
148 kValidIndexRangeStart * 2,
149 kSharedMemoryId,
150 kSharedMemoryOffset);
151 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
152 EXPECT_EQ(100u, *result);
153 EXPECT_EQ(GL_NO_ERROR, GetGLError());
155 cmd.Init(kInvalidClientId,
156 kValidIndexRangeCount,
157 GL_UNSIGNED_SHORT,
158 kValidIndexRangeStart * 2,
159 kSharedMemoryId,
160 kSharedMemoryOffset);
161 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
162 EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
163 cmd.Init(client_element_buffer_id_,
164 kOutOfRangeIndexRangeEnd,
165 GL_UNSIGNED_SHORT,
166 kValidIndexRangeStart * 2,
167 kSharedMemoryId,
168 kSharedMemoryOffset);
169 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
170 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
171 cmd.Init(client_element_buffer_id_,
172 kValidIndexRangeCount + 1,
173 GL_UNSIGNED_SHORT,
174 kOutOfRangeIndexRangeEnd * 2,
175 kSharedMemoryId,
176 kSharedMemoryOffset);
177 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
178 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
179 cmd.Init(client_element_buffer_id_,
180 kValidIndexRangeCount + 1,
181 GL_UNSIGNED_SHORT,
182 kValidIndexRangeStart * 2,
183 kSharedMemoryId,
184 kSharedMemoryOffset);
185 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
186 cmd.Init(client_buffer_id_,
187 kValidIndexRangeCount + 1,
188 GL_UNSIGNED_SHORT,
189 kValidIndexRangeStart * 2,
190 kSharedMemoryId,
191 kSharedMemoryOffset);
192 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
193 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
194 cmd.Init(client_element_buffer_id_,
195 kValidIndexRangeCount + 1,
196 GL_UNSIGNED_SHORT,
197 kValidIndexRangeStart * 2,
198 kInvalidSharedMemoryId,
199 kSharedMemoryOffset);
200 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
201 cmd.Init(client_element_buffer_id_,
202 kValidIndexRangeCount + 1,
203 GL_UNSIGNED_SHORT,
204 kValidIndexRangeStart * 2,
205 kSharedMemoryId,
206 kInvalidSharedMemoryOffset);
207 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
210 TEST_P(GLES2DecoderTest, IsBuffer) {
211 EXPECT_FALSE(DoIsBuffer(client_buffer_id_));
212 DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
213 EXPECT_TRUE(DoIsBuffer(client_buffer_id_));
214 DoDeleteBuffer(client_buffer_id_, kServiceBufferId);
215 EXPECT_FALSE(DoIsBuffer(client_buffer_id_));
218 TEST_P(GLES2DecoderTest, IsFramebuffer) {
219 EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_));
220 DoBindFramebuffer(
221 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
222 EXPECT_TRUE(DoIsFramebuffer(client_framebuffer_id_));
223 DoDeleteFramebuffer(client_framebuffer_id_,
224 kServiceFramebufferId,
225 true,
226 GL_FRAMEBUFFER,
228 true,
229 GL_FRAMEBUFFER,
231 EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_));
234 TEST_P(GLES2DecoderTest, IsProgram) {
235 // IsProgram is true as soon as the program is created.
236 EXPECT_TRUE(DoIsProgram(client_program_id_));
237 EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId))
238 .Times(1)
239 .RetiresOnSaturation();
240 DoDeleteProgram(client_program_id_, kServiceProgramId);
241 EXPECT_FALSE(DoIsProgram(client_program_id_));
244 TEST_P(GLES2DecoderTest, IsRenderbuffer) {
245 EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_));
246 DoBindRenderbuffer(
247 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
248 EXPECT_TRUE(DoIsRenderbuffer(client_renderbuffer_id_));
249 DoDeleteRenderbuffer(client_renderbuffer_id_, kServiceRenderbufferId);
250 EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_));
253 TEST_P(GLES2DecoderTest, IsShader) {
254 // IsShader is true as soon as the program is created.
255 EXPECT_TRUE(DoIsShader(client_shader_id_));
256 DoDeleteShader(client_shader_id_, kServiceShaderId);
257 EXPECT_FALSE(DoIsShader(client_shader_id_));
260 TEST_P(GLES2DecoderTest, IsTexture) {
261 EXPECT_FALSE(DoIsTexture(client_texture_id_));
262 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
263 EXPECT_TRUE(DoIsTexture(client_texture_id_));
264 DoDeleteTexture(client_texture_id_, kServiceTextureId);
265 EXPECT_FALSE(DoIsTexture(client_texture_id_));
268 TEST_P(GLES2DecoderTest, ClientWaitSyncValid) {
269 typedef cmds::ClientWaitSync::Result Result;
270 Result* result = static_cast<Result*>(shared_memory_address_);
271 cmds::ClientWaitSync cmd;
272 uint32_t v32_0 = 0, v32_1 = 0;
273 GLES2Util::MapUint64ToTwoUint32(0, &v32_0, &v32_1);
274 cmd.Init(client_sync_id_, GL_SYNC_FLUSH_COMMANDS_BIT, v32_0, v32_1,
275 shared_memory_id_, shared_memory_offset_);
276 EXPECT_CALL(*gl_,
277 ClientWaitSync(reinterpret_cast<GLsync>(kServiceSyncId),
278 GL_SYNC_FLUSH_COMMANDS_BIT, 0))
279 .WillOnce(Return(GL_CONDITION_SATISFIED))
280 .RetiresOnSaturation();
281 *result = GL_WAIT_FAILED;
282 decoder_->set_unsafe_es3_apis_enabled(true);
283 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
284 EXPECT_EQ(static_cast<GLenum>(GL_CONDITION_SATISFIED), *result);
285 EXPECT_EQ(GL_NO_ERROR, GetGLError());
286 decoder_->set_unsafe_es3_apis_enabled(false);
287 EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
290 TEST_P(GLES2DecoderTest, ClientWaitSyncNonZeroTimeoutValid) {
291 typedef cmds::ClientWaitSync::Result Result;
292 Result* result = static_cast<Result*>(shared_memory_address_);
293 cmds::ClientWaitSync cmd;
294 const GLuint64 kTimeout = 0xABCDEF0123456789;
295 uint32_t v32_0 = 0, v32_1 = 0;
296 GLES2Util::MapUint64ToTwoUint32(kTimeout, &v32_0, &v32_1);
297 cmd.Init(client_sync_id_, GL_SYNC_FLUSH_COMMANDS_BIT, v32_0, v32_1,
298 shared_memory_id_, shared_memory_offset_);
299 EXPECT_CALL(*gl_,
300 ClientWaitSync(reinterpret_cast<GLsync>(kServiceSyncId),
301 GL_SYNC_FLUSH_COMMANDS_BIT, kTimeout))
302 .WillOnce(Return(GL_CONDITION_SATISFIED))
303 .RetiresOnSaturation();
304 *result = GL_WAIT_FAILED;
305 decoder_->set_unsafe_es3_apis_enabled(true);
306 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
307 EXPECT_EQ(static_cast<GLenum>(GL_CONDITION_SATISFIED), *result);
308 EXPECT_EQ(GL_NO_ERROR, GetGLError());
309 decoder_->set_unsafe_es3_apis_enabled(false);
310 EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
313 TEST_P(GLES2DecoderTest, ClientWaitSyncInvalidSyncFails) {
314 typedef cmds::ClientWaitSync::Result Result;
315 Result* result = static_cast<Result*>(shared_memory_address_);
316 cmds::ClientWaitSync cmd;
317 uint32_t v32_0 = 0, v32_1 = 0;
318 GLES2Util::MapUint64ToTwoUint32(0, &v32_0, &v32_1);
319 decoder_->set_unsafe_es3_apis_enabled(true);
320 cmd.Init(kInvalidClientId, GL_SYNC_FLUSH_COMMANDS_BIT, v32_0, v32_1,
321 shared_memory_id_, shared_memory_offset_);
322 *result = GL_WAIT_FAILED;
323 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
324 EXPECT_EQ(static_cast<GLenum>(GL_WAIT_FAILED), *result);
325 EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
328 TEST_P(GLES2DecoderTest, ClientWaitSyncResultNotInitFails) {
329 typedef cmds::ClientWaitSync::Result Result;
330 Result* result = static_cast<Result*>(shared_memory_address_);
331 cmds::ClientWaitSync cmd;
332 uint32_t v32_0 = 0, v32_1 = 0;
333 GLES2Util::MapUint64ToTwoUint32(0, &v32_0, &v32_1);
334 decoder_->set_unsafe_es3_apis_enabled(true);
335 cmd.Init(client_sync_id_, GL_SYNC_FLUSH_COMMANDS_BIT, v32_0, v32_1,
336 shared_memory_id_, shared_memory_offset_);
337 *result = 1; // Any value other than GL_WAIT_FAILED
338 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
341 TEST_P(GLES2DecoderTest, ClientWaitSyncBadSharedMemoryFails) {
342 typedef cmds::ClientWaitSync::Result Result;
343 Result* result = static_cast<Result*>(shared_memory_address_);
344 cmds::ClientWaitSync cmd;
345 uint32_t v32_0 = 0, v32_1 = 0;
346 GLES2Util::MapUint64ToTwoUint32(0, &v32_0, &v32_1);
347 decoder_->set_unsafe_es3_apis_enabled(true);
348 *result = GL_WAIT_FAILED;
349 cmd.Init(client_sync_id_, GL_SYNC_FLUSH_COMMANDS_BIT, v32_0, v32_1,
350 kInvalidSharedMemoryId, shared_memory_offset_);
351 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
353 *result = GL_WAIT_FAILED;
354 cmd.Init(client_sync_id_, GL_SYNC_FLUSH_COMMANDS_BIT, v32_0, v32_1,
355 shared_memory_id_, kInvalidSharedMemoryOffset);
356 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
359 TEST_P(GLES2DecoderTest, WaitSyncValidArgs) {
360 const GLuint64 kTimeout = GL_TIMEOUT_IGNORED;
361 EXPECT_CALL(*gl_, WaitSync(reinterpret_cast<GLsync>(kServiceSyncId),
362 0, kTimeout))
363 .Times(1)
364 .RetiresOnSaturation();
366 uint32_t v32_0 = 0, v32_1 = 0;
367 GLES2Util::MapUint64ToTwoUint32(kTimeout, &v32_0, &v32_1);
368 cmds::WaitSync cmd;
369 cmd.Init(client_sync_id_, 0, v32_0, v32_1);
370 decoder_->set_unsafe_es3_apis_enabled(true);
371 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
372 EXPECT_EQ(GL_NO_ERROR, GetGLError());
373 decoder_->set_unsafe_es3_apis_enabled(false);
374 EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
377 TEST_P(GLES2DecoderManualInitTest, BindGeneratesResourceFalse) {
378 InitState init;
379 InitDecoder(init);
381 BindTexture cmd1;
382 cmd1.Init(GL_TEXTURE_2D, kInvalidClientId);
383 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
384 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
386 BindBuffer cmd2;
387 cmd2.Init(GL_ARRAY_BUFFER, kInvalidClientId);
388 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
389 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
391 BindFramebuffer cmd3;
392 cmd3.Init(GL_FRAMEBUFFER, kInvalidClientId);
393 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd3));
394 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
396 BindRenderbuffer cmd4;
397 cmd4.Init(GL_RENDERBUFFER, kInvalidClientId);
398 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd4));
399 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
402 TEST_P(GLES2DecoderTest, EnableFeatureCHROMIUMBadBucket) {
403 const uint32 kBadBucketId = 123;
404 EnableFeatureCHROMIUM cmd;
405 cmd.Init(kBadBucketId, shared_memory_id_, shared_memory_offset_);
406 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
409 TEST_P(GLES2DecoderTest, RequestExtensionCHROMIUMBadBucket) {
410 const uint32 kBadBucketId = 123;
411 RequestExtensionCHROMIUM cmd;
412 cmd.Init(kBadBucketId);
413 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
416 TEST_P(GLES2DecoderTest, BeginQueryEXTDisabled) {
417 // Test something fails if off.
420 TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXT) {
421 InitState init;
422 init.extensions = "GL_EXT_occlusion_query_boolean";
423 init.gl_version = "opengl es 2.0";
424 init.has_alpha = true;
425 init.request_alpha = true;
426 init.bind_generates_resource = true;
427 InitDecoder(init);
429 // Test end fails if no begin.
430 EndQueryEXT end_cmd;
431 end_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, 1);
432 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
433 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
435 BeginQueryEXT begin_cmd;
437 // Test id = 0 fails.
438 begin_cmd.Init(
439 GL_ANY_SAMPLES_PASSED_EXT, 0, kSharedMemoryId, kSharedMemoryOffset);
440 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
441 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
443 GenHelper<GenQueriesEXTImmediate>(kNewClientId);
445 // Test valid parameters work.
446 EXPECT_CALL(*gl_, GenQueries(1, _))
447 .WillOnce(SetArgumentPointee<1>(kNewServiceId))
448 .RetiresOnSaturation();
449 EXPECT_CALL(*gl_, BeginQuery(GL_ANY_SAMPLES_PASSED_EXT, kNewServiceId))
450 .Times(1)
451 .RetiresOnSaturation();
453 // Query object should not be created untill BeginQueriesEXT.
454 QueryManager* query_manager = decoder_->GetQueryManager();
455 ASSERT_TRUE(query_manager != NULL);
456 QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
457 EXPECT_TRUE(query == NULL);
459 // BeginQueryEXT should fail if id is not generated from GenQueriesEXT.
460 begin_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT,
461 kInvalidClientId,
462 kSharedMemoryId,
463 kSharedMemoryOffset);
464 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
465 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
467 begin_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT,
468 kNewClientId,
469 kSharedMemoryId,
470 kSharedMemoryOffset);
471 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
472 EXPECT_EQ(GL_NO_ERROR, GetGLError());
474 // After BeginQueriesEXT id name should have query object associated with it.
475 query = query_manager->GetQuery(kNewClientId);
476 ASSERT_TRUE(query != NULL);
477 EXPECT_FALSE(query->pending());
479 // Test trying begin again fails
480 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
481 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
483 // Test end fails with different target
484 end_cmd.Init(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, 1);
485 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
486 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
488 // Test end succeeds
489 EXPECT_CALL(*gl_, EndQuery(GL_ANY_SAMPLES_PASSED_EXT))
490 .Times(1)
491 .RetiresOnSaturation();
492 end_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, 1);
493 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
494 EXPECT_EQ(GL_NO_ERROR, GetGLError());
495 EXPECT_TRUE(query->pending());
497 EXPECT_CALL(*gl_, DeleteQueries(1, _)).Times(1).RetiresOnSaturation();
500 struct QueryType {
501 GLenum type;
502 bool is_gl;
505 const QueryType kQueryTypes[] = {
506 {GL_COMMANDS_ISSUED_CHROMIUM, false},
507 {GL_LATENCY_QUERY_CHROMIUM, false},
508 {GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM, false},
509 {GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, false},
510 {GL_GET_ERROR_QUERY_CHROMIUM, false},
511 {GL_COMMANDS_COMPLETED_CHROMIUM, false},
512 {GL_ANY_SAMPLES_PASSED_EXT, true},
515 static void CheckBeginEndQueryBadMemoryFails(GLES2DecoderTestBase* test,
516 GLuint client_id,
517 GLuint service_id,
518 const QueryType& query_type,
519 int32 shm_id,
520 uint32 shm_offset) {
521 // We need to reset the decoder on each iteration, because we lose the
522 // context every time.
523 GLES2DecoderTestBase::InitState init;
524 init.extensions = "GL_EXT_occlusion_query_boolean GL_ARB_sync";
525 init.gl_version = "opengl es 2.0";
526 init.has_alpha = true;
527 init.request_alpha = true;
528 init.bind_generates_resource = true;
529 test->InitDecoder(init);
530 ::testing::StrictMock< ::gfx::MockGLInterface>* gl = test->GetGLMock();
532 BeginQueryEXT begin_cmd;
534 test->GenHelper<GenQueriesEXTImmediate>(client_id);
536 if (query_type.is_gl) {
537 EXPECT_CALL(*gl, GenQueries(1, _))
538 .WillOnce(SetArgumentPointee<1>(service_id))
539 .RetiresOnSaturation();
540 EXPECT_CALL(*gl, BeginQuery(query_type.type, service_id))
541 .Times(1)
542 .RetiresOnSaturation();
545 // Test bad shared memory fails
546 begin_cmd.Init(query_type.type, client_id, shm_id, shm_offset);
547 error::Error error1 = test->ExecuteCmd(begin_cmd);
549 if (query_type.is_gl) {
550 EXPECT_CALL(*gl, EndQuery(query_type.type))
551 .Times(1)
552 .RetiresOnSaturation();
554 if (query_type.type == GL_GET_ERROR_QUERY_CHROMIUM) {
555 EXPECT_CALL(*gl, GetError())
556 .WillOnce(Return(GL_NO_ERROR))
557 .RetiresOnSaturation();
559 GLsync kGlSync = reinterpret_cast<GLsync>(0xdeadbeef);
560 if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM) {
561 EXPECT_CALL(*gl, Flush()).RetiresOnSaturation();
562 EXPECT_CALL(*gl, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0))
563 .WillOnce(Return(kGlSync))
564 .RetiresOnSaturation();
565 #if DCHECK_IS_ON()
566 EXPECT_CALL(*gl, IsSync(kGlSync))
567 .WillOnce(Return(GL_TRUE))
568 .RetiresOnSaturation();
569 #endif
572 EndQueryEXT end_cmd;
573 end_cmd.Init(query_type.type, 1);
574 error::Error error2 = test->ExecuteCmd(end_cmd);
576 if (query_type.is_gl) {
577 EXPECT_CALL(
578 *gl, GetQueryObjectuiv(service_id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
579 .WillOnce(SetArgumentPointee<2>(1))
580 .RetiresOnSaturation();
581 EXPECT_CALL(*gl, GetQueryObjectuiv(service_id, GL_QUERY_RESULT_EXT, _))
582 .WillOnce(SetArgumentPointee<2>(1))
583 .RetiresOnSaturation();
585 if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM) {
586 #if DCHECK_IS_ON()
587 EXPECT_CALL(*gl, IsSync(kGlSync))
588 .WillOnce(Return(GL_TRUE))
589 .RetiresOnSaturation();
590 #endif
591 EXPECT_CALL(*gl, ClientWaitSync(kGlSync, _, _))
592 .WillOnce(Return(GL_ALREADY_SIGNALED))
593 .RetiresOnSaturation();
596 QueryManager* query_manager = test->GetDecoder()->GetQueryManager();
597 ASSERT_TRUE(query_manager != NULL);
598 bool process_success = query_manager->ProcessPendingQueries(false);
600 EXPECT_TRUE(error1 != error::kNoError || error2 != error::kNoError ||
601 !process_success);
603 if (query_type.is_gl) {
604 EXPECT_CALL(*gl, DeleteQueries(1, _)).Times(1).RetiresOnSaturation();
606 if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM) {
607 #if DCHECK_IS_ON()
608 EXPECT_CALL(*gl, IsSync(kGlSync))
609 .WillOnce(Return(GL_TRUE))
610 .RetiresOnSaturation();
611 #endif
612 EXPECT_CALL(*gl, DeleteSync(kGlSync)).Times(1).RetiresOnSaturation();
614 test->ResetDecoder();
617 TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTBadMemoryIdFails) {
618 for (size_t i = 0; i < arraysize(kQueryTypes); ++i) {
619 CheckBeginEndQueryBadMemoryFails(this,
620 kNewClientId,
621 kNewServiceId,
622 kQueryTypes[i],
623 kInvalidSharedMemoryId,
624 kSharedMemoryOffset);
628 TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTBadMemoryOffsetFails) {
629 for (size_t i = 0; i < arraysize(kQueryTypes); ++i) {
630 // Out-of-bounds.
631 CheckBeginEndQueryBadMemoryFails(this,
632 kNewClientId,
633 kNewServiceId,
634 kQueryTypes[i],
635 kSharedMemoryId,
636 kInvalidSharedMemoryOffset);
637 // Overflow.
638 CheckBeginEndQueryBadMemoryFails(this,
639 kNewClientId,
640 kNewServiceId,
641 kQueryTypes[i],
642 kSharedMemoryId,
643 0xfffffffcu);
647 TEST_P(GLES2DecoderTest, BeginEndQueryEXTCommandsIssuedCHROMIUM) {
648 BeginQueryEXT begin_cmd;
650 GenHelper<GenQueriesEXTImmediate>(kNewClientId);
652 // Test valid parameters work.
653 begin_cmd.Init(GL_COMMANDS_ISSUED_CHROMIUM,
654 kNewClientId,
655 kSharedMemoryId,
656 kSharedMemoryOffset);
657 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
658 EXPECT_EQ(GL_NO_ERROR, GetGLError());
660 QueryManager* query_manager = decoder_->GetQueryManager();
661 ASSERT_TRUE(query_manager != NULL);
662 QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
663 ASSERT_TRUE(query != NULL);
664 EXPECT_FALSE(query->pending());
666 // Test end succeeds
667 EndQueryEXT end_cmd;
668 end_cmd.Init(GL_COMMANDS_ISSUED_CHROMIUM, 1);
669 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
670 EXPECT_EQ(GL_NO_ERROR, GetGLError());
671 EXPECT_FALSE(query->pending());
674 TEST_P(GLES2DecoderTest, BeginEndQueryEXTGetErrorQueryCHROMIUM) {
675 BeginQueryEXT begin_cmd;
677 GenHelper<GenQueriesEXTImmediate>(kNewClientId);
679 // Test valid parameters work.
680 begin_cmd.Init(GL_GET_ERROR_QUERY_CHROMIUM,
681 kNewClientId,
682 kSharedMemoryId,
683 kSharedMemoryOffset);
684 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
685 EXPECT_EQ(GL_NO_ERROR, GetGLError());
687 QueryManager* query_manager = decoder_->GetQueryManager();
688 ASSERT_TRUE(query_manager != NULL);
689 QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
690 ASSERT_TRUE(query != NULL);
691 EXPECT_FALSE(query->pending());
693 // Test end succeeds
694 QuerySync* sync = static_cast<QuerySync*>(shared_memory_address_);
696 EXPECT_CALL(*gl_, GetError())
697 .WillOnce(Return(GL_INVALID_VALUE))
698 .RetiresOnSaturation();
700 EndQueryEXT end_cmd;
701 end_cmd.Init(GL_GET_ERROR_QUERY_CHROMIUM, 1);
702 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
703 EXPECT_EQ(GL_NO_ERROR, GetGLError());
704 EXPECT_FALSE(query->pending());
705 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE),
706 static_cast<GLenum>(sync->result));
709 TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTCommandsCompletedCHROMIUM) {
710 InitState init;
711 init.extensions = "GL_EXT_occlusion_query_boolean GL_ARB_sync";
712 init.gl_version = "opengl es 2.0";
713 init.has_alpha = true;
714 init.request_alpha = true;
715 init.bind_generates_resource = true;
716 InitDecoder(init);
718 GenHelper<GenQueriesEXTImmediate>(kNewClientId);
720 BeginQueryEXT begin_cmd;
721 begin_cmd.Init(GL_COMMANDS_COMPLETED_CHROMIUM,
722 kNewClientId,
723 kSharedMemoryId,
724 kSharedMemoryOffset);
725 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
726 EXPECT_EQ(GL_NO_ERROR, GetGLError());
728 QueryManager* query_manager = decoder_->GetQueryManager();
729 ASSERT_TRUE(query_manager != NULL);
730 QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
731 ASSERT_TRUE(query != NULL);
732 EXPECT_FALSE(query->pending());
734 GLsync kGlSync = reinterpret_cast<GLsync>(0xdeadbeef);
735 EXPECT_CALL(*gl_, Flush()).RetiresOnSaturation();
736 EXPECT_CALL(*gl_, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0))
737 .WillOnce(Return(kGlSync))
738 .RetiresOnSaturation();
739 #if DCHECK_IS_ON()
740 EXPECT_CALL(*gl_, IsSync(kGlSync))
741 .WillOnce(Return(GL_TRUE))
742 .RetiresOnSaturation();
743 #endif
745 EndQueryEXT end_cmd;
746 end_cmd.Init(GL_COMMANDS_COMPLETED_CHROMIUM, 1);
747 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
748 EXPECT_EQ(GL_NO_ERROR, GetGLError());
749 EXPECT_TRUE(query->pending());
751 #if DCHECK_IS_ON()
752 EXPECT_CALL(*gl_, IsSync(kGlSync))
753 .WillOnce(Return(GL_TRUE))
754 .RetiresOnSaturation();
755 #endif
756 EXPECT_CALL(*gl_, ClientWaitSync(kGlSync, _, _))
757 .WillOnce(Return(GL_TIMEOUT_EXPIRED))
758 .RetiresOnSaturation();
759 bool process_success = query_manager->ProcessPendingQueries(false);
761 EXPECT_TRUE(process_success);
762 EXPECT_TRUE(query->pending());
764 #if DCHECK_IS_ON()
765 EXPECT_CALL(*gl_, IsSync(kGlSync))
766 .WillOnce(Return(GL_TRUE))
767 .RetiresOnSaturation();
768 #endif
769 EXPECT_CALL(*gl_, ClientWaitSync(kGlSync, _, _))
770 .WillOnce(Return(GL_ALREADY_SIGNALED))
771 .RetiresOnSaturation();
772 process_success = query_manager->ProcessPendingQueries(false);
774 EXPECT_TRUE(process_success);
775 EXPECT_FALSE(query->pending());
777 #if DCHECK_IS_ON()
778 EXPECT_CALL(*gl_, IsSync(kGlSync))
779 .WillOnce(Return(GL_TRUE))
780 .RetiresOnSaturation();
781 #endif
782 EXPECT_CALL(*gl_, DeleteSync(kGlSync)).Times(1).RetiresOnSaturation();
783 ResetDecoder();
786 TEST_P(GLES2DecoderTest, IsEnabledReturnsCachedValue) {
787 // NOTE: There are no expectations because no GL functions should be
788 // called for DEPTH_TEST or STENCIL_TEST
789 static const GLenum kStates[] = {
790 GL_DEPTH_TEST, GL_STENCIL_TEST,
792 for (size_t ii = 0; ii < arraysize(kStates); ++ii) {
793 Enable enable_cmd;
794 GLenum state = kStates[ii];
795 enable_cmd.Init(state);
796 EXPECT_EQ(error::kNoError, ExecuteCmd(enable_cmd));
797 IsEnabled::Result* result =
798 static_cast<IsEnabled::Result*>(shared_memory_address_);
799 IsEnabled is_enabled_cmd;
800 is_enabled_cmd.Init(state, shared_memory_id_, shared_memory_offset_);
801 EXPECT_EQ(error::kNoError, ExecuteCmd(is_enabled_cmd));
802 EXPECT_NE(0u, *result);
803 Disable disable_cmd;
804 disable_cmd.Init(state);
805 EXPECT_EQ(error::kNoError, ExecuteCmd(disable_cmd));
806 EXPECT_EQ(error::kNoError, ExecuteCmd(is_enabled_cmd));
807 EXPECT_EQ(0u, *result);
811 TEST_P(GLES2DecoderManualInitTest, GpuMemoryManagerCHROMIUM) {
812 InitState init;
813 init.extensions = "GL_ARB_texture_rectangle";
814 init.bind_generates_resource = true;
815 InitDecoder(init);
817 Texture* texture = GetTexture(client_texture_id_)->texture();
818 EXPECT_TRUE(texture != NULL);
819 EXPECT_TRUE(texture->pool() == GL_TEXTURE_POOL_UNMANAGED_CHROMIUM);
821 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
823 TexParameteri cmd;
824 cmd.Init(GL_TEXTURE_2D,
825 GL_TEXTURE_POOL_CHROMIUM,
826 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM);
827 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
828 EXPECT_EQ(GL_NO_ERROR, GetGLError());
830 cmd.Init(GL_TEXTURE_2D,
831 GL_TEXTURE_POOL_CHROMIUM,
832 GL_TEXTURE_POOL_MANAGED_CHROMIUM);
833 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
834 EXPECT_EQ(GL_NO_ERROR, GetGLError());
836 EXPECT_TRUE(texture->pool() == GL_TEXTURE_POOL_MANAGED_CHROMIUM);
838 cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_POOL_CHROMIUM, GL_NONE);
839 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
840 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
843 namespace {
845 class SizeOnlyMemoryTracker : public MemoryTracker {
846 public:
847 SizeOnlyMemoryTracker() {
848 // These are the default textures. 1 for TEXTURE_2D and 6 faces for
849 // TEXTURE_CUBE_MAP.
850 const size_t kInitialUnmanagedPoolSize = 7 * 4;
851 const size_t kInitialManagedPoolSize = 0;
852 pool_infos_[MemoryTracker::kUnmanaged].initial_size =
853 kInitialUnmanagedPoolSize;
854 pool_infos_[MemoryTracker::kManaged].initial_size = kInitialManagedPoolSize;
857 // Ensure a certain amount of GPU memory is free. Returns true on success.
858 MOCK_METHOD1(EnsureGPUMemoryAvailable, bool(size_t size_needed));
860 virtual void TrackMemoryAllocatedChange(size_t old_size,
861 size_t new_size,
862 Pool pool) {
863 PoolInfo& info = pool_infos_[pool];
864 info.size += new_size - old_size;
867 size_t GetPoolSize(Pool pool) {
868 const PoolInfo& info = pool_infos_[pool];
869 return info.size - info.initial_size;
872 private:
873 virtual ~SizeOnlyMemoryTracker() {}
874 struct PoolInfo {
875 PoolInfo() : initial_size(0), size(0) {}
876 size_t initial_size;
877 size_t size;
879 std::map<Pool, PoolInfo> pool_infos_;
882 } // anonymous namespace.
884 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerInitialSize) {
885 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
886 new SizeOnlyMemoryTracker();
887 set_memory_tracker(memory_tracker.get());
888 InitState init;
889 init.bind_generates_resource = true;
890 InitDecoder(init);
891 // Expect that initial size - size is 0.
892 EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
893 EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kManaged));
896 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerTexImage2D) {
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 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
904 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
905 .WillOnce(Return(true))
906 .RetiresOnSaturation();
907 DoTexImage2D(GL_TEXTURE_2D,
909 GL_RGBA,
913 GL_RGBA,
914 GL_UNSIGNED_BYTE,
915 kSharedMemoryId,
916 kSharedMemoryOffset);
917 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
918 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(64))
919 .WillOnce(Return(true))
920 .RetiresOnSaturation();
921 DoTexImage2D(GL_TEXTURE_2D,
923 GL_RGBA,
927 GL_RGBA,
928 GL_UNSIGNED_BYTE,
929 kSharedMemoryId,
930 kSharedMemoryOffset);
931 EXPECT_EQ(64u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
932 EXPECT_EQ(GL_NO_ERROR, GetGLError());
933 // Check we get out of memory and no call to glTexImage2D if Ensure fails.
934 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(64))
935 .WillOnce(Return(false))
936 .RetiresOnSaturation();
937 TexImage2D cmd;
938 cmd.Init(GL_TEXTURE_2D,
940 GL_RGBA,
943 GL_RGBA,
944 GL_UNSIGNED_BYTE,
945 kSharedMemoryId,
946 kSharedMemoryOffset);
947 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
948 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
949 EXPECT_EQ(64u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
952 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerTexStorage2DEXT) {
953 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
954 new SizeOnlyMemoryTracker();
955 set_memory_tracker(memory_tracker.get());
956 InitState init;
957 init.bind_generates_resource = true;
958 InitDecoder(init);
959 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
960 // Check we get out of memory and no call to glTexStorage2DEXT
961 // if Ensure fails.
962 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
963 .WillOnce(Return(false))
964 .RetiresOnSaturation();
965 TexStorage2DEXT cmd;
966 cmd.Init(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 4);
967 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
968 EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
969 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
972 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerCopyTexImage2D) {
973 GLenum target = GL_TEXTURE_2D;
974 GLint level = 0;
975 GLenum internal_format = GL_RGBA;
976 GLsizei width = 4;
977 GLsizei height = 8;
978 GLint border = 0;
979 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
980 new SizeOnlyMemoryTracker();
981 set_memory_tracker(memory_tracker.get());
982 InitState init;
983 init.has_alpha = true;
984 init.request_alpha = true;
985 init.bind_generates_resource = true;
986 InitDecoder(init);
987 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
988 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
989 .WillOnce(Return(true))
990 .RetiresOnSaturation();
991 EXPECT_CALL(*gl_, GetError())
992 .WillOnce(Return(GL_NO_ERROR))
993 .WillOnce(Return(GL_NO_ERROR))
994 .RetiresOnSaturation();
995 EXPECT_CALL(*gl_,
996 CopyTexImage2D(
997 target, level, internal_format, 0, 0, width, height, border))
998 .Times(1)
999 .RetiresOnSaturation();
1000 CopyTexImage2D cmd;
1001 cmd.Init(target, level, internal_format, 0, 0, width, height);
1002 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1003 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1004 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1005 // Check we get out of memory and no call to glCopyTexImage2D if Ensure fails.
1006 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1007 .WillOnce(Return(false))
1008 .RetiresOnSaturation();
1009 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1010 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
1011 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1014 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerRenderbufferStorage) {
1015 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
1016 new SizeOnlyMemoryTracker();
1017 set_memory_tracker(memory_tracker.get());
1018 InitState init;
1019 init.bind_generates_resource = true;
1020 InitDecoder(init);
1021 DoBindRenderbuffer(
1022 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
1023 EnsureRenderbufferBound(false);
1024 EXPECT_CALL(*gl_, GetError())
1025 .WillOnce(Return(GL_NO_ERROR))
1026 .WillOnce(Return(GL_NO_ERROR))
1027 .RetiresOnSaturation();
1028 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1029 .WillOnce(Return(true))
1030 .RetiresOnSaturation();
1031 EXPECT_CALL(*gl_, RenderbufferStorageEXT(GL_RENDERBUFFER, GL_RGBA, 8, 4))
1032 .Times(1)
1033 .RetiresOnSaturation();
1034 RenderbufferStorage cmd;
1035 cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 8, 4);
1036 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1037 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1038 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1039 // Check we get out of memory and no call to glRenderbufferStorage if Ensure
1040 // fails.
1041 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1042 .WillOnce(Return(false))
1043 .RetiresOnSaturation();
1044 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1045 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
1046 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1049 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerBufferData) {
1050 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
1051 new SizeOnlyMemoryTracker();
1052 set_memory_tracker(memory_tracker.get());
1053 InitState init;
1054 init.bind_generates_resource = true;
1055 InitDecoder(init);
1056 DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
1057 EXPECT_CALL(*gl_, GetError())
1058 .WillOnce(Return(GL_NO_ERROR))
1059 .WillOnce(Return(GL_NO_ERROR))
1060 .RetiresOnSaturation();
1061 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1062 .WillOnce(Return(true))
1063 .RetiresOnSaturation();
1064 EXPECT_CALL(*gl_, BufferData(GL_ARRAY_BUFFER, 128, _, GL_STREAM_DRAW))
1065 .Times(1)
1066 .RetiresOnSaturation();
1067 BufferData cmd;
1068 cmd.Init(GL_ARRAY_BUFFER, 128, 0, 0, GL_STREAM_DRAW);
1069 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1070 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1071 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kManaged));
1072 // Check we get out of memory and no call to glBufferData if Ensure
1073 // fails.
1074 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1075 .WillOnce(Return(false))
1076 .RetiresOnSaturation();
1077 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1078 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
1079 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kManaged));
1082 TEST_P(GLES2DecoderManualInitTest, ImmutableCopyTexImage2D) {
1083 const GLenum kTarget = GL_TEXTURE_2D;
1084 const GLint kLevel = 0;
1085 const GLenum kInternalFormat = GL_RGBA;
1086 const GLenum kSizedInternalFormat = GL_RGBA8;
1087 const GLsizei kWidth = 4;
1088 const GLsizei kHeight = 8;
1089 const GLint kBorder = 0;
1090 InitState init;
1091 init.extensions = "GL_EXT_texture_storage";
1092 init.has_alpha = true;
1093 init.request_alpha = true;
1094 init.bind_generates_resource = true;
1095 InitDecoder(init);
1096 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
1098 // CopyTexImage2D will call arbitrary amount of GetErrors.
1099 EXPECT_CALL(*gl_, GetError())
1100 .Times(AtLeast(1));
1102 EXPECT_CALL(*gl_,
1103 CopyTexImage2D(
1104 kTarget, kLevel, kInternalFormat, 0, 0, kWidth, kHeight,
1105 kBorder))
1106 .Times(1);
1108 EXPECT_CALL(*gl_,
1109 TexStorage2DEXT(
1110 kTarget, kLevel, kSizedInternalFormat, kWidth, kHeight))
1111 .Times(1);
1112 CopyTexImage2D copy_cmd;
1113 copy_cmd.Init(kTarget, kLevel, kInternalFormat, 0, 0, kWidth, kHeight);
1114 EXPECT_EQ(error::kNoError, ExecuteCmd(copy_cmd));
1115 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1117 TexStorage2DEXT storage_cmd;
1118 storage_cmd.Init(kTarget, kLevel, kSizedInternalFormat, kWidth, kHeight);
1119 EXPECT_EQ(error::kNoError, ExecuteCmd(storage_cmd));
1120 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1122 // This should not invoke CopyTexImage2D.
1123 copy_cmd.Init(kTarget, kLevel, kInternalFormat, 0, 0, kWidth, kHeight);
1124 EXPECT_EQ(error::kNoError, ExecuteCmd(copy_cmd));
1125 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
1128 TEST_P(GLES2DecoderTest, LoseContextCHROMIUMValidArgs) {
1129 EXPECT_CALL(*mock_decoder_, LoseContext(GL_GUILTY_CONTEXT_RESET_ARB))
1130 .Times(1);
1131 cmds::LoseContextCHROMIUM cmd;
1132 cmd.Init(GL_GUILTY_CONTEXT_RESET_ARB, GL_GUILTY_CONTEXT_RESET_ARB);
1133 EXPECT_EQ(error::kLostContext, ExecuteCmd(cmd));
1134 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1137 TEST_P(GLES2DecoderTest, LoseContextCHROMIUMInvalidArgs0_0) {
1138 EXPECT_CALL(*mock_decoder_, LoseContext(_))
1139 .Times(0);
1140 cmds::LoseContextCHROMIUM cmd;
1141 cmd.Init(GL_NONE, GL_GUILTY_CONTEXT_RESET_ARB);
1142 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1143 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
1146 TEST_P(GLES2DecoderTest, LoseContextCHROMIUMInvalidArgs1_0) {
1147 EXPECT_CALL(*mock_decoder_, LoseContext(_))
1148 .Times(0);
1149 cmds::LoseContextCHROMIUM cmd;
1150 cmd.Init(GL_GUILTY_CONTEXT_RESET_ARB, GL_NONE);
1151 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1152 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
1155 class GLES2DecoderDoCommandsTest : public GLES2DecoderTest {
1156 public:
1157 GLES2DecoderDoCommandsTest() {
1158 for (int i = 0; i < 3; i++) {
1159 cmds_[i].Init(GL_BLEND);
1161 entries_per_cmd_ = ComputeNumEntries(cmds_[0].ComputeSize());
1164 void SetExpectationsForNCommands(int num_commands) {
1165 for (int i = 0; i < num_commands; i++)
1166 SetupExpectationsForEnableDisable(GL_BLEND, true);
1169 protected:
1170 Enable cmds_[3];
1171 int entries_per_cmd_;
1174 // Test that processing with 0 entries does nothing.
1175 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsOneOfZero) {
1176 int num_processed = -1;
1177 SetExpectationsForNCommands(0);
1178 EXPECT_EQ(
1179 error::kNoError,
1180 decoder_->DoCommands(1, &cmds_, entries_per_cmd_ * 0, &num_processed));
1181 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1182 EXPECT_EQ(0, num_processed);
1185 // Test processing at granularity of single commands.
1186 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsOneOfOne) {
1187 int num_processed = -1;
1188 SetExpectationsForNCommands(1);
1189 EXPECT_EQ(
1190 error::kNoError,
1191 decoder_->DoCommands(1, &cmds_, entries_per_cmd_ * 1, &num_processed));
1192 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1193 EXPECT_EQ(entries_per_cmd_, num_processed);
1196 // Test processing at granularity of multiple commands.
1197 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsThreeOfThree) {
1198 int num_processed = -1;
1199 SetExpectationsForNCommands(3);
1200 EXPECT_EQ(
1201 error::kNoError,
1202 decoder_->DoCommands(3, &cmds_, entries_per_cmd_ * 3, &num_processed));
1203 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1204 EXPECT_EQ(entries_per_cmd_ * 3, num_processed);
1207 // Test processing a request smaller than available entries.
1208 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsTwoOfThree) {
1209 int num_processed = -1;
1210 SetExpectationsForNCommands(2);
1211 EXPECT_EQ(
1212 error::kNoError,
1213 decoder_->DoCommands(2, &cmds_, entries_per_cmd_ * 3, &num_processed));
1214 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1215 EXPECT_EQ(entries_per_cmd_ * 2, num_processed);
1218 // Test that processing stops on a command with size 0.
1219 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsZeroCmdSize) {
1220 cmds_[1].header.size = 0;
1221 int num_processed = -1;
1222 SetExpectationsForNCommands(1);
1223 EXPECT_EQ(
1224 error::kInvalidSize,
1225 decoder_->DoCommands(2, &cmds_, entries_per_cmd_ * 2, &num_processed));
1226 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1227 EXPECT_EQ(entries_per_cmd_, num_processed);
1230 // Test that processing stops on a command with size greater than available.
1231 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsOutOfBounds) {
1232 int num_processed = -1;
1233 SetExpectationsForNCommands(1);
1234 EXPECT_EQ(error::kOutOfBounds,
1235 decoder_->DoCommands(
1236 2, &cmds_, entries_per_cmd_ * 2 - 1, &num_processed));
1237 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1238 EXPECT_EQ(entries_per_cmd_, num_processed);
1241 // Test that commands with bad argument size are skipped without processing.
1242 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsBadArgSize) {
1243 cmds_[1].header.size += 1;
1244 int num_processed = -1;
1245 SetExpectationsForNCommands(1);
1246 EXPECT_EQ(error::kInvalidArguments,
1247 decoder_->DoCommands(
1248 2, &cmds_, entries_per_cmd_ * 2 + 1, &num_processed));
1249 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1250 EXPECT_EQ(entries_per_cmd_ + cmds_[1].header.size, num_processed);
1253 INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderTest, ::testing::Bool());
1255 INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderWithShaderTest, ::testing::Bool());
1257 INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderManualInitTest, ::testing::Bool());
1259 INSTANTIATE_TEST_CASE_P(Service,
1260 GLES2DecoderRGBBackbufferTest,
1261 ::testing::Bool());
1263 INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderDoCommandsTest, ::testing::Bool());
1265 } // namespace gles2
1266 } // namespace gpu