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/common/id_allocator.h"
12 #include "gpu/command_buffer/service/async_pixel_transfer_delegate_mock.h"
13 #include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
14 #include "gpu/command_buffer/service/async_pixel_transfer_manager_mock.h"
15 #include "gpu/command_buffer/service/cmd_buffer_engine.h"
16 #include "gpu/command_buffer/service/context_group.h"
17 #include "gpu/command_buffer/service/context_state.h"
18 #include "gpu/command_buffer/service/gl_surface_mock.h"
19 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
20 #include "gpu/command_buffer/service/gpu_switches.h"
21 #include "gpu/command_buffer/service/image_manager.h"
22 #include "gpu/command_buffer/service/mailbox_manager.h"
23 #include "gpu/command_buffer/service/mocks.h"
24 #include "gpu/command_buffer/service/program_manager.h"
25 #include "gpu/command_buffer/service/test_helper.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27 #include "ui/gl/gl_implementation.h"
28 #include "ui/gl/gl_mock.h"
29 #include "ui/gl/gl_surface_stub.h"
32 #if !defined(GL_DEPTH24_STENCIL8)
33 #define GL_DEPTH24_STENCIL8 0x88F0
36 using ::gfx::MockGLInterface;
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;
57 void GLES2DecoderRGBBackbufferTest::SetUp() {
58 // Test codepath with workaround clear_alpha_in_readpixels because
59 // ReadPixelsEmulator emulates the incorrect driver behavior.
60 CommandLine command_line(0, NULL);
61 command_line.AppendSwitchASCII(
62 switches::kGpuDriverBugWorkarounds,
63 base::IntToString(gpu::CLEAR_ALPHA_IN_READPIXELS));
65 init.gl_version = "3.0";
66 init.bind_generates_resource = true;
67 InitDecoderWithCommandLine(init, &command_line);
68 SetupDefaultProgram();
71 // Override default setup so nothing gets setup.
72 void GLES2DecoderManualInitTest::SetUp() {
75 void GLES2DecoderManualInitTest::EnableDisableTest(GLenum cap,
79 SetupExpectationsForEnableDisable(cap, enable);
84 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
85 EXPECT_EQ(GL_NO_ERROR, GetGLError());
89 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
90 EXPECT_EQ(GL_NO_ERROR, GetGLError());
94 TEST_P(GLES2DecoderTest, GetIntegervCached) {
101 GL_MAX_TEXTURE_SIZE, TestHelper::kMaxTextureSize,
104 GL_MAX_CUBE_MAP_TEXTURE_SIZE, TestHelper::kMaxCubeMapTextureSize,
107 GL_MAX_RENDERBUFFER_SIZE, TestHelper::kMaxRenderbufferSize,
110 typedef GetIntegerv::Result Result;
111 for (size_t ii = 0; ii < sizeof(tests) / sizeof(tests[0]); ++ii) {
112 const TestInfo& test = tests[ii];
113 Result* result = static_cast<Result*>(shared_memory_address_);
114 EXPECT_CALL(*gl_, GetError())
115 .WillOnce(Return(GL_NO_ERROR))
116 .WillOnce(Return(GL_NO_ERROR))
117 .RetiresOnSaturation();
118 EXPECT_CALL(*gl_, GetIntegerv(test.pname, _)).Times(0);
121 cmd2.Init(test.pname, shared_memory_id_, shared_memory_offset_);
122 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
123 EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(test.pname),
124 result->GetNumResults());
125 EXPECT_EQ(GL_NO_ERROR, GetGLError());
126 EXPECT_EQ(test.expected, result->GetData()[0]);
130 TEST_P(GLES2DecoderWithShaderTest, GetMaxValueInBufferCHROMIUM) {
132 GetMaxValueInBufferCHROMIUM::Result* result =
133 static_cast<GetMaxValueInBufferCHROMIUM::Result*>(shared_memory_address_);
136 GetMaxValueInBufferCHROMIUM cmd;
137 cmd.Init(client_element_buffer_id_,
138 kValidIndexRangeCount,
140 kValidIndexRangeStart * 2,
142 kSharedMemoryOffset);
143 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
144 EXPECT_EQ(7u, *result);
145 EXPECT_EQ(GL_NO_ERROR, GetGLError());
146 cmd.Init(client_element_buffer_id_,
147 kValidIndexRangeCount + 1,
149 kValidIndexRangeStart * 2,
151 kSharedMemoryOffset);
152 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
153 EXPECT_EQ(100u, *result);
154 EXPECT_EQ(GL_NO_ERROR, GetGLError());
156 cmd.Init(kInvalidClientId,
157 kValidIndexRangeCount,
159 kValidIndexRangeStart * 2,
161 kSharedMemoryOffset);
162 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
163 EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
164 cmd.Init(client_element_buffer_id_,
165 kOutOfRangeIndexRangeEnd,
167 kValidIndexRangeStart * 2,
169 kSharedMemoryOffset);
170 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
171 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
172 cmd.Init(client_element_buffer_id_,
173 kValidIndexRangeCount + 1,
175 kOutOfRangeIndexRangeEnd * 2,
177 kSharedMemoryOffset);
178 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
179 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
180 cmd.Init(client_element_buffer_id_,
181 kValidIndexRangeCount + 1,
183 kValidIndexRangeStart * 2,
185 kSharedMemoryOffset);
186 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
187 cmd.Init(client_buffer_id_,
188 kValidIndexRangeCount + 1,
190 kValidIndexRangeStart * 2,
192 kSharedMemoryOffset);
193 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
194 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
195 cmd.Init(client_element_buffer_id_,
196 kValidIndexRangeCount + 1,
198 kValidIndexRangeStart * 2,
199 kInvalidSharedMemoryId,
200 kSharedMemoryOffset);
201 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
202 cmd.Init(client_element_buffer_id_,
203 kValidIndexRangeCount + 1,
205 kValidIndexRangeStart * 2,
207 kInvalidSharedMemoryOffset);
208 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
211 TEST_P(GLES2DecoderTest, SharedIds) {
212 GenSharedIdsCHROMIUM gen_cmd;
213 RegisterSharedIdsCHROMIUM reg_cmd;
214 DeleteSharedIdsCHROMIUM del_cmd;
216 const GLuint kNamespaceId = id_namespaces::kTextures;
217 const GLuint kExpectedId1 = 1;
218 const GLuint kExpectedId2 = 2;
219 const GLuint kExpectedId3 = 4;
220 const GLuint kRegisterId = 3;
221 GLuint* ids = GetSharedMemoryAs<GLuint*>();
222 gen_cmd.Init(kNamespaceId, 0, 2, kSharedMemoryId, kSharedMemoryOffset);
223 EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd));
224 IdAllocatorInterface* id_allocator = GetIdAllocator(kNamespaceId);
225 ASSERT_TRUE(id_allocator != NULL);
226 // This check is implementation dependant but it's kind of hard to check
228 EXPECT_EQ(kExpectedId1, ids[0]);
229 EXPECT_EQ(kExpectedId2, ids[1]);
230 EXPECT_TRUE(id_allocator->InUse(kExpectedId1));
231 EXPECT_TRUE(id_allocator->InUse(kExpectedId2));
232 EXPECT_FALSE(id_allocator->InUse(kRegisterId));
233 EXPECT_FALSE(id_allocator->InUse(kExpectedId3));
236 ids[0] = kRegisterId;
237 reg_cmd.Init(kNamespaceId, 1, kSharedMemoryId, kSharedMemoryOffset);
238 EXPECT_EQ(error::kNoError, ExecuteCmd(reg_cmd));
239 EXPECT_TRUE(id_allocator->InUse(kExpectedId1));
240 EXPECT_TRUE(id_allocator->InUse(kExpectedId2));
241 EXPECT_TRUE(id_allocator->InUse(kRegisterId));
242 EXPECT_FALSE(id_allocator->InUse(kExpectedId3));
245 gen_cmd.Init(kNamespaceId, 0, 1, kSharedMemoryId, kSharedMemoryOffset);
246 EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd));
247 EXPECT_EQ(kExpectedId3, ids[0]);
248 EXPECT_TRUE(id_allocator->InUse(kExpectedId1));
249 EXPECT_TRUE(id_allocator->InUse(kExpectedId2));
250 EXPECT_TRUE(id_allocator->InUse(kRegisterId));
251 EXPECT_TRUE(id_allocator->InUse(kExpectedId3));
254 ids[0] = kExpectedId1;
255 ids[1] = kRegisterId;
256 del_cmd.Init(kNamespaceId, 2, kSharedMemoryId, kSharedMemoryOffset);
257 EXPECT_EQ(error::kNoError, ExecuteCmd(del_cmd));
258 EXPECT_FALSE(id_allocator->InUse(kExpectedId1));
259 EXPECT_TRUE(id_allocator->InUse(kExpectedId2));
260 EXPECT_FALSE(id_allocator->InUse(kRegisterId));
261 EXPECT_TRUE(id_allocator->InUse(kExpectedId3));
264 ids[0] = kExpectedId3;
265 ids[1] = kExpectedId2;
266 del_cmd.Init(kNamespaceId, 2, kSharedMemoryId, kSharedMemoryOffset);
267 EXPECT_EQ(error::kNoError, ExecuteCmd(del_cmd));
268 EXPECT_FALSE(id_allocator->InUse(kExpectedId1));
269 EXPECT_FALSE(id_allocator->InUse(kExpectedId2));
270 EXPECT_FALSE(id_allocator->InUse(kRegisterId));
271 EXPECT_FALSE(id_allocator->InUse(kExpectedId3));
273 // Check passing in an id_offset.
275 const GLuint kOffset = 0xABCDEF;
276 gen_cmd.Init(kNamespaceId, kOffset, 2, kSharedMemoryId, kSharedMemoryOffset);
277 EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd));
278 EXPECT_EQ(kOffset, ids[0]);
279 EXPECT_EQ(kOffset + 1, ids[1]);
282 TEST_P(GLES2DecoderTest, GenSharedIdsCHROMIUMBadArgs) {
283 const GLuint kNamespaceId = id_namespaces::kTextures;
284 GenSharedIdsCHROMIUM cmd;
285 cmd.Init(kNamespaceId, 0, -1, kSharedMemoryId, kSharedMemoryOffset);
286 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
287 cmd.Init(kNamespaceId, 0, 1, kInvalidSharedMemoryId, kSharedMemoryOffset);
288 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
289 cmd.Init(kNamespaceId, 0, 1, kSharedMemoryId, kInvalidSharedMemoryOffset);
290 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
293 TEST_P(GLES2DecoderTest, RegisterSharedIdsCHROMIUMBadArgs) {
294 const GLuint kNamespaceId = id_namespaces::kTextures;
295 RegisterSharedIdsCHROMIUM cmd;
296 cmd.Init(kNamespaceId, -1, kSharedMemoryId, kSharedMemoryOffset);
297 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
298 cmd.Init(kNamespaceId, 1, kInvalidSharedMemoryId, kSharedMemoryOffset);
299 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
300 cmd.Init(kNamespaceId, 1, kSharedMemoryId, kInvalidSharedMemoryOffset);
301 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
304 TEST_P(GLES2DecoderTest, RegisterSharedIdsCHROMIUMDuplicateIds) {
305 const GLuint kNamespaceId = id_namespaces::kTextures;
306 const GLuint kRegisterId = 3;
307 RegisterSharedIdsCHROMIUM cmd;
308 GLuint* ids = GetSharedMemoryAs<GLuint*>();
309 ids[0] = kRegisterId;
310 cmd.Init(kNamespaceId, 1, kSharedMemoryId, kSharedMemoryOffset);
311 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
312 cmd.Init(kNamespaceId, 1, kSharedMemoryId, kSharedMemoryOffset);
313 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
314 EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
317 TEST_P(GLES2DecoderTest, DeleteSharedIdsCHROMIUMBadArgs) {
318 const GLuint kNamespaceId = id_namespaces::kTextures;
319 DeleteSharedIdsCHROMIUM cmd;
320 cmd.Init(kNamespaceId, -1, kSharedMemoryId, kSharedMemoryOffset);
321 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
322 cmd.Init(kNamespaceId, 1, kInvalidSharedMemoryId, kSharedMemoryOffset);
323 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
324 cmd.Init(kNamespaceId, 1, kSharedMemoryId, kInvalidSharedMemoryOffset);
325 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
328 TEST_P(GLES2DecoderTest, IsBuffer) {
329 EXPECT_FALSE(DoIsBuffer(client_buffer_id_));
330 DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
331 EXPECT_TRUE(DoIsBuffer(client_buffer_id_));
332 DoDeleteBuffer(client_buffer_id_, kServiceBufferId);
333 EXPECT_FALSE(DoIsBuffer(client_buffer_id_));
336 TEST_P(GLES2DecoderTest, IsFramebuffer) {
337 EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_));
339 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
340 EXPECT_TRUE(DoIsFramebuffer(client_framebuffer_id_));
341 DoDeleteFramebuffer(client_framebuffer_id_,
342 kServiceFramebufferId,
349 EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_));
352 TEST_P(GLES2DecoderTest, IsProgram) {
353 // IsProgram is true as soon as the program is created.
354 EXPECT_TRUE(DoIsProgram(client_program_id_));
355 EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId))
357 .RetiresOnSaturation();
358 DoDeleteProgram(client_program_id_, kServiceProgramId);
359 EXPECT_FALSE(DoIsProgram(client_program_id_));
362 TEST_P(GLES2DecoderTest, IsRenderbuffer) {
363 EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_));
365 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
366 EXPECT_TRUE(DoIsRenderbuffer(client_renderbuffer_id_));
367 DoDeleteRenderbuffer(client_renderbuffer_id_, kServiceRenderbufferId);
368 EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_));
371 TEST_P(GLES2DecoderTest, IsShader) {
372 // IsShader is true as soon as the program is created.
373 EXPECT_TRUE(DoIsShader(client_shader_id_));
374 DoDeleteShader(client_shader_id_, kServiceShaderId);
375 EXPECT_FALSE(DoIsShader(client_shader_id_));
378 TEST_P(GLES2DecoderTest, IsTexture) {
379 EXPECT_FALSE(DoIsTexture(client_texture_id_));
380 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
381 EXPECT_TRUE(DoIsTexture(client_texture_id_));
382 DoDeleteTexture(client_texture_id_, kServiceTextureId);
383 EXPECT_FALSE(DoIsTexture(client_texture_id_));
386 TEST_P(GLES2DecoderTest, GetMultipleIntegervCHROMIUMValidArgs) {
387 const GLsizei kCount = 3;
388 GLenum* pnames = GetSharedMemoryAs<GLenum*>();
389 pnames[0] = GL_DEPTH_WRITEMASK;
390 pnames[1] = GL_COLOR_WRITEMASK;
391 pnames[2] = GL_STENCIL_WRITEMASK;
393 GetSharedMemoryAsWithOffset<GLint*>(sizeof(*pnames) * kCount);
395 GLsizei num_results = 0;
396 for (GLsizei ii = 0; ii < kCount; ++ii) {
397 num_results += decoder_->GetGLES2Util()->GLGetNumValuesReturned(pnames[ii]);
399 const GLsizei result_size = num_results * sizeof(*results);
400 memset(results, 0, result_size);
402 const GLint kSentinel = 0x12345678;
403 results[num_results] = kSentinel;
405 GetMultipleIntegervCHROMIUM cmd;
406 cmd.Init(kSharedMemoryId,
410 kSharedMemoryOffset + sizeof(*pnames) * kCount,
413 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
414 EXPECT_EQ(GL_NO_ERROR, GetGLError());
415 EXPECT_EQ(1, results[0]); // Depth writemask
416 EXPECT_EQ(1, results[1]); // color writemask red
417 EXPECT_EQ(1, results[2]); // color writemask green
418 EXPECT_EQ(1, results[3]); // color writemask blue
419 EXPECT_EQ(1, results[4]); // color writemask alpha
420 EXPECT_EQ(-1, results[5]); // stencil writemask alpha
421 EXPECT_EQ(kSentinel, results[num_results]); // End of results
424 TEST_P(GLES2DecoderTest, GetMultipleIntegervCHROMIUMInvalidArgs) {
425 const GLsizei kCount = 3;
426 // Offset the pnames because GLGetError will use the first uint32.
427 const uint32 kPnameOffset = sizeof(uint32);
428 const uint32 kResultsOffset = kPnameOffset + sizeof(GLint) * kCount;
429 GLenum* pnames = GetSharedMemoryAsWithOffset<GLenum*>(kPnameOffset);
430 pnames[0] = GL_DEPTH_WRITEMASK;
431 pnames[1] = GL_COLOR_WRITEMASK;
432 pnames[2] = GL_STENCIL_WRITEMASK;
433 GLint* results = GetSharedMemoryAsWithOffset<GLint*>(kResultsOffset);
435 GLsizei num_results = 0;
436 for (GLsizei ii = 0; ii < kCount; ++ii) {
437 num_results += decoder_->GetGLES2Util()->GLGetNumValuesReturned(pnames[ii]);
439 const GLsizei result_size = num_results * sizeof(*results);
440 memset(results, 0, result_size);
442 const GLint kSentinel = 0x12345678;
443 results[num_results] = kSentinel;
445 GetMultipleIntegervCHROMIUM cmd;
446 // Check bad pnames pointer.
447 cmd.Init(kInvalidSharedMemoryId,
448 kSharedMemoryOffset + kPnameOffset,
451 kSharedMemoryOffset + kResultsOffset,
453 EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
454 EXPECT_EQ(GL_NO_ERROR, GetGLError());
455 // Check bad pnames pointer.
456 cmd.Init(kSharedMemoryId,
457 kInvalidSharedMemoryOffset,
460 kSharedMemoryOffset + kResultsOffset,
462 EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
463 EXPECT_EQ(GL_NO_ERROR, GetGLError());
465 cmd.Init(kSharedMemoryId,
466 kSharedMemoryOffset + kPnameOffset,
469 kSharedMemoryOffset + kResultsOffset,
471 EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
472 EXPECT_EQ(GL_NO_ERROR, GetGLError());
473 // Check bad results pointer.
474 cmd.Init(kSharedMemoryId,
475 kSharedMemoryOffset + kPnameOffset,
477 kInvalidSharedMemoryId,
478 kSharedMemoryOffset + kResultsOffset,
480 EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
481 EXPECT_EQ(GL_NO_ERROR, GetGLError());
482 // Check bad results pointer.
483 cmd.Init(kSharedMemoryId,
484 kSharedMemoryOffset + kPnameOffset,
487 kInvalidSharedMemoryOffset,
489 EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
490 EXPECT_EQ(GL_NO_ERROR, GetGLError());
492 cmd.Init(kSharedMemoryId,
493 kSharedMemoryOffset + kPnameOffset,
496 kSharedMemoryOffset + kResultsOffset,
498 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
499 EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
501 cmd.Init(kSharedMemoryId,
502 kSharedMemoryOffset + kPnameOffset,
505 kSharedMemoryOffset + kResultsOffset,
507 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
508 EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
510 cmd.Init(kSharedMemoryId,
511 kSharedMemoryOffset + kPnameOffset,
514 kSharedMemoryOffset + kResultsOffset,
516 GLenum temp = pnames[2];
518 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
519 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
521 // Check results area has not been cleared by client.
523 EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
524 // Check buffer is what we expect
525 EXPECT_EQ(0, results[0]);
526 EXPECT_EQ(1, results[1]);
527 EXPECT_EQ(0, results[2]);
528 EXPECT_EQ(0, results[3]);
529 EXPECT_EQ(0, results[4]);
530 EXPECT_EQ(0, results[5]);
531 EXPECT_EQ(kSentinel, results[num_results]); // End of results
534 TEST_P(GLES2DecoderManualInitTest, BindGeneratesResourceFalse) {
536 init.gl_version = "3.0";
540 cmd1.Init(GL_TEXTURE_2D, kInvalidClientId);
541 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
542 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
545 cmd2.Init(GL_ARRAY_BUFFER, kInvalidClientId);
546 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
547 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
549 BindFramebuffer cmd3;
550 cmd3.Init(GL_FRAMEBUFFER, kInvalidClientId);
551 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd3));
552 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
554 BindRenderbuffer cmd4;
555 cmd4.Init(GL_RENDERBUFFER, kInvalidClientId);
556 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd4));
557 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
560 TEST_P(GLES2DecoderTest, EnableFeatureCHROMIUMBadBucket) {
561 const uint32 kBadBucketId = 123;
562 EnableFeatureCHROMIUM cmd;
563 cmd.Init(kBadBucketId, shared_memory_id_, shared_memory_offset_);
564 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
567 TEST_P(GLES2DecoderTest, RequestExtensionCHROMIUMBadBucket) {
568 const uint32 kBadBucketId = 123;
569 RequestExtensionCHROMIUM cmd;
570 cmd.Init(kBadBucketId);
571 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
574 TEST_P(GLES2DecoderTest, BeginQueryEXTDisabled) {
575 // Test something fails if off.
578 TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXT) {
580 init.extensions = "GL_EXT_occlusion_query_boolean";
581 init.gl_version = "opengl es 2.0";
582 init.has_alpha = true;
583 init.request_alpha = true;
584 init.bind_generates_resource = true;
587 // Test end fails if no begin.
589 end_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, 1);
590 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
591 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
593 BeginQueryEXT begin_cmd;
595 // Test id = 0 fails.
597 GL_ANY_SAMPLES_PASSED_EXT, 0, kSharedMemoryId, kSharedMemoryOffset);
598 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
599 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
601 GenHelper<GenQueriesEXTImmediate>(kNewClientId);
603 // Test valid parameters work.
604 EXPECT_CALL(*gl_, GenQueriesARB(1, _))
605 .WillOnce(SetArgumentPointee<1>(kNewServiceId))
606 .RetiresOnSaturation();
607 EXPECT_CALL(*gl_, BeginQueryARB(GL_ANY_SAMPLES_PASSED_EXT, kNewServiceId))
609 .RetiresOnSaturation();
611 // Query object should not be created untill BeginQueriesEXT.
612 QueryManager* query_manager = decoder_->GetQueryManager();
613 ASSERT_TRUE(query_manager != NULL);
614 QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
615 EXPECT_TRUE(query == NULL);
617 // BeginQueryEXT should fail if id is not generated from GenQueriesEXT.
618 begin_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT,
621 kSharedMemoryOffset);
622 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
623 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
625 begin_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT,
628 kSharedMemoryOffset);
629 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
630 EXPECT_EQ(GL_NO_ERROR, GetGLError());
632 // After BeginQueriesEXT id name should have query object associated with it.
633 query = query_manager->GetQuery(kNewClientId);
634 ASSERT_TRUE(query != NULL);
635 EXPECT_FALSE(query->pending());
637 // Test trying begin again fails
638 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
639 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
641 // Test end fails with different target
642 end_cmd.Init(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, 1);
643 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
644 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
647 EXPECT_CALL(*gl_, EndQueryARB(GL_ANY_SAMPLES_PASSED_EXT))
649 .RetiresOnSaturation();
650 end_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, 1);
651 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
652 EXPECT_EQ(GL_NO_ERROR, GetGLError());
653 EXPECT_TRUE(query->pending());
655 EXPECT_CALL(*gl_, DeleteQueriesARB(1, _)).Times(1).RetiresOnSaturation();
663 const QueryType kQueryTypes[] = {
664 {GL_COMMANDS_ISSUED_CHROMIUM, false},
665 {GL_LATENCY_QUERY_CHROMIUM, false},
666 {GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM, false},
667 {GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, false},
668 {GL_GET_ERROR_QUERY_CHROMIUM, false},
669 {GL_COMMANDS_COMPLETED_CHROMIUM, false},
670 {GL_ANY_SAMPLES_PASSED_EXT, true},
673 static void CheckBeginEndQueryBadMemoryFails(GLES2DecoderTestBase* test,
676 const QueryType& query_type,
679 // We need to reset the decoder on each iteration, because we lose the
680 // context every time.
681 GLES2DecoderTestBase::InitState init;
682 init.extensions = "GL_EXT_occlusion_query_boolean GL_ARB_sync";
683 init.gl_version = "opengl es 2.0";
684 init.has_alpha = true;
685 init.request_alpha = true;
686 init.bind_generates_resource = true;
687 test->InitDecoder(init);
688 ::testing::StrictMock< ::gfx::MockGLInterface>* gl = test->GetGLMock();
690 BeginQueryEXT begin_cmd;
692 test->GenHelper<GenQueriesEXTImmediate>(client_id);
694 if (query_type.is_gl) {
695 EXPECT_CALL(*gl, GenQueriesARB(1, _))
696 .WillOnce(SetArgumentPointee<1>(service_id))
697 .RetiresOnSaturation();
698 EXPECT_CALL(*gl, BeginQueryARB(query_type.type, service_id))
700 .RetiresOnSaturation();
703 // Test bad shared memory fails
704 begin_cmd.Init(query_type.type, client_id, shm_id, shm_offset);
705 error::Error error1 = test->ExecuteCmd(begin_cmd);
707 if (query_type.is_gl) {
708 EXPECT_CALL(*gl, EndQueryARB(query_type.type))
710 .RetiresOnSaturation();
712 if (query_type.type == GL_GET_ERROR_QUERY_CHROMIUM) {
713 EXPECT_CALL(*gl, GetError())
714 .WillOnce(Return(GL_NO_ERROR))
715 .RetiresOnSaturation();
717 GLsync kGlSync = reinterpret_cast<GLsync>(0xdeadbeef);
718 if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM) {
719 EXPECT_CALL(*gl, Flush()).RetiresOnSaturation();
720 EXPECT_CALL(*gl, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0))
721 .WillOnce(Return(kGlSync))
722 .RetiresOnSaturation();
726 end_cmd.Init(query_type.type, 1);
727 error::Error error2 = test->ExecuteCmd(end_cmd);
729 if (query_type.is_gl) {
731 *gl, GetQueryObjectuivARB(service_id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
732 .WillOnce(SetArgumentPointee<2>(1))
733 .RetiresOnSaturation();
734 EXPECT_CALL(*gl, GetQueryObjectuivARB(service_id, GL_QUERY_RESULT_EXT, _))
735 .WillOnce(SetArgumentPointee<2>(1))
736 .RetiresOnSaturation();
738 if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM) {
739 EXPECT_CALL(*gl, ClientWaitSync(kGlSync, _, _))
740 .WillOnce(Return(GL_ALREADY_SIGNALED))
741 .RetiresOnSaturation();
744 QueryManager* query_manager = test->GetDecoder()->GetQueryManager();
745 ASSERT_TRUE(query_manager != NULL);
746 bool process_success = query_manager->ProcessPendingQueries();
748 EXPECT_TRUE(error1 != error::kNoError || error2 != error::kNoError ||
751 if (query_type.is_gl) {
752 EXPECT_CALL(*gl, DeleteQueriesARB(1, _)).Times(1).RetiresOnSaturation();
754 if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM)
755 EXPECT_CALL(*gl, DeleteSync(kGlSync)).Times(1).RetiresOnSaturation();
756 test->ResetDecoder();
759 TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTBadMemoryIdFails) {
760 for (size_t i = 0; i < arraysize(kQueryTypes); ++i) {
761 CheckBeginEndQueryBadMemoryFails(this,
765 kInvalidSharedMemoryId,
766 kSharedMemoryOffset);
770 TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTBadMemoryOffsetFails) {
771 for (size_t i = 0; i < arraysize(kQueryTypes); ++i) {
773 CheckBeginEndQueryBadMemoryFails(this,
778 kInvalidSharedMemoryOffset);
780 CheckBeginEndQueryBadMemoryFails(this,
789 TEST_P(GLES2DecoderTest, BeginEndQueryEXTCommandsIssuedCHROMIUM) {
790 BeginQueryEXT begin_cmd;
792 GenHelper<GenQueriesEXTImmediate>(kNewClientId);
794 // Test valid parameters work.
795 begin_cmd.Init(GL_COMMANDS_ISSUED_CHROMIUM,
798 kSharedMemoryOffset);
799 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
800 EXPECT_EQ(GL_NO_ERROR, GetGLError());
802 QueryManager* query_manager = decoder_->GetQueryManager();
803 ASSERT_TRUE(query_manager != NULL);
804 QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
805 ASSERT_TRUE(query != NULL);
806 EXPECT_FALSE(query->pending());
810 end_cmd.Init(GL_COMMANDS_ISSUED_CHROMIUM, 1);
811 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
812 EXPECT_EQ(GL_NO_ERROR, GetGLError());
813 EXPECT_FALSE(query->pending());
816 TEST_P(GLES2DecoderTest, BeginEndQueryEXTGetErrorQueryCHROMIUM) {
817 BeginQueryEXT begin_cmd;
819 GenHelper<GenQueriesEXTImmediate>(kNewClientId);
821 // Test valid parameters work.
822 begin_cmd.Init(GL_GET_ERROR_QUERY_CHROMIUM,
825 kSharedMemoryOffset);
826 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
827 EXPECT_EQ(GL_NO_ERROR, GetGLError());
829 QueryManager* query_manager = decoder_->GetQueryManager();
830 ASSERT_TRUE(query_manager != NULL);
831 QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
832 ASSERT_TRUE(query != NULL);
833 EXPECT_FALSE(query->pending());
836 QuerySync* sync = static_cast<QuerySync*>(shared_memory_address_);
838 EXPECT_CALL(*gl_, GetError())
839 .WillOnce(Return(GL_INVALID_VALUE))
840 .RetiresOnSaturation();
843 end_cmd.Init(GL_GET_ERROR_QUERY_CHROMIUM, 1);
844 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
845 EXPECT_EQ(GL_NO_ERROR, GetGLError());
846 EXPECT_FALSE(query->pending());
847 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE),
848 static_cast<GLenum>(sync->result));
851 TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTCommandsCompletedCHROMIUM) {
853 init.extensions = "GL_EXT_occlusion_query_boolean GL_ARB_sync";
854 init.gl_version = "opengl es 2.0";
855 init.has_alpha = true;
856 init.request_alpha = true;
857 init.bind_generates_resource = true;
860 GenHelper<GenQueriesEXTImmediate>(kNewClientId);
862 BeginQueryEXT begin_cmd;
863 begin_cmd.Init(GL_COMMANDS_COMPLETED_CHROMIUM,
866 kSharedMemoryOffset);
867 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
868 EXPECT_EQ(GL_NO_ERROR, GetGLError());
870 QueryManager* query_manager = decoder_->GetQueryManager();
871 ASSERT_TRUE(query_manager != NULL);
872 QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
873 ASSERT_TRUE(query != NULL);
874 EXPECT_FALSE(query->pending());
876 GLsync kGlSync = reinterpret_cast<GLsync>(0xdeadbeef);
877 EXPECT_CALL(*gl_, Flush()).RetiresOnSaturation();
878 EXPECT_CALL(*gl_, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0))
879 .WillOnce(Return(kGlSync))
880 .RetiresOnSaturation();
883 end_cmd.Init(GL_COMMANDS_COMPLETED_CHROMIUM, 1);
884 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
885 EXPECT_EQ(GL_NO_ERROR, GetGLError());
886 EXPECT_TRUE(query->pending());
888 EXPECT_CALL(*gl_, ClientWaitSync(kGlSync, _, _))
889 .WillOnce(Return(GL_TIMEOUT_EXPIRED))
890 .RetiresOnSaturation();
891 bool process_success = query_manager->ProcessPendingQueries();
893 EXPECT_TRUE(process_success);
894 EXPECT_TRUE(query->pending());
896 EXPECT_CALL(*gl_, ClientWaitSync(kGlSync, _, _))
897 .WillOnce(Return(GL_ALREADY_SIGNALED))
898 .RetiresOnSaturation();
899 process_success = query_manager->ProcessPendingQueries();
901 EXPECT_TRUE(process_success);
902 EXPECT_FALSE(query->pending());
903 QuerySync* sync = static_cast<QuerySync*>(shared_memory_address_);
904 EXPECT_EQ(static_cast<GLenum>(0), static_cast<GLenum>(sync->result));
906 EXPECT_CALL(*gl_, DeleteSync(kGlSync)).Times(1).RetiresOnSaturation();
910 TEST_P(GLES2DecoderTest, IsEnabledReturnsCachedValue) {
911 // NOTE: There are no expectations because no GL functions should be
912 // called for DEPTH_TEST or STENCIL_TEST
913 static const GLenum kStates[] = {
914 GL_DEPTH_TEST, GL_STENCIL_TEST,
916 for (size_t ii = 0; ii < arraysize(kStates); ++ii) {
918 GLenum state = kStates[ii];
919 enable_cmd.Init(state);
920 EXPECT_EQ(error::kNoError, ExecuteCmd(enable_cmd));
921 IsEnabled::Result* result =
922 static_cast<IsEnabled::Result*>(shared_memory_address_);
923 IsEnabled is_enabled_cmd;
924 is_enabled_cmd.Init(state, shared_memory_id_, shared_memory_offset_);
925 EXPECT_EQ(error::kNoError, ExecuteCmd(is_enabled_cmd));
926 EXPECT_NE(0u, *result);
928 disable_cmd.Init(state);
929 EXPECT_EQ(error::kNoError, ExecuteCmd(disable_cmd));
930 EXPECT_EQ(error::kNoError, ExecuteCmd(is_enabled_cmd));
931 EXPECT_EQ(0u, *result);
935 TEST_P(GLES2DecoderManualInitTest, GpuMemoryManagerCHROMIUM) {
937 init.extensions = "GL_ARB_texture_rectangle";
938 init.gl_version = "3.0";
939 init.bind_generates_resource = true;
942 Texture* texture = GetTexture(client_texture_id_)->texture();
943 EXPECT_TRUE(texture != NULL);
944 EXPECT_TRUE(texture->pool() == GL_TEXTURE_POOL_UNMANAGED_CHROMIUM);
946 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
949 cmd.Init(GL_TEXTURE_2D,
950 GL_TEXTURE_POOL_CHROMIUM,
951 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM);
952 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
953 EXPECT_EQ(GL_NO_ERROR, GetGLError());
955 cmd.Init(GL_TEXTURE_2D,
956 GL_TEXTURE_POOL_CHROMIUM,
957 GL_TEXTURE_POOL_MANAGED_CHROMIUM);
958 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
959 EXPECT_EQ(GL_NO_ERROR, GetGLError());
961 EXPECT_TRUE(texture->pool() == GL_TEXTURE_POOL_MANAGED_CHROMIUM);
963 cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_POOL_CHROMIUM, GL_NONE);
964 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
965 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
970 class SizeOnlyMemoryTracker : public MemoryTracker {
972 SizeOnlyMemoryTracker() {
973 // These are the default textures. 1 for TEXTURE_2D and 6 faces for
975 const size_t kInitialUnmanagedPoolSize = 7 * 4;
976 const size_t kInitialManagedPoolSize = 0;
977 pool_infos_[MemoryTracker::kUnmanaged].initial_size =
978 kInitialUnmanagedPoolSize;
979 pool_infos_[MemoryTracker::kManaged].initial_size = kInitialManagedPoolSize;
982 // Ensure a certain amount of GPU memory is free. Returns true on success.
983 MOCK_METHOD1(EnsureGPUMemoryAvailable, bool(size_t size_needed));
985 virtual void TrackMemoryAllocatedChange(size_t old_size,
988 PoolInfo& info = pool_infos_[pool];
989 info.size += new_size - old_size;
992 size_t GetPoolSize(Pool pool) {
993 const PoolInfo& info = pool_infos_[pool];
994 return info.size - info.initial_size;
998 virtual ~SizeOnlyMemoryTracker() {}
1000 PoolInfo() : initial_size(0), size(0) {}
1001 size_t initial_size;
1004 std::map<Pool, PoolInfo> pool_infos_;
1007 } // anonymous namespace.
1009 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerInitialSize) {
1010 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
1011 new SizeOnlyMemoryTracker();
1012 set_memory_tracker(memory_tracker.get());
1014 init.gl_version = "3.0";
1015 init.bind_generates_resource = true;
1017 // Expect that initial size - size is 0.
1018 EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1019 EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kManaged));
1022 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerTexImage2D) {
1023 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
1024 new SizeOnlyMemoryTracker();
1025 set_memory_tracker(memory_tracker.get());
1027 init.gl_version = "3.0";
1028 init.bind_generates_resource = true;
1030 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
1031 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1032 .WillOnce(Return(true))
1033 .RetiresOnSaturation();
1034 DoTexImage2D(GL_TEXTURE_2D,
1043 kSharedMemoryOffset);
1044 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1045 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(64))
1046 .WillOnce(Return(true))
1047 .RetiresOnSaturation();
1048 DoTexImage2D(GL_TEXTURE_2D,
1057 kSharedMemoryOffset);
1058 EXPECT_EQ(64u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1059 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1060 // Check we get out of memory and no call to glTexImage2D if Ensure fails.
1061 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(64))
1062 .WillOnce(Return(false))
1063 .RetiresOnSaturation();
1065 cmd.Init(GL_TEXTURE_2D,
1074 kSharedMemoryOffset);
1075 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1076 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
1077 EXPECT_EQ(64u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1080 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerTexStorage2DEXT) {
1081 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
1082 new SizeOnlyMemoryTracker();
1083 set_memory_tracker(memory_tracker.get());
1085 init.gl_version = "3.0";
1086 init.bind_generates_resource = true;
1088 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
1089 // Check we get out of memory and no call to glTexStorage2DEXT
1091 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1092 .WillOnce(Return(false))
1093 .RetiresOnSaturation();
1094 TexStorage2DEXT cmd;
1095 cmd.Init(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 4);
1096 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1097 EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1098 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
1101 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerCopyTexImage2D) {
1102 GLenum target = GL_TEXTURE_2D;
1104 GLenum internal_format = GL_RGBA;
1108 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
1109 new SizeOnlyMemoryTracker();
1110 set_memory_tracker(memory_tracker.get());
1112 init.gl_version = "3.0";
1113 init.has_alpha = true;
1114 init.request_alpha = true;
1115 init.bind_generates_resource = true;
1117 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
1118 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1119 .WillOnce(Return(true))
1120 .RetiresOnSaturation();
1121 EXPECT_CALL(*gl_, GetError())
1122 .WillOnce(Return(GL_NO_ERROR))
1123 .WillOnce(Return(GL_NO_ERROR))
1124 .RetiresOnSaturation();
1127 target, level, internal_format, 0, 0, width, height, border))
1129 .RetiresOnSaturation();
1131 cmd.Init(target, level, internal_format, 0, 0, width, height, border);
1132 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1133 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1134 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1135 // Check we get out of memory and no call to glCopyTexImage2D if Ensure fails.
1136 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1137 .WillOnce(Return(false))
1138 .RetiresOnSaturation();
1139 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1140 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
1141 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1144 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerRenderbufferStorage) {
1145 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
1146 new SizeOnlyMemoryTracker();
1147 set_memory_tracker(memory_tracker.get());
1149 init.gl_version = "3.0";
1150 init.bind_generates_resource = true;
1153 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
1154 EXPECT_CALL(*gl_, GetError())
1155 .WillOnce(Return(GL_NO_ERROR))
1156 .WillOnce(Return(GL_NO_ERROR))
1157 .RetiresOnSaturation();
1158 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1159 .WillOnce(Return(true))
1160 .RetiresOnSaturation();
1161 EXPECT_CALL(*gl_, RenderbufferStorageEXT(GL_RENDERBUFFER, GL_RGBA, 8, 4))
1163 .RetiresOnSaturation();
1164 RenderbufferStorage cmd;
1165 cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 8, 4);
1166 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1167 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1168 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1169 // Check we get out of memory and no call to glRenderbufferStorage if Ensure
1171 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1172 .WillOnce(Return(false))
1173 .RetiresOnSaturation();
1174 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1175 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
1176 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1179 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerBufferData) {
1180 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
1181 new SizeOnlyMemoryTracker();
1182 set_memory_tracker(memory_tracker.get());
1184 init.gl_version = "3.0";
1185 init.bind_generates_resource = true;
1187 DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
1188 EXPECT_CALL(*gl_, GetError())
1189 .WillOnce(Return(GL_NO_ERROR))
1190 .WillOnce(Return(GL_NO_ERROR))
1191 .RetiresOnSaturation();
1192 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1193 .WillOnce(Return(true))
1194 .RetiresOnSaturation();
1195 EXPECT_CALL(*gl_, BufferData(GL_ARRAY_BUFFER, 128, _, GL_STREAM_DRAW))
1197 .RetiresOnSaturation();
1199 cmd.Init(GL_ARRAY_BUFFER, 128, 0, 0, GL_STREAM_DRAW);
1200 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1201 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1202 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kManaged));
1203 // Check we get out of memory and no call to glBufferData if Ensure
1205 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1206 .WillOnce(Return(false))
1207 .RetiresOnSaturation();
1208 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1209 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
1210 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kManaged));
1213 INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderTest, ::testing::Bool());
1215 INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderWithShaderTest, ::testing::Bool());
1217 INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderManualInitTest, ::testing::Bool());
1219 INSTANTIATE_TEST_CASE_P(Service,
1220 GLES2DecoderRGBBackbufferTest,
1223 } // namespace gles2