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::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
;
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
));
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
,
80 SetupExpectationsForEnableDisable(cap
, enable
);
85 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
86 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
90 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
91 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
95 TEST_P(GLES2DecoderTest
, GetIntegervCached
) {
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);
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
) {
133 GetMaxValueInBufferCHROMIUM::Result
* result
=
134 static_cast<GetMaxValueInBufferCHROMIUM::Result
*>(shared_memory_address_
);
137 GetMaxValueInBufferCHROMIUM cmd
;
138 cmd
.Init(client_element_buffer_id_
,
139 kValidIndexRangeCount
,
141 kValidIndexRangeStart
* 2,
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,
150 kValidIndexRangeStart
* 2,
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
,
160 kValidIndexRangeStart
* 2,
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
,
168 kValidIndexRangeStart
* 2,
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,
176 kOutOfRangeIndexRangeEnd
* 2,
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,
184 kValidIndexRangeStart
* 2,
186 kSharedMemoryOffset
);
187 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
188 cmd
.Init(client_buffer_id_
,
189 kValidIndexRangeCount
+ 1,
191 kValidIndexRangeStart
* 2,
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,
199 kValidIndexRangeStart
* 2,
200 kInvalidSharedMemoryId
,
201 kSharedMemoryOffset
);
202 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
203 cmd
.Init(client_element_buffer_id_
,
204 kValidIndexRangeCount
+ 1,
206 kValidIndexRangeStart
* 2,
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
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
));
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
));
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
));
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
));
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.
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_
));
340 GL_FRAMEBUFFER
, client_framebuffer_id_
, kServiceFramebufferId
);
341 EXPECT_TRUE(DoIsFramebuffer(client_framebuffer_id_
));
342 DoDeleteFramebuffer(client_framebuffer_id_
,
343 kServiceFramebufferId
,
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
))
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_
));
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
;
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
,
411 kSharedMemoryOffset
+ sizeof(*pnames
) * kCount
,
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
,
452 kSharedMemoryOffset
+ kResultsOffset
,
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
,
461 kSharedMemoryOffset
+ kResultsOffset
,
463 EXPECT_EQ(error::kOutOfBounds
, ExecuteCmd(cmd
));
464 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
466 cmd
.Init(kSharedMemoryId
,
467 kSharedMemoryOffset
+ kPnameOffset
,
468 static_cast<GLuint
>(-1),
470 kSharedMemoryOffset
+ kResultsOffset
,
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
,
478 kInvalidSharedMemoryId
,
479 kSharedMemoryOffset
+ kResultsOffset
,
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
,
488 kInvalidSharedMemoryOffset
,
490 EXPECT_EQ(error::kOutOfBounds
, ExecuteCmd(cmd
));
491 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
493 cmd
.Init(kSharedMemoryId
,
494 kSharedMemoryOffset
+ kPnameOffset
,
497 kSharedMemoryOffset
+ kResultsOffset
,
499 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
500 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
502 cmd
.Init(kSharedMemoryId
,
503 kSharedMemoryOffset
+ kPnameOffset
,
506 kSharedMemoryOffset
+ kResultsOffset
,
508 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
509 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
511 cmd
.Init(kSharedMemoryId
,
512 kSharedMemoryOffset
+ kPnameOffset
,
515 kSharedMemoryOffset
+ kResultsOffset
,
517 GLenum temp
= pnames
[2];
519 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
520 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
522 // Check results area has not been cleared by client.
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
) {
537 init
.gl_version
= "3.0";
541 cmd1
.Init(GL_TEXTURE_2D
, kInvalidClientId
);
542 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd1
));
543 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
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
) {
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;
588 // Test end fails if no begin.
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.
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
))
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
,
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
,
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());
648 EXPECT_CALL(*gl_
, EndQueryARB(GL_ANY_SAMPLES_PASSED_EXT
))
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();
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
,
677 const QueryType
& query_type
,
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
))
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
))
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();
725 EXPECT_CALL(*gl
, IsSync(kGlSync
))
726 .WillOnce(Return(GL_TRUE
))
727 .RetiresOnSaturation();
732 end_cmd
.Init(query_type
.type
, 1);
733 error::Error error2
= test
->ExecuteCmd(end_cmd
);
735 if (query_type
.is_gl
) {
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
) {
746 EXPECT_CALL(*gl
, IsSync(kGlSync
))
747 .WillOnce(Return(GL_TRUE
))
748 .RetiresOnSaturation();
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
||
762 if (query_type
.is_gl
) {
763 EXPECT_CALL(*gl
, DeleteQueriesARB(1, _
)).Times(1).RetiresOnSaturation();
765 if (query_type
.type
== GL_COMMANDS_COMPLETED_CHROMIUM
) {
767 EXPECT_CALL(*gl
, IsSync(kGlSync
))
768 .WillOnce(Return(GL_TRUE
))
769 .RetiresOnSaturation();
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,
782 kInvalidSharedMemoryId
,
783 kSharedMemoryOffset
);
787 TEST_P(GLES2DecoderManualInitTest
, BeginEndQueryEXTBadMemoryOffsetFails
) {
788 for (size_t i
= 0; i
< arraysize(kQueryTypes
); ++i
) {
790 CheckBeginEndQueryBadMemoryFails(this,
795 kInvalidSharedMemoryOffset
);
797 CheckBeginEndQueryBadMemoryFails(this,
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
,
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());
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
,
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());
853 QuerySync
* sync
= static_cast<QuerySync
*>(shared_memory_address_
);
855 EXPECT_CALL(*gl_
, GetError())
856 .WillOnce(Return(GL_INVALID_VALUE
))
857 .RetiresOnSaturation();
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
) {
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;
877 GenHelper
<GenQueriesEXTImmediate
>(kNewClientId
);
879 BeginQueryEXT begin_cmd
;
880 begin_cmd
.Init(GL_COMMANDS_COMPLETED_CHROMIUM
,
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();
899 EXPECT_CALL(*gl_
, IsSync(kGlSync
))
900 .WillOnce(Return(GL_TRUE
))
901 .RetiresOnSaturation();
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());
911 EXPECT_CALL(*gl_
, IsSync(kGlSync
))
912 .WillOnce(Return(GL_TRUE
))
913 .RetiresOnSaturation();
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());
924 EXPECT_CALL(*gl_
, IsSync(kGlSync
))
925 .WillOnce(Return(GL_TRUE
))
926 .RetiresOnSaturation();
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
));
939 EXPECT_CALL(*gl_
, IsSync(kGlSync
))
940 .WillOnce(Return(GL_TRUE
))
941 .RetiresOnSaturation();
943 EXPECT_CALL(*gl_
, DeleteSync(kGlSync
)).Times(1).RetiresOnSaturation();
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
) {
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
);
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
) {
974 init
.extensions
= "GL_ARB_texture_rectangle";
975 init
.gl_version
= "3.0";
976 init
.bind_generates_resource
= true;
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
);
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());
1007 class SizeOnlyMemoryTracker
: public MemoryTracker
{
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
,
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
;
1035 virtual ~SizeOnlyMemoryTracker() {}
1037 PoolInfo() : initial_size(0), size(0) {}
1038 size_t initial_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());
1051 init
.gl_version
= "3.0";
1052 init
.bind_generates_resource
= true;
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());
1064 init
.gl_version
= "3.0";
1065 init
.bind_generates_resource
= true;
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
,
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
,
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();
1102 cmd
.Init(GL_TEXTURE_2D
,
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());
1121 init
.gl_version
= "3.0";
1122 init
.bind_generates_resource
= true;
1124 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
1125 // Check we get out of memory and no call to glTexStorage2DEXT
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
;
1140 GLenum internal_format
= GL_RGBA
;
1144 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
1145 new SizeOnlyMemoryTracker();
1146 set_memory_tracker(memory_tracker
.get());
1148 init
.gl_version
= "3.0";
1149 init
.has_alpha
= true;
1150 init
.request_alpha
= true;
1151 init
.bind_generates_resource
= true;
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();
1163 target
, level
, internal_format
, 0, 0, width
, height
, border
))
1165 .RetiresOnSaturation();
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());
1185 init
.gl_version
= "3.0";
1186 init
.bind_generates_resource
= true;
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))
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
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());
1221 init
.gl_version
= "3.0";
1222 init
.bind_generates_resource
= true;
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
))
1234 .RetiresOnSaturation();
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
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;
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;
1265 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
1267 // CopyTexImage2D will call arbitrary amount of GetErrors.
1268 EXPECT_CALL(*gl_
, GetError())
1273 kTarget
, kLevel
, kInternalFormat
, 0, 0, kWidth
, kHeight
,
1279 kTarget
, kLevel
, kSizedInternalFormat
, kWidth
, kHeight
))
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
))
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(_
))
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(_
))
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
{
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);
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);
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);
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);
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);
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);
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
,
1432 INSTANTIATE_TEST_CASE_P(Service
, GLES2DecoderDoCommandsTest
, ::testing::Bool());
1434 } // namespace gles2