Handle account removal correctly on all platforms.
[chromium-blink-merge.git] / gpu / command_buffer / service / gles2_cmd_decoder_unittest.cc
blob9ddadf83f41ccde50466be7a381c29881f66c0df
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
34 #endif
36 using ::gfx::MockGLInterface;
37 using ::testing::_;
38 using ::testing::AtLeast;
39 using ::testing::DoAll;
40 using ::testing::InSequence;
41 using ::testing::Invoke;
42 using ::testing::MatcherCast;
43 using ::testing::Mock;
44 using ::testing::Pointee;
45 using ::testing::Return;
46 using ::testing::SaveArg;
47 using ::testing::SetArrayArgument;
48 using ::testing::SetArgumentPointee;
49 using ::testing::SetArgPointee;
50 using ::testing::StrEq;
51 using ::testing::StrictMock;
53 namespace gpu {
54 namespace gles2 {
56 using namespace cmds;
58 void GLES2DecoderRGBBackbufferTest::SetUp() {
59 // Test codepath with workaround clear_alpha_in_readpixels because
60 // ReadPixelsEmulator emulates the incorrect driver behavior.
61 CommandLine command_line(0, NULL);
62 command_line.AppendSwitchASCII(
63 switches::kGpuDriverBugWorkarounds,
64 base::IntToString(gpu::CLEAR_ALPHA_IN_READPIXELS));
65 InitState init;
66 init.gl_version = "3.0";
67 init.bind_generates_resource = true;
68 InitDecoderWithCommandLine(init, &command_line);
69 SetupDefaultProgram();
72 // Override default setup so nothing gets setup.
73 void GLES2DecoderManualInitTest::SetUp() {
76 void GLES2DecoderManualInitTest::EnableDisableTest(GLenum cap,
77 bool enable,
78 bool expect_set) {
79 if (expect_set) {
80 SetupExpectationsForEnableDisable(cap, enable);
82 if (enable) {
83 Enable cmd;
84 cmd.Init(cap);
85 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
86 EXPECT_EQ(GL_NO_ERROR, GetGLError());
87 } else {
88 Disable cmd;
89 cmd.Init(cap);
90 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
91 EXPECT_EQ(GL_NO_ERROR, GetGLError());
95 TEST_P(GLES2DecoderTest, GetIntegervCached) {
96 struct TestInfo {
97 GLenum pname;
98 GLint expected;
100 TestInfo tests[] = {
102 GL_MAX_TEXTURE_SIZE, TestHelper::kMaxTextureSize,
105 GL_MAX_CUBE_MAP_TEXTURE_SIZE, TestHelper::kMaxCubeMapTextureSize,
108 GL_MAX_RENDERBUFFER_SIZE, TestHelper::kMaxRenderbufferSize,
111 typedef GetIntegerv::Result Result;
112 for (size_t ii = 0; ii < sizeof(tests) / sizeof(tests[0]); ++ii) {
113 const TestInfo& test = tests[ii];
114 Result* result = static_cast<Result*>(shared_memory_address_);
115 EXPECT_CALL(*gl_, GetError())
116 .WillOnce(Return(GL_NO_ERROR))
117 .WillOnce(Return(GL_NO_ERROR))
118 .RetiresOnSaturation();
119 EXPECT_CALL(*gl_, GetIntegerv(test.pname, _)).Times(0);
120 result->size = 0;
121 GetIntegerv cmd2;
122 cmd2.Init(test.pname, shared_memory_id_, shared_memory_offset_);
123 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
124 EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(test.pname),
125 result->GetNumResults());
126 EXPECT_EQ(GL_NO_ERROR, GetGLError());
127 EXPECT_EQ(test.expected, result->GetData()[0]);
131 TEST_P(GLES2DecoderWithShaderTest, GetMaxValueInBufferCHROMIUM) {
132 SetupIndexBuffer();
133 GetMaxValueInBufferCHROMIUM::Result* result =
134 static_cast<GetMaxValueInBufferCHROMIUM::Result*>(shared_memory_address_);
135 *result = 0;
137 GetMaxValueInBufferCHROMIUM cmd;
138 cmd.Init(client_element_buffer_id_,
139 kValidIndexRangeCount,
140 GL_UNSIGNED_SHORT,
141 kValidIndexRangeStart * 2,
142 kSharedMemoryId,
143 kSharedMemoryOffset);
144 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
145 EXPECT_EQ(7u, *result);
146 EXPECT_EQ(GL_NO_ERROR, GetGLError());
147 cmd.Init(client_element_buffer_id_,
148 kValidIndexRangeCount + 1,
149 GL_UNSIGNED_SHORT,
150 kValidIndexRangeStart * 2,
151 kSharedMemoryId,
152 kSharedMemoryOffset);
153 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
154 EXPECT_EQ(100u, *result);
155 EXPECT_EQ(GL_NO_ERROR, GetGLError());
157 cmd.Init(kInvalidClientId,
158 kValidIndexRangeCount,
159 GL_UNSIGNED_SHORT,
160 kValidIndexRangeStart * 2,
161 kSharedMemoryId,
162 kSharedMemoryOffset);
163 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
164 EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
165 cmd.Init(client_element_buffer_id_,
166 kOutOfRangeIndexRangeEnd,
167 GL_UNSIGNED_SHORT,
168 kValidIndexRangeStart * 2,
169 kSharedMemoryId,
170 kSharedMemoryOffset);
171 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
172 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
173 cmd.Init(client_element_buffer_id_,
174 kValidIndexRangeCount + 1,
175 GL_UNSIGNED_SHORT,
176 kOutOfRangeIndexRangeEnd * 2,
177 kSharedMemoryId,
178 kSharedMemoryOffset);
179 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
180 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
181 cmd.Init(client_element_buffer_id_,
182 kValidIndexRangeCount + 1,
183 GL_UNSIGNED_SHORT,
184 kValidIndexRangeStart * 2,
185 kSharedMemoryId,
186 kSharedMemoryOffset);
187 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
188 cmd.Init(client_buffer_id_,
189 kValidIndexRangeCount + 1,
190 GL_UNSIGNED_SHORT,
191 kValidIndexRangeStart * 2,
192 kSharedMemoryId,
193 kSharedMemoryOffset);
194 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
195 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
196 cmd.Init(client_element_buffer_id_,
197 kValidIndexRangeCount + 1,
198 GL_UNSIGNED_SHORT,
199 kValidIndexRangeStart * 2,
200 kInvalidSharedMemoryId,
201 kSharedMemoryOffset);
202 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
203 cmd.Init(client_element_buffer_id_,
204 kValidIndexRangeCount + 1,
205 GL_UNSIGNED_SHORT,
206 kValidIndexRangeStart * 2,
207 kSharedMemoryId,
208 kInvalidSharedMemoryOffset);
209 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
212 TEST_P(GLES2DecoderTest, SharedIds) {
213 GenSharedIdsCHROMIUM gen_cmd;
214 RegisterSharedIdsCHROMIUM reg_cmd;
215 DeleteSharedIdsCHROMIUM del_cmd;
217 const GLuint kNamespaceId = id_namespaces::kTextures;
218 const GLuint kExpectedId1 = 1;
219 const GLuint kExpectedId2 = 2;
220 const GLuint kExpectedId3 = 4;
221 const GLuint kRegisterId = 3;
222 GLuint* ids = GetSharedMemoryAs<GLuint*>();
223 gen_cmd.Init(kNamespaceId, 0, 2, kSharedMemoryId, kSharedMemoryOffset);
224 EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd));
225 IdAllocatorInterface* id_allocator = GetIdAllocator(kNamespaceId);
226 ASSERT_TRUE(id_allocator != NULL);
227 // This check is implementation dependant but it's kind of hard to check
228 // otherwise.
229 EXPECT_EQ(kExpectedId1, ids[0]);
230 EXPECT_EQ(kExpectedId2, ids[1]);
231 EXPECT_TRUE(id_allocator->InUse(kExpectedId1));
232 EXPECT_TRUE(id_allocator->InUse(kExpectedId2));
233 EXPECT_FALSE(id_allocator->InUse(kRegisterId));
234 EXPECT_FALSE(id_allocator->InUse(kExpectedId3));
236 ClearSharedMemory();
237 ids[0] = kRegisterId;
238 reg_cmd.Init(kNamespaceId, 1, kSharedMemoryId, kSharedMemoryOffset);
239 EXPECT_EQ(error::kNoError, ExecuteCmd(reg_cmd));
240 EXPECT_TRUE(id_allocator->InUse(kExpectedId1));
241 EXPECT_TRUE(id_allocator->InUse(kExpectedId2));
242 EXPECT_TRUE(id_allocator->InUse(kRegisterId));
243 EXPECT_FALSE(id_allocator->InUse(kExpectedId3));
245 ClearSharedMemory();
246 gen_cmd.Init(kNamespaceId, 0, 1, kSharedMemoryId, kSharedMemoryOffset);
247 EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd));
248 EXPECT_EQ(kExpectedId3, ids[0]);
249 EXPECT_TRUE(id_allocator->InUse(kExpectedId1));
250 EXPECT_TRUE(id_allocator->InUse(kExpectedId2));
251 EXPECT_TRUE(id_allocator->InUse(kRegisterId));
252 EXPECT_TRUE(id_allocator->InUse(kExpectedId3));
254 ClearSharedMemory();
255 ids[0] = kExpectedId1;
256 ids[1] = kRegisterId;
257 del_cmd.Init(kNamespaceId, 2, kSharedMemoryId, kSharedMemoryOffset);
258 EXPECT_EQ(error::kNoError, ExecuteCmd(del_cmd));
259 EXPECT_FALSE(id_allocator->InUse(kExpectedId1));
260 EXPECT_TRUE(id_allocator->InUse(kExpectedId2));
261 EXPECT_FALSE(id_allocator->InUse(kRegisterId));
262 EXPECT_TRUE(id_allocator->InUse(kExpectedId3));
264 ClearSharedMemory();
265 ids[0] = kExpectedId3;
266 ids[1] = kExpectedId2;
267 del_cmd.Init(kNamespaceId, 2, kSharedMemoryId, kSharedMemoryOffset);
268 EXPECT_EQ(error::kNoError, ExecuteCmd(del_cmd));
269 EXPECT_FALSE(id_allocator->InUse(kExpectedId1));
270 EXPECT_FALSE(id_allocator->InUse(kExpectedId2));
271 EXPECT_FALSE(id_allocator->InUse(kRegisterId));
272 EXPECT_FALSE(id_allocator->InUse(kExpectedId3));
274 // Check passing in an id_offset.
275 ClearSharedMemory();
276 const GLuint kOffset = 0xABCDEF;
277 gen_cmd.Init(kNamespaceId, kOffset, 2, kSharedMemoryId, kSharedMemoryOffset);
278 EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd));
279 EXPECT_EQ(kOffset, ids[0]);
280 EXPECT_EQ(kOffset + 1, ids[1]);
283 TEST_P(GLES2DecoderTest, GenSharedIdsCHROMIUMBadArgs) {
284 const GLuint kNamespaceId = id_namespaces::kTextures;
285 GenSharedIdsCHROMIUM cmd;
286 cmd.Init(kNamespaceId, 0, -1, kSharedMemoryId, kSharedMemoryOffset);
287 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
288 cmd.Init(kNamespaceId, 0, 1, kInvalidSharedMemoryId, kSharedMemoryOffset);
289 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
290 cmd.Init(kNamespaceId, 0, 1, kSharedMemoryId, kInvalidSharedMemoryOffset);
291 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
294 TEST_P(GLES2DecoderTest, RegisterSharedIdsCHROMIUMBadArgs) {
295 const GLuint kNamespaceId = id_namespaces::kTextures;
296 RegisterSharedIdsCHROMIUM cmd;
297 cmd.Init(kNamespaceId, -1, kSharedMemoryId, kSharedMemoryOffset);
298 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
299 cmd.Init(kNamespaceId, 1, kInvalidSharedMemoryId, kSharedMemoryOffset);
300 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
301 cmd.Init(kNamespaceId, 1, kSharedMemoryId, kInvalidSharedMemoryOffset);
302 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
305 TEST_P(GLES2DecoderTest, RegisterSharedIdsCHROMIUMDuplicateIds) {
306 const GLuint kNamespaceId = id_namespaces::kTextures;
307 const GLuint kRegisterId = 3;
308 RegisterSharedIdsCHROMIUM cmd;
309 GLuint* ids = GetSharedMemoryAs<GLuint*>();
310 ids[0] = kRegisterId;
311 cmd.Init(kNamespaceId, 1, kSharedMemoryId, kSharedMemoryOffset);
312 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
313 cmd.Init(kNamespaceId, 1, kSharedMemoryId, kSharedMemoryOffset);
314 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
315 EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
318 TEST_P(GLES2DecoderTest, DeleteSharedIdsCHROMIUMBadArgs) {
319 const GLuint kNamespaceId = id_namespaces::kTextures;
320 DeleteSharedIdsCHROMIUM cmd;
321 cmd.Init(kNamespaceId, -1, kSharedMemoryId, kSharedMemoryOffset);
322 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
323 cmd.Init(kNamespaceId, 1, kInvalidSharedMemoryId, kSharedMemoryOffset);
324 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
325 cmd.Init(kNamespaceId, 1, kSharedMemoryId, kInvalidSharedMemoryOffset);
326 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
329 TEST_P(GLES2DecoderTest, IsBuffer) {
330 EXPECT_FALSE(DoIsBuffer(client_buffer_id_));
331 DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
332 EXPECT_TRUE(DoIsBuffer(client_buffer_id_));
333 DoDeleteBuffer(client_buffer_id_, kServiceBufferId);
334 EXPECT_FALSE(DoIsBuffer(client_buffer_id_));
337 TEST_P(GLES2DecoderTest, IsFramebuffer) {
338 EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_));
339 DoBindFramebuffer(
340 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
341 EXPECT_TRUE(DoIsFramebuffer(client_framebuffer_id_));
342 DoDeleteFramebuffer(client_framebuffer_id_,
343 kServiceFramebufferId,
344 true,
345 GL_FRAMEBUFFER,
347 true,
348 GL_FRAMEBUFFER,
350 EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_));
353 TEST_P(GLES2DecoderTest, IsProgram) {
354 // IsProgram is true as soon as the program is created.
355 EXPECT_TRUE(DoIsProgram(client_program_id_));
356 EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId))
357 .Times(1)
358 .RetiresOnSaturation();
359 DoDeleteProgram(client_program_id_, kServiceProgramId);
360 EXPECT_FALSE(DoIsProgram(client_program_id_));
363 TEST_P(GLES2DecoderTest, IsRenderbuffer) {
364 EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_));
365 DoBindRenderbuffer(
366 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
367 EXPECT_TRUE(DoIsRenderbuffer(client_renderbuffer_id_));
368 DoDeleteRenderbuffer(client_renderbuffer_id_, kServiceRenderbufferId);
369 EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_));
372 TEST_P(GLES2DecoderTest, IsShader) {
373 // IsShader is true as soon as the program is created.
374 EXPECT_TRUE(DoIsShader(client_shader_id_));
375 DoDeleteShader(client_shader_id_, kServiceShaderId);
376 EXPECT_FALSE(DoIsShader(client_shader_id_));
379 TEST_P(GLES2DecoderTest, IsTexture) {
380 EXPECT_FALSE(DoIsTexture(client_texture_id_));
381 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
382 EXPECT_TRUE(DoIsTexture(client_texture_id_));
383 DoDeleteTexture(client_texture_id_, kServiceTextureId);
384 EXPECT_FALSE(DoIsTexture(client_texture_id_));
387 TEST_P(GLES2DecoderTest, GetMultipleIntegervCHROMIUMValidArgs) {
388 const GLsizei kCount = 3;
389 GLenum* pnames = GetSharedMemoryAs<GLenum*>();
390 pnames[0] = GL_DEPTH_WRITEMASK;
391 pnames[1] = GL_COLOR_WRITEMASK;
392 pnames[2] = GL_STENCIL_WRITEMASK;
393 GLint* results =
394 GetSharedMemoryAsWithOffset<GLint*>(sizeof(*pnames) * kCount);
396 GLsizei num_results = 0;
397 for (GLsizei ii = 0; ii < kCount; ++ii) {
398 num_results += decoder_->GetGLES2Util()->GLGetNumValuesReturned(pnames[ii]);
400 const GLsizei result_size = num_results * sizeof(*results);
401 memset(results, 0, result_size);
403 const GLint kSentinel = 0x12345678;
404 results[num_results] = kSentinel;
406 GetMultipleIntegervCHROMIUM cmd;
407 cmd.Init(kSharedMemoryId,
408 kSharedMemoryOffset,
409 kCount,
410 kSharedMemoryId,
411 kSharedMemoryOffset + sizeof(*pnames) * kCount,
412 result_size);
414 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
415 EXPECT_EQ(GL_NO_ERROR, GetGLError());
416 EXPECT_EQ(1, results[0]); // Depth writemask
417 EXPECT_EQ(1, results[1]); // color writemask red
418 EXPECT_EQ(1, results[2]); // color writemask green
419 EXPECT_EQ(1, results[3]); // color writemask blue
420 EXPECT_EQ(1, results[4]); // color writemask alpha
421 EXPECT_EQ(-1, results[5]); // stencil writemask alpha
422 EXPECT_EQ(kSentinel, results[num_results]); // End of results
425 TEST_P(GLES2DecoderTest, GetMultipleIntegervCHROMIUMInvalidArgs) {
426 const GLsizei kCount = 3;
427 // Offset the pnames because GLGetError will use the first uint32.
428 const uint32 kPnameOffset = sizeof(uint32);
429 const uint32 kResultsOffset = kPnameOffset + sizeof(GLint) * kCount;
430 GLenum* pnames = GetSharedMemoryAsWithOffset<GLenum*>(kPnameOffset);
431 pnames[0] = GL_DEPTH_WRITEMASK;
432 pnames[1] = GL_COLOR_WRITEMASK;
433 pnames[2] = GL_STENCIL_WRITEMASK;
434 GLint* results = GetSharedMemoryAsWithOffset<GLint*>(kResultsOffset);
436 GLsizei num_results = 0;
437 for (GLsizei ii = 0; ii < kCount; ++ii) {
438 num_results += decoder_->GetGLES2Util()->GLGetNumValuesReturned(pnames[ii]);
440 const GLsizei result_size = num_results * sizeof(*results);
441 memset(results, 0, result_size);
443 const GLint kSentinel = 0x12345678;
444 results[num_results] = kSentinel;
446 GetMultipleIntegervCHROMIUM cmd;
447 // Check bad pnames pointer.
448 cmd.Init(kInvalidSharedMemoryId,
449 kSharedMemoryOffset + kPnameOffset,
450 kCount,
451 kSharedMemoryId,
452 kSharedMemoryOffset + kResultsOffset,
453 result_size);
454 EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
455 EXPECT_EQ(GL_NO_ERROR, GetGLError());
456 // Check bad pnames pointer.
457 cmd.Init(kSharedMemoryId,
458 kInvalidSharedMemoryOffset,
459 kCount,
460 kSharedMemoryId,
461 kSharedMemoryOffset + kResultsOffset,
462 result_size);
463 EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
464 EXPECT_EQ(GL_NO_ERROR, GetGLError());
465 // Check bad count.
466 cmd.Init(kSharedMemoryId,
467 kSharedMemoryOffset + kPnameOffset,
468 static_cast<GLuint>(-1),
469 kSharedMemoryId,
470 kSharedMemoryOffset + kResultsOffset,
471 result_size);
472 EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
473 EXPECT_EQ(GL_NO_ERROR, GetGLError());
474 // Check bad results pointer.
475 cmd.Init(kSharedMemoryId,
476 kSharedMemoryOffset + kPnameOffset,
477 kCount,
478 kInvalidSharedMemoryId,
479 kSharedMemoryOffset + kResultsOffset,
480 result_size);
481 EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
482 EXPECT_EQ(GL_NO_ERROR, GetGLError());
483 // Check bad results pointer.
484 cmd.Init(kSharedMemoryId,
485 kSharedMemoryOffset + kPnameOffset,
486 kCount,
487 kSharedMemoryId,
488 kInvalidSharedMemoryOffset,
489 result_size);
490 EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
491 EXPECT_EQ(GL_NO_ERROR, GetGLError());
492 // Check bad size.
493 cmd.Init(kSharedMemoryId,
494 kSharedMemoryOffset + kPnameOffset,
495 kCount,
496 kSharedMemoryId,
497 kSharedMemoryOffset + kResultsOffset,
498 result_size + 1);
499 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
500 EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
501 // Check bad size.
502 cmd.Init(kSharedMemoryId,
503 kSharedMemoryOffset + kPnameOffset,
504 kCount,
505 kSharedMemoryId,
506 kSharedMemoryOffset + kResultsOffset,
507 result_size - 1);
508 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
509 EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
510 // Check bad enum.
511 cmd.Init(kSharedMemoryId,
512 kSharedMemoryOffset + kPnameOffset,
513 kCount,
514 kSharedMemoryId,
515 kSharedMemoryOffset + kResultsOffset,
516 result_size);
517 GLenum temp = pnames[2];
518 pnames[2] = GL_TRUE;
519 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
520 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
521 pnames[2] = temp;
522 // Check results area has not been cleared by client.
523 results[1] = 1;
524 EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
525 // Check buffer is what we expect
526 EXPECT_EQ(0, results[0]);
527 EXPECT_EQ(1, results[1]);
528 EXPECT_EQ(0, results[2]);
529 EXPECT_EQ(0, results[3]);
530 EXPECT_EQ(0, results[4]);
531 EXPECT_EQ(0, results[5]);
532 EXPECT_EQ(kSentinel, results[num_results]); // End of results
535 TEST_P(GLES2DecoderManualInitTest, BindGeneratesResourceFalse) {
536 InitState init;
537 init.gl_version = "3.0";
538 InitDecoder(init);
540 BindTexture cmd1;
541 cmd1.Init(GL_TEXTURE_2D, kInvalidClientId);
542 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
543 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
545 BindBuffer cmd2;
546 cmd2.Init(GL_ARRAY_BUFFER, kInvalidClientId);
547 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
548 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
550 BindFramebuffer cmd3;
551 cmd3.Init(GL_FRAMEBUFFER, kInvalidClientId);
552 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd3));
553 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
555 BindRenderbuffer cmd4;
556 cmd4.Init(GL_RENDERBUFFER, kInvalidClientId);
557 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd4));
558 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
561 TEST_P(GLES2DecoderTest, EnableFeatureCHROMIUMBadBucket) {
562 const uint32 kBadBucketId = 123;
563 EnableFeatureCHROMIUM cmd;
564 cmd.Init(kBadBucketId, shared_memory_id_, shared_memory_offset_);
565 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
568 TEST_P(GLES2DecoderTest, RequestExtensionCHROMIUMBadBucket) {
569 const uint32 kBadBucketId = 123;
570 RequestExtensionCHROMIUM cmd;
571 cmd.Init(kBadBucketId);
572 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
575 TEST_P(GLES2DecoderTest, BeginQueryEXTDisabled) {
576 // Test something fails if off.
579 TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXT) {
580 InitState init;
581 init.extensions = "GL_EXT_occlusion_query_boolean";
582 init.gl_version = "opengl es 2.0";
583 init.has_alpha = true;
584 init.request_alpha = true;
585 init.bind_generates_resource = true;
586 InitDecoder(init);
588 // Test end fails if no begin.
589 EndQueryEXT end_cmd;
590 end_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, 1);
591 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
592 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
594 BeginQueryEXT begin_cmd;
596 // Test id = 0 fails.
597 begin_cmd.Init(
598 GL_ANY_SAMPLES_PASSED_EXT, 0, kSharedMemoryId, kSharedMemoryOffset);
599 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
600 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
602 GenHelper<GenQueriesEXTImmediate>(kNewClientId);
604 // Test valid parameters work.
605 EXPECT_CALL(*gl_, GenQueriesARB(1, _))
606 .WillOnce(SetArgumentPointee<1>(kNewServiceId))
607 .RetiresOnSaturation();
608 EXPECT_CALL(*gl_, BeginQueryARB(GL_ANY_SAMPLES_PASSED_EXT, kNewServiceId))
609 .Times(1)
610 .RetiresOnSaturation();
612 // Query object should not be created untill BeginQueriesEXT.
613 QueryManager* query_manager = decoder_->GetQueryManager();
614 ASSERT_TRUE(query_manager != NULL);
615 QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
616 EXPECT_TRUE(query == NULL);
618 // BeginQueryEXT should fail if id is not generated from GenQueriesEXT.
619 begin_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT,
620 kInvalidClientId,
621 kSharedMemoryId,
622 kSharedMemoryOffset);
623 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
624 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
626 begin_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT,
627 kNewClientId,
628 kSharedMemoryId,
629 kSharedMemoryOffset);
630 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
631 EXPECT_EQ(GL_NO_ERROR, GetGLError());
633 // After BeginQueriesEXT id name should have query object associated with it.
634 query = query_manager->GetQuery(kNewClientId);
635 ASSERT_TRUE(query != NULL);
636 EXPECT_FALSE(query->pending());
638 // Test trying begin again fails
639 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
640 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
642 // Test end fails with different target
643 end_cmd.Init(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, 1);
644 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
645 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
647 // Test end succeeds
648 EXPECT_CALL(*gl_, EndQueryARB(GL_ANY_SAMPLES_PASSED_EXT))
649 .Times(1)
650 .RetiresOnSaturation();
651 end_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, 1);
652 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
653 EXPECT_EQ(GL_NO_ERROR, GetGLError());
654 EXPECT_TRUE(query->pending());
656 EXPECT_CALL(*gl_, DeleteQueriesARB(1, _)).Times(1).RetiresOnSaturation();
659 struct QueryType {
660 GLenum type;
661 bool is_gl;
664 const QueryType kQueryTypes[] = {
665 {GL_COMMANDS_ISSUED_CHROMIUM, false},
666 {GL_LATENCY_QUERY_CHROMIUM, false},
667 {GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM, false},
668 {GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, false},
669 {GL_GET_ERROR_QUERY_CHROMIUM, false},
670 {GL_COMMANDS_COMPLETED_CHROMIUM, false},
671 {GL_ANY_SAMPLES_PASSED_EXT, true},
674 static void CheckBeginEndQueryBadMemoryFails(GLES2DecoderTestBase* test,
675 GLuint client_id,
676 GLuint service_id,
677 const QueryType& query_type,
678 int32 shm_id,
679 uint32 shm_offset) {
680 // We need to reset the decoder on each iteration, because we lose the
681 // context every time.
682 GLES2DecoderTestBase::InitState init;
683 init.extensions = "GL_EXT_occlusion_query_boolean GL_ARB_sync";
684 init.gl_version = "opengl es 2.0";
685 init.has_alpha = true;
686 init.request_alpha = true;
687 init.bind_generates_resource = true;
688 test->InitDecoder(init);
689 ::testing::StrictMock< ::gfx::MockGLInterface>* gl = test->GetGLMock();
691 BeginQueryEXT begin_cmd;
693 test->GenHelper<GenQueriesEXTImmediate>(client_id);
695 if (query_type.is_gl) {
696 EXPECT_CALL(*gl, GenQueriesARB(1, _))
697 .WillOnce(SetArgumentPointee<1>(service_id))
698 .RetiresOnSaturation();
699 EXPECT_CALL(*gl, BeginQueryARB(query_type.type, service_id))
700 .Times(1)
701 .RetiresOnSaturation();
704 // Test bad shared memory fails
705 begin_cmd.Init(query_type.type, client_id, shm_id, shm_offset);
706 error::Error error1 = test->ExecuteCmd(begin_cmd);
708 if (query_type.is_gl) {
709 EXPECT_CALL(*gl, EndQueryARB(query_type.type))
710 .Times(1)
711 .RetiresOnSaturation();
713 if (query_type.type == GL_GET_ERROR_QUERY_CHROMIUM) {
714 EXPECT_CALL(*gl, GetError())
715 .WillOnce(Return(GL_NO_ERROR))
716 .RetiresOnSaturation();
718 GLsync kGlSync = reinterpret_cast<GLsync>(0xdeadbeef);
719 if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM) {
720 EXPECT_CALL(*gl, Flush()).RetiresOnSaturation();
721 EXPECT_CALL(*gl, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0))
722 .WillOnce(Return(kGlSync))
723 .RetiresOnSaturation();
724 #if DCHECK_IS_ON
725 EXPECT_CALL(*gl, IsSync(kGlSync))
726 .WillOnce(Return(GL_TRUE))
727 .RetiresOnSaturation();
728 #endif
731 EndQueryEXT end_cmd;
732 end_cmd.Init(query_type.type, 1);
733 error::Error error2 = test->ExecuteCmd(end_cmd);
735 if (query_type.is_gl) {
736 EXPECT_CALL(
737 *gl, GetQueryObjectuivARB(service_id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
738 .WillOnce(SetArgumentPointee<2>(1))
739 .RetiresOnSaturation();
740 EXPECT_CALL(*gl, GetQueryObjectuivARB(service_id, GL_QUERY_RESULT_EXT, _))
741 .WillOnce(SetArgumentPointee<2>(1))
742 .RetiresOnSaturation();
744 if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM) {
745 #if DCHECK_IS_ON
746 EXPECT_CALL(*gl, IsSync(kGlSync))
747 .WillOnce(Return(GL_TRUE))
748 .RetiresOnSaturation();
749 #endif
750 EXPECT_CALL(*gl, ClientWaitSync(kGlSync, _, _))
751 .WillOnce(Return(GL_ALREADY_SIGNALED))
752 .RetiresOnSaturation();
755 QueryManager* query_manager = test->GetDecoder()->GetQueryManager();
756 ASSERT_TRUE(query_manager != NULL);
757 bool process_success = query_manager->ProcessPendingQueries();
759 EXPECT_TRUE(error1 != error::kNoError || error2 != error::kNoError ||
760 !process_success);
762 if (query_type.is_gl) {
763 EXPECT_CALL(*gl, DeleteQueriesARB(1, _)).Times(1).RetiresOnSaturation();
765 if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM) {
766 #if DCHECK_IS_ON
767 EXPECT_CALL(*gl, IsSync(kGlSync))
768 .WillOnce(Return(GL_TRUE))
769 .RetiresOnSaturation();
770 #endif
771 EXPECT_CALL(*gl, DeleteSync(kGlSync)).Times(1).RetiresOnSaturation();
773 test->ResetDecoder();
776 TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTBadMemoryIdFails) {
777 for (size_t i = 0; i < arraysize(kQueryTypes); ++i) {
778 CheckBeginEndQueryBadMemoryFails(this,
779 kNewClientId,
780 kNewServiceId,
781 kQueryTypes[i],
782 kInvalidSharedMemoryId,
783 kSharedMemoryOffset);
787 TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTBadMemoryOffsetFails) {
788 for (size_t i = 0; i < arraysize(kQueryTypes); ++i) {
789 // Out-of-bounds.
790 CheckBeginEndQueryBadMemoryFails(this,
791 kNewClientId,
792 kNewServiceId,
793 kQueryTypes[i],
794 kSharedMemoryId,
795 kInvalidSharedMemoryOffset);
796 // Overflow.
797 CheckBeginEndQueryBadMemoryFails(this,
798 kNewClientId,
799 kNewServiceId,
800 kQueryTypes[i],
801 kSharedMemoryId,
802 0xfffffffcu);
806 TEST_P(GLES2DecoderTest, BeginEndQueryEXTCommandsIssuedCHROMIUM) {
807 BeginQueryEXT begin_cmd;
809 GenHelper<GenQueriesEXTImmediate>(kNewClientId);
811 // Test valid parameters work.
812 begin_cmd.Init(GL_COMMANDS_ISSUED_CHROMIUM,
813 kNewClientId,
814 kSharedMemoryId,
815 kSharedMemoryOffset);
816 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
817 EXPECT_EQ(GL_NO_ERROR, GetGLError());
819 QueryManager* query_manager = decoder_->GetQueryManager();
820 ASSERT_TRUE(query_manager != NULL);
821 QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
822 ASSERT_TRUE(query != NULL);
823 EXPECT_FALSE(query->pending());
825 // Test end succeeds
826 EndQueryEXT end_cmd;
827 end_cmd.Init(GL_COMMANDS_ISSUED_CHROMIUM, 1);
828 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
829 EXPECT_EQ(GL_NO_ERROR, GetGLError());
830 EXPECT_FALSE(query->pending());
833 TEST_P(GLES2DecoderTest, BeginEndQueryEXTGetErrorQueryCHROMIUM) {
834 BeginQueryEXT begin_cmd;
836 GenHelper<GenQueriesEXTImmediate>(kNewClientId);
838 // Test valid parameters work.
839 begin_cmd.Init(GL_GET_ERROR_QUERY_CHROMIUM,
840 kNewClientId,
841 kSharedMemoryId,
842 kSharedMemoryOffset);
843 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
844 EXPECT_EQ(GL_NO_ERROR, GetGLError());
846 QueryManager* query_manager = decoder_->GetQueryManager();
847 ASSERT_TRUE(query_manager != NULL);
848 QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
849 ASSERT_TRUE(query != NULL);
850 EXPECT_FALSE(query->pending());
852 // Test end succeeds
853 QuerySync* sync = static_cast<QuerySync*>(shared_memory_address_);
855 EXPECT_CALL(*gl_, GetError())
856 .WillOnce(Return(GL_INVALID_VALUE))
857 .RetiresOnSaturation();
859 EndQueryEXT end_cmd;
860 end_cmd.Init(GL_GET_ERROR_QUERY_CHROMIUM, 1);
861 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
862 EXPECT_EQ(GL_NO_ERROR, GetGLError());
863 EXPECT_FALSE(query->pending());
864 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE),
865 static_cast<GLenum>(sync->result));
868 TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTCommandsCompletedCHROMIUM) {
869 InitState init;
870 init.extensions = "GL_EXT_occlusion_query_boolean GL_ARB_sync";
871 init.gl_version = "opengl es 2.0";
872 init.has_alpha = true;
873 init.request_alpha = true;
874 init.bind_generates_resource = true;
875 InitDecoder(init);
877 GenHelper<GenQueriesEXTImmediate>(kNewClientId);
879 BeginQueryEXT begin_cmd;
880 begin_cmd.Init(GL_COMMANDS_COMPLETED_CHROMIUM,
881 kNewClientId,
882 kSharedMemoryId,
883 kSharedMemoryOffset);
884 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
885 EXPECT_EQ(GL_NO_ERROR, GetGLError());
887 QueryManager* query_manager = decoder_->GetQueryManager();
888 ASSERT_TRUE(query_manager != NULL);
889 QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
890 ASSERT_TRUE(query != NULL);
891 EXPECT_FALSE(query->pending());
893 GLsync kGlSync = reinterpret_cast<GLsync>(0xdeadbeef);
894 EXPECT_CALL(*gl_, Flush()).RetiresOnSaturation();
895 EXPECT_CALL(*gl_, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0))
896 .WillOnce(Return(kGlSync))
897 .RetiresOnSaturation();
898 #if DCHECK_IS_ON
899 EXPECT_CALL(*gl_, IsSync(kGlSync))
900 .WillOnce(Return(GL_TRUE))
901 .RetiresOnSaturation();
902 #endif
904 EndQueryEXT end_cmd;
905 end_cmd.Init(GL_COMMANDS_COMPLETED_CHROMIUM, 1);
906 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
907 EXPECT_EQ(GL_NO_ERROR, GetGLError());
908 EXPECT_TRUE(query->pending());
910 #if DCHECK_IS_ON
911 EXPECT_CALL(*gl_, IsSync(kGlSync))
912 .WillOnce(Return(GL_TRUE))
913 .RetiresOnSaturation();
914 #endif
915 EXPECT_CALL(*gl_, ClientWaitSync(kGlSync, _, _))
916 .WillOnce(Return(GL_TIMEOUT_EXPIRED))
917 .RetiresOnSaturation();
918 bool process_success = query_manager->ProcessPendingQueries();
920 EXPECT_TRUE(process_success);
921 EXPECT_TRUE(query->pending());
923 #if DCHECK_IS_ON
924 EXPECT_CALL(*gl_, IsSync(kGlSync))
925 .WillOnce(Return(GL_TRUE))
926 .RetiresOnSaturation();
927 #endif
928 EXPECT_CALL(*gl_, ClientWaitSync(kGlSync, _, _))
929 .WillOnce(Return(GL_ALREADY_SIGNALED))
930 .RetiresOnSaturation();
931 process_success = query_manager->ProcessPendingQueries();
933 EXPECT_TRUE(process_success);
934 EXPECT_FALSE(query->pending());
935 QuerySync* sync = static_cast<QuerySync*>(shared_memory_address_);
936 EXPECT_EQ(static_cast<GLenum>(0), static_cast<GLenum>(sync->result));
938 #if DCHECK_IS_ON
939 EXPECT_CALL(*gl_, IsSync(kGlSync))
940 .WillOnce(Return(GL_TRUE))
941 .RetiresOnSaturation();
942 #endif
943 EXPECT_CALL(*gl_, DeleteSync(kGlSync)).Times(1).RetiresOnSaturation();
944 ResetDecoder();
947 TEST_P(GLES2DecoderTest, IsEnabledReturnsCachedValue) {
948 // NOTE: There are no expectations because no GL functions should be
949 // called for DEPTH_TEST or STENCIL_TEST
950 static const GLenum kStates[] = {
951 GL_DEPTH_TEST, GL_STENCIL_TEST,
953 for (size_t ii = 0; ii < arraysize(kStates); ++ii) {
954 Enable enable_cmd;
955 GLenum state = kStates[ii];
956 enable_cmd.Init(state);
957 EXPECT_EQ(error::kNoError, ExecuteCmd(enable_cmd));
958 IsEnabled::Result* result =
959 static_cast<IsEnabled::Result*>(shared_memory_address_);
960 IsEnabled is_enabled_cmd;
961 is_enabled_cmd.Init(state, shared_memory_id_, shared_memory_offset_);
962 EXPECT_EQ(error::kNoError, ExecuteCmd(is_enabled_cmd));
963 EXPECT_NE(0u, *result);
964 Disable disable_cmd;
965 disable_cmd.Init(state);
966 EXPECT_EQ(error::kNoError, ExecuteCmd(disable_cmd));
967 EXPECT_EQ(error::kNoError, ExecuteCmd(is_enabled_cmd));
968 EXPECT_EQ(0u, *result);
972 TEST_P(GLES2DecoderManualInitTest, GpuMemoryManagerCHROMIUM) {
973 InitState init;
974 init.extensions = "GL_ARB_texture_rectangle";
975 init.gl_version = "3.0";
976 init.bind_generates_resource = true;
977 InitDecoder(init);
979 Texture* texture = GetTexture(client_texture_id_)->texture();
980 EXPECT_TRUE(texture != NULL);
981 EXPECT_TRUE(texture->pool() == GL_TEXTURE_POOL_UNMANAGED_CHROMIUM);
983 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
985 TexParameteri cmd;
986 cmd.Init(GL_TEXTURE_2D,
987 GL_TEXTURE_POOL_CHROMIUM,
988 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM);
989 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
990 EXPECT_EQ(GL_NO_ERROR, GetGLError());
992 cmd.Init(GL_TEXTURE_2D,
993 GL_TEXTURE_POOL_CHROMIUM,
994 GL_TEXTURE_POOL_MANAGED_CHROMIUM);
995 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
996 EXPECT_EQ(GL_NO_ERROR, GetGLError());
998 EXPECT_TRUE(texture->pool() == GL_TEXTURE_POOL_MANAGED_CHROMIUM);
1000 cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_POOL_CHROMIUM, GL_NONE);
1001 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1002 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
1005 namespace {
1007 class SizeOnlyMemoryTracker : public MemoryTracker {
1008 public:
1009 SizeOnlyMemoryTracker() {
1010 // These are the default textures. 1 for TEXTURE_2D and 6 faces for
1011 // TEXTURE_CUBE_MAP.
1012 const size_t kInitialUnmanagedPoolSize = 7 * 4;
1013 const size_t kInitialManagedPoolSize = 0;
1014 pool_infos_[MemoryTracker::kUnmanaged].initial_size =
1015 kInitialUnmanagedPoolSize;
1016 pool_infos_[MemoryTracker::kManaged].initial_size = kInitialManagedPoolSize;
1019 // Ensure a certain amount of GPU memory is free. Returns true on success.
1020 MOCK_METHOD1(EnsureGPUMemoryAvailable, bool(size_t size_needed));
1022 virtual void TrackMemoryAllocatedChange(size_t old_size,
1023 size_t new_size,
1024 Pool pool) {
1025 PoolInfo& info = pool_infos_[pool];
1026 info.size += new_size - old_size;
1029 size_t GetPoolSize(Pool pool) {
1030 const PoolInfo& info = pool_infos_[pool];
1031 return info.size - info.initial_size;
1034 private:
1035 virtual ~SizeOnlyMemoryTracker() {}
1036 struct PoolInfo {
1037 PoolInfo() : initial_size(0), size(0) {}
1038 size_t initial_size;
1039 size_t size;
1041 std::map<Pool, PoolInfo> pool_infos_;
1044 } // anonymous namespace.
1046 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerInitialSize) {
1047 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
1048 new SizeOnlyMemoryTracker();
1049 set_memory_tracker(memory_tracker.get());
1050 InitState init;
1051 init.gl_version = "3.0";
1052 init.bind_generates_resource = true;
1053 InitDecoder(init);
1054 // Expect that initial size - size is 0.
1055 EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1056 EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kManaged));
1059 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerTexImage2D) {
1060 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
1061 new SizeOnlyMemoryTracker();
1062 set_memory_tracker(memory_tracker.get());
1063 InitState init;
1064 init.gl_version = "3.0";
1065 init.bind_generates_resource = true;
1066 InitDecoder(init);
1067 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
1068 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1069 .WillOnce(Return(true))
1070 .RetiresOnSaturation();
1071 DoTexImage2D(GL_TEXTURE_2D,
1073 GL_RGBA,
1077 GL_RGBA,
1078 GL_UNSIGNED_BYTE,
1079 kSharedMemoryId,
1080 kSharedMemoryOffset);
1081 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1082 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(64))
1083 .WillOnce(Return(true))
1084 .RetiresOnSaturation();
1085 DoTexImage2D(GL_TEXTURE_2D,
1087 GL_RGBA,
1091 GL_RGBA,
1092 GL_UNSIGNED_BYTE,
1093 kSharedMemoryId,
1094 kSharedMemoryOffset);
1095 EXPECT_EQ(64u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1096 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1097 // Check we get out of memory and no call to glTexImage2D if Ensure fails.
1098 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(64))
1099 .WillOnce(Return(false))
1100 .RetiresOnSaturation();
1101 TexImage2D cmd;
1102 cmd.Init(GL_TEXTURE_2D,
1104 GL_RGBA,
1107 GL_RGBA,
1108 GL_UNSIGNED_BYTE,
1109 kSharedMemoryId,
1110 kSharedMemoryOffset);
1111 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1112 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
1113 EXPECT_EQ(64u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1116 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerTexStorage2DEXT) {
1117 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
1118 new SizeOnlyMemoryTracker();
1119 set_memory_tracker(memory_tracker.get());
1120 InitState init;
1121 init.gl_version = "3.0";
1122 init.bind_generates_resource = true;
1123 InitDecoder(init);
1124 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
1125 // Check we get out of memory and no call to glTexStorage2DEXT
1126 // if Ensure fails.
1127 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1128 .WillOnce(Return(false))
1129 .RetiresOnSaturation();
1130 TexStorage2DEXT cmd;
1131 cmd.Init(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 4);
1132 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1133 EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1134 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
1137 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerCopyTexImage2D) {
1138 GLenum target = GL_TEXTURE_2D;
1139 GLint level = 0;
1140 GLenum internal_format = GL_RGBA;
1141 GLsizei width = 4;
1142 GLsizei height = 8;
1143 GLint border = 0;
1144 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
1145 new SizeOnlyMemoryTracker();
1146 set_memory_tracker(memory_tracker.get());
1147 InitState init;
1148 init.gl_version = "3.0";
1149 init.has_alpha = true;
1150 init.request_alpha = true;
1151 init.bind_generates_resource = true;
1152 InitDecoder(init);
1153 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
1154 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1155 .WillOnce(Return(true))
1156 .RetiresOnSaturation();
1157 EXPECT_CALL(*gl_, GetError())
1158 .WillOnce(Return(GL_NO_ERROR))
1159 .WillOnce(Return(GL_NO_ERROR))
1160 .RetiresOnSaturation();
1161 EXPECT_CALL(*gl_,
1162 CopyTexImage2D(
1163 target, level, internal_format, 0, 0, width, height, border))
1164 .Times(1)
1165 .RetiresOnSaturation();
1166 CopyTexImage2D cmd;
1167 cmd.Init(target, level, internal_format, 0, 0, width, height);
1168 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1169 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1170 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1171 // Check we get out of memory and no call to glCopyTexImage2D if Ensure fails.
1172 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1173 .WillOnce(Return(false))
1174 .RetiresOnSaturation();
1175 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1176 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
1177 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1180 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerRenderbufferStorage) {
1181 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
1182 new SizeOnlyMemoryTracker();
1183 set_memory_tracker(memory_tracker.get());
1184 InitState init;
1185 init.gl_version = "3.0";
1186 init.bind_generates_resource = true;
1187 InitDecoder(init);
1188 DoBindRenderbuffer(
1189 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
1190 EnsureRenderbufferBound(false);
1191 EXPECT_CALL(*gl_, GetError())
1192 .WillOnce(Return(GL_NO_ERROR))
1193 .WillOnce(Return(GL_NO_ERROR))
1194 .RetiresOnSaturation();
1195 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1196 .WillOnce(Return(true))
1197 .RetiresOnSaturation();
1198 EXPECT_CALL(*gl_, RenderbufferStorageEXT(GL_RENDERBUFFER, GL_RGBA, 8, 4))
1199 .Times(1)
1200 .RetiresOnSaturation();
1201 RenderbufferStorage cmd;
1202 cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 8, 4);
1203 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1204 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1205 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1206 // Check we get out of memory and no call to glRenderbufferStorage if Ensure
1207 // fails.
1208 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1209 .WillOnce(Return(false))
1210 .RetiresOnSaturation();
1211 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1212 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
1213 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1216 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerBufferData) {
1217 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
1218 new SizeOnlyMemoryTracker();
1219 set_memory_tracker(memory_tracker.get());
1220 InitState init;
1221 init.gl_version = "3.0";
1222 init.bind_generates_resource = true;
1223 InitDecoder(init);
1224 DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
1225 EXPECT_CALL(*gl_, GetError())
1226 .WillOnce(Return(GL_NO_ERROR))
1227 .WillOnce(Return(GL_NO_ERROR))
1228 .RetiresOnSaturation();
1229 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1230 .WillOnce(Return(true))
1231 .RetiresOnSaturation();
1232 EXPECT_CALL(*gl_, BufferData(GL_ARRAY_BUFFER, 128, _, GL_STREAM_DRAW))
1233 .Times(1)
1234 .RetiresOnSaturation();
1235 BufferData cmd;
1236 cmd.Init(GL_ARRAY_BUFFER, 128, 0, 0, GL_STREAM_DRAW);
1237 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1238 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1239 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kManaged));
1240 // Check we get out of memory and no call to glBufferData if Ensure
1241 // fails.
1242 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1243 .WillOnce(Return(false))
1244 .RetiresOnSaturation();
1245 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1246 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
1247 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kManaged));
1250 TEST_P(GLES2DecoderManualInitTest, ImmutableCopyTexImage2D) {
1251 const GLenum kTarget = GL_TEXTURE_2D;
1252 const GLint kLevel = 0;
1253 const GLenum kInternalFormat = GL_RGBA;
1254 const GLenum kSizedInternalFormat = GL_RGBA8;
1255 const GLsizei kWidth = 4;
1256 const GLsizei kHeight = 8;
1257 const GLint kBorder = 0;
1258 InitState init;
1259 init.extensions = "GL_EXT_texture_storage";
1260 init.gl_version = "3.0";
1261 init.has_alpha = true;
1262 init.request_alpha = true;
1263 init.bind_generates_resource = true;
1264 InitDecoder(init);
1265 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
1267 // CopyTexImage2D will call arbitrary amount of GetErrors.
1268 EXPECT_CALL(*gl_, GetError())
1269 .Times(AtLeast(1));
1271 EXPECT_CALL(*gl_,
1272 CopyTexImage2D(
1273 kTarget, kLevel, kInternalFormat, 0, 0, kWidth, kHeight,
1274 kBorder))
1275 .Times(1);
1277 EXPECT_CALL(*gl_,
1278 TexStorage2DEXT(
1279 kTarget, kLevel, kSizedInternalFormat, kWidth, kHeight))
1280 .Times(1);
1281 CopyTexImage2D copy_cmd;
1282 copy_cmd.Init(kTarget, kLevel, kInternalFormat, 0, 0, kWidth, kHeight);
1283 EXPECT_EQ(error::kNoError, ExecuteCmd(copy_cmd));
1284 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1286 TexStorage2DEXT storage_cmd;
1287 storage_cmd.Init(kTarget, kLevel, kSizedInternalFormat, kWidth, kHeight);
1288 EXPECT_EQ(error::kNoError, ExecuteCmd(storage_cmd));
1289 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1291 // This should not invoke CopyTexImage2D.
1292 copy_cmd.Init(kTarget, kLevel, kInternalFormat, 0, 0, kWidth, kHeight);
1293 EXPECT_EQ(error::kNoError, ExecuteCmd(copy_cmd));
1294 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
1297 TEST_P(GLES2DecoderTest, LoseContextCHROMIUMValidArgs) {
1298 EXPECT_CALL(*mock_decoder_, LoseContext(GL_GUILTY_CONTEXT_RESET_ARB))
1299 .Times(1);
1300 cmds::LoseContextCHROMIUM cmd;
1301 cmd.Init(GL_GUILTY_CONTEXT_RESET_ARB, GL_GUILTY_CONTEXT_RESET_ARB);
1302 EXPECT_EQ(error::kLostContext, ExecuteCmd(cmd));
1303 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1306 TEST_P(GLES2DecoderTest, LoseContextCHROMIUMInvalidArgs0_0) {
1307 EXPECT_CALL(*mock_decoder_, LoseContext(_))
1308 .Times(0);
1309 cmds::LoseContextCHROMIUM cmd;
1310 cmd.Init(GL_NONE, GL_GUILTY_CONTEXT_RESET_ARB);
1311 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1312 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
1315 TEST_P(GLES2DecoderTest, LoseContextCHROMIUMInvalidArgs1_0) {
1316 EXPECT_CALL(*mock_decoder_, LoseContext(_))
1317 .Times(0);
1318 cmds::LoseContextCHROMIUM cmd;
1319 cmd.Init(GL_GUILTY_CONTEXT_RESET_ARB, GL_NONE);
1320 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1321 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
1324 class GLES2DecoderDoCommandsTest : public GLES2DecoderTest {
1325 public:
1326 GLES2DecoderDoCommandsTest() {
1327 for (int i = 0; i < 3; i++) {
1328 cmds_[i].Init(GL_BLEND);
1330 entries_per_cmd_ = ComputeNumEntries(cmds_[0].ComputeSize());
1333 void SetExpectationsForNCommands(int num_commands) {
1334 for (int i = 0; i < num_commands; i++)
1335 SetupExpectationsForEnableDisable(GL_BLEND, true);
1338 protected:
1339 Enable cmds_[3];
1340 int entries_per_cmd_;
1343 // Test that processing with 0 entries does nothing.
1344 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsOneOfZero) {
1345 int num_processed = -1;
1346 SetExpectationsForNCommands(0);
1347 EXPECT_EQ(
1348 error::kNoError,
1349 decoder_->DoCommands(1, &cmds_, entries_per_cmd_ * 0, &num_processed));
1350 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1351 EXPECT_EQ(0, num_processed);
1354 // Test processing at granularity of single commands.
1355 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsOneOfOne) {
1356 int num_processed = -1;
1357 SetExpectationsForNCommands(1);
1358 EXPECT_EQ(
1359 error::kNoError,
1360 decoder_->DoCommands(1, &cmds_, entries_per_cmd_ * 1, &num_processed));
1361 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1362 EXPECT_EQ(entries_per_cmd_, num_processed);
1365 // Test processing at granularity of multiple commands.
1366 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsThreeOfThree) {
1367 int num_processed = -1;
1368 SetExpectationsForNCommands(3);
1369 EXPECT_EQ(
1370 error::kNoError,
1371 decoder_->DoCommands(3, &cmds_, entries_per_cmd_ * 3, &num_processed));
1372 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1373 EXPECT_EQ(entries_per_cmd_ * 3, num_processed);
1376 // Test processing a request smaller than available entries.
1377 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsTwoOfThree) {
1378 int num_processed = -1;
1379 SetExpectationsForNCommands(2);
1380 EXPECT_EQ(
1381 error::kNoError,
1382 decoder_->DoCommands(2, &cmds_, entries_per_cmd_ * 3, &num_processed));
1383 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1384 EXPECT_EQ(entries_per_cmd_ * 2, num_processed);
1387 // Test that processing stops on a command with size 0.
1388 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsZeroCmdSize) {
1389 cmds_[1].header.size = 0;
1390 int num_processed = -1;
1391 SetExpectationsForNCommands(1);
1392 EXPECT_EQ(
1393 error::kInvalidSize,
1394 decoder_->DoCommands(2, &cmds_, entries_per_cmd_ * 2, &num_processed));
1395 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1396 EXPECT_EQ(entries_per_cmd_, num_processed);
1399 // Test that processing stops on a command with size greater than available.
1400 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsOutOfBounds) {
1401 int num_processed = -1;
1402 SetExpectationsForNCommands(1);
1403 EXPECT_EQ(error::kOutOfBounds,
1404 decoder_->DoCommands(
1405 2, &cmds_, entries_per_cmd_ * 2 - 1, &num_processed));
1406 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1407 EXPECT_EQ(entries_per_cmd_, num_processed);
1410 // Test that commands with bad argument size are skipped without processing.
1411 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsBadArgSize) {
1412 cmds_[1].header.size += 1;
1413 int num_processed = -1;
1414 SetExpectationsForNCommands(1);
1415 EXPECT_EQ(error::kInvalidArguments,
1416 decoder_->DoCommands(
1417 2, &cmds_, entries_per_cmd_ * 2 + 1, &num_processed));
1418 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1419 EXPECT_EQ(entries_per_cmd_ + cmds_[1].header.size, num_processed);
1422 INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderTest, ::testing::Bool());
1424 INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderWithShaderTest, ::testing::Bool());
1426 INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderManualInitTest, ::testing::Bool());
1428 INSTANTIATE_TEST_CASE_P(Service,
1429 GLES2DecoderRGBBackbufferTest,
1430 ::testing::Bool());
1432 INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderDoCommandsTest, ::testing::Bool());
1434 } // namespace gles2
1435 } // namespace gpu