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_VERSION
))
390 .WillOnce(Return(reinterpret_cast<const uint8
*>(gl_version
)))
391 .RetiresOnSaturation();
392 EXPECT_CALL(*gl
, GetString(GL_RENDERER
))
393 .WillOnce(Return(reinterpret_cast<const uint8
*>(gl_renderer
)))
394 .RetiresOnSaturation();
396 if (strstr(extensions
, "GL_ARB_texture_float") ||
397 (gl_info
.is_es3
&& strstr(extensions
, "GL_EXT_color_buffer_float"))) {
398 static const GLuint tx_ids
[] = {101, 102};
399 static const GLuint fb_ids
[] = {103, 104};
400 const GLsizei width
= 16;
401 EXPECT_CALL(*gl
, GetIntegerv(GL_FRAMEBUFFER_BINDING
, _
))
402 .WillOnce(SetArgumentPointee
<1>(fb_ids
[0]))
403 .RetiresOnSaturation();
404 EXPECT_CALL(*gl
, GetIntegerv(GL_TEXTURE_BINDING_2D
, _
))
405 .WillOnce(SetArgumentPointee
<1>(tx_ids
[0]))
406 .RetiresOnSaturation();
407 EXPECT_CALL(*gl
, GenTextures(1, _
))
408 .WillOnce(SetArrayArgument
<1>(tx_ids
+ 1, tx_ids
+ 2))
409 .RetiresOnSaturation();
410 EXPECT_CALL(*gl
, GenFramebuffersEXT(1, _
))
411 .WillOnce(SetArrayArgument
<1>(fb_ids
+ 1, fb_ids
+ 2))
412 .RetiresOnSaturation();
413 EXPECT_CALL(*gl
, BindTexture(GL_TEXTURE_2D
, tx_ids
[1]))
415 .RetiresOnSaturation();
416 EXPECT_CALL(*gl
, TexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
,
419 .RetiresOnSaturation();
420 EXPECT_CALL(*gl
, TexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA32F
, width
, width
, 0,
421 GL_RGBA
, GL_FLOAT
, _
))
423 .RetiresOnSaturation();
424 EXPECT_CALL(*gl
, BindFramebufferEXT(GL_FRAMEBUFFER
, fb_ids
[1]))
426 .RetiresOnSaturation();
427 EXPECT_CALL(*gl
, FramebufferTexture2DEXT(GL_FRAMEBUFFER
,
428 GL_COLOR_ATTACHMENT0
, GL_TEXTURE_2D
, tx_ids
[1], 0))
430 .RetiresOnSaturation();
431 EXPECT_CALL(*gl
, CheckFramebufferStatusEXT(GL_FRAMEBUFFER
))
432 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE
))
433 .RetiresOnSaturation();
434 EXPECT_CALL(*gl
, TexImage2D(GL_TEXTURE_2D
, 0, GL_RGB32F
, width
, width
, 0,
435 GL_RGB
, GL_FLOAT
, _
))
437 .RetiresOnSaturation();
438 if (gl_info
.is_es3
) {
439 EXPECT_CALL(*gl
, CheckFramebufferStatusEXT(GL_FRAMEBUFFER
))
440 .WillOnce(Return(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
))
441 .RetiresOnSaturation();
443 EXPECT_CALL(*gl
, CheckFramebufferStatusEXT(GL_FRAMEBUFFER
))
444 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE
))
445 .RetiresOnSaturation();
447 EXPECT_CALL(*gl
, DeleteFramebuffersEXT(1, _
))
449 .RetiresOnSaturation();
450 EXPECT_CALL(*gl
, DeleteTextures(1, _
))
452 .RetiresOnSaturation();
453 EXPECT_CALL(*gl
, BindFramebufferEXT(GL_FRAMEBUFFER
, fb_ids
[0]))
455 .RetiresOnSaturation();
456 EXPECT_CALL(*gl
, BindTexture(GL_TEXTURE_2D
, tx_ids
[0]))
458 .RetiresOnSaturation();
460 EXPECT_CALL(*gl
, GetError())
461 .WillOnce(Return(GL_NO_ERROR
))
462 .RetiresOnSaturation();
466 if (strstr(extensions
, "GL_EXT_draw_buffers") ||
467 strstr(extensions
, "GL_ARB_draw_buffers") ||
468 (gl_info
.is_es3
&& strstr(extensions
, "GL_NV_draw_buffers"))) {
469 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT
, _
))
470 .WillOnce(SetArgumentPointee
<1>(8))
471 .RetiresOnSaturation();
472 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_DRAW_BUFFERS_ARB
, _
))
473 .WillOnce(SetArgumentPointee
<1>(8))
474 .RetiresOnSaturation();
477 if (gl_info
.is_es3
|| strstr(extensions
, "GL_EXT_texture_rg") ||
478 (strstr(extensions
, "GL_ARB_texture_rg"))) {
479 static const GLuint tx_ids
[] = {101, 102};
480 static const GLuint fb_ids
[] = {103, 104};
481 const GLsizei width
= 1;
482 EXPECT_CALL(*gl
, GetIntegerv(GL_FRAMEBUFFER_BINDING
, _
))
483 .WillOnce(SetArgumentPointee
<1>(fb_ids
[0]))
484 .RetiresOnSaturation();
485 EXPECT_CALL(*gl
, GetIntegerv(GL_TEXTURE_BINDING_2D
, _
))
486 .WillOnce(SetArgumentPointee
<1>(tx_ids
[0]))
487 .RetiresOnSaturation();
488 EXPECT_CALL(*gl
, GenTextures(1, _
))
489 .WillOnce(SetArrayArgument
<1>(tx_ids
+ 1, tx_ids
+ 2))
490 .RetiresOnSaturation();
491 EXPECT_CALL(*gl
, BindTexture(GL_TEXTURE_2D
, tx_ids
[1]))
493 .RetiresOnSaturation();
494 EXPECT_CALL(*gl
, TexImage2D(GL_TEXTURE_2D
, 0, _
, width
, width
, 0,
495 GL_RED_EXT
, GL_UNSIGNED_BYTE
, _
))
497 .RetiresOnSaturation();
498 EXPECT_CALL(*gl
, GenFramebuffersEXT(1, _
))
499 .WillOnce(SetArrayArgument
<1>(fb_ids
+ 1, fb_ids
+ 2))
500 .RetiresOnSaturation();
501 EXPECT_CALL(*gl
, BindFramebufferEXT(GL_FRAMEBUFFER
, fb_ids
[1]))
503 .RetiresOnSaturation();
504 EXPECT_CALL(*gl
, FramebufferTexture2DEXT(GL_FRAMEBUFFER
,
505 GL_COLOR_ATTACHMENT0
, GL_TEXTURE_2D
, tx_ids
[1], 0))
507 .RetiresOnSaturation();
508 EXPECT_CALL(*gl
, CheckFramebufferStatusEXT(GL_FRAMEBUFFER
))
509 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE
))
510 .RetiresOnSaturation();
511 EXPECT_CALL(*gl
, DeleteFramebuffersEXT(1, _
))
513 .RetiresOnSaturation();
514 EXPECT_CALL(*gl
, DeleteTextures(1, _
))
516 .RetiresOnSaturation();
517 EXPECT_CALL(*gl
, BindFramebufferEXT(GL_FRAMEBUFFER
, fb_ids
[0]))
519 .RetiresOnSaturation();
520 EXPECT_CALL(*gl
, BindTexture(GL_TEXTURE_2D
, tx_ids
[0]))
522 .RetiresOnSaturation();
524 EXPECT_CALL(*gl
, GetError())
525 .WillOnce(Return(GL_NO_ERROR
))
526 .RetiresOnSaturation();
531 void TestHelper::SetupExpectationsForClearingUniforms(
532 ::gfx::MockGLInterface
* gl
, UniformInfo
* uniforms
, size_t num_uniforms
) {
533 for (size_t ii
= 0; ii
< num_uniforms
; ++ii
) {
534 const UniformInfo
& info
= uniforms
[ii
];
537 EXPECT_CALL(*gl
, Uniform1fv(info
.real_location
, info
.size
, _
))
539 .RetiresOnSaturation();
542 EXPECT_CALL(*gl
, Uniform2fv(info
.real_location
, info
.size
, _
))
544 .RetiresOnSaturation();
547 EXPECT_CALL(*gl
, Uniform3fv(info
.real_location
, info
.size
, _
))
549 .RetiresOnSaturation();
552 EXPECT_CALL(*gl
, Uniform4fv(info
.real_location
, info
.size
, _
))
554 .RetiresOnSaturation();
559 case GL_SAMPLER_CUBE
:
560 case GL_SAMPLER_EXTERNAL_OES
:
561 case GL_SAMPLER_3D_OES
:
562 case GL_SAMPLER_2D_RECT_ARB
:
563 EXPECT_CALL(*gl
, Uniform1iv(info
.real_location
, info
.size
, _
))
565 .RetiresOnSaturation();
569 EXPECT_CALL(*gl
, Uniform2iv(info
.real_location
, info
.size
, _
))
571 .RetiresOnSaturation();
575 EXPECT_CALL(*gl
, Uniform3iv(info
.real_location
, info
.size
, _
))
577 .RetiresOnSaturation();
581 EXPECT_CALL(*gl
, Uniform4iv(info
.real_location
, info
.size
, _
))
583 .RetiresOnSaturation();
586 EXPECT_CALL(*gl
, UniformMatrix2fv(
587 info
.real_location
, info
.size
, false, _
))
589 .RetiresOnSaturation();
592 EXPECT_CALL(*gl
, UniformMatrix3fv(
593 info
.real_location
, info
.size
, false, _
))
595 .RetiresOnSaturation();
598 EXPECT_CALL(*gl
, UniformMatrix4fv(
599 info
.real_location
, info
.size
, false, _
))
601 .RetiresOnSaturation();
610 void TestHelper::SetupProgramSuccessExpectations(
611 ::gfx::MockGLInterface
* gl
,
612 AttribInfo
* attribs
, size_t num_attribs
,
613 UniformInfo
* uniforms
, size_t num_uniforms
,
616 GetProgramiv(service_id
, GL_LINK_STATUS
, _
))
617 .WillOnce(SetArgumentPointee
<2>(1))
618 .RetiresOnSaturation();
620 GetProgramiv(service_id
, GL_INFO_LOG_LENGTH
, _
))
621 .WillOnce(SetArgumentPointee
<2>(0))
622 .RetiresOnSaturation();
624 GetProgramiv(service_id
, GL_ACTIVE_ATTRIBUTES
, _
))
625 .WillOnce(SetArgumentPointee
<2>(num_attribs
))
626 .RetiresOnSaturation();
627 size_t max_attrib_len
= 0;
628 for (size_t ii
= 0; ii
< num_attribs
; ++ii
) {
629 size_t len
= strlen(attribs
[ii
].name
) + 1;
630 max_attrib_len
= std::max(max_attrib_len
, len
);
633 GetProgramiv(service_id
, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
, _
))
634 .WillOnce(SetArgumentPointee
<2>(max_attrib_len
))
635 .RetiresOnSaturation();
637 for (size_t ii
= 0; ii
< num_attribs
; ++ii
) {
638 const AttribInfo
& info
= attribs
[ii
];
640 GetActiveAttrib(service_id
, ii
,
641 max_attrib_len
, _
, _
, _
, _
))
643 SetArgumentPointee
<3>(strlen(info
.name
)),
644 SetArgumentPointee
<4>(info
.size
),
645 SetArgumentPointee
<5>(info
.type
),
646 SetArrayArgument
<6>(info
.name
,
647 info
.name
+ strlen(info
.name
) + 1)))
648 .RetiresOnSaturation();
649 if (!ProgramManager::IsInvalidPrefix(info
.name
, strlen(info
.name
))) {
650 EXPECT_CALL(*gl
, GetAttribLocation(service_id
, StrEq(info
.name
)))
651 .WillOnce(Return(info
.location
))
652 .RetiresOnSaturation();
656 GetProgramiv(service_id
, GL_ACTIVE_UNIFORMS
, _
))
657 .WillOnce(SetArgumentPointee
<2>(num_uniforms
))
658 .RetiresOnSaturation();
660 size_t max_uniform_len
= 0;
661 for (size_t ii
= 0; ii
< num_uniforms
; ++ii
) {
662 size_t len
= strlen(uniforms
[ii
].name
) + 1;
663 max_uniform_len
= std::max(max_uniform_len
, len
);
666 GetProgramiv(service_id
, GL_ACTIVE_UNIFORM_MAX_LENGTH
, _
))
667 .WillOnce(SetArgumentPointee
<2>(max_uniform_len
))
668 .RetiresOnSaturation();
669 for (size_t ii
= 0; ii
< num_uniforms
; ++ii
) {
670 const UniformInfo
& info
= uniforms
[ii
];
672 GetActiveUniform(service_id
, ii
,
673 max_uniform_len
, _
, _
, _
, _
))
675 SetArgumentPointee
<3>(strlen(info
.name
)),
676 SetArgumentPointee
<4>(info
.size
),
677 SetArgumentPointee
<5>(info
.type
),
678 SetArrayArgument
<6>(info
.name
,
679 info
.name
+ strlen(info
.name
) + 1)))
680 .RetiresOnSaturation();
683 for (int pass
= 0; pass
< 2; ++pass
) {
684 for (size_t ii
= 0; ii
< num_uniforms
; ++ii
) {
685 const UniformInfo
& info
= uniforms
[ii
];
686 if (pass
== 0 && info
.real_location
!= -1) {
687 EXPECT_CALL(*gl
, GetUniformLocation(service_id
, StrEq(info
.name
)))
688 .WillOnce(Return(info
.real_location
))
689 .RetiresOnSaturation();
691 if ((pass
== 0 && info
.desired_location
>= 0) ||
692 (pass
== 1 && info
.desired_location
< 0)) {
694 std::string base_name
= info
.name
;
695 size_t array_pos
= base_name
.rfind("[0]");
696 if (base_name
.size() > 3 && array_pos
== base_name
.size() - 3) {
697 base_name
= base_name
.substr(0, base_name
.size() - 3);
699 for (GLsizei jj
= 1; jj
< info
.size
; ++jj
) {
700 std::string
element_name(
701 std::string(base_name
) + "[" + base::IntToString(jj
) + "]");
702 EXPECT_CALL(*gl
, GetUniformLocation(
703 service_id
, StrEq(element_name
)))
704 .WillOnce(Return(info
.real_location
+ jj
* 2))
705 .RetiresOnSaturation();
713 void TestHelper::SetupShader(
714 ::gfx::MockGLInterface
* gl
,
715 AttribInfo
* attribs
, size_t num_attribs
,
716 UniformInfo
* uniforms
, size_t num_uniforms
,
721 LinkProgram(service_id
))
723 .RetiresOnSaturation();
725 SetupProgramSuccessExpectations(
726 gl
, attribs
, num_attribs
, uniforms
, num_uniforms
, service_id
);
729 void TestHelper::DoBufferData(
730 ::gfx::MockGLInterface
* gl
, MockErrorState
* error_state
,
731 BufferManager
* manager
, Buffer
* buffer
, GLenum target
, GLsizeiptr size
,
732 GLenum usage
, const GLvoid
* data
, GLenum error
) {
733 EXPECT_CALL(*error_state
, CopyRealGLErrorsToWrapper(_
, _
, _
))
735 .RetiresOnSaturation();
736 if (manager
->IsUsageClientSideArray(usage
)) {
737 EXPECT_CALL(*gl
, BufferData(target
, 0, _
, usage
))
739 .RetiresOnSaturation();
741 EXPECT_CALL(*gl
, BufferData(target
, size
, _
, usage
))
743 .RetiresOnSaturation();
745 EXPECT_CALL(*error_state
, PeekGLError(_
, _
, _
))
746 .WillOnce(Return(error
))
747 .RetiresOnSaturation();
748 manager
->DoBufferData(error_state
, buffer
, target
, size
, usage
, data
);
751 void TestHelper::SetTexParameteriWithExpectations(
752 ::gfx::MockGLInterface
* gl
, MockErrorState
* error_state
,
753 TextureManager
* manager
, TextureRef
* texture_ref
,
754 GLenum pname
, GLint value
, GLenum error
) {
755 if (error
== GL_NO_ERROR
) {
756 if (pname
!= GL_TEXTURE_POOL_CHROMIUM
) {
757 EXPECT_CALL(*gl
, TexParameteri(texture_ref
->texture()->target(),
760 .RetiresOnSaturation();
762 } else if (error
== GL_INVALID_ENUM
) {
763 EXPECT_CALL(*error_state
, SetGLErrorInvalidEnum(_
, _
, _
, value
, _
))
765 .RetiresOnSaturation();
767 EXPECT_CALL(*error_state
, SetGLErrorInvalidParami(_
, _
, error
, _
, _
, _
))
769 .RetiresOnSaturation();
771 manager
->SetParameteri("", error_state
, texture_ref
, pname
, value
);
775 void TestHelper::SetShaderStates(
776 ::gfx::MockGLInterface
* gl
, Shader
* shader
,
778 const std::string
* const expected_log_info
,
779 const std::string
* const expected_translated_source
,
780 const int* const expected_shader_version
,
781 const AttributeMap
* const expected_attrib_map
,
782 const UniformMap
* const expected_uniform_map
,
783 const VaryingMap
* const expected_varying_map
,
784 const NameMap
* const expected_name_map
) {
785 const std::string empty_log_info
;
786 const std::string
* log_info
= (expected_log_info
&& !expected_valid
) ?
787 expected_log_info
: &empty_log_info
;
788 const std::string empty_translated_source
;
789 const std::string
* translated_source
=
790 (expected_translated_source
&& expected_valid
) ?
791 expected_translated_source
: &empty_translated_source
;
792 int default_shader_version
= 100;
793 const int* shader_version
= (expected_shader_version
&& expected_valid
) ?
794 expected_shader_version
: &default_shader_version
;
795 const AttributeMap empty_attrib_map
;
796 const AttributeMap
* attrib_map
= (expected_attrib_map
&& expected_valid
) ?
797 expected_attrib_map
: &empty_attrib_map
;
798 const UniformMap empty_uniform_map
;
799 const UniformMap
* uniform_map
= (expected_uniform_map
&& expected_valid
) ?
800 expected_uniform_map
: &empty_uniform_map
;
801 const VaryingMap empty_varying_map
;
802 const VaryingMap
* varying_map
= (expected_varying_map
&& expected_valid
) ?
803 expected_varying_map
: &empty_varying_map
;
804 const NameMap empty_name_map
;
805 const NameMap
* name_map
= (expected_name_map
&& expected_valid
) ?
806 expected_name_map
: &empty_name_map
;
808 MockShaderTranslator
* mock_translator
= new MockShaderTranslator
;
809 scoped_refptr
<ShaderTranslatorInterface
> translator(mock_translator
);
810 EXPECT_CALL(*mock_translator
, Translate(_
,
811 NotNull(), // log_info
812 NotNull(), // translated_source
813 NotNull(), // shader_version
814 NotNull(), // attrib_map
815 NotNull(), // uniform_map
816 NotNull(), // varying_map
817 NotNull())) // name_map
818 .WillOnce(DoAll(SetArgumentPointee
<1>(*log_info
),
819 SetArgumentPointee
<2>(*translated_source
),
820 SetArgumentPointee
<3>(*shader_version
),
821 SetArgumentPointee
<4>(*attrib_map
),
822 SetArgumentPointee
<5>(*uniform_map
),
823 SetArgumentPointee
<6>(*varying_map
),
824 SetArgumentPointee
<7>(*name_map
),
825 Return(expected_valid
)))
826 .RetiresOnSaturation();
827 if (expected_valid
) {
828 EXPECT_CALL(*gl
, ShaderSource(shader
->service_id(), 1, _
, NULL
))
830 .RetiresOnSaturation();
831 EXPECT_CALL(*gl
, CompileShader(shader
->service_id()))
833 .RetiresOnSaturation();
834 EXPECT_CALL(*gl
, GetShaderiv(shader
->service_id(),
836 NotNull())) // status
837 .WillOnce(SetArgumentPointee
<2>(GL_TRUE
))
838 .RetiresOnSaturation();
840 shader
->RequestCompile(translator
, Shader::kGL
);
845 void TestHelper::SetShaderStates(
846 ::gfx::MockGLInterface
* gl
, Shader
* shader
, bool valid
) {
847 SetShaderStates(gl
, shader
, valid
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
851 sh::Attribute
TestHelper::ConstructAttribute(
852 GLenum type
, GLint array_size
, GLenum precision
,
853 bool static_use
, const std::string
& name
) {
854 return ConstructShaderVariable
<sh::Attribute
>(
855 type
, array_size
, precision
, static_use
, name
);
859 sh::Uniform
TestHelper::ConstructUniform(
860 GLenum type
, GLint array_size
, GLenum precision
,
861 bool static_use
, const std::string
& name
) {
862 return ConstructShaderVariable
<sh::Uniform
>(
863 type
, array_size
, precision
, static_use
, name
);
867 sh::Varying
TestHelper::ConstructVarying(
868 GLenum type
, GLint array_size
, GLenum precision
,
869 bool static_use
, const std::string
& name
) {
870 return ConstructShaderVariable
<sh::Varying
>(
871 type
, array_size
, precision
, static_use
, name
);
874 ScopedGLImplementationSetter::ScopedGLImplementationSetter(
875 gfx::GLImplementation implementation
)
876 : old_implementation_(gfx::GetGLImplementation()) {
877 gfx::SetGLImplementation(implementation
);
880 ScopedGLImplementationSetter::~ScopedGLImplementationSetter() {
881 gfx::SetGLImplementation(old_implementation_
);