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::kNumVertexAttribs
;
73 const GLint
TestHelper::kNumTextureUnits
;
74 const GLint
TestHelper::kMaxTextureImageUnits
;
75 const GLint
TestHelper::kMaxVertexTextureImageUnits
;
76 const GLint
TestHelper::kMaxFragmentUniformVectors
;
77 const GLint
TestHelper::kMaxFragmentUniformComponents
;
78 const GLint
TestHelper::kMaxVaryingVectors
;
79 const GLint
TestHelper::kMaxVaryingFloats
;
80 const GLint
TestHelper::kMaxVertexUniformVectors
;
81 const GLint
TestHelper::kMaxVertexUniformComponents
;
84 std::vector
<std::string
> TestHelper::split_extensions_
;
86 void TestHelper::SetupTextureInitializationExpectations(
87 ::gfx::MockGLInterface
* gl
,
89 bool use_default_textures
) {
92 bool needs_initialization
= (target
!= GL_TEXTURE_EXTERNAL_OES
);
93 bool needs_faces
= (target
== GL_TEXTURE_CUBE_MAP
);
95 static GLuint texture_2d_ids
[] = {
96 kServiceBlackTexture2dId
,
97 kServiceDefaultTexture2dId
};
98 static GLuint texture_cube_map_ids
[] = {
99 kServiceBlackTextureCubemapId
,
100 kServiceDefaultTextureCubemapId
};
101 static GLuint texture_external_oes_ids
[] = {
102 kServiceBlackExternalTextureId
,
103 kServiceDefaultExternalTextureId
};
104 static GLuint texture_rectangle_arb_ids
[] = {
105 kServiceBlackRectangleTextureId
,
106 kServiceDefaultRectangleTextureId
};
108 const GLuint
* texture_ids
= NULL
;
111 texture_ids
= &texture_2d_ids
[0];
113 case GL_TEXTURE_CUBE_MAP
:
114 texture_ids
= &texture_cube_map_ids
[0];
116 case GL_TEXTURE_EXTERNAL_OES
:
117 texture_ids
= &texture_external_oes_ids
[0];
119 case GL_TEXTURE_RECTANGLE_ARB
:
120 texture_ids
= &texture_rectangle_arb_ids
[0];
126 int array_size
= use_default_textures
? 2 : 1;
128 EXPECT_CALL(*gl
, GenTextures(array_size
, _
))
129 .WillOnce(SetArrayArgument
<1>(texture_ids
,
130 texture_ids
+ array_size
))
131 .RetiresOnSaturation();
132 for (int ii
= 0; ii
< array_size
; ++ii
) {
133 EXPECT_CALL(*gl
, BindTexture(target
, texture_ids
[ii
]))
135 .RetiresOnSaturation();
136 if (needs_initialization
) {
138 static GLenum faces
[] = {
139 GL_TEXTURE_CUBE_MAP_POSITIVE_X
,
140 GL_TEXTURE_CUBE_MAP_NEGATIVE_X
,
141 GL_TEXTURE_CUBE_MAP_POSITIVE_Y
,
142 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
,
143 GL_TEXTURE_CUBE_MAP_POSITIVE_Z
,
144 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
,
146 for (size_t ii
= 0; ii
< arraysize(faces
); ++ii
) {
147 EXPECT_CALL(*gl
, TexImage2D(faces
[ii
], 0, GL_RGBA
, 1, 1, 0, GL_RGBA
,
148 GL_UNSIGNED_BYTE
, _
))
150 .RetiresOnSaturation();
153 EXPECT_CALL(*gl
, TexImage2D(target
, 0, GL_RGBA
, 1, 1, 0, GL_RGBA
,
154 GL_UNSIGNED_BYTE
, _
))
156 .RetiresOnSaturation();
160 EXPECT_CALL(*gl
, BindTexture(target
, 0))
162 .RetiresOnSaturation();
165 void TestHelper::SetupTextureManagerInitExpectations(
166 ::gfx::MockGLInterface
* gl
,
167 const char* extensions
,
168 bool use_default_textures
) {
171 SetupTextureInitializationExpectations(
172 gl
, GL_TEXTURE_2D
, use_default_textures
);
173 SetupTextureInitializationExpectations(
174 gl
, GL_TEXTURE_CUBE_MAP
, use_default_textures
);
176 bool ext_image_external
= false;
177 bool arb_texture_rectangle
= false;
178 base::CStringTokenizer
t(extensions
, extensions
+ strlen(extensions
), " ");
179 while (t
.GetNext()) {
180 if (t
.token() == "GL_OES_EGL_image_external") {
181 ext_image_external
= true;
184 if (t
.token() == "GL_ARB_texture_rectangle") {
185 arb_texture_rectangle
= true;
190 if (ext_image_external
) {
191 SetupTextureInitializationExpectations(
192 gl
, GL_TEXTURE_EXTERNAL_OES
, use_default_textures
);
194 if (arb_texture_rectangle
) {
195 SetupTextureInitializationExpectations(
196 gl
, GL_TEXTURE_RECTANGLE_ARB
, use_default_textures
);
200 void TestHelper::SetupTextureDestructionExpectations(
201 ::gfx::MockGLInterface
* gl
,
203 bool use_default_textures
) {
204 if (!use_default_textures
)
207 GLuint texture_id
= 0;
210 texture_id
= kServiceDefaultTexture2dId
;
212 case GL_TEXTURE_CUBE_MAP
:
213 texture_id
= kServiceDefaultTextureCubemapId
;
215 case GL_TEXTURE_EXTERNAL_OES
:
216 texture_id
= kServiceDefaultExternalTextureId
;
218 case GL_TEXTURE_RECTANGLE_ARB
:
219 texture_id
= kServiceDefaultRectangleTextureId
;
225 EXPECT_CALL(*gl
, DeleteTextures(1, Pointee(texture_id
)))
227 .RetiresOnSaturation();
230 void TestHelper::SetupTextureManagerDestructionExpectations(
231 ::gfx::MockGLInterface
* gl
,
232 const char* extensions
,
233 bool use_default_textures
) {
234 SetupTextureDestructionExpectations(gl
, GL_TEXTURE_2D
, use_default_textures
);
235 SetupTextureDestructionExpectations(
236 gl
, GL_TEXTURE_CUBE_MAP
, use_default_textures
);
238 bool ext_image_external
= false;
239 bool arb_texture_rectangle
= false;
240 base::CStringTokenizer
t(extensions
, extensions
+ strlen(extensions
), " ");
241 while (t
.GetNext()) {
242 if (t
.token() == "GL_OES_EGL_image_external") {
243 ext_image_external
= true;
246 if (t
.token() == "GL_ARB_texture_rectangle") {
247 arb_texture_rectangle
= true;
252 if (ext_image_external
) {
253 SetupTextureDestructionExpectations(
254 gl
, GL_TEXTURE_EXTERNAL_OES
, use_default_textures
);
256 if (arb_texture_rectangle
) {
257 SetupTextureDestructionExpectations(
258 gl
, GL_TEXTURE_RECTANGLE_ARB
, use_default_textures
);
261 EXPECT_CALL(*gl
, DeleteTextures(4, _
))
263 .RetiresOnSaturation();
266 void TestHelper::SetupContextGroupInitExpectations(
267 ::gfx::MockGLInterface
* gl
,
268 const DisallowedFeatures
& disallowed_features
,
269 const char* extensions
,
270 const char* gl_version
,
271 bool bind_generates_resource
) {
274 SetupFeatureInfoInitExpectationsWithGLVersion(gl
, extensions
, "", gl_version
);
276 gfx::GLVersionInfo
gl_info(gl_version
, "", extensions
);
278 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_RENDERBUFFER_SIZE
, _
))
279 .WillOnce(SetArgumentPointee
<1>(kMaxRenderbufferSize
))
280 .RetiresOnSaturation();
281 if (strstr(extensions
, "GL_EXT_framebuffer_multisample") ||
282 strstr(extensions
, "GL_EXT_multisampled_render_to_texture") ||
284 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_SAMPLES
, _
))
285 .WillOnce(SetArgumentPointee
<1>(kMaxSamples
))
286 .RetiresOnSaturation();
287 } else if (strstr(extensions
, "GL_IMG_multisampled_render_to_texture")) {
288 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_SAMPLES_IMG
, _
))
289 .WillOnce(SetArgumentPointee
<1>(kMaxSamples
))
290 .RetiresOnSaturation();
292 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_VERTEX_ATTRIBS
, _
))
293 .WillOnce(SetArgumentPointee
<1>(kNumVertexAttribs
))
294 .RetiresOnSaturation();
295 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
, _
))
296 .WillOnce(SetArgumentPointee
<1>(kNumTextureUnits
))
297 .RetiresOnSaturation();
298 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_TEXTURE_SIZE
, _
))
299 .WillOnce(SetArgumentPointee
<1>(kMaxTextureSize
))
300 .RetiresOnSaturation();
301 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE
, _
))
302 .WillOnce(SetArgumentPointee
<1>(kMaxCubeMapTextureSize
))
303 .RetiresOnSaturation();
304 if (strstr(extensions
, "GL_ARB_texture_rectangle")) {
305 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE
, _
))
306 .WillOnce(SetArgumentPointee
<1>(kMaxRectangleTextureSize
))
307 .RetiresOnSaturation();
309 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS
, _
))
310 .WillOnce(SetArgumentPointee
<1>(kMaxTextureImageUnits
))
311 .RetiresOnSaturation();
312 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS
, _
))
313 .WillOnce(SetArgumentPointee
<1>(kMaxVertexTextureImageUnits
))
314 .RetiresOnSaturation();
317 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS
, _
))
318 .WillOnce(SetArgumentPointee
<1>(kMaxFragmentUniformVectors
))
319 .RetiresOnSaturation();
320 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_VARYING_VECTORS
, _
))
321 .WillOnce(SetArgumentPointee
<1>(kMaxVaryingVectors
))
322 .RetiresOnSaturation();
323 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS
, _
))
324 .WillOnce(SetArgumentPointee
<1>(kMaxVertexUniformVectors
))
325 .RetiresOnSaturation();
327 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS
, _
))
328 .WillOnce(SetArgumentPointee
<1>(kMaxFragmentUniformComponents
))
329 .RetiresOnSaturation();
330 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_VARYING_FLOATS
, _
))
331 .WillOnce(SetArgumentPointee
<1>(kMaxVaryingFloats
))
332 .RetiresOnSaturation();
333 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS
, _
))
334 .WillOnce(SetArgumentPointee
<1>(kMaxVertexUniformComponents
))
335 .RetiresOnSaturation();
338 bool use_default_textures
= bind_generates_resource
;
339 SetupTextureManagerInitExpectations(gl
, extensions
, use_default_textures
);
342 void TestHelper::SetupFeatureInfoInitExpectations(
343 ::gfx::MockGLInterface
* gl
, const char* extensions
) {
344 SetupFeatureInfoInitExpectationsWithGLVersion(gl
, extensions
, "", "");
347 void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(
348 ::gfx::MockGLInterface
* gl
,
349 const char* extensions
,
350 const char* gl_renderer
,
351 const char* gl_version
) {
354 EXPECT_CALL(*gl
, GetString(GL_VERSION
))
355 .WillOnce(Return(reinterpret_cast<const uint8
*>(gl_version
)))
356 .RetiresOnSaturation();
358 // Persistent storage is needed for the split extension string.
359 split_extensions_
.clear();
361 Tokenize(extensions
, " ", &split_extensions_
);
364 gfx::GLVersionInfo
gl_info(gl_version
, gl_renderer
, extensions
);
365 if (!gl_info
.is_es
&& gl_info
.major_version
>= 3) {
366 EXPECT_CALL(*gl
, GetIntegerv(GL_NUM_EXTENSIONS
, _
))
367 .WillOnce(SetArgumentPointee
<1>(split_extensions_
.size()))
368 .RetiresOnSaturation();
369 for (size_t ii
= 0; ii
< split_extensions_
.size(); ++ii
) {
370 EXPECT_CALL(*gl
, GetStringi(GL_EXTENSIONS
, ii
))
371 .WillOnce(Return(reinterpret_cast<const uint8
*>(
372 split_extensions_
[ii
].c_str())))
373 .RetiresOnSaturation();
376 EXPECT_CALL(*gl
, GetString(GL_EXTENSIONS
))
377 .WillOnce(Return(reinterpret_cast<const uint8
*>(extensions
)))
378 .RetiresOnSaturation();
381 EXPECT_CALL(*gl
, GetString(GL_RENDERER
))
382 .WillOnce(Return(reinterpret_cast<const uint8
*>(gl_renderer
)))
383 .RetiresOnSaturation();
385 if (strstr(extensions
, "GL_ARB_texture_float") ||
386 (gl_info
.is_es3
&& strstr(extensions
, "GL_EXT_color_buffer_float"))) {
387 static const GLuint tx_ids
[] = {101, 102};
388 static const GLuint fb_ids
[] = {103, 104};
389 const GLsizei width
= 16;
390 EXPECT_CALL(*gl
, GetIntegerv(GL_FRAMEBUFFER_BINDING
, _
))
391 .WillOnce(SetArgumentPointee
<1>(fb_ids
[0]))
392 .RetiresOnSaturation();
393 EXPECT_CALL(*gl
, GetIntegerv(GL_TEXTURE_BINDING_2D
, _
))
394 .WillOnce(SetArgumentPointee
<1>(tx_ids
[0]))
395 .RetiresOnSaturation();
396 EXPECT_CALL(*gl
, GenTextures(1, _
))
397 .WillOnce(SetArrayArgument
<1>(tx_ids
+ 1, tx_ids
+ 2))
398 .RetiresOnSaturation();
399 EXPECT_CALL(*gl
, GenFramebuffersEXT(1, _
))
400 .WillOnce(SetArrayArgument
<1>(fb_ids
+ 1, fb_ids
+ 2))
401 .RetiresOnSaturation();
402 EXPECT_CALL(*gl
, BindTexture(GL_TEXTURE_2D
, tx_ids
[1]))
404 .RetiresOnSaturation();
405 EXPECT_CALL(*gl
, TexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
,
408 .RetiresOnSaturation();
409 EXPECT_CALL(*gl
, TexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA32F
, width
, width
, 0,
410 GL_RGBA
, GL_FLOAT
, _
))
412 .RetiresOnSaturation();
413 EXPECT_CALL(*gl
, BindFramebufferEXT(GL_FRAMEBUFFER
, fb_ids
[1]))
415 .RetiresOnSaturation();
416 EXPECT_CALL(*gl
, FramebufferTexture2DEXT(GL_FRAMEBUFFER
,
417 GL_COLOR_ATTACHMENT0
, GL_TEXTURE_2D
, tx_ids
[1], 0))
419 .RetiresOnSaturation();
420 EXPECT_CALL(*gl
, CheckFramebufferStatusEXT(GL_FRAMEBUFFER
))
421 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE
))
422 .RetiresOnSaturation();
423 EXPECT_CALL(*gl
, TexImage2D(GL_TEXTURE_2D
, 0, GL_RGB32F
, width
, width
, 0,
424 GL_RGB
, GL_FLOAT
, _
))
426 .RetiresOnSaturation();
427 if (gl_info
.is_es3
) {
428 EXPECT_CALL(*gl
, CheckFramebufferStatusEXT(GL_FRAMEBUFFER
))
429 .WillOnce(Return(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
))
430 .RetiresOnSaturation();
432 EXPECT_CALL(*gl
, CheckFramebufferStatusEXT(GL_FRAMEBUFFER
))
433 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE
))
434 .RetiresOnSaturation();
436 EXPECT_CALL(*gl
, DeleteFramebuffersEXT(1, _
))
438 .RetiresOnSaturation();
439 EXPECT_CALL(*gl
, DeleteTextures(1, _
))
441 .RetiresOnSaturation();
442 EXPECT_CALL(*gl
, BindFramebufferEXT(GL_FRAMEBUFFER
, fb_ids
[0]))
444 .RetiresOnSaturation();
445 EXPECT_CALL(*gl
, BindTexture(GL_TEXTURE_2D
, tx_ids
[0]))
447 .RetiresOnSaturation();
449 EXPECT_CALL(*gl
, GetError())
450 .WillOnce(Return(GL_NO_ERROR
))
451 .RetiresOnSaturation();
455 if (strstr(extensions
, "GL_EXT_draw_buffers") ||
456 strstr(extensions
, "GL_ARB_draw_buffers") ||
457 (gl_info
.is_es3
&& strstr(extensions
, "GL_NV_draw_buffers"))) {
458 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT
, _
))
459 .WillOnce(SetArgumentPointee
<1>(8))
460 .RetiresOnSaturation();
461 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_DRAW_BUFFERS_ARB
, _
))
462 .WillOnce(SetArgumentPointee
<1>(8))
463 .RetiresOnSaturation();
466 if (gl_info
.is_es3
|| strstr(extensions
, "GL_EXT_texture_rg") ||
467 (strstr(extensions
, "GL_ARB_texture_rg"))) {
468 static const GLuint tx_ids
[] = {101, 102};
469 static const GLuint fb_ids
[] = {103, 104};
470 const GLsizei width
= 1;
471 EXPECT_CALL(*gl
, GetIntegerv(GL_FRAMEBUFFER_BINDING
, _
))
472 .WillOnce(SetArgumentPointee
<1>(fb_ids
[0]))
473 .RetiresOnSaturation();
474 EXPECT_CALL(*gl
, GetIntegerv(GL_TEXTURE_BINDING_2D
, _
))
475 .WillOnce(SetArgumentPointee
<1>(tx_ids
[0]))
476 .RetiresOnSaturation();
477 EXPECT_CALL(*gl
, GenTextures(1, _
))
478 .WillOnce(SetArrayArgument
<1>(tx_ids
+ 1, tx_ids
+ 2))
479 .RetiresOnSaturation();
480 EXPECT_CALL(*gl
, BindTexture(GL_TEXTURE_2D
, tx_ids
[1]))
482 .RetiresOnSaturation();
483 EXPECT_CALL(*gl
, TexImage2D(GL_TEXTURE_2D
, 0, _
, width
, width
, 0,
484 GL_RED_EXT
, GL_UNSIGNED_BYTE
, _
))
486 .RetiresOnSaturation();
487 EXPECT_CALL(*gl
, GenFramebuffersEXT(1, _
))
488 .WillOnce(SetArrayArgument
<1>(fb_ids
+ 1, fb_ids
+ 2))
489 .RetiresOnSaturation();
490 EXPECT_CALL(*gl
, BindFramebufferEXT(GL_FRAMEBUFFER
, fb_ids
[1]))
492 .RetiresOnSaturation();
493 EXPECT_CALL(*gl
, FramebufferTexture2DEXT(GL_FRAMEBUFFER
,
494 GL_COLOR_ATTACHMENT0
, GL_TEXTURE_2D
, tx_ids
[1], 0))
496 .RetiresOnSaturation();
497 EXPECT_CALL(*gl
, CheckFramebufferStatusEXT(GL_FRAMEBUFFER
))
498 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE
))
499 .RetiresOnSaturation();
500 EXPECT_CALL(*gl
, DeleteFramebuffersEXT(1, _
))
502 .RetiresOnSaturation();
503 EXPECT_CALL(*gl
, DeleteTextures(1, _
))
505 .RetiresOnSaturation();
506 EXPECT_CALL(*gl
, BindFramebufferEXT(GL_FRAMEBUFFER
, fb_ids
[0]))
508 .RetiresOnSaturation();
509 EXPECT_CALL(*gl
, BindTexture(GL_TEXTURE_2D
, tx_ids
[0]))
511 .RetiresOnSaturation();
513 EXPECT_CALL(*gl
, GetError())
514 .WillOnce(Return(GL_NO_ERROR
))
515 .RetiresOnSaturation();
520 void TestHelper::SetupExpectationsForClearingUniforms(
521 ::gfx::MockGLInterface
* gl
, UniformInfo
* uniforms
, size_t num_uniforms
) {
522 for (size_t ii
= 0; ii
< num_uniforms
; ++ii
) {
523 const UniformInfo
& info
= uniforms
[ii
];
526 EXPECT_CALL(*gl
, Uniform1fv(info
.real_location
, info
.size
, _
))
528 .RetiresOnSaturation();
531 EXPECT_CALL(*gl
, Uniform2fv(info
.real_location
, info
.size
, _
))
533 .RetiresOnSaturation();
536 EXPECT_CALL(*gl
, Uniform3fv(info
.real_location
, info
.size
, _
))
538 .RetiresOnSaturation();
541 EXPECT_CALL(*gl
, Uniform4fv(info
.real_location
, info
.size
, _
))
543 .RetiresOnSaturation();
548 case GL_SAMPLER_CUBE
:
549 case GL_SAMPLER_EXTERNAL_OES
:
550 case GL_SAMPLER_3D_OES
:
551 case GL_SAMPLER_2D_RECT_ARB
:
552 EXPECT_CALL(*gl
, Uniform1iv(info
.real_location
, info
.size
, _
))
554 .RetiresOnSaturation();
558 EXPECT_CALL(*gl
, Uniform2iv(info
.real_location
, info
.size
, _
))
560 .RetiresOnSaturation();
564 EXPECT_CALL(*gl
, Uniform3iv(info
.real_location
, info
.size
, _
))
566 .RetiresOnSaturation();
570 EXPECT_CALL(*gl
, Uniform4iv(info
.real_location
, info
.size
, _
))
572 .RetiresOnSaturation();
575 EXPECT_CALL(*gl
, UniformMatrix2fv(
576 info
.real_location
, info
.size
, false, _
))
578 .RetiresOnSaturation();
581 EXPECT_CALL(*gl
, UniformMatrix3fv(
582 info
.real_location
, info
.size
, false, _
))
584 .RetiresOnSaturation();
587 EXPECT_CALL(*gl
, UniformMatrix4fv(
588 info
.real_location
, info
.size
, false, _
))
590 .RetiresOnSaturation();
599 void TestHelper::SetupProgramSuccessExpectations(
600 ::gfx::MockGLInterface
* gl
,
601 AttribInfo
* attribs
, size_t num_attribs
,
602 UniformInfo
* uniforms
, size_t num_uniforms
,
605 GetProgramiv(service_id
, GL_LINK_STATUS
, _
))
606 .WillOnce(SetArgumentPointee
<2>(1))
607 .RetiresOnSaturation();
609 GetProgramiv(service_id
, GL_INFO_LOG_LENGTH
, _
))
610 .WillOnce(SetArgumentPointee
<2>(0))
611 .RetiresOnSaturation();
613 GetProgramiv(service_id
, GL_ACTIVE_ATTRIBUTES
, _
))
614 .WillOnce(SetArgumentPointee
<2>(num_attribs
))
615 .RetiresOnSaturation();
616 size_t max_attrib_len
= 0;
617 for (size_t ii
= 0; ii
< num_attribs
; ++ii
) {
618 size_t len
= strlen(attribs
[ii
].name
) + 1;
619 max_attrib_len
= std::max(max_attrib_len
, len
);
622 GetProgramiv(service_id
, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
, _
))
623 .WillOnce(SetArgumentPointee
<2>(max_attrib_len
))
624 .RetiresOnSaturation();
626 for (size_t ii
= 0; ii
< num_attribs
; ++ii
) {
627 const AttribInfo
& info
= attribs
[ii
];
629 GetActiveAttrib(service_id
, ii
,
630 max_attrib_len
, _
, _
, _
, _
))
632 SetArgumentPointee
<3>(strlen(info
.name
)),
633 SetArgumentPointee
<4>(info
.size
),
634 SetArgumentPointee
<5>(info
.type
),
635 SetArrayArgument
<6>(info
.name
,
636 info
.name
+ strlen(info
.name
) + 1)))
637 .RetiresOnSaturation();
638 if (!ProgramManager::IsInvalidPrefix(info
.name
, strlen(info
.name
))) {
639 EXPECT_CALL(*gl
, GetAttribLocation(service_id
, StrEq(info
.name
)))
640 .WillOnce(Return(info
.location
))
641 .RetiresOnSaturation();
645 GetProgramiv(service_id
, GL_ACTIVE_UNIFORMS
, _
))
646 .WillOnce(SetArgumentPointee
<2>(num_uniforms
))
647 .RetiresOnSaturation();
649 size_t max_uniform_len
= 0;
650 for (size_t ii
= 0; ii
< num_uniforms
; ++ii
) {
651 size_t len
= strlen(uniforms
[ii
].name
) + 1;
652 max_uniform_len
= std::max(max_uniform_len
, len
);
655 GetProgramiv(service_id
, GL_ACTIVE_UNIFORM_MAX_LENGTH
, _
))
656 .WillOnce(SetArgumentPointee
<2>(max_uniform_len
))
657 .RetiresOnSaturation();
658 for (size_t ii
= 0; ii
< num_uniforms
; ++ii
) {
659 const UniformInfo
& info
= uniforms
[ii
];
661 GetActiveUniform(service_id
, ii
,
662 max_uniform_len
, _
, _
, _
, _
))
664 SetArgumentPointee
<3>(strlen(info
.name
)),
665 SetArgumentPointee
<4>(info
.size
),
666 SetArgumentPointee
<5>(info
.type
),
667 SetArrayArgument
<6>(info
.name
,
668 info
.name
+ strlen(info
.name
) + 1)))
669 .RetiresOnSaturation();
672 for (int pass
= 0; pass
< 2; ++pass
) {
673 for (size_t ii
= 0; ii
< num_uniforms
; ++ii
) {
674 const UniformInfo
& info
= uniforms
[ii
];
675 if (ProgramManager::IsInvalidPrefix(info
.name
, strlen(info
.name
))) {
679 EXPECT_CALL(*gl
, GetUniformLocation(service_id
, StrEq(info
.name
)))
680 .WillOnce(Return(info
.real_location
))
681 .RetiresOnSaturation();
683 if ((pass
== 0 && info
.desired_location
>= 0) ||
684 (pass
== 1 && info
.desired_location
< 0)) {
686 std::string base_name
= info
.name
;
687 size_t array_pos
= base_name
.rfind("[0]");
688 if (base_name
.size() > 3 && array_pos
== base_name
.size() - 3) {
689 base_name
= base_name
.substr(0, base_name
.size() - 3);
691 for (GLsizei jj
= 1; jj
< info
.size
; ++jj
) {
692 std::string
element_name(
693 std::string(base_name
) + "[" + base::IntToString(jj
) + "]");
694 EXPECT_CALL(*gl
, GetUniformLocation(
695 service_id
, StrEq(element_name
)))
696 .WillOnce(Return(info
.real_location
+ jj
* 2))
697 .RetiresOnSaturation();
705 void TestHelper::SetupShader(
706 ::gfx::MockGLInterface
* gl
,
707 AttribInfo
* attribs
, size_t num_attribs
,
708 UniformInfo
* uniforms
, size_t num_uniforms
,
713 LinkProgram(service_id
))
715 .RetiresOnSaturation();
717 SetupProgramSuccessExpectations(
718 gl
, attribs
, num_attribs
, uniforms
, num_uniforms
, service_id
);
721 void TestHelper::DoBufferData(
722 ::gfx::MockGLInterface
* gl
, MockErrorState
* error_state
,
723 BufferManager
* manager
, Buffer
* buffer
, GLsizeiptr size
, GLenum usage
,
724 const GLvoid
* data
, GLenum error
) {
725 EXPECT_CALL(*error_state
, CopyRealGLErrorsToWrapper(_
, _
, _
))
727 .RetiresOnSaturation();
728 if (manager
->IsUsageClientSideArray(usage
)) {
729 EXPECT_CALL(*gl
, BufferData(
730 buffer
->target(), 0, _
, usage
))
732 .RetiresOnSaturation();
734 EXPECT_CALL(*gl
, BufferData(
735 buffer
->target(), size
, _
, usage
))
737 .RetiresOnSaturation();
739 EXPECT_CALL(*error_state
, PeekGLError(_
, _
, _
))
740 .WillOnce(Return(error
))
741 .RetiresOnSaturation();
742 manager
->DoBufferData(error_state
, buffer
, size
, usage
, data
);
745 void TestHelper::SetTexParameteriWithExpectations(
746 ::gfx::MockGLInterface
* gl
, MockErrorState
* error_state
,
747 TextureManager
* manager
, TextureRef
* texture_ref
,
748 GLenum pname
, GLint value
, GLenum error
) {
749 if (error
== GL_NO_ERROR
) {
750 if (pname
!= GL_TEXTURE_POOL_CHROMIUM
) {
751 EXPECT_CALL(*gl
, TexParameteri(texture_ref
->texture()->target(),
754 .RetiresOnSaturation();
756 } else if (error
== GL_INVALID_ENUM
) {
757 EXPECT_CALL(*error_state
, SetGLErrorInvalidEnum(_
, _
, _
, value
, _
))
759 .RetiresOnSaturation();
761 EXPECT_CALL(*error_state
, SetGLErrorInvalidParami(_
, _
, error
, _
, _
, _
))
763 .RetiresOnSaturation();
765 manager
->SetParameteri("", error_state
, texture_ref
, pname
, value
);
769 void TestHelper::SetShaderStates(
770 ::gfx::MockGLInterface
* gl
, Shader
* shader
,
772 const std::string
* const expected_log_info
,
773 const std::string
* const expected_translated_source
,
774 const AttributeMap
* const expected_attrib_map
,
775 const UniformMap
* const expected_uniform_map
,
776 const VaryingMap
* const expected_varying_map
,
777 const NameMap
* const expected_name_map
) {
778 const std::string empty_log_info
;
779 const std::string
* log_info
= (expected_log_info
&& !expected_valid
) ?
780 expected_log_info
: &empty_log_info
;
781 const std::string empty_translated_source
;
782 const std::string
* translated_source
=
783 (expected_translated_source
&& expected_valid
) ?
784 expected_translated_source
: &empty_translated_source
;
785 const AttributeMap empty_attrib_map
;
786 const AttributeMap
* attrib_map
= (expected_attrib_map
&& expected_valid
) ?
787 expected_attrib_map
: &empty_attrib_map
;
788 const UniformMap empty_uniform_map
;
789 const UniformMap
* uniform_map
= (expected_uniform_map
&& expected_valid
) ?
790 expected_uniform_map
: &empty_uniform_map
;
791 const VaryingMap empty_varying_map
;
792 const VaryingMap
* varying_map
= (expected_varying_map
&& expected_valid
) ?
793 expected_varying_map
: &empty_varying_map
;
794 const NameMap empty_name_map
;
795 const NameMap
* name_map
= (expected_name_map
&& expected_valid
) ?
796 expected_name_map
: &empty_name_map
;
798 MockShaderTranslator
* mock_translator
= new MockShaderTranslator
;
799 scoped_refptr
<ShaderTranslatorInterface
> translator(mock_translator
);
800 EXPECT_CALL(*mock_translator
, Translate(_
,
801 NotNull(), // log_info
802 NotNull(), // translated_source
803 NotNull(), // attrib_map
804 NotNull(), // uniform_map
805 NotNull(), // varying_map
806 NotNull())) // name_map
807 .WillOnce(DoAll(SetArgumentPointee
<1>(*log_info
),
808 SetArgumentPointee
<2>(*translated_source
),
809 SetArgumentPointee
<3>(*attrib_map
),
810 SetArgumentPointee
<4>(*uniform_map
),
811 SetArgumentPointee
<5>(*varying_map
),
812 SetArgumentPointee
<6>(*name_map
),
813 Return(expected_valid
)))
814 .RetiresOnSaturation();
815 if (expected_valid
) {
816 EXPECT_CALL(*gl
, ShaderSource(shader
->service_id(), 1, _
, NULL
))
818 .RetiresOnSaturation();
819 EXPECT_CALL(*gl
, CompileShader(shader
->service_id()))
821 .RetiresOnSaturation();
822 EXPECT_CALL(*gl
, GetShaderiv(shader
->service_id(),
824 NotNull())) // status
825 .WillOnce(SetArgumentPointee
<2>(GL_TRUE
))
826 .RetiresOnSaturation();
828 shader
->RequestCompile(translator
, Shader::kGL
);
833 void TestHelper::SetShaderStates(
834 ::gfx::MockGLInterface
* gl
, Shader
* shader
, bool valid
) {
835 SetShaderStates(gl
, shader
, valid
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
839 sh::Attribute
TestHelper::ConstructAttribute(
840 GLenum type
, GLint array_size
, GLenum precision
,
841 bool static_use
, const std::string
& name
) {
842 return ConstructShaderVariable
<sh::Attribute
>(
843 type
, array_size
, precision
, static_use
, name
);
847 sh::Uniform
TestHelper::ConstructUniform(
848 GLenum type
, GLint array_size
, GLenum precision
,
849 bool static_use
, const std::string
& name
) {
850 return ConstructShaderVariable
<sh::Uniform
>(
851 type
, array_size
, precision
, static_use
, name
);
855 sh::Varying
TestHelper::ConstructVarying(
856 GLenum type
, GLint array_size
, GLenum precision
,
857 bool static_use
, const std::string
& name
) {
858 return ConstructShaderVariable
<sh::Varying
>(
859 type
, array_size
, precision
, static_use
, name
);
862 ScopedGLImplementationSetter::ScopedGLImplementationSetter(
863 gfx::GLImplementation implementation
)
864 : old_implementation_(gfx::GetGLImplementation()) {
865 gfx::SetGLImplementation(implementation
);
868 ScopedGLImplementationSetter::~ScopedGLImplementationSetter() {
869 gfx::SetGLImplementation(old_implementation_
);