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"
23 using ::testing::DoAll
;
24 using ::testing::InSequence
;
25 using ::testing::MatcherCast
;
26 using ::testing::Pointee
;
27 using ::testing::NotNull
;
28 using ::testing::Return
;
29 using ::testing::SetArrayArgument
;
30 using ::testing::SetArgumentPointee
;
31 using ::testing::StrEq
;
32 using ::testing::StrictMock
;
40 T
ConstructShaderVariable(
41 GLenum type
, GLint array_size
, GLenum precision
,
42 bool static_use
, const std::string
& name
) {
45 var
.arraySize
= array_size
;
46 var
.precision
= precision
;
47 var
.staticUse
= static_use
;
49 var
.mappedName
= name
; // No name hashing.
53 } // namespace anonymous
55 // GCC requires these declarations, but MSVC requires they not be present
57 const GLuint
TestHelper::kServiceBlackTexture2dId
;
58 const GLuint
TestHelper::kServiceDefaultTexture2dId
;
59 const GLuint
TestHelper::kServiceBlackTextureCubemapId
;
60 const GLuint
TestHelper::kServiceDefaultTextureCubemapId
;
61 const GLuint
TestHelper::kServiceBlackExternalTextureId
;
62 const GLuint
TestHelper::kServiceDefaultExternalTextureId
;
63 const GLuint
TestHelper::kServiceBlackRectangleTextureId
;
64 const GLuint
TestHelper::kServiceDefaultRectangleTextureId
;
66 const GLint
TestHelper::kMaxSamples
;
67 const GLint
TestHelper::kMaxRenderbufferSize
;
68 const GLint
TestHelper::kMaxTextureSize
;
69 const GLint
TestHelper::kMaxCubeMapTextureSize
;
70 const GLint
TestHelper::kMaxRectangleTextureSize
;
71 const GLint
TestHelper::kNumVertexAttribs
;
72 const GLint
TestHelper::kNumTextureUnits
;
73 const GLint
TestHelper::kMaxTextureImageUnits
;
74 const GLint
TestHelper::kMaxVertexTextureImageUnits
;
75 const GLint
TestHelper::kMaxFragmentUniformVectors
;
76 const GLint
TestHelper::kMaxFragmentUniformComponents
;
77 const GLint
TestHelper::kMaxVaryingVectors
;
78 const GLint
TestHelper::kMaxVaryingFloats
;
79 const GLint
TestHelper::kMaxVertexUniformVectors
;
80 const GLint
TestHelper::kMaxVertexUniformComponents
;
83 void TestHelper::SetupTextureInitializationExpectations(
84 ::gfx::MockGLInterface
* gl
,
86 bool use_default_textures
) {
89 bool needs_initialization
= (target
!= GL_TEXTURE_EXTERNAL_OES
);
90 bool needs_faces
= (target
== GL_TEXTURE_CUBE_MAP
);
92 static GLuint texture_2d_ids
[] = {
93 kServiceBlackTexture2dId
,
94 kServiceDefaultTexture2dId
};
95 static GLuint texture_cube_map_ids
[] = {
96 kServiceBlackTextureCubemapId
,
97 kServiceDefaultTextureCubemapId
};
98 static GLuint texture_external_oes_ids
[] = {
99 kServiceBlackExternalTextureId
,
100 kServiceDefaultExternalTextureId
};
101 static GLuint texture_rectangle_arb_ids
[] = {
102 kServiceBlackRectangleTextureId
,
103 kServiceDefaultRectangleTextureId
};
105 const GLuint
* texture_ids
= NULL
;
108 texture_ids
= &texture_2d_ids
[0];
110 case GL_TEXTURE_CUBE_MAP
:
111 texture_ids
= &texture_cube_map_ids
[0];
113 case GL_TEXTURE_EXTERNAL_OES
:
114 texture_ids
= &texture_external_oes_ids
[0];
116 case GL_TEXTURE_RECTANGLE_ARB
:
117 texture_ids
= &texture_rectangle_arb_ids
[0];
123 int array_size
= use_default_textures
? 2 : 1;
125 EXPECT_CALL(*gl
, GenTextures(array_size
, _
))
126 .WillOnce(SetArrayArgument
<1>(texture_ids
,
127 texture_ids
+ array_size
))
128 .RetiresOnSaturation();
129 for (int ii
= 0; ii
< array_size
; ++ii
) {
130 EXPECT_CALL(*gl
, BindTexture(target
, texture_ids
[ii
]))
132 .RetiresOnSaturation();
133 if (needs_initialization
) {
135 static GLenum faces
[] = {
136 GL_TEXTURE_CUBE_MAP_POSITIVE_X
,
137 GL_TEXTURE_CUBE_MAP_NEGATIVE_X
,
138 GL_TEXTURE_CUBE_MAP_POSITIVE_Y
,
139 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
,
140 GL_TEXTURE_CUBE_MAP_POSITIVE_Z
,
141 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
,
143 for (size_t ii
= 0; ii
< arraysize(faces
); ++ii
) {
144 EXPECT_CALL(*gl
, TexImage2D(faces
[ii
], 0, GL_RGBA
, 1, 1, 0, GL_RGBA
,
145 GL_UNSIGNED_BYTE
, _
))
147 .RetiresOnSaturation();
150 EXPECT_CALL(*gl
, TexImage2D(target
, 0, GL_RGBA
, 1, 1, 0, GL_RGBA
,
151 GL_UNSIGNED_BYTE
, _
))
153 .RetiresOnSaturation();
157 EXPECT_CALL(*gl
, BindTexture(target
, 0))
159 .RetiresOnSaturation();
162 void TestHelper::SetupTextureManagerInitExpectations(
163 ::gfx::MockGLInterface
* gl
,
164 const char* extensions
,
165 bool use_default_textures
) {
168 SetupTextureInitializationExpectations(
169 gl
, GL_TEXTURE_2D
, use_default_textures
);
170 SetupTextureInitializationExpectations(
171 gl
, GL_TEXTURE_CUBE_MAP
, use_default_textures
);
173 bool ext_image_external
= false;
174 bool arb_texture_rectangle
= false;
175 base::CStringTokenizer
t(extensions
, extensions
+ strlen(extensions
), " ");
176 while (t
.GetNext()) {
177 if (t
.token() == "GL_OES_EGL_image_external") {
178 ext_image_external
= true;
181 if (t
.token() == "GL_ARB_texture_rectangle") {
182 arb_texture_rectangle
= true;
187 if (ext_image_external
) {
188 SetupTextureInitializationExpectations(
189 gl
, GL_TEXTURE_EXTERNAL_OES
, use_default_textures
);
191 if (arb_texture_rectangle
) {
192 SetupTextureInitializationExpectations(
193 gl
, GL_TEXTURE_RECTANGLE_ARB
, use_default_textures
);
197 void TestHelper::SetupTextureDestructionExpectations(
198 ::gfx::MockGLInterface
* gl
,
200 bool use_default_textures
) {
201 if (!use_default_textures
)
204 GLuint texture_id
= 0;
207 texture_id
= kServiceDefaultTexture2dId
;
209 case GL_TEXTURE_CUBE_MAP
:
210 texture_id
= kServiceDefaultTextureCubemapId
;
212 case GL_TEXTURE_EXTERNAL_OES
:
213 texture_id
= kServiceDefaultExternalTextureId
;
215 case GL_TEXTURE_RECTANGLE_ARB
:
216 texture_id
= kServiceDefaultRectangleTextureId
;
222 EXPECT_CALL(*gl
, DeleteTextures(1, Pointee(texture_id
)))
224 .RetiresOnSaturation();
227 void TestHelper::SetupTextureManagerDestructionExpectations(
228 ::gfx::MockGLInterface
* gl
,
229 const char* extensions
,
230 bool use_default_textures
) {
231 SetupTextureDestructionExpectations(gl
, GL_TEXTURE_2D
, use_default_textures
);
232 SetupTextureDestructionExpectations(
233 gl
, GL_TEXTURE_CUBE_MAP
, use_default_textures
);
235 bool ext_image_external
= false;
236 bool arb_texture_rectangle
= false;
237 base::CStringTokenizer
t(extensions
, extensions
+ strlen(extensions
), " ");
238 while (t
.GetNext()) {
239 if (t
.token() == "GL_OES_EGL_image_external") {
240 ext_image_external
= true;
243 if (t
.token() == "GL_ARB_texture_rectangle") {
244 arb_texture_rectangle
= true;
249 if (ext_image_external
) {
250 SetupTextureDestructionExpectations(
251 gl
, GL_TEXTURE_EXTERNAL_OES
, use_default_textures
);
253 if (arb_texture_rectangle
) {
254 SetupTextureDestructionExpectations(
255 gl
, GL_TEXTURE_RECTANGLE_ARB
, use_default_textures
);
258 EXPECT_CALL(*gl
, DeleteTextures(4, _
))
260 .RetiresOnSaturation();
263 void TestHelper::SetupContextGroupInitExpectations(
264 ::gfx::MockGLInterface
* gl
,
265 const DisallowedFeatures
& disallowed_features
,
266 const char* extensions
,
267 const char* gl_version
,
268 bool bind_generates_resource
) {
271 SetupFeatureInfoInitExpectationsWithGLVersion(gl
, extensions
, "", gl_version
);
273 std::string
l_version(base::StringToLowerASCII(std::string(gl_version
)));
274 bool is_es3
= (l_version
.substr(0, 12) == "opengl es 3.");
276 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_RENDERBUFFER_SIZE
, _
))
277 .WillOnce(SetArgumentPointee
<1>(kMaxRenderbufferSize
))
278 .RetiresOnSaturation();
279 if (strstr(extensions
, "GL_EXT_framebuffer_multisample") ||
280 strstr(extensions
, "GL_EXT_multisampled_render_to_texture") || is_es3
) {
281 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_SAMPLES
, _
))
282 .WillOnce(SetArgumentPointee
<1>(kMaxSamples
))
283 .RetiresOnSaturation();
284 } else if (strstr(extensions
, "GL_IMG_multisampled_render_to_texture")) {
285 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_SAMPLES_IMG
, _
))
286 .WillOnce(SetArgumentPointee
<1>(kMaxSamples
))
287 .RetiresOnSaturation();
289 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_VERTEX_ATTRIBS
, _
))
290 .WillOnce(SetArgumentPointee
<1>(kNumVertexAttribs
))
291 .RetiresOnSaturation();
292 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
, _
))
293 .WillOnce(SetArgumentPointee
<1>(kNumTextureUnits
))
294 .RetiresOnSaturation();
295 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_TEXTURE_SIZE
, _
))
296 .WillOnce(SetArgumentPointee
<1>(kMaxTextureSize
))
297 .RetiresOnSaturation();
298 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE
, _
))
299 .WillOnce(SetArgumentPointee
<1>(kMaxCubeMapTextureSize
))
300 .RetiresOnSaturation();
301 if (strstr(extensions
, "GL_ARB_texture_rectangle")) {
302 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE
, _
))
303 .WillOnce(SetArgumentPointee
<1>(kMaxRectangleTextureSize
))
304 .RetiresOnSaturation();
306 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS
, _
))
307 .WillOnce(SetArgumentPointee
<1>(kMaxTextureImageUnits
))
308 .RetiresOnSaturation();
309 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS
, _
))
310 .WillOnce(SetArgumentPointee
<1>(kMaxVertexTextureImageUnits
))
311 .RetiresOnSaturation();
312 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS
, _
))
313 .WillOnce(SetArgumentPointee
<1>(kMaxFragmentUniformComponents
))
314 .RetiresOnSaturation();
315 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_VARYING_FLOATS
, _
))
316 .WillOnce(SetArgumentPointee
<1>(kMaxVaryingFloats
))
317 .RetiresOnSaturation();
318 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS
, _
))
319 .WillOnce(SetArgumentPointee
<1>(kMaxVertexUniformComponents
))
320 .RetiresOnSaturation();
322 bool use_default_textures
= bind_generates_resource
;
323 SetupTextureManagerInitExpectations(gl
, extensions
, use_default_textures
);
326 void TestHelper::SetupFeatureInfoInitExpectations(
327 ::gfx::MockGLInterface
* gl
, const char* extensions
) {
328 SetupFeatureInfoInitExpectationsWithGLVersion(gl
, extensions
, "", "");
331 void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(
332 ::gfx::MockGLInterface
* gl
,
333 const char* extensions
,
334 const char* gl_renderer
,
335 const char* gl_version
) {
338 EXPECT_CALL(*gl
, GetString(GL_EXTENSIONS
))
339 .WillOnce(Return(reinterpret_cast<const uint8
*>(extensions
)))
340 .RetiresOnSaturation();
341 EXPECT_CALL(*gl
, GetString(GL_RENDERER
))
342 .WillOnce(Return(reinterpret_cast<const uint8
*>(gl_renderer
)))
343 .RetiresOnSaturation();
344 EXPECT_CALL(*gl
, GetString(GL_VERSION
))
345 .WillOnce(Return(reinterpret_cast<const uint8
*>(gl_version
)))
346 .RetiresOnSaturation();
348 std::string
l_version(base::StringToLowerASCII(std::string(gl_version
)));
349 bool is_es3
= (l_version
.substr(0, 12) == "opengl es 3.");
351 if (strstr(extensions
, "GL_ARB_texture_float") ||
352 (is_es3
&& strstr(extensions
, "GL_EXT_color_buffer_float"))) {
353 static const GLuint tx_ids
[] = {101, 102};
354 static const GLuint fb_ids
[] = {103, 104};
355 const GLsizei width
= 16;
356 EXPECT_CALL(*gl
, GetIntegerv(GL_FRAMEBUFFER_BINDING
, _
))
357 .WillOnce(SetArgumentPointee
<1>(fb_ids
[0]))
358 .RetiresOnSaturation();
359 EXPECT_CALL(*gl
, GetIntegerv(GL_TEXTURE_BINDING_2D
, _
))
360 .WillOnce(SetArgumentPointee
<1>(tx_ids
[0]))
361 .RetiresOnSaturation();
362 EXPECT_CALL(*gl
, GenTextures(1, _
))
363 .WillOnce(SetArrayArgument
<1>(tx_ids
+ 1, tx_ids
+ 2))
364 .RetiresOnSaturation();
365 EXPECT_CALL(*gl
, GenFramebuffersEXT(1, _
))
366 .WillOnce(SetArrayArgument
<1>(fb_ids
+ 1, fb_ids
+ 2))
367 .RetiresOnSaturation();
368 EXPECT_CALL(*gl
, BindTexture(GL_TEXTURE_2D
, tx_ids
[1]))
370 .RetiresOnSaturation();
371 EXPECT_CALL(*gl
, TexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
,
374 .RetiresOnSaturation();
375 EXPECT_CALL(*gl
, TexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA32F
, width
, width
, 0,
376 GL_RGBA
, GL_FLOAT
, _
))
378 .RetiresOnSaturation();
379 EXPECT_CALL(*gl
, BindFramebufferEXT(GL_FRAMEBUFFER
, fb_ids
[1]))
381 .RetiresOnSaturation();
382 EXPECT_CALL(*gl
, FramebufferTexture2DEXT(GL_FRAMEBUFFER
,
383 GL_COLOR_ATTACHMENT0
, GL_TEXTURE_2D
, tx_ids
[1], 0))
385 .RetiresOnSaturation();
386 EXPECT_CALL(*gl
, CheckFramebufferStatusEXT(GL_FRAMEBUFFER
))
387 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE
))
388 .RetiresOnSaturation();
389 EXPECT_CALL(*gl
, TexImage2D(GL_TEXTURE_2D
, 0, GL_RGB32F
, width
, width
, 0,
390 GL_RGB
, GL_FLOAT
, _
))
392 .RetiresOnSaturation();
394 EXPECT_CALL(*gl
, CheckFramebufferStatusEXT(GL_FRAMEBUFFER
))
395 .WillOnce(Return(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
))
396 .RetiresOnSaturation();
398 EXPECT_CALL(*gl
, CheckFramebufferStatusEXT(GL_FRAMEBUFFER
))
399 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE
))
400 .RetiresOnSaturation();
402 EXPECT_CALL(*gl
, DeleteFramebuffersEXT(1, _
))
404 .RetiresOnSaturation();
405 EXPECT_CALL(*gl
, DeleteTextures(1, _
))
407 .RetiresOnSaturation();
408 EXPECT_CALL(*gl
, BindFramebufferEXT(GL_FRAMEBUFFER
, fb_ids
[0]))
410 .RetiresOnSaturation();
411 EXPECT_CALL(*gl
, BindTexture(GL_TEXTURE_2D
, tx_ids
[0]))
413 .RetiresOnSaturation();
415 EXPECT_CALL(*gl
, GetError())
416 .WillOnce(Return(GL_NO_ERROR
))
417 .RetiresOnSaturation();
421 if (strstr(extensions
, "GL_EXT_draw_buffers") ||
422 strstr(extensions
, "GL_ARB_draw_buffers") ||
423 (is_es3
&& strstr(extensions
, "GL_NV_draw_buffers"))) {
424 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT
, _
))
425 .WillOnce(SetArgumentPointee
<1>(8))
426 .RetiresOnSaturation();
427 EXPECT_CALL(*gl
, GetIntegerv(GL_MAX_DRAW_BUFFERS_ARB
, _
))
428 .WillOnce(SetArgumentPointee
<1>(8))
429 .RetiresOnSaturation();
432 if (is_es3
|| strstr(extensions
, "GL_EXT_texture_rg") ||
433 (strstr(extensions
, "GL_ARB_texture_rg"))) {
434 static const GLuint tx_ids
[] = {101, 102};
435 static const GLuint fb_ids
[] = {103, 104};
436 const GLsizei width
= 1;
437 EXPECT_CALL(*gl
, GetIntegerv(GL_FRAMEBUFFER_BINDING
, _
))
438 .WillOnce(SetArgumentPointee
<1>(fb_ids
[0]))
439 .RetiresOnSaturation();
440 EXPECT_CALL(*gl
, GetIntegerv(GL_TEXTURE_BINDING_2D
, _
))
441 .WillOnce(SetArgumentPointee
<1>(tx_ids
[0]))
442 .RetiresOnSaturation();
443 EXPECT_CALL(*gl
, GenTextures(1, _
))
444 .WillOnce(SetArrayArgument
<1>(tx_ids
+ 1, tx_ids
+ 2))
445 .RetiresOnSaturation();
446 EXPECT_CALL(*gl
, BindTexture(GL_TEXTURE_2D
, tx_ids
[1]))
448 .RetiresOnSaturation();
449 EXPECT_CALL(*gl
, TexImage2D(GL_TEXTURE_2D
, 0, _
, width
, width
, 0,
450 GL_RED_EXT
, GL_UNSIGNED_BYTE
, _
))
452 .RetiresOnSaturation();
453 EXPECT_CALL(*gl
, GenFramebuffersEXT(1, _
))
454 .WillOnce(SetArrayArgument
<1>(fb_ids
+ 1, fb_ids
+ 2))
455 .RetiresOnSaturation();
456 EXPECT_CALL(*gl
, BindFramebufferEXT(GL_FRAMEBUFFER
, fb_ids
[1]))
458 .RetiresOnSaturation();
459 EXPECT_CALL(*gl
, FramebufferTexture2DEXT(GL_FRAMEBUFFER
,
460 GL_COLOR_ATTACHMENT0
, GL_TEXTURE_2D
, tx_ids
[1], 0))
462 .RetiresOnSaturation();
463 EXPECT_CALL(*gl
, CheckFramebufferStatusEXT(GL_FRAMEBUFFER
))
464 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE
))
465 .RetiresOnSaturation();
466 EXPECT_CALL(*gl
, DeleteFramebuffersEXT(1, _
))
468 .RetiresOnSaturation();
469 EXPECT_CALL(*gl
, DeleteTextures(1, _
))
471 .RetiresOnSaturation();
472 EXPECT_CALL(*gl
, BindFramebufferEXT(GL_FRAMEBUFFER
, fb_ids
[0]))
474 .RetiresOnSaturation();
475 EXPECT_CALL(*gl
, BindTexture(GL_TEXTURE_2D
, tx_ids
[0]))
477 .RetiresOnSaturation();
479 EXPECT_CALL(*gl
, GetError())
480 .WillOnce(Return(GL_NO_ERROR
))
481 .RetiresOnSaturation();
486 void TestHelper::SetupExpectationsForClearingUniforms(
487 ::gfx::MockGLInterface
* gl
, UniformInfo
* uniforms
, size_t num_uniforms
) {
488 for (size_t ii
= 0; ii
< num_uniforms
; ++ii
) {
489 const UniformInfo
& info
= uniforms
[ii
];
492 EXPECT_CALL(*gl
, Uniform1fv(info
.real_location
, info
.size
, _
))
494 .RetiresOnSaturation();
497 EXPECT_CALL(*gl
, Uniform2fv(info
.real_location
, info
.size
, _
))
499 .RetiresOnSaturation();
502 EXPECT_CALL(*gl
, Uniform3fv(info
.real_location
, info
.size
, _
))
504 .RetiresOnSaturation();
507 EXPECT_CALL(*gl
, Uniform4fv(info
.real_location
, info
.size
, _
))
509 .RetiresOnSaturation();
514 case GL_SAMPLER_CUBE
:
515 case GL_SAMPLER_EXTERNAL_OES
:
516 case GL_SAMPLER_3D_OES
:
517 case GL_SAMPLER_2D_RECT_ARB
:
518 EXPECT_CALL(*gl
, Uniform1iv(info
.real_location
, info
.size
, _
))
520 .RetiresOnSaturation();
524 EXPECT_CALL(*gl
, Uniform2iv(info
.real_location
, info
.size
, _
))
526 .RetiresOnSaturation();
530 EXPECT_CALL(*gl
, Uniform3iv(info
.real_location
, info
.size
, _
))
532 .RetiresOnSaturation();
536 EXPECT_CALL(*gl
, Uniform4iv(info
.real_location
, info
.size
, _
))
538 .RetiresOnSaturation();
541 EXPECT_CALL(*gl
, UniformMatrix2fv(
542 info
.real_location
, info
.size
, false, _
))
544 .RetiresOnSaturation();
547 EXPECT_CALL(*gl
, UniformMatrix3fv(
548 info
.real_location
, info
.size
, false, _
))
550 .RetiresOnSaturation();
553 EXPECT_CALL(*gl
, UniformMatrix4fv(
554 info
.real_location
, info
.size
, false, _
))
556 .RetiresOnSaturation();
565 void TestHelper::SetupProgramSuccessExpectations(
566 ::gfx::MockGLInterface
* gl
,
567 AttribInfo
* attribs
, size_t num_attribs
,
568 UniformInfo
* uniforms
, size_t num_uniforms
,
571 GetProgramiv(service_id
, GL_LINK_STATUS
, _
))
572 .WillOnce(SetArgumentPointee
<2>(1))
573 .RetiresOnSaturation();
575 GetProgramiv(service_id
, GL_INFO_LOG_LENGTH
, _
))
576 .WillOnce(SetArgumentPointee
<2>(0))
577 .RetiresOnSaturation();
579 GetProgramiv(service_id
, GL_ACTIVE_ATTRIBUTES
, _
))
580 .WillOnce(SetArgumentPointee
<2>(num_attribs
))
581 .RetiresOnSaturation();
582 size_t max_attrib_len
= 0;
583 for (size_t ii
= 0; ii
< num_attribs
; ++ii
) {
584 size_t len
= strlen(attribs
[ii
].name
) + 1;
585 max_attrib_len
= std::max(max_attrib_len
, len
);
588 GetProgramiv(service_id
, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
, _
))
589 .WillOnce(SetArgumentPointee
<2>(max_attrib_len
))
590 .RetiresOnSaturation();
592 for (size_t ii
= 0; ii
< num_attribs
; ++ii
) {
593 const AttribInfo
& info
= attribs
[ii
];
595 GetActiveAttrib(service_id
, ii
,
596 max_attrib_len
, _
, _
, _
, _
))
598 SetArgumentPointee
<3>(strlen(info
.name
)),
599 SetArgumentPointee
<4>(info
.size
),
600 SetArgumentPointee
<5>(info
.type
),
601 SetArrayArgument
<6>(info
.name
,
602 info
.name
+ strlen(info
.name
) + 1)))
603 .RetiresOnSaturation();
604 if (!ProgramManager::IsInvalidPrefix(info
.name
, strlen(info
.name
))) {
605 EXPECT_CALL(*gl
, GetAttribLocation(service_id
, StrEq(info
.name
)))
606 .WillOnce(Return(info
.location
))
607 .RetiresOnSaturation();
611 GetProgramiv(service_id
, GL_ACTIVE_UNIFORMS
, _
))
612 .WillOnce(SetArgumentPointee
<2>(num_uniforms
))
613 .RetiresOnSaturation();
615 size_t max_uniform_len
= 0;
616 for (size_t ii
= 0; ii
< num_uniforms
; ++ii
) {
617 size_t len
= strlen(uniforms
[ii
].name
) + 1;
618 max_uniform_len
= std::max(max_uniform_len
, len
);
621 GetProgramiv(service_id
, GL_ACTIVE_UNIFORM_MAX_LENGTH
, _
))
622 .WillOnce(SetArgumentPointee
<2>(max_uniform_len
))
623 .RetiresOnSaturation();
624 for (size_t ii
= 0; ii
< num_uniforms
; ++ii
) {
625 const UniformInfo
& info
= uniforms
[ii
];
627 GetActiveUniform(service_id
, ii
,
628 max_uniform_len
, _
, _
, _
, _
))
630 SetArgumentPointee
<3>(strlen(info
.name
)),
631 SetArgumentPointee
<4>(info
.size
),
632 SetArgumentPointee
<5>(info
.type
),
633 SetArrayArgument
<6>(info
.name
,
634 info
.name
+ strlen(info
.name
) + 1)))
635 .RetiresOnSaturation();
638 for (int pass
= 0; pass
< 2; ++pass
) {
639 for (size_t ii
= 0; ii
< num_uniforms
; ++ii
) {
640 const UniformInfo
& info
= uniforms
[ii
];
641 if (ProgramManager::IsInvalidPrefix(info
.name
, strlen(info
.name
))) {
645 EXPECT_CALL(*gl
, GetUniformLocation(service_id
, StrEq(info
.name
)))
646 .WillOnce(Return(info
.real_location
))
647 .RetiresOnSaturation();
649 if ((pass
== 0 && info
.desired_location
>= 0) ||
650 (pass
== 1 && info
.desired_location
< 0)) {
652 std::string base_name
= info
.name
;
653 size_t array_pos
= base_name
.rfind("[0]");
654 if (base_name
.size() > 3 && array_pos
== base_name
.size() - 3) {
655 base_name
= base_name
.substr(0, base_name
.size() - 3);
657 for (GLsizei jj
= 1; jj
< info
.size
; ++jj
) {
658 std::string
element_name(
659 std::string(base_name
) + "[" + base::IntToString(jj
) + "]");
660 EXPECT_CALL(*gl
, GetUniformLocation(
661 service_id
, StrEq(element_name
)))
662 .WillOnce(Return(info
.real_location
+ jj
* 2))
663 .RetiresOnSaturation();
671 void TestHelper::SetupShader(
672 ::gfx::MockGLInterface
* gl
,
673 AttribInfo
* attribs
, size_t num_attribs
,
674 UniformInfo
* uniforms
, size_t num_uniforms
,
679 LinkProgram(service_id
))
681 .RetiresOnSaturation();
683 SetupProgramSuccessExpectations(
684 gl
, attribs
, num_attribs
, uniforms
, num_uniforms
, service_id
);
687 void TestHelper::DoBufferData(
688 ::gfx::MockGLInterface
* gl
, MockErrorState
* error_state
,
689 BufferManager
* manager
, Buffer
* buffer
, GLsizeiptr size
, GLenum usage
,
690 const GLvoid
* data
, GLenum error
) {
691 EXPECT_CALL(*error_state
, CopyRealGLErrorsToWrapper(_
, _
, _
))
693 .RetiresOnSaturation();
694 if (manager
->IsUsageClientSideArray(usage
)) {
695 EXPECT_CALL(*gl
, BufferData(
696 buffer
->target(), 0, _
, usage
))
698 .RetiresOnSaturation();
700 EXPECT_CALL(*gl
, BufferData(
701 buffer
->target(), size
, _
, usage
))
703 .RetiresOnSaturation();
705 EXPECT_CALL(*error_state
, PeekGLError(_
, _
, _
))
706 .WillOnce(Return(error
))
707 .RetiresOnSaturation();
708 manager
->DoBufferData(error_state
, buffer
, size
, usage
, data
);
711 void TestHelper::SetTexParameteriWithExpectations(
712 ::gfx::MockGLInterface
* gl
, MockErrorState
* error_state
,
713 TextureManager
* manager
, TextureRef
* texture_ref
,
714 GLenum pname
, GLint value
, GLenum error
) {
715 if (error
== GL_NO_ERROR
) {
716 if (pname
!= GL_TEXTURE_POOL_CHROMIUM
) {
717 EXPECT_CALL(*gl
, TexParameteri(texture_ref
->texture()->target(),
720 .RetiresOnSaturation();
722 } else if (error
== GL_INVALID_ENUM
) {
723 EXPECT_CALL(*error_state
, SetGLErrorInvalidEnum(_
, _
, _
, value
, _
))
725 .RetiresOnSaturation();
727 EXPECT_CALL(*error_state
, SetGLErrorInvalidParami(_
, _
, error
, _
, _
, _
))
729 .RetiresOnSaturation();
731 manager
->SetParameteri("", error_state
, texture_ref
, pname
, value
);
735 void TestHelper::SetShaderStates(
736 ::gfx::MockGLInterface
* gl
, Shader
* shader
,
738 const std::string
* const expected_log_info
,
739 const std::string
* const expected_translated_source
,
740 const AttributeMap
* const expected_attrib_map
,
741 const UniformMap
* const expected_uniform_map
,
742 const VaryingMap
* const expected_varying_map
,
743 const NameMap
* const expected_name_map
) {
744 const std::string empty_log_info
;
745 const std::string
* log_info
= (expected_log_info
&& !expected_valid
) ?
746 expected_log_info
: &empty_log_info
;
747 const std::string empty_translated_source
;
748 const std::string
* translated_source
=
749 (expected_translated_source
&& expected_valid
) ?
750 expected_translated_source
: &empty_translated_source
;
751 const AttributeMap empty_attrib_map
;
752 const AttributeMap
* attrib_map
= (expected_attrib_map
&& expected_valid
) ?
753 expected_attrib_map
: &empty_attrib_map
;
754 const UniformMap empty_uniform_map
;
755 const UniformMap
* uniform_map
= (expected_uniform_map
&& expected_valid
) ?
756 expected_uniform_map
: &empty_uniform_map
;
757 const VaryingMap empty_varying_map
;
758 const VaryingMap
* varying_map
= (expected_varying_map
&& expected_valid
) ?
759 expected_varying_map
: &empty_varying_map
;
760 const NameMap empty_name_map
;
761 const NameMap
* name_map
= (expected_name_map
&& expected_valid
) ?
762 expected_name_map
: &empty_name_map
;
764 MockShaderTranslator
* mock_translator
= new MockShaderTranslator
;
765 scoped_refptr
<ShaderTranslatorInterface
> translator(mock_translator
);
766 EXPECT_CALL(*mock_translator
, Translate(_
,
767 NotNull(), // log_info
768 NotNull(), // translated_source
769 NotNull(), // attrib_map
770 NotNull(), // uniform_map
771 NotNull(), // varying_map
772 NotNull())) // name_map
773 .WillOnce(DoAll(SetArgumentPointee
<1>(*log_info
),
774 SetArgumentPointee
<2>(*translated_source
),
775 SetArgumentPointee
<3>(*attrib_map
),
776 SetArgumentPointee
<4>(*uniform_map
),
777 SetArgumentPointee
<5>(*varying_map
),
778 SetArgumentPointee
<6>(*name_map
),
779 Return(expected_valid
)))
780 .RetiresOnSaturation();
781 if (expected_valid
) {
782 EXPECT_CALL(*gl
, ShaderSource(shader
->service_id(), 1, _
, NULL
))
784 .RetiresOnSaturation();
785 EXPECT_CALL(*gl
, CompileShader(shader
->service_id()))
787 .RetiresOnSaturation();
788 EXPECT_CALL(*gl
, GetShaderiv(shader
->service_id(),
790 NotNull())) // status
791 .WillOnce(SetArgumentPointee
<2>(GL_TRUE
))
792 .RetiresOnSaturation();
794 shader
->RequestCompile(translator
, Shader::kGL
);
799 void TestHelper::SetShaderStates(
800 ::gfx::MockGLInterface
* gl
, Shader
* shader
, bool valid
) {
801 SetShaderStates(gl
, shader
, valid
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
805 sh::Attribute
TestHelper::ConstructAttribute(
806 GLenum type
, GLint array_size
, GLenum precision
,
807 bool static_use
, const std::string
& name
) {
808 return ConstructShaderVariable
<sh::Attribute
>(
809 type
, array_size
, precision
, static_use
, name
);
813 sh::Uniform
TestHelper::ConstructUniform(
814 GLenum type
, GLint array_size
, GLenum precision
,
815 bool static_use
, const std::string
& name
) {
816 return ConstructShaderVariable
<sh::Uniform
>(
817 type
, array_size
, precision
, static_use
, name
);
821 sh::Varying
TestHelper::ConstructVarying(
822 GLenum type
, GLint array_size
, GLenum precision
,
823 bool static_use
, const std::string
& name
) {
824 return ConstructShaderVariable
<sh::Varying
>(
825 type
, array_size
, precision
, static_use
, name
);
828 ScopedGLImplementationSetter::ScopedGLImplementationSetter(
829 gfx::GLImplementation implementation
)
830 : old_implementation_(gfx::GetGLImplementation()) {
831 gfx::SetGLImplementation(implementation
);
834 ScopedGLImplementationSetter::~ScopedGLImplementationSetter() {
835 gfx::SetGLImplementation(old_implementation_
);