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_split.h"
12 #include "base/strings/string_tokenizer.h"
13 #include "gpu/command_buffer/service/buffer_manager.h"
14 #include "gpu/command_buffer/service/error_state_mock.h"
15 #include "gpu/command_buffer/service/gl_utils.h"
16 #include "gpu/command_buffer/service/gpu_switches.h"
17 #include "gpu/command_buffer/service/mocks.h"
18 #include "gpu/command_buffer/service/program_manager.h"
19 #include "gpu/command_buffer/service/texture_manager.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "ui/gl/gl_mock.h"
22 #include "ui/gl/gl_version_info.h"
25 using ::testing::DoAll
;
26 using ::testing::InSequence
;
27 using ::testing::MatcherCast
;
28 using ::testing::Pointee
;
29 using ::testing::NotNull
;
30 using ::testing::Return
;
31 using ::testing::SetArrayArgument
;
32 using ::testing::SetArgumentPointee
;
33 using ::testing::StrEq
;
34 using ::testing::StrictMock
;
42 T
ConstructShaderVariable(
43 GLenum type
, GLint array_size
, GLenum precision
,
44 bool static_use
, const std::string
& name
) {
47 var
.arraySize
= array_size
;
48 var
.precision
= precision
;
49 var
.staticUse
= static_use
;
51 var
.mappedName
= name
; // No name hashing.
55 } // namespace anonymous
57 // GCC requires these declarations, but MSVC requires they not be present
59 const GLuint
TestHelper::kServiceBlackTexture2dId
;
60 const GLuint
TestHelper::kServiceDefaultTexture2dId
;
61 const GLuint
TestHelper::kServiceBlackTextureCubemapId
;
62 const GLuint
TestHelper::kServiceDefaultTextureCubemapId
;
63 const GLuint
TestHelper::kServiceBlackExternalTextureId
;
64 const GLuint
TestHelper::kServiceDefaultExternalTextureId
;
65 const GLuint
TestHelper::kServiceBlackRectangleTextureId
;
66 const GLuint
TestHelper::kServiceDefaultRectangleTextureId
;
68 const GLint
TestHelper::kMaxSamples
;
69 const GLint
TestHelper::kMaxRenderbufferSize
;
70 const GLint
TestHelper::kMaxTextureSize
;
71 const GLint
TestHelper::kMaxCubeMapTextureSize
;
72 const GLint
TestHelper::kMaxRectangleTextureSize
;
73 const GLint
TestHelper::kMax3DTextureSize
;
74 const GLint
TestHelper::kNumVertexAttribs
;
75 const GLint
TestHelper::kNumTextureUnits
;
76 const GLint
TestHelper::kMaxTextureImageUnits
;
77 const GLint
TestHelper::kMaxVertexTextureImageUnits
;
78 const GLint
TestHelper::kMaxFragmentUniformVectors
;
79 const GLint
TestHelper::kMaxFragmentUniformComponents
;
80 const GLint
TestHelper::kMaxVaryingVectors
;
81 const GLint
TestHelper::kMaxVaryingFloats
;
82 const GLint
TestHelper::kMaxVertexUniformVectors
;
83 const GLint
TestHelper::kMaxVertexUniformComponents
;
86 std::vector
<std::string
> TestHelper::split_extensions_
;
88 void TestHelper::SetupTextureInitializationExpectations(
89 ::gfx::MockGLInterface
* gl
,
91 bool use_default_textures
) {
94 bool needs_initialization
= (target
!= GL_TEXTURE_EXTERNAL_OES
);
95 bool needs_faces
= (target
== GL_TEXTURE_CUBE_MAP
);
97 static GLuint texture_2d_ids
[] = {
98 kServiceBlackTexture2dId
,
99 kServiceDefaultTexture2dId
};
100 static GLuint texture_cube_map_ids
[] = {
101 kServiceBlackTextureCubemapId
,
102 kServiceDefaultTextureCubemapId
};
103 static GLuint texture_external_oes_ids
[] = {
104 kServiceBlackExternalTextureId
,
105 kServiceDefaultExternalTextureId
};
106 static GLuint texture_rectangle_arb_ids
[] = {
107 kServiceBlackRectangleTextureId
,
108 kServiceDefaultRectangleTextureId
};
110 const GLuint
* texture_ids
= NULL
;
113 texture_ids
= &texture_2d_ids
[0];
115 case GL_TEXTURE_CUBE_MAP
:
116 texture_ids
= &texture_cube_map_ids
[0];
118 case GL_TEXTURE_EXTERNAL_OES
:
119 texture_ids
= &texture_external_oes_ids
[0];
121 case GL_TEXTURE_RECTANGLE_ARB
:
122 texture_ids
= &texture_rectangle_arb_ids
[0];
128 int array_size
= use_default_textures
? 2 : 1;
130 EXPECT_CALL(*gl
, GenTextures(array_size
, _
))
131 .WillOnce(SetArrayArgument
<1>(texture_ids
,
132 texture_ids
+ array_size
))
133 .RetiresOnSaturation();
134 for (int ii
= 0; ii
< array_size
; ++ii
) {
135 EXPECT_CALL(*gl
, BindTexture(target
, texture_ids
[ii
]))
137 .RetiresOnSaturation();
138 if (needs_initialization
) {
140 static GLenum faces
[] = {
141 GL_TEXTURE_CUBE_MAP_POSITIVE_X
,
142 GL_TEXTURE_CUBE_MAP_NEGATIVE_X
,
143 GL_TEXTURE_CUBE_MAP_POSITIVE_Y
,
144 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
,
145 GL_TEXTURE_CUBE_MAP_POSITIVE_Z
,
146 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
,
148 for (size_t ii
= 0; ii
< arraysize(faces
); ++ii
) {
149 EXPECT_CALL(*gl
, TexImage2D(faces
[ii
], 0, GL_RGBA
, 1, 1, 0, GL_RGBA
,
150 GL_UNSIGNED_BYTE
, _
))
152 .RetiresOnSaturation();
155 EXPECT_CALL(*gl
, TexImage2D(target
, 0, GL_RGBA
, 1, 1, 0, GL_RGBA
,
156 GL_UNSIGNED_BYTE
, _
))
158 .RetiresOnSaturation();
162 EXPECT_CALL(*gl
, BindTexture(target
, 0))
164 .RetiresOnSaturation();
167 void TestHelper::SetupTextureManagerInitExpectations(
168 ::gfx::MockGLInterface
* gl
,
169 const char* extensions
,
170 bool use_default_textures
) {
173 SetupTextureInitializationExpectations(
174 gl
, GL_TEXTURE_2D
, use_default_textures
);
175 SetupTextureInitializationExpectations(
176 gl
, GL_TEXTURE_CUBE_MAP
, use_default_textures
);
178 bool ext_image_external
= false;
179 bool arb_texture_rectangle
= false;
180 base::CStringTokenizer
t(extensions
, extensions
+ strlen(extensions
), " ");
181 while (t
.GetNext()) {
182 if (t
.token() == "GL_OES_EGL_image_external") {
183 ext_image_external
= true;
186 if (t
.token() == "GL_ARB_texture_rectangle") {
187 arb_texture_rectangle
= true;
192 if (ext_image_external
) {
193 SetupTextureInitializationExpectations(
194 gl
, GL_TEXTURE_EXTERNAL_OES
, use_default_textures
);
196 if (arb_texture_rectangle
) {
197 SetupTextureInitializationExpectations(
198 gl
, GL_TEXTURE_RECTANGLE_ARB
, use_default_textures
);
202 void TestHelper::SetupTextureDestructionExpectations(
203 ::gfx::MockGLInterface
* gl
,
205 bool use_default_textures
) {
206 if (!use_default_textures
)
209 GLuint texture_id
= 0;
212 texture_id
= kServiceDefaultTexture2dId
;
214 case GL_TEXTURE_CUBE_MAP
:
215 texture_id
= kServiceDefaultTextureCubemapId
;
217 case GL_TEXTURE_EXTERNAL_OES
:
218 texture_id
= kServiceDefaultExternalTextureId
;
220 case GL_TEXTURE_RECTANGLE_ARB
:
221 texture_id
= kServiceDefaultRectangleTextureId
;
227 EXPECT_CALL(*gl
, DeleteTextures(1, Pointee(texture_id
)))
229 .RetiresOnSaturation();
232 void TestHelper::SetupTextureManagerDestructionExpectations(
233 ::gfx::MockGLInterface
* gl
,
234 const char* extensions
,
235 bool use_default_textures
) {
236 SetupTextureDestructionExpectations(gl
, GL_TEXTURE_2D
, use_default_textures
);
237 SetupTextureDestructionExpectations(
238 gl
, GL_TEXTURE_CUBE_MAP
, use_default_textures
);
240 bool ext_image_external
= false;
241 bool arb_texture_rectangle
= false;
242 base::CStringTokenizer
t(extensions
, extensions
+ strlen(extensions
), " ");
243 while (t
.GetNext()) {
244 if (t
.token() == "GL_OES_EGL_image_external") {
245 ext_image_external
= true;
248 if (t
.token() == "GL_ARB_texture_rectangle") {
249 arb_texture_rectangle
= true;
254 if (ext_image_external
) {
255 SetupTextureDestructionExpectations(
256 gl
, GL_TEXTURE_EXTERNAL_OES
, use_default_textures
);
258 if (arb_texture_rectangle
) {
259 SetupTextureDestructionExpectations(
260 gl
, GL_TEXTURE_RECTANGLE_ARB
, use_default_textures
);
263 EXPECT_CALL(*gl
, DeleteTextures(4, _
))
265 .RetiresOnSaturation();
268 void TestHelper::SetupContextGroupInitExpectations(
269 ::gfx::MockGLInterface
* gl
,
270 const DisallowedFeatures
& disallowed_features
,
271 const char* extensions
,
272 const char* gl_version
,
273 bool bind_generates_resource
) {
276 SetupFeatureInfoInitExpectationsWithGLVersion(gl
, extensions
, "", gl_version
);
278 gfx::GLVersionInfo
gl_info(gl_version
, "", extensions
);
280 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_RENDERBUFFER_SIZE
, _
))
281 .WillOnce(SetArgumentPointee
<1>(kMaxRenderbufferSize
))
282 .RetiresOnSaturation();
283 if (strstr(extensions
, "GL_EXT_framebuffer_multisample") ||
284 strstr(extensions
, "GL_EXT_multisampled_render_to_texture") ||
286 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_SAMPLES
, _
))
287 .WillOnce(SetArgumentPointee
<1>(kMaxSamples
))
288 .RetiresOnSaturation();
289 } else if (strstr(extensions
, "GL_IMG_multisampled_render_to_texture")) {
290 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_SAMPLES_IMG
, _
))
291 .WillOnce(SetArgumentPointee
<1>(kMaxSamples
))
292 .RetiresOnSaturation();
294 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_VERTEX_ATTRIBS
, _
))
295 .WillOnce(SetArgumentPointee
<1>(kNumVertexAttribs
))
296 .RetiresOnSaturation();
297 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
, _
))
298 .WillOnce(SetArgumentPointee
<1>(kNumTextureUnits
))
299 .RetiresOnSaturation();
300 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_TEXTURE_SIZE
, _
))
301 .WillOnce(SetArgumentPointee
<1>(kMaxTextureSize
))
302 .RetiresOnSaturation();
303 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE
, _
))
304 .WillOnce(SetArgumentPointee
<1>(kMaxCubeMapTextureSize
))
305 .RetiresOnSaturation();
306 if (gl_info
.IsES3Capable()) {
307 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_3D_TEXTURE_SIZE
, _
))
308 .WillOnce(SetArgumentPointee
<1>(kMax3DTextureSize
))
309 .RetiresOnSaturation();
311 if (strstr(extensions
, "GL_ARB_texture_rectangle")) {
312 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE
, _
))
313 .WillOnce(SetArgumentPointee
<1>(kMaxRectangleTextureSize
))
314 .RetiresOnSaturation();
316 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS
, _
))
317 .WillOnce(SetArgumentPointee
<1>(kMaxTextureImageUnits
))
318 .RetiresOnSaturation();
319 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS
, _
))
320 .WillOnce(SetArgumentPointee
<1>(kMaxVertexTextureImageUnits
))
321 .RetiresOnSaturation();
324 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS
, _
))
325 .WillOnce(SetArgumentPointee
<1>(kMaxFragmentUniformVectors
))
326 .RetiresOnSaturation();
327 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_VARYING_VECTORS
, _
))
328 .WillOnce(SetArgumentPointee
<1>(kMaxVaryingVectors
))
329 .RetiresOnSaturation();
330 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS
, _
))
331 .WillOnce(SetArgumentPointee
<1>(kMaxVertexUniformVectors
))
332 .RetiresOnSaturation();
334 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS
, _
))
335 .WillOnce(SetArgumentPointee
<1>(kMaxFragmentUniformComponents
))
336 .RetiresOnSaturation();
337 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_VARYING_FLOATS
, _
))
338 .WillOnce(SetArgumentPointee
<1>(kMaxVaryingFloats
))
339 .RetiresOnSaturation();
340 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS
, _
))
341 .WillOnce(SetArgumentPointee
<1>(kMaxVertexUniformComponents
))
342 .RetiresOnSaturation();
345 bool use_default_textures
= bind_generates_resource
;
346 SetupTextureManagerInitExpectations(gl
, extensions
, use_default_textures
);
349 void TestHelper::SetupFeatureInfoInitExpectations(
350 ::gfx::MockGLInterface
* gl
, const char* extensions
) {
351 SetupFeatureInfoInitExpectationsWithGLVersion(gl
, extensions
, "", "");
354 void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(
355 ::gfx::MockGLInterface
* gl
,
356 const char* extensions
,
357 const char* gl_renderer
,
358 const char* gl_version
) {
361 EXPECT_CALL(*gl
, GetString(GL_VERSION
))
362 .WillOnce(Return(reinterpret_cast<const uint8
*>(gl_version
)))
363 .RetiresOnSaturation();
365 // Persistent storage is needed for the split extension string.
366 split_extensions_
.clear();
368 split_extensions_
= base::SplitString(
369 extensions
, " ", base::KEEP_WHITESPACE
, base::SPLIT_WANT_NONEMPTY
);
372 gfx::GLVersionInfo
gl_info(gl_version
, gl_renderer
, extensions
);
373 if (!gl_info
.is_es
&& gl_info
.major_version
>= 3) {
374 EXPECT_CALL(*gl
, GetIntegerv(GL_NUM_EXTENSIONS
, _
))
375 .WillOnce(SetArgumentPointee
<1>(split_extensions_
.size()))
376 .RetiresOnSaturation();
377 for (size_t ii
= 0; ii
< split_extensions_
.size(); ++ii
) {
378 EXPECT_CALL(*gl
, GetStringi(GL_EXTENSIONS
, ii
))
379 .WillOnce(Return(reinterpret_cast<const uint8
*>(
380 split_extensions_
[ii
].c_str())))
381 .RetiresOnSaturation();
384 EXPECT_CALL(*gl
, GetString(GL_EXTENSIONS
))
385 .WillOnce(Return(reinterpret_cast<const uint8
*>(extensions
)))
386 .RetiresOnSaturation();
389 EXPECT_CALL(*gl
, GetString(GL_RENDERER
))
390 .WillOnce(Return(reinterpret_cast<const uint8
*>(gl_renderer
)))
391 .RetiresOnSaturation();
393 if (strstr(extensions
, "GL_ARB_texture_float") ||
394 (gl_info
.is_es3
&& strstr(extensions
, "GL_EXT_color_buffer_float"))) {
395 static const GLuint tx_ids
[] = {101, 102};
396 static const GLuint fb_ids
[] = {103, 104};
397 const GLsizei width
= 16;
398 EXPECT_CALL(*gl
, GetIntegerv(GL_FRAMEBUFFER_BINDING
, _
))
399 .WillOnce(SetArgumentPointee
<1>(fb_ids
[0]))
400 .RetiresOnSaturation();
401 EXPECT_CALL(*gl
, GetIntegerv(GL_TEXTURE_BINDING_2D
, _
))
402 .WillOnce(SetArgumentPointee
<1>(tx_ids
[0]))
403 .RetiresOnSaturation();
404 EXPECT_CALL(*gl
, GenTextures(1, _
))
405 .WillOnce(SetArrayArgument
<1>(tx_ids
+ 1, tx_ids
+ 2))
406 .RetiresOnSaturation();
407 EXPECT_CALL(*gl
, GenFramebuffersEXT(1, _
))
408 .WillOnce(SetArrayArgument
<1>(fb_ids
+ 1, fb_ids
+ 2))
409 .RetiresOnSaturation();
410 EXPECT_CALL(*gl
, BindTexture(GL_TEXTURE_2D
, tx_ids
[1]))
412 .RetiresOnSaturation();
413 EXPECT_CALL(*gl
, TexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
,
416 .RetiresOnSaturation();
417 EXPECT_CALL(*gl
, TexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA32F
, width
, width
, 0,
418 GL_RGBA
, GL_FLOAT
, _
))
420 .RetiresOnSaturation();
421 EXPECT_CALL(*gl
, BindFramebufferEXT(GL_FRAMEBUFFER
, fb_ids
[1]))
423 .RetiresOnSaturation();
424 EXPECT_CALL(*gl
, FramebufferTexture2DEXT(GL_FRAMEBUFFER
,
425 GL_COLOR_ATTACHMENT0
, GL_TEXTURE_2D
, tx_ids
[1], 0))
427 .RetiresOnSaturation();
428 EXPECT_CALL(*gl
, CheckFramebufferStatusEXT(GL_FRAMEBUFFER
))
429 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE
))
430 .RetiresOnSaturation();
431 EXPECT_CALL(*gl
, TexImage2D(GL_TEXTURE_2D
, 0, GL_RGB32F
, width
, width
, 0,
432 GL_RGB
, GL_FLOAT
, _
))
434 .RetiresOnSaturation();
435 if (gl_info
.is_es3
) {
436 EXPECT_CALL(*gl
, CheckFramebufferStatusEXT(GL_FRAMEBUFFER
))
437 .WillOnce(Return(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
))
438 .RetiresOnSaturation();
440 EXPECT_CALL(*gl
, CheckFramebufferStatusEXT(GL_FRAMEBUFFER
))
441 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE
))
442 .RetiresOnSaturation();
444 EXPECT_CALL(*gl
, DeleteFramebuffersEXT(1, _
))
446 .RetiresOnSaturation();
447 EXPECT_CALL(*gl
, DeleteTextures(1, _
))
449 .RetiresOnSaturation();
450 EXPECT_CALL(*gl
, BindFramebufferEXT(GL_FRAMEBUFFER
, fb_ids
[0]))
452 .RetiresOnSaturation();
453 EXPECT_CALL(*gl
, BindTexture(GL_TEXTURE_2D
, tx_ids
[0]))
455 .RetiresOnSaturation();
457 EXPECT_CALL(*gl
, GetError())
458 .WillOnce(Return(GL_NO_ERROR
))
459 .RetiresOnSaturation();
463 if (strstr(extensions
, "GL_EXT_draw_buffers") ||
464 strstr(extensions
, "GL_ARB_draw_buffers") ||
465 (gl_info
.is_es3
&& strstr(extensions
, "GL_NV_draw_buffers"))) {
466 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT
, _
))
467 .WillOnce(SetArgumentPointee
<1>(8))
468 .RetiresOnSaturation();
469 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_DRAW_BUFFERS_ARB
, _
))
470 .WillOnce(SetArgumentPointee
<1>(8))
471 .RetiresOnSaturation();
474 if (gl_info
.is_es3
|| strstr(extensions
, "GL_EXT_texture_rg") ||
475 (strstr(extensions
, "GL_ARB_texture_rg"))) {
476 static const GLuint tx_ids
[] = {101, 102};
477 static const GLuint fb_ids
[] = {103, 104};
478 const GLsizei width
= 1;
479 EXPECT_CALL(*gl
, GetIntegerv(GL_FRAMEBUFFER_BINDING
, _
))
480 .WillOnce(SetArgumentPointee
<1>(fb_ids
[0]))
481 .RetiresOnSaturation();
482 EXPECT_CALL(*gl
, GetIntegerv(GL_TEXTURE_BINDING_2D
, _
))
483 .WillOnce(SetArgumentPointee
<1>(tx_ids
[0]))
484 .RetiresOnSaturation();
485 EXPECT_CALL(*gl
, GenTextures(1, _
))
486 .WillOnce(SetArrayArgument
<1>(tx_ids
+ 1, tx_ids
+ 2))
487 .RetiresOnSaturation();
488 EXPECT_CALL(*gl
, BindTexture(GL_TEXTURE_2D
, tx_ids
[1]))
490 .RetiresOnSaturation();
491 EXPECT_CALL(*gl
, TexImage2D(GL_TEXTURE_2D
, 0, _
, width
, width
, 0,
492 GL_RED_EXT
, GL_UNSIGNED_BYTE
, _
))
494 .RetiresOnSaturation();
495 EXPECT_CALL(*gl
, GenFramebuffersEXT(1, _
))
496 .WillOnce(SetArrayArgument
<1>(fb_ids
+ 1, fb_ids
+ 2))
497 .RetiresOnSaturation();
498 EXPECT_CALL(*gl
, BindFramebufferEXT(GL_FRAMEBUFFER
, fb_ids
[1]))
500 .RetiresOnSaturation();
501 EXPECT_CALL(*gl
, FramebufferTexture2DEXT(GL_FRAMEBUFFER
,
502 GL_COLOR_ATTACHMENT0
, GL_TEXTURE_2D
, tx_ids
[1], 0))
504 .RetiresOnSaturation();
505 EXPECT_CALL(*gl
, CheckFramebufferStatusEXT(GL_FRAMEBUFFER
))
506 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE
))
507 .RetiresOnSaturation();
508 EXPECT_CALL(*gl
, DeleteFramebuffersEXT(1, _
))
510 .RetiresOnSaturation();
511 EXPECT_CALL(*gl
, DeleteTextures(1, _
))
513 .RetiresOnSaturation();
514 EXPECT_CALL(*gl
, BindFramebufferEXT(GL_FRAMEBUFFER
, fb_ids
[0]))
516 .RetiresOnSaturation();
517 EXPECT_CALL(*gl
, BindTexture(GL_TEXTURE_2D
, tx_ids
[0]))
519 .RetiresOnSaturation();
521 EXPECT_CALL(*gl
, GetError())
522 .WillOnce(Return(GL_NO_ERROR
))
523 .RetiresOnSaturation();
528 void TestHelper::SetupExpectationsForClearingUniforms(
529 ::gfx::MockGLInterface
* gl
, UniformInfo
* uniforms
, size_t num_uniforms
) {
530 for (size_t ii
= 0; ii
< num_uniforms
; ++ii
) {
531 const UniformInfo
& info
= uniforms
[ii
];
534 EXPECT_CALL(*gl
, Uniform1fv(info
.real_location
, info
.size
, _
))
536 .RetiresOnSaturation();
539 EXPECT_CALL(*gl
, Uniform2fv(info
.real_location
, info
.size
, _
))
541 .RetiresOnSaturation();
544 EXPECT_CALL(*gl
, Uniform3fv(info
.real_location
, info
.size
, _
))
546 .RetiresOnSaturation();
549 EXPECT_CALL(*gl
, Uniform4fv(info
.real_location
, info
.size
, _
))
551 .RetiresOnSaturation();
556 case GL_SAMPLER_CUBE
:
557 case GL_SAMPLER_EXTERNAL_OES
:
558 case GL_SAMPLER_3D_OES
:
559 case GL_SAMPLER_2D_RECT_ARB
:
560 EXPECT_CALL(*gl
, Uniform1iv(info
.real_location
, info
.size
, _
))
562 .RetiresOnSaturation();
566 EXPECT_CALL(*gl
, Uniform2iv(info
.real_location
, info
.size
, _
))
568 .RetiresOnSaturation();
572 EXPECT_CALL(*gl
, Uniform3iv(info
.real_location
, info
.size
, _
))
574 .RetiresOnSaturation();
578 EXPECT_CALL(*gl
, Uniform4iv(info
.real_location
, info
.size
, _
))
580 .RetiresOnSaturation();
583 EXPECT_CALL(*gl
, UniformMatrix2fv(
584 info
.real_location
, info
.size
, false, _
))
586 .RetiresOnSaturation();
589 EXPECT_CALL(*gl
, UniformMatrix3fv(
590 info
.real_location
, info
.size
, false, _
))
592 .RetiresOnSaturation();
595 EXPECT_CALL(*gl
, UniformMatrix4fv(
596 info
.real_location
, info
.size
, false, _
))
598 .RetiresOnSaturation();
607 void TestHelper::SetupProgramSuccessExpectations(
608 ::gfx::MockGLInterface
* gl
,
609 AttribInfo
* attribs
, size_t num_attribs
,
610 UniformInfo
* uniforms
, size_t num_uniforms
,
613 GetProgramiv(service_id
, GL_LINK_STATUS
, _
))
614 .WillOnce(SetArgumentPointee
<2>(1))
615 .RetiresOnSaturation();
617 GetProgramiv(service_id
, GL_INFO_LOG_LENGTH
, _
))
618 .WillOnce(SetArgumentPointee
<2>(0))
619 .RetiresOnSaturation();
621 GetProgramiv(service_id
, GL_ACTIVE_ATTRIBUTES
, _
))
622 .WillOnce(SetArgumentPointee
<2>(num_attribs
))
623 .RetiresOnSaturation();
624 size_t max_attrib_len
= 0;
625 for (size_t ii
= 0; ii
< num_attribs
; ++ii
) {
626 size_t len
= strlen(attribs
[ii
].name
) + 1;
627 max_attrib_len
= std::max(max_attrib_len
, len
);
630 GetProgramiv(service_id
, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
, _
))
631 .WillOnce(SetArgumentPointee
<2>(max_attrib_len
))
632 .RetiresOnSaturation();
634 for (size_t ii
= 0; ii
< num_attribs
; ++ii
) {
635 const AttribInfo
& info
= attribs
[ii
];
637 GetActiveAttrib(service_id
, ii
,
638 max_attrib_len
, _
, _
, _
, _
))
640 SetArgumentPointee
<3>(strlen(info
.name
)),
641 SetArgumentPointee
<4>(info
.size
),
642 SetArgumentPointee
<5>(info
.type
),
643 SetArrayArgument
<6>(info
.name
,
644 info
.name
+ strlen(info
.name
) + 1)))
645 .RetiresOnSaturation();
646 if (!ProgramManager::IsInvalidPrefix(info
.name
, strlen(info
.name
))) {
647 EXPECT_CALL(*gl
, GetAttribLocation(service_id
, StrEq(info
.name
)))
648 .WillOnce(Return(info
.location
))
649 .RetiresOnSaturation();
653 GetProgramiv(service_id
, GL_ACTIVE_UNIFORMS
, _
))
654 .WillOnce(SetArgumentPointee
<2>(num_uniforms
))
655 .RetiresOnSaturation();
657 size_t max_uniform_len
= 0;
658 for (size_t ii
= 0; ii
< num_uniforms
; ++ii
) {
659 size_t len
= strlen(uniforms
[ii
].name
) + 1;
660 max_uniform_len
= std::max(max_uniform_len
, len
);
663 GetProgramiv(service_id
, GL_ACTIVE_UNIFORM_MAX_LENGTH
, _
))
664 .WillOnce(SetArgumentPointee
<2>(max_uniform_len
))
665 .RetiresOnSaturation();
666 for (size_t ii
= 0; ii
< num_uniforms
; ++ii
) {
667 const UniformInfo
& info
= uniforms
[ii
];
669 GetActiveUniform(service_id
, ii
,
670 max_uniform_len
, _
, _
, _
, _
))
672 SetArgumentPointee
<3>(strlen(info
.name
)),
673 SetArgumentPointee
<4>(info
.size
),
674 SetArgumentPointee
<5>(info
.type
),
675 SetArrayArgument
<6>(info
.name
,
676 info
.name
+ strlen(info
.name
) + 1)))
677 .RetiresOnSaturation();
680 for (int pass
= 0; pass
< 2; ++pass
) {
681 for (size_t ii
= 0; ii
< num_uniforms
; ++ii
) {
682 const UniformInfo
& info
= uniforms
[ii
];
683 if (pass
== 0 && info
.real_location
!= -1) {
684 EXPECT_CALL(*gl
, GetUniformLocation(service_id
, StrEq(info
.name
)))
685 .WillOnce(Return(info
.real_location
))
686 .RetiresOnSaturation();
688 if ((pass
== 0 && info
.desired_location
>= 0) ||
689 (pass
== 1 && info
.desired_location
< 0)) {
691 std::string base_name
= info
.name
;
692 size_t array_pos
= base_name
.rfind("[0]");
693 if (base_name
.size() > 3 && array_pos
== base_name
.size() - 3) {
694 base_name
= base_name
.substr(0, base_name
.size() - 3);
696 for (GLsizei jj
= 1; jj
< info
.size
; ++jj
) {
697 std::string
element_name(
698 std::string(base_name
) + "[" + base::IntToString(jj
) + "]");
699 EXPECT_CALL(*gl
, GetUniformLocation(
700 service_id
, StrEq(element_name
)))
701 .WillOnce(Return(info
.real_location
+ jj
* 2))
702 .RetiresOnSaturation();
710 void TestHelper::SetupShader(
711 ::gfx::MockGLInterface
* gl
,
712 AttribInfo
* attribs
, size_t num_attribs
,
713 UniformInfo
* uniforms
, size_t num_uniforms
,
718 LinkProgram(service_id
))
720 .RetiresOnSaturation();
722 SetupProgramSuccessExpectations(
723 gl
, attribs
, num_attribs
, uniforms
, num_uniforms
, service_id
);
726 void TestHelper::DoBufferData(
727 ::gfx::MockGLInterface
* gl
, MockErrorState
* error_state
,
728 BufferManager
* manager
, Buffer
* buffer
, GLenum target
, GLsizeiptr size
,
729 GLenum usage
, const GLvoid
* data
, GLenum error
) {
730 EXPECT_CALL(*error_state
, CopyRealGLErrorsToWrapper(_
, _
, _
))
732 .RetiresOnSaturation();
733 if (manager
->IsUsageClientSideArray(usage
)) {
734 EXPECT_CALL(*gl
, BufferData(target
, 0, _
, usage
))
736 .RetiresOnSaturation();
738 EXPECT_CALL(*gl
, BufferData(target
, size
, _
, usage
))
740 .RetiresOnSaturation();
742 EXPECT_CALL(*error_state
, PeekGLError(_
, _
, _
))
743 .WillOnce(Return(error
))
744 .RetiresOnSaturation();
745 manager
->DoBufferData(error_state
, buffer
, target
, size
, usage
, data
);
748 void TestHelper::SetTexParameteriWithExpectations(
749 ::gfx::MockGLInterface
* gl
, MockErrorState
* error_state
,
750 TextureManager
* manager
, TextureRef
* texture_ref
,
751 GLenum pname
, GLint value
, GLenum error
) {
752 if (error
== GL_NO_ERROR
) {
753 if (pname
!= GL_TEXTURE_POOL_CHROMIUM
) {
754 EXPECT_CALL(*gl
, TexParameteri(texture_ref
->texture()->target(),
757 .RetiresOnSaturation();
759 } else if (error
== GL_INVALID_ENUM
) {
760 EXPECT_CALL(*error_state
, SetGLErrorInvalidEnum(_
, _
, _
, value
, _
))
762 .RetiresOnSaturation();
764 EXPECT_CALL(*error_state
, SetGLErrorInvalidParami(_
, _
, error
, _
, _
, _
))
766 .RetiresOnSaturation();
768 manager
->SetParameteri("", error_state
, texture_ref
, pname
, value
);
772 void TestHelper::SetShaderStates(
773 ::gfx::MockGLInterface
* gl
, Shader
* shader
,
775 const std::string
* const expected_log_info
,
776 const std::string
* const expected_translated_source
,
777 const int* const expected_shader_version
,
778 const AttributeMap
* const expected_attrib_map
,
779 const UniformMap
* const expected_uniform_map
,
780 const VaryingMap
* const expected_varying_map
,
781 const NameMap
* const expected_name_map
) {
782 const std::string empty_log_info
;
783 const std::string
* log_info
= (expected_log_info
&& !expected_valid
) ?
784 expected_log_info
: &empty_log_info
;
785 const std::string empty_translated_source
;
786 const std::string
* translated_source
=
787 (expected_translated_source
&& expected_valid
) ?
788 expected_translated_source
: &empty_translated_source
;
789 int default_shader_version
= 100;
790 const int* shader_version
= (expected_shader_version
&& expected_valid
) ?
791 expected_shader_version
: &default_shader_version
;
792 const AttributeMap empty_attrib_map
;
793 const AttributeMap
* attrib_map
= (expected_attrib_map
&& expected_valid
) ?
794 expected_attrib_map
: &empty_attrib_map
;
795 const UniformMap empty_uniform_map
;
796 const UniformMap
* uniform_map
= (expected_uniform_map
&& expected_valid
) ?
797 expected_uniform_map
: &empty_uniform_map
;
798 const VaryingMap empty_varying_map
;
799 const VaryingMap
* varying_map
= (expected_varying_map
&& expected_valid
) ?
800 expected_varying_map
: &empty_varying_map
;
801 const NameMap empty_name_map
;
802 const NameMap
* name_map
= (expected_name_map
&& expected_valid
) ?
803 expected_name_map
: &empty_name_map
;
805 MockShaderTranslator
* mock_translator
= new MockShaderTranslator
;
806 scoped_refptr
<ShaderTranslatorInterface
> translator(mock_translator
);
807 EXPECT_CALL(*mock_translator
, Translate(_
,
808 NotNull(), // log_info
809 NotNull(), // translated_source
810 NotNull(), // shader_version
811 NotNull(), // attrib_map
812 NotNull(), // uniform_map
813 NotNull(), // varying_map
814 NotNull())) // name_map
815 .WillOnce(DoAll(SetArgumentPointee
<1>(*log_info
),
816 SetArgumentPointee
<2>(*translated_source
),
817 SetArgumentPointee
<3>(*shader_version
),
818 SetArgumentPointee
<4>(*attrib_map
),
819 SetArgumentPointee
<5>(*uniform_map
),
820 SetArgumentPointee
<6>(*varying_map
),
821 SetArgumentPointee
<7>(*name_map
),
822 Return(expected_valid
)))
823 .RetiresOnSaturation();
824 if (expected_valid
) {
825 EXPECT_CALL(*gl
, ShaderSource(shader
->service_id(), 1, _
, NULL
))
827 .RetiresOnSaturation();
828 EXPECT_CALL(*gl
, CompileShader(shader
->service_id()))
830 .RetiresOnSaturation();
831 EXPECT_CALL(*gl
, GetShaderiv(shader
->service_id(),
833 NotNull())) // status
834 .WillOnce(SetArgumentPointee
<2>(GL_TRUE
))
835 .RetiresOnSaturation();
837 shader
->RequestCompile(translator
, Shader::kGL
);
842 void TestHelper::SetShaderStates(
843 ::gfx::MockGLInterface
* gl
, Shader
* shader
, bool valid
) {
844 SetShaderStates(gl
, shader
, valid
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
848 sh::Attribute
TestHelper::ConstructAttribute(
849 GLenum type
, GLint array_size
, GLenum precision
,
850 bool static_use
, const std::string
& name
) {
851 return ConstructShaderVariable
<sh::Attribute
>(
852 type
, array_size
, precision
, static_use
, name
);
856 sh::Uniform
TestHelper::ConstructUniform(
857 GLenum type
, GLint array_size
, GLenum precision
,
858 bool static_use
, const std::string
& name
) {
859 return ConstructShaderVariable
<sh::Uniform
>(
860 type
, array_size
, precision
, static_use
, name
);
864 sh::Varying
TestHelper::ConstructVarying(
865 GLenum type
, GLint array_size
, GLenum precision
,
866 bool static_use
, const std::string
& name
) {
867 return ConstructShaderVariable
<sh::Varying
>(
868 type
, array_size
, precision
, static_use
, name
);
871 ScopedGLImplementationSetter::ScopedGLImplementationSetter(
872 gfx::GLImplementation implementation
)
873 : old_implementation_(gfx::GetGLImplementation()) {
874 gfx::SetGLImplementation(implementation
);
877 ScopedGLImplementationSetter::~ScopedGLImplementationSetter() {
878 gfx::SetGLImplementation(old_implementation_
);