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/test_helper.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_tokenizer.h"
12 #include "gpu/command_buffer/service/buffer_manager.h"
13 #include "gpu/command_buffer/service/error_state_mock.h"
14 #include "gpu/command_buffer/service/gl_utils.h"
15 #include "gpu/command_buffer/service/gpu_switches.h"
16 #include "gpu/command_buffer/service/mocks.h"
17 #include "gpu/command_buffer/service/program_manager.h"
18 #include "gpu/command_buffer/service/texture_manager.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "ui/gl/gl_mock.h"
21 #include "ui/gl/gl_version_info.h"
24 using ::testing::DoAll
;
25 using ::testing::InSequence
;
26 using ::testing::MatcherCast
;
27 using ::testing::Pointee
;
28 using ::testing::NotNull
;
29 using ::testing::Return
;
30 using ::testing::SetArrayArgument
;
31 using ::testing::SetArgumentPointee
;
32 using ::testing::StrEq
;
33 using ::testing::StrictMock
;
41 T
ConstructShaderVariable(
42 GLenum type
, GLint array_size
, GLenum precision
,
43 bool static_use
, const std::string
& name
) {
46 var
.arraySize
= array_size
;
47 var
.precision
= precision
;
48 var
.staticUse
= static_use
;
50 var
.mappedName
= name
; // No name hashing.
54 } // namespace anonymous
56 // GCC requires these declarations, but MSVC requires they not be present
58 const GLuint
TestHelper::kServiceBlackTexture2dId
;
59 const GLuint
TestHelper::kServiceDefaultTexture2dId
;
60 const GLuint
TestHelper::kServiceBlackTextureCubemapId
;
61 const GLuint
TestHelper::kServiceDefaultTextureCubemapId
;
62 const GLuint
TestHelper::kServiceBlackExternalTextureId
;
63 const GLuint
TestHelper::kServiceDefaultExternalTextureId
;
64 const GLuint
TestHelper::kServiceBlackRectangleTextureId
;
65 const GLuint
TestHelper::kServiceDefaultRectangleTextureId
;
67 const GLint
TestHelper::kMaxSamples
;
68 const GLint
TestHelper::kMaxRenderbufferSize
;
69 const GLint
TestHelper::kMaxTextureSize
;
70 const GLint
TestHelper::kMaxCubeMapTextureSize
;
71 const GLint
TestHelper::kMaxRectangleTextureSize
;
72 const GLint
TestHelper::kMax3DTextureSize
;
73 const GLint
TestHelper::kNumVertexAttribs
;
74 const GLint
TestHelper::kNumTextureUnits
;
75 const GLint
TestHelper::kMaxTextureImageUnits
;
76 const GLint
TestHelper::kMaxVertexTextureImageUnits
;
77 const GLint
TestHelper::kMaxFragmentUniformVectors
;
78 const GLint
TestHelper::kMaxFragmentUniformComponents
;
79 const GLint
TestHelper::kMaxVaryingVectors
;
80 const GLint
TestHelper::kMaxVaryingFloats
;
81 const GLint
TestHelper::kMaxVertexUniformVectors
;
82 const GLint
TestHelper::kMaxVertexUniformComponents
;
85 std::vector
<std::string
> TestHelper::split_extensions_
;
87 void TestHelper::SetupTextureInitializationExpectations(
88 ::gfx::MockGLInterface
* gl
,
90 bool use_default_textures
) {
93 bool needs_initialization
= (target
!= GL_TEXTURE_EXTERNAL_OES
);
94 bool needs_faces
= (target
== GL_TEXTURE_CUBE_MAP
);
96 static GLuint texture_2d_ids
[] = {
97 kServiceBlackTexture2dId
,
98 kServiceDefaultTexture2dId
};
99 static GLuint texture_cube_map_ids
[] = {
100 kServiceBlackTextureCubemapId
,
101 kServiceDefaultTextureCubemapId
};
102 static GLuint texture_external_oes_ids
[] = {
103 kServiceBlackExternalTextureId
,
104 kServiceDefaultExternalTextureId
};
105 static GLuint texture_rectangle_arb_ids
[] = {
106 kServiceBlackRectangleTextureId
,
107 kServiceDefaultRectangleTextureId
};
109 const GLuint
* texture_ids
= NULL
;
112 texture_ids
= &texture_2d_ids
[0];
114 case GL_TEXTURE_CUBE_MAP
:
115 texture_ids
= &texture_cube_map_ids
[0];
117 case GL_TEXTURE_EXTERNAL_OES
:
118 texture_ids
= &texture_external_oes_ids
[0];
120 case GL_TEXTURE_RECTANGLE_ARB
:
121 texture_ids
= &texture_rectangle_arb_ids
[0];
127 int array_size
= use_default_textures
? 2 : 1;
129 EXPECT_CALL(*gl
, GenTextures(array_size
, _
))
130 .WillOnce(SetArrayArgument
<1>(texture_ids
,
131 texture_ids
+ array_size
))
132 .RetiresOnSaturation();
133 for (int ii
= 0; ii
< array_size
; ++ii
) {
134 EXPECT_CALL(*gl
, BindTexture(target
, texture_ids
[ii
]))
136 .RetiresOnSaturation();
137 if (needs_initialization
) {
139 static GLenum faces
[] = {
140 GL_TEXTURE_CUBE_MAP_POSITIVE_X
,
141 GL_TEXTURE_CUBE_MAP_NEGATIVE_X
,
142 GL_TEXTURE_CUBE_MAP_POSITIVE_Y
,
143 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
,
144 GL_TEXTURE_CUBE_MAP_POSITIVE_Z
,
145 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
,
147 for (size_t ii
= 0; ii
< arraysize(faces
); ++ii
) {
148 EXPECT_CALL(*gl
, TexImage2D(faces
[ii
], 0, GL_RGBA
, 1, 1, 0, GL_RGBA
,
149 GL_UNSIGNED_BYTE
, _
))
151 .RetiresOnSaturation();
154 EXPECT_CALL(*gl
, TexImage2D(target
, 0, GL_RGBA
, 1, 1, 0, GL_RGBA
,
155 GL_UNSIGNED_BYTE
, _
))
157 .RetiresOnSaturation();
161 EXPECT_CALL(*gl
, BindTexture(target
, 0))
163 .RetiresOnSaturation();
166 void TestHelper::SetupTextureManagerInitExpectations(
167 ::gfx::MockGLInterface
* gl
,
168 const char* extensions
,
169 bool use_default_textures
) {
172 SetupTextureInitializationExpectations(
173 gl
, GL_TEXTURE_2D
, use_default_textures
);
174 SetupTextureInitializationExpectations(
175 gl
, GL_TEXTURE_CUBE_MAP
, use_default_textures
);
177 bool ext_image_external
= false;
178 bool arb_texture_rectangle
= false;
179 base::CStringTokenizer
t(extensions
, extensions
+ strlen(extensions
), " ");
180 while (t
.GetNext()) {
181 if (t
.token() == "GL_OES_EGL_image_external") {
182 ext_image_external
= true;
185 if (t
.token() == "GL_ARB_texture_rectangle") {
186 arb_texture_rectangle
= true;
191 if (ext_image_external
) {
192 SetupTextureInitializationExpectations(
193 gl
, GL_TEXTURE_EXTERNAL_OES
, use_default_textures
);
195 if (arb_texture_rectangle
) {
196 SetupTextureInitializationExpectations(
197 gl
, GL_TEXTURE_RECTANGLE_ARB
, use_default_textures
);
201 void TestHelper::SetupTextureDestructionExpectations(
202 ::gfx::MockGLInterface
* gl
,
204 bool use_default_textures
) {
205 if (!use_default_textures
)
208 GLuint texture_id
= 0;
211 texture_id
= kServiceDefaultTexture2dId
;
213 case GL_TEXTURE_CUBE_MAP
:
214 texture_id
= kServiceDefaultTextureCubemapId
;
216 case GL_TEXTURE_EXTERNAL_OES
:
217 texture_id
= kServiceDefaultExternalTextureId
;
219 case GL_TEXTURE_RECTANGLE_ARB
:
220 texture_id
= kServiceDefaultRectangleTextureId
;
226 EXPECT_CALL(*gl
, DeleteTextures(1, Pointee(texture_id
)))
228 .RetiresOnSaturation();
231 void TestHelper::SetupTextureManagerDestructionExpectations(
232 ::gfx::MockGLInterface
* gl
,
233 const char* extensions
,
234 bool use_default_textures
) {
235 SetupTextureDestructionExpectations(gl
, GL_TEXTURE_2D
, use_default_textures
);
236 SetupTextureDestructionExpectations(
237 gl
, GL_TEXTURE_CUBE_MAP
, use_default_textures
);
239 bool ext_image_external
= false;
240 bool arb_texture_rectangle
= false;
241 base::CStringTokenizer
t(extensions
, extensions
+ strlen(extensions
), " ");
242 while (t
.GetNext()) {
243 if (t
.token() == "GL_OES_EGL_image_external") {
244 ext_image_external
= true;
247 if (t
.token() == "GL_ARB_texture_rectangle") {
248 arb_texture_rectangle
= true;
253 if (ext_image_external
) {
254 SetupTextureDestructionExpectations(
255 gl
, GL_TEXTURE_EXTERNAL_OES
, use_default_textures
);
257 if (arb_texture_rectangle
) {
258 SetupTextureDestructionExpectations(
259 gl
, GL_TEXTURE_RECTANGLE_ARB
, use_default_textures
);
262 EXPECT_CALL(*gl
, DeleteTextures(4, _
))
264 .RetiresOnSaturation();
267 void TestHelper::SetupContextGroupInitExpectations(
268 ::gfx::MockGLInterface
* gl
,
269 const DisallowedFeatures
& disallowed_features
,
270 const char* extensions
,
271 const char* gl_version
,
272 bool bind_generates_resource
) {
275 SetupFeatureInfoInitExpectationsWithGLVersion(gl
, extensions
, "", gl_version
);
277 gfx::GLVersionInfo
gl_info(gl_version
, "", extensions
);
279 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_RENDERBUFFER_SIZE
, _
))
280 .WillOnce(SetArgumentPointee
<1>(kMaxRenderbufferSize
))
281 .RetiresOnSaturation();
282 if (strstr(extensions
, "GL_EXT_framebuffer_multisample") ||
283 strstr(extensions
, "GL_EXT_multisampled_render_to_texture") ||
285 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_SAMPLES
, _
))
286 .WillOnce(SetArgumentPointee
<1>(kMaxSamples
))
287 .RetiresOnSaturation();
288 } else if (strstr(extensions
, "GL_IMG_multisampled_render_to_texture")) {
289 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_SAMPLES_IMG
, _
))
290 .WillOnce(SetArgumentPointee
<1>(kMaxSamples
))
291 .RetiresOnSaturation();
293 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_VERTEX_ATTRIBS
, _
))
294 .WillOnce(SetArgumentPointee
<1>(kNumVertexAttribs
))
295 .RetiresOnSaturation();
296 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
, _
))
297 .WillOnce(SetArgumentPointee
<1>(kNumTextureUnits
))
298 .RetiresOnSaturation();
299 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_TEXTURE_SIZE
, _
))
300 .WillOnce(SetArgumentPointee
<1>(kMaxTextureSize
))
301 .RetiresOnSaturation();
302 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE
, _
))
303 .WillOnce(SetArgumentPointee
<1>(kMaxCubeMapTextureSize
))
304 .RetiresOnSaturation();
305 if (gl_info
.IsES3Capable()) {
306 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_3D_TEXTURE_SIZE
, _
))
307 .WillOnce(SetArgumentPointee
<1>(kMax3DTextureSize
))
308 .RetiresOnSaturation();
310 if (strstr(extensions
, "GL_ARB_texture_rectangle")) {
311 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE
, _
))
312 .WillOnce(SetArgumentPointee
<1>(kMaxRectangleTextureSize
))
313 .RetiresOnSaturation();
315 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS
, _
))
316 .WillOnce(SetArgumentPointee
<1>(kMaxTextureImageUnits
))
317 .RetiresOnSaturation();
318 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS
, _
))
319 .WillOnce(SetArgumentPointee
<1>(kMaxVertexTextureImageUnits
))
320 .RetiresOnSaturation();
323 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS
, _
))
324 .WillOnce(SetArgumentPointee
<1>(kMaxFragmentUniformVectors
))
325 .RetiresOnSaturation();
326 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_VARYING_VECTORS
, _
))
327 .WillOnce(SetArgumentPointee
<1>(kMaxVaryingVectors
))
328 .RetiresOnSaturation();
329 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS
, _
))
330 .WillOnce(SetArgumentPointee
<1>(kMaxVertexUniformVectors
))
331 .RetiresOnSaturation();
333 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS
, _
))
334 .WillOnce(SetArgumentPointee
<1>(kMaxFragmentUniformComponents
))
335 .RetiresOnSaturation();
336 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_VARYING_FLOATS
, _
))
337 .WillOnce(SetArgumentPointee
<1>(kMaxVaryingFloats
))
338 .RetiresOnSaturation();
339 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS
, _
))
340 .WillOnce(SetArgumentPointee
<1>(kMaxVertexUniformComponents
))
341 .RetiresOnSaturation();
344 bool use_default_textures
= bind_generates_resource
;
345 SetupTextureManagerInitExpectations(gl
, extensions
, use_default_textures
);
348 void TestHelper::SetupFeatureInfoInitExpectations(
349 ::gfx::MockGLInterface
* gl
, const char* extensions
) {
350 SetupFeatureInfoInitExpectationsWithGLVersion(gl
, extensions
, "", "");
353 void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(
354 ::gfx::MockGLInterface
* gl
,
355 const char* extensions
,
356 const char* gl_renderer
,
357 const char* gl_version
) {
360 EXPECT_CALL(*gl
, GetString(GL_VERSION
))
361 .WillOnce(Return(reinterpret_cast<const uint8
*>(gl_version
)))
362 .RetiresOnSaturation();
364 // Persistent storage is needed for the split extension string.
365 split_extensions_
.clear();
367 Tokenize(extensions
, " ", &split_extensions_
);
370 gfx::GLVersionInfo
gl_info(gl_version
, gl_renderer
, extensions
);
371 if (!gl_info
.is_es
&& gl_info
.major_version
>= 3) {
372 EXPECT_CALL(*gl
, GetIntegerv(GL_NUM_EXTENSIONS
, _
))
373 .WillOnce(SetArgumentPointee
<1>(split_extensions_
.size()))
374 .RetiresOnSaturation();
375 for (size_t ii
= 0; ii
< split_extensions_
.size(); ++ii
) {
376 EXPECT_CALL(*gl
, GetStringi(GL_EXTENSIONS
, ii
))
377 .WillOnce(Return(reinterpret_cast<const uint8
*>(
378 split_extensions_
[ii
].c_str())))
379 .RetiresOnSaturation();
382 EXPECT_CALL(*gl
, GetString(GL_EXTENSIONS
))
383 .WillOnce(Return(reinterpret_cast<const uint8
*>(extensions
)))
384 .RetiresOnSaturation();
387 EXPECT_CALL(*gl
, GetString(GL_RENDERER
))
388 .WillOnce(Return(reinterpret_cast<const uint8
*>(gl_renderer
)))
389 .RetiresOnSaturation();
391 if (strstr(extensions
, "GL_ARB_texture_float") ||
392 (gl_info
.is_es3
&& strstr(extensions
, "GL_EXT_color_buffer_float"))) {
393 static const GLuint tx_ids
[] = {101, 102};
394 static const GLuint fb_ids
[] = {103, 104};
395 const GLsizei width
= 16;
396 EXPECT_CALL(*gl
, GetIntegerv(GL_FRAMEBUFFER_BINDING
, _
))
397 .WillOnce(SetArgumentPointee
<1>(fb_ids
[0]))
398 .RetiresOnSaturation();
399 EXPECT_CALL(*gl
, GetIntegerv(GL_TEXTURE_BINDING_2D
, _
))
400 .WillOnce(SetArgumentPointee
<1>(tx_ids
[0]))
401 .RetiresOnSaturation();
402 EXPECT_CALL(*gl
, GenTextures(1, _
))
403 .WillOnce(SetArrayArgument
<1>(tx_ids
+ 1, tx_ids
+ 2))
404 .RetiresOnSaturation();
405 EXPECT_CALL(*gl
, GenFramebuffersEXT(1, _
))
406 .WillOnce(SetArrayArgument
<1>(fb_ids
+ 1, fb_ids
+ 2))
407 .RetiresOnSaturation();
408 EXPECT_CALL(*gl
, BindTexture(GL_TEXTURE_2D
, tx_ids
[1]))
410 .RetiresOnSaturation();
411 EXPECT_CALL(*gl
, TexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
,
414 .RetiresOnSaturation();
415 EXPECT_CALL(*gl
, TexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA32F
, width
, width
, 0,
416 GL_RGBA
, GL_FLOAT
, _
))
418 .RetiresOnSaturation();
419 EXPECT_CALL(*gl
, BindFramebufferEXT(GL_FRAMEBUFFER
, fb_ids
[1]))
421 .RetiresOnSaturation();
422 EXPECT_CALL(*gl
, FramebufferTexture2DEXT(GL_FRAMEBUFFER
,
423 GL_COLOR_ATTACHMENT0
, GL_TEXTURE_2D
, tx_ids
[1], 0))
425 .RetiresOnSaturation();
426 EXPECT_CALL(*gl
, CheckFramebufferStatusEXT(GL_FRAMEBUFFER
))
427 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE
))
428 .RetiresOnSaturation();
429 EXPECT_CALL(*gl
, TexImage2D(GL_TEXTURE_2D
, 0, GL_RGB32F
, width
, width
, 0,
430 GL_RGB
, GL_FLOAT
, _
))
432 .RetiresOnSaturation();
433 if (gl_info
.is_es3
) {
434 EXPECT_CALL(*gl
, CheckFramebufferStatusEXT(GL_FRAMEBUFFER
))
435 .WillOnce(Return(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
))
436 .RetiresOnSaturation();
438 EXPECT_CALL(*gl
, CheckFramebufferStatusEXT(GL_FRAMEBUFFER
))
439 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE
))
440 .RetiresOnSaturation();
442 EXPECT_CALL(*gl
, DeleteFramebuffersEXT(1, _
))
444 .RetiresOnSaturation();
445 EXPECT_CALL(*gl
, DeleteTextures(1, _
))
447 .RetiresOnSaturation();
448 EXPECT_CALL(*gl
, BindFramebufferEXT(GL_FRAMEBUFFER
, fb_ids
[0]))
450 .RetiresOnSaturation();
451 EXPECT_CALL(*gl
, BindTexture(GL_TEXTURE_2D
, tx_ids
[0]))
453 .RetiresOnSaturation();
455 EXPECT_CALL(*gl
, GetError())
456 .WillOnce(Return(GL_NO_ERROR
))
457 .RetiresOnSaturation();
461 if (strstr(extensions
, "GL_EXT_draw_buffers") ||
462 strstr(extensions
, "GL_ARB_draw_buffers") ||
463 (gl_info
.is_es3
&& strstr(extensions
, "GL_NV_draw_buffers"))) {
464 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT
, _
))
465 .WillOnce(SetArgumentPointee
<1>(8))
466 .RetiresOnSaturation();
467 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_DRAW_BUFFERS_ARB
, _
))
468 .WillOnce(SetArgumentPointee
<1>(8))
469 .RetiresOnSaturation();
472 if (gl_info
.is_es3
|| strstr(extensions
, "GL_EXT_texture_rg") ||
473 (strstr(extensions
, "GL_ARB_texture_rg"))) {
474 static const GLuint tx_ids
[] = {101, 102};
475 static const GLuint fb_ids
[] = {103, 104};
476 const GLsizei width
= 1;
477 EXPECT_CALL(*gl
, GetIntegerv(GL_FRAMEBUFFER_BINDING
, _
))
478 .WillOnce(SetArgumentPointee
<1>(fb_ids
[0]))
479 .RetiresOnSaturation();
480 EXPECT_CALL(*gl
, GetIntegerv(GL_TEXTURE_BINDING_2D
, _
))
481 .WillOnce(SetArgumentPointee
<1>(tx_ids
[0]))
482 .RetiresOnSaturation();
483 EXPECT_CALL(*gl
, GenTextures(1, _
))
484 .WillOnce(SetArrayArgument
<1>(tx_ids
+ 1, tx_ids
+ 2))
485 .RetiresOnSaturation();
486 EXPECT_CALL(*gl
, BindTexture(GL_TEXTURE_2D
, tx_ids
[1]))
488 .RetiresOnSaturation();
489 EXPECT_CALL(*gl
, TexImage2D(GL_TEXTURE_2D
, 0, _
, width
, width
, 0,
490 GL_RED_EXT
, GL_UNSIGNED_BYTE
, _
))
492 .RetiresOnSaturation();
493 EXPECT_CALL(*gl
, GenFramebuffersEXT(1, _
))
494 .WillOnce(SetArrayArgument
<1>(fb_ids
+ 1, fb_ids
+ 2))
495 .RetiresOnSaturation();
496 EXPECT_CALL(*gl
, BindFramebufferEXT(GL_FRAMEBUFFER
, fb_ids
[1]))
498 .RetiresOnSaturation();
499 EXPECT_CALL(*gl
, FramebufferTexture2DEXT(GL_FRAMEBUFFER
,
500 GL_COLOR_ATTACHMENT0
, GL_TEXTURE_2D
, tx_ids
[1], 0))
502 .RetiresOnSaturation();
503 EXPECT_CALL(*gl
, CheckFramebufferStatusEXT(GL_FRAMEBUFFER
))
504 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE
))
505 .RetiresOnSaturation();
506 EXPECT_CALL(*gl
, DeleteFramebuffersEXT(1, _
))
508 .RetiresOnSaturation();
509 EXPECT_CALL(*gl
, DeleteTextures(1, _
))
511 .RetiresOnSaturation();
512 EXPECT_CALL(*gl
, BindFramebufferEXT(GL_FRAMEBUFFER
, fb_ids
[0]))
514 .RetiresOnSaturation();
515 EXPECT_CALL(*gl
, BindTexture(GL_TEXTURE_2D
, tx_ids
[0]))
517 .RetiresOnSaturation();
519 EXPECT_CALL(*gl
, GetError())
520 .WillOnce(Return(GL_NO_ERROR
))
521 .RetiresOnSaturation();
526 void TestHelper::SetupExpectationsForClearingUniforms(
527 ::gfx::MockGLInterface
* gl
, UniformInfo
* uniforms
, size_t num_uniforms
) {
528 for (size_t ii
= 0; ii
< num_uniforms
; ++ii
) {
529 const UniformInfo
& info
= uniforms
[ii
];
532 EXPECT_CALL(*gl
, Uniform1fv(info
.real_location
, info
.size
, _
))
534 .RetiresOnSaturation();
537 EXPECT_CALL(*gl
, Uniform2fv(info
.real_location
, info
.size
, _
))
539 .RetiresOnSaturation();
542 EXPECT_CALL(*gl
, Uniform3fv(info
.real_location
, info
.size
, _
))
544 .RetiresOnSaturation();
547 EXPECT_CALL(*gl
, Uniform4fv(info
.real_location
, info
.size
, _
))
549 .RetiresOnSaturation();
554 case GL_SAMPLER_CUBE
:
555 case GL_SAMPLER_EXTERNAL_OES
:
556 case GL_SAMPLER_3D_OES
:
557 case GL_SAMPLER_2D_RECT_ARB
:
558 EXPECT_CALL(*gl
, Uniform1iv(info
.real_location
, info
.size
, _
))
560 .RetiresOnSaturation();
564 EXPECT_CALL(*gl
, Uniform2iv(info
.real_location
, info
.size
, _
))
566 .RetiresOnSaturation();
570 EXPECT_CALL(*gl
, Uniform3iv(info
.real_location
, info
.size
, _
))
572 .RetiresOnSaturation();
576 EXPECT_CALL(*gl
, Uniform4iv(info
.real_location
, info
.size
, _
))
578 .RetiresOnSaturation();
581 EXPECT_CALL(*gl
, UniformMatrix2fv(
582 info
.real_location
, info
.size
, false, _
))
584 .RetiresOnSaturation();
587 EXPECT_CALL(*gl
, UniformMatrix3fv(
588 info
.real_location
, info
.size
, false, _
))
590 .RetiresOnSaturation();
593 EXPECT_CALL(*gl
, UniformMatrix4fv(
594 info
.real_location
, info
.size
, false, _
))
596 .RetiresOnSaturation();
605 void TestHelper::SetupProgramSuccessExpectations(
606 ::gfx::MockGLInterface
* gl
,
607 AttribInfo
* attribs
, size_t num_attribs
,
608 UniformInfo
* uniforms
, size_t num_uniforms
,
611 GetProgramiv(service_id
, GL_LINK_STATUS
, _
))
612 .WillOnce(SetArgumentPointee
<2>(1))
613 .RetiresOnSaturation();
615 GetProgramiv(service_id
, GL_INFO_LOG_LENGTH
, _
))
616 .WillOnce(SetArgumentPointee
<2>(0))
617 .RetiresOnSaturation();
619 GetProgramiv(service_id
, GL_ACTIVE_ATTRIBUTES
, _
))
620 .WillOnce(SetArgumentPointee
<2>(num_attribs
))
621 .RetiresOnSaturation();
622 size_t max_attrib_len
= 0;
623 for (size_t ii
= 0; ii
< num_attribs
; ++ii
) {
624 size_t len
= strlen(attribs
[ii
].name
) + 1;
625 max_attrib_len
= std::max(max_attrib_len
, len
);
628 GetProgramiv(service_id
, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
, _
))
629 .WillOnce(SetArgumentPointee
<2>(max_attrib_len
))
630 .RetiresOnSaturation();
632 for (size_t ii
= 0; ii
< num_attribs
; ++ii
) {
633 const AttribInfo
& info
= attribs
[ii
];
635 GetActiveAttrib(service_id
, ii
,
636 max_attrib_len
, _
, _
, _
, _
))
638 SetArgumentPointee
<3>(strlen(info
.name
)),
639 SetArgumentPointee
<4>(info
.size
),
640 SetArgumentPointee
<5>(info
.type
),
641 SetArrayArgument
<6>(info
.name
,
642 info
.name
+ strlen(info
.name
) + 1)))
643 .RetiresOnSaturation();
644 if (!ProgramManager::IsInvalidPrefix(info
.name
, strlen(info
.name
))) {
645 EXPECT_CALL(*gl
, GetAttribLocation(service_id
, StrEq(info
.name
)))
646 .WillOnce(Return(info
.location
))
647 .RetiresOnSaturation();
651 GetProgramiv(service_id
, GL_ACTIVE_UNIFORMS
, _
))
652 .WillOnce(SetArgumentPointee
<2>(num_uniforms
))
653 .RetiresOnSaturation();
655 size_t max_uniform_len
= 0;
656 for (size_t ii
= 0; ii
< num_uniforms
; ++ii
) {
657 size_t len
= strlen(uniforms
[ii
].name
) + 1;
658 max_uniform_len
= std::max(max_uniform_len
, len
);
661 GetProgramiv(service_id
, GL_ACTIVE_UNIFORM_MAX_LENGTH
, _
))
662 .WillOnce(SetArgumentPointee
<2>(max_uniform_len
))
663 .RetiresOnSaturation();
664 for (size_t ii
= 0; ii
< num_uniforms
; ++ii
) {
665 const UniformInfo
& info
= uniforms
[ii
];
667 GetActiveUniform(service_id
, ii
,
668 max_uniform_len
, _
, _
, _
, _
))
670 SetArgumentPointee
<3>(strlen(info
.name
)),
671 SetArgumentPointee
<4>(info
.size
),
672 SetArgumentPointee
<5>(info
.type
),
673 SetArrayArgument
<6>(info
.name
,
674 info
.name
+ strlen(info
.name
) + 1)))
675 .RetiresOnSaturation();
678 for (int pass
= 0; pass
< 2; ++pass
) {
679 for (size_t ii
= 0; ii
< num_uniforms
; ++ii
) {
680 const UniformInfo
& info
= uniforms
[ii
];
681 if (pass
== 0 && info
.real_location
!= -1) {
682 EXPECT_CALL(*gl
, GetUniformLocation(service_id
, StrEq(info
.name
)))
683 .WillOnce(Return(info
.real_location
))
684 .RetiresOnSaturation();
686 if ((pass
== 0 && info
.desired_location
>= 0) ||
687 (pass
== 1 && info
.desired_location
< 0)) {
689 std::string base_name
= info
.name
;
690 size_t array_pos
= base_name
.rfind("[0]");
691 if (base_name
.size() > 3 && array_pos
== base_name
.size() - 3) {
692 base_name
= base_name
.substr(0, base_name
.size() - 3);
694 for (GLsizei jj
= 1; jj
< info
.size
; ++jj
) {
695 std::string
element_name(
696 std::string(base_name
) + "[" + base::IntToString(jj
) + "]");
697 EXPECT_CALL(*gl
, GetUniformLocation(
698 service_id
, StrEq(element_name
)))
699 .WillOnce(Return(info
.real_location
+ jj
* 2))
700 .RetiresOnSaturation();
708 void TestHelper::SetupShader(
709 ::gfx::MockGLInterface
* gl
,
710 AttribInfo
* attribs
, size_t num_attribs
,
711 UniformInfo
* uniforms
, size_t num_uniforms
,
716 LinkProgram(service_id
))
718 .RetiresOnSaturation();
720 SetupProgramSuccessExpectations(
721 gl
, attribs
, num_attribs
, uniforms
, num_uniforms
, service_id
);
724 void TestHelper::DoBufferData(
725 ::gfx::MockGLInterface
* gl
, MockErrorState
* error_state
,
726 BufferManager
* manager
, Buffer
* buffer
, GLenum target
, GLsizeiptr size
,
727 GLenum usage
, const GLvoid
* data
, GLenum error
) {
728 EXPECT_CALL(*error_state
, CopyRealGLErrorsToWrapper(_
, _
, _
))
730 .RetiresOnSaturation();
731 if (manager
->IsUsageClientSideArray(usage
)) {
732 EXPECT_CALL(*gl
, BufferData(target
, 0, _
, usage
))
734 .RetiresOnSaturation();
736 EXPECT_CALL(*gl
, BufferData(target
, size
, _
, usage
))
738 .RetiresOnSaturation();
740 EXPECT_CALL(*error_state
, PeekGLError(_
, _
, _
))
741 .WillOnce(Return(error
))
742 .RetiresOnSaturation();
743 manager
->DoBufferData(error_state
, buffer
, target
, size
, usage
, data
);
746 void TestHelper::SetTexParameteriWithExpectations(
747 ::gfx::MockGLInterface
* gl
, MockErrorState
* error_state
,
748 TextureManager
* manager
, TextureRef
* texture_ref
,
749 GLenum pname
, GLint value
, GLenum error
) {
750 if (error
== GL_NO_ERROR
) {
751 if (pname
!= GL_TEXTURE_POOL_CHROMIUM
) {
752 EXPECT_CALL(*gl
, TexParameteri(texture_ref
->texture()->target(),
755 .RetiresOnSaturation();
757 } else if (error
== GL_INVALID_ENUM
) {
758 EXPECT_CALL(*error_state
, SetGLErrorInvalidEnum(_
, _
, _
, value
, _
))
760 .RetiresOnSaturation();
762 EXPECT_CALL(*error_state
, SetGLErrorInvalidParami(_
, _
, error
, _
, _
, _
))
764 .RetiresOnSaturation();
766 manager
->SetParameteri("", error_state
, texture_ref
, pname
, value
);
770 void TestHelper::SetShaderStates(
771 ::gfx::MockGLInterface
* gl
, Shader
* shader
,
773 const std::string
* const expected_log_info
,
774 const std::string
* const expected_translated_source
,
775 const int* const expected_shader_version
,
776 const AttributeMap
* const expected_attrib_map
,
777 const UniformMap
* const expected_uniform_map
,
778 const VaryingMap
* const expected_varying_map
,
779 const NameMap
* const expected_name_map
) {
780 const std::string empty_log_info
;
781 const std::string
* log_info
= (expected_log_info
&& !expected_valid
) ?
782 expected_log_info
: &empty_log_info
;
783 const std::string empty_translated_source
;
784 const std::string
* translated_source
=
785 (expected_translated_source
&& expected_valid
) ?
786 expected_translated_source
: &empty_translated_source
;
787 int default_shader_version
= 100;
788 const int* shader_version
= (expected_shader_version
&& expected_valid
) ?
789 expected_shader_version
: &default_shader_version
;
790 const AttributeMap empty_attrib_map
;
791 const AttributeMap
* attrib_map
= (expected_attrib_map
&& expected_valid
) ?
792 expected_attrib_map
: &empty_attrib_map
;
793 const UniformMap empty_uniform_map
;
794 const UniformMap
* uniform_map
= (expected_uniform_map
&& expected_valid
) ?
795 expected_uniform_map
: &empty_uniform_map
;
796 const VaryingMap empty_varying_map
;
797 const VaryingMap
* varying_map
= (expected_varying_map
&& expected_valid
) ?
798 expected_varying_map
: &empty_varying_map
;
799 const NameMap empty_name_map
;
800 const NameMap
* name_map
= (expected_name_map
&& expected_valid
) ?
801 expected_name_map
: &empty_name_map
;
803 MockShaderTranslator
* mock_translator
= new MockShaderTranslator
;
804 scoped_refptr
<ShaderTranslatorInterface
> translator(mock_translator
);
805 EXPECT_CALL(*mock_translator
, Translate(_
,
806 NotNull(), // log_info
807 NotNull(), // translated_source
808 NotNull(), // shader_version
809 NotNull(), // attrib_map
810 NotNull(), // uniform_map
811 NotNull(), // varying_map
812 NotNull())) // name_map
813 .WillOnce(DoAll(SetArgumentPointee
<1>(*log_info
),
814 SetArgumentPointee
<2>(*translated_source
),
815 SetArgumentPointee
<3>(*shader_version
),
816 SetArgumentPointee
<4>(*attrib_map
),
817 SetArgumentPointee
<5>(*uniform_map
),
818 SetArgumentPointee
<6>(*varying_map
),
819 SetArgumentPointee
<7>(*name_map
),
820 Return(expected_valid
)))
821 .RetiresOnSaturation();
822 if (expected_valid
) {
823 EXPECT_CALL(*gl
, ShaderSource(shader
->service_id(), 1, _
, NULL
))
825 .RetiresOnSaturation();
826 EXPECT_CALL(*gl
, CompileShader(shader
->service_id()))
828 .RetiresOnSaturation();
829 EXPECT_CALL(*gl
, GetShaderiv(shader
->service_id(),
831 NotNull())) // status
832 .WillOnce(SetArgumentPointee
<2>(GL_TRUE
))
833 .RetiresOnSaturation();
835 shader
->RequestCompile(translator
, Shader::kGL
);
840 void TestHelper::SetShaderStates(
841 ::gfx::MockGLInterface
* gl
, Shader
* shader
, bool valid
) {
842 SetShaderStates(gl
, shader
, valid
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
846 sh::Attribute
TestHelper::ConstructAttribute(
847 GLenum type
, GLint array_size
, GLenum precision
,
848 bool static_use
, const std::string
& name
) {
849 return ConstructShaderVariable
<sh::Attribute
>(
850 type
, array_size
, precision
, static_use
, name
);
854 sh::Uniform
TestHelper::ConstructUniform(
855 GLenum type
, GLint array_size
, GLenum precision
,
856 bool static_use
, const std::string
& name
) {
857 return ConstructShaderVariable
<sh::Uniform
>(
858 type
, array_size
, precision
, static_use
, name
);
862 sh::Varying
TestHelper::ConstructVarying(
863 GLenum type
, GLint array_size
, GLenum precision
,
864 bool static_use
, const std::string
& name
) {
865 return ConstructShaderVariable
<sh::Varying
>(
866 type
, array_size
, precision
, static_use
, name
);
869 ScopedGLImplementationSetter::ScopedGLImplementationSetter(
870 gfx::GLImplementation implementation
)
871 : old_implementation_(gfx::GetGLImplementation()) {
872 gfx::SetGLImplementation(implementation
);
875 ScopedGLImplementationSetter::~ScopedGLImplementationSetter() {
876 gfx::SetGLImplementation(old_implementation_
);