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.
4
5 #include "gpu/command_buffer/service/test_helper.h"
6
7 #include <algorithm>
8 #include <string>
9
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/program_manager.h"
17 #include "gpu/command_buffer/service/texture_manager.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "ui/gl/gl_mock.h"
20
21 using ::testing::_;
22 using ::testing::DoAll;
23 using ::testing::InSequence;
24 using ::testing::MatcherCast;
25 using ::testing::Pointee;
26 using ::testing::Return;
27 using ::testing::SetArrayArgument;
28 using ::testing::SetArgumentPointee;
29 using ::testing::StrEq;
30 using ::testing::StrictMock;
31
32 namespace gpu {
33 namespace gles2 {
34
35 // GCC requires these declarations, but MSVC requires they not be present
36 #ifndef COMPILER_MSVC
37 const GLuint TestHelper::kServiceBlackTexture2dId;
38 const GLuint TestHelper::kServiceDefaultTexture2dId;
39 const GLuint TestHelper::kServiceBlackTextureCubemapId;
40 const GLuint TestHelper::kServiceDefaultTextureCubemapId;
41 const GLuint TestHelper::kServiceBlackExternalTextureId;
42 const GLuint TestHelper::kServiceDefaultExternalTextureId;
43 const GLuint TestHelper::kServiceBlackRectangleTextureId;
44 const GLuint TestHelper::kServiceDefaultRectangleTextureId;
45
46 const GLint TestHelper::kMaxSamples;
47 const GLint TestHelper::kMaxRenderbufferSize;
48 const GLint TestHelper::kMaxTextureSize;
49 const GLint TestHelper::kMaxCubeMapTextureSize;
50 const GLint TestHelper::kNumVertexAttribs;
51 const GLint TestHelper::kNumTextureUnits;
52 const GLint TestHelper::kMaxTextureImageUnits;
53 const GLint TestHelper::kMaxVertexTextureImageUnits;
54 const GLint TestHelper::kMaxFragmentUniformVectors;
55 const GLint TestHelper::kMaxFragmentUniformComponents;
56 const GLint TestHelper::kMaxVaryingVectors;
57 const GLint TestHelper::kMaxVaryingFloats;
58 const GLint TestHelper::kMaxVertexUniformVectors;
59 const GLint TestHelper::kMaxVertexUniformComponents;
60 #endif
61
SetupTextureInitializationExpectations(::gfx::MockGLInterface * gl,GLenum target,bool use_default_textures)62 void TestHelper::SetupTextureInitializationExpectations(
63 ::gfx::MockGLInterface* gl,
64 GLenum target,
65 bool use_default_textures) {
66 InSequence sequence;
67
68 bool needs_initialization = (target != GL_TEXTURE_EXTERNAL_OES);
69 bool needs_faces = (target == GL_TEXTURE_CUBE_MAP);
70
71 static GLuint texture_2d_ids[] = {
72 kServiceBlackTexture2dId,
73 kServiceDefaultTexture2dId };
74 static GLuint texture_cube_map_ids[] = {
75 kServiceBlackTextureCubemapId,
76 kServiceDefaultTextureCubemapId };
77 static GLuint texture_external_oes_ids[] = {
78 kServiceBlackExternalTextureId,
79 kServiceDefaultExternalTextureId };
80 static GLuint texture_rectangle_arb_ids[] = {
81 kServiceBlackRectangleTextureId,
82 kServiceDefaultRectangleTextureId };
83
84 const GLuint* texture_ids = NULL;
85 switch (target) {
86 case GL_TEXTURE_2D:
87 texture_ids = &texture_2d_ids[0];
88 break;
89 case GL_TEXTURE_CUBE_MAP:
90 texture_ids = &texture_cube_map_ids[0];
91 break;
92 case GL_TEXTURE_EXTERNAL_OES:
93 texture_ids = &texture_external_oes_ids[0];
94 break;
95 case GL_TEXTURE_RECTANGLE_ARB:
96 texture_ids = &texture_rectangle_arb_ids[0];
97 break;
98 default:
99 NOTREACHED();
100 }
101
102 int array_size = use_default_textures ? 2 : 1;
103
104 EXPECT_CALL(*gl, GenTextures(array_size, _))
105 .WillOnce(SetArrayArgument<1>(texture_ids,
106 texture_ids + array_size))
107 .RetiresOnSaturation();
108 for (int ii = 0; ii < array_size; ++ii) {
109 EXPECT_CALL(*gl, BindTexture(target, texture_ids[ii]))
110 .Times(1)
111 .RetiresOnSaturation();
112 if (needs_initialization) {
113 if (needs_faces) {
114 static GLenum faces[] = {
115 GL_TEXTURE_CUBE_MAP_POSITIVE_X,
116 GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
117 GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
118 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
119 GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
120 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
121 };
122 for (size_t ii = 0; ii < arraysize(faces); ++ii) {
123 EXPECT_CALL(*gl, TexImage2D(faces[ii], 0, GL_RGBA, 1, 1, 0, GL_RGBA,
124 GL_UNSIGNED_BYTE, _))
125 .Times(1)
126 .RetiresOnSaturation();
127 }
128 } else {
129 EXPECT_CALL(*gl, TexImage2D(target, 0, GL_RGBA, 1, 1, 0, GL_RGBA,
130 GL_UNSIGNED_BYTE, _))
131 .Times(1)
132 .RetiresOnSaturation();
133 }
134 }
135 }
136 EXPECT_CALL(*gl, BindTexture(target, 0))
137 .Times(1)
138 .RetiresOnSaturation();
139 }
140
SetupTextureManagerInitExpectations(::gfx::MockGLInterface * gl,const char * extensions,bool use_default_textures)141 void TestHelper::SetupTextureManagerInitExpectations(
142 ::gfx::MockGLInterface* gl,
143 const char* extensions,
144 bool use_default_textures) {
145 InSequence sequence;
146
147 SetupTextureInitializationExpectations(
148 gl, GL_TEXTURE_2D, use_default_textures);
149 SetupTextureInitializationExpectations(
150 gl, GL_TEXTURE_CUBE_MAP, use_default_textures);
151
152 bool ext_image_external = false;
153 bool arb_texture_rectangle = false;
154 base::CStringTokenizer t(extensions, extensions + strlen(extensions), " ");
155 while (t.GetNext()) {
156 if (t.token() == "GL_OES_EGL_image_external") {
157 ext_image_external = true;
158 break;
159 }
160 if (t.token() == "GL_ARB_texture_rectangle") {
161 arb_texture_rectangle = true;
162 break;
163 }
164 }
165
166 if (ext_image_external) {
167 SetupTextureInitializationExpectations(
168 gl, GL_TEXTURE_EXTERNAL_OES, use_default_textures);
169 }
170 if (arb_texture_rectangle) {
171 SetupTextureInitializationExpectations(
172 gl, GL_TEXTURE_RECTANGLE_ARB, use_default_textures);
173 }
174 }
175
SetupTextureDestructionExpectations(::gfx::MockGLInterface * gl,GLenum target,bool use_default_textures)176 void TestHelper::SetupTextureDestructionExpectations(
177 ::gfx::MockGLInterface* gl,
178 GLenum target,
179 bool use_default_textures) {
180 if (!use_default_textures)
181 return;
182
183 GLuint texture_id = 0;
184 switch (target) {
185 case GL_TEXTURE_2D:
186 texture_id = kServiceDefaultTexture2dId;
187 break;
188 case GL_TEXTURE_CUBE_MAP:
189 texture_id = kServiceDefaultTextureCubemapId;
190 break;
191 case GL_TEXTURE_EXTERNAL_OES:
192 texture_id = kServiceDefaultExternalTextureId;
193 break;
194 case GL_TEXTURE_RECTANGLE_ARB:
195 texture_id = kServiceDefaultRectangleTextureId;
196 break;
197 default:
198 NOTREACHED();
199 }
200
201 EXPECT_CALL(*gl, DeleteTextures(1, Pointee(texture_id)))
202 .Times(1)
203 .RetiresOnSaturation();
204 }
205
SetupTextureManagerDestructionExpectations(::gfx::MockGLInterface * gl,const char * extensions,bool use_default_textures)206 void TestHelper::SetupTextureManagerDestructionExpectations(
207 ::gfx::MockGLInterface* gl,
208 const char* extensions,
209 bool use_default_textures) {
210 SetupTextureDestructionExpectations(gl, GL_TEXTURE_2D, use_default_textures);
211 SetupTextureDestructionExpectations(
212 gl, GL_TEXTURE_CUBE_MAP, use_default_textures);
213
214 bool ext_image_external = false;
215 bool arb_texture_rectangle = false;
216 base::CStringTokenizer t(extensions, extensions + strlen(extensions), " ");
217 while (t.GetNext()) {
218 if (t.token() == "GL_OES_EGL_image_external") {
219 ext_image_external = true;
220 break;
221 }
222 if (t.token() == "GL_ARB_texture_rectangle") {
223 arb_texture_rectangle = true;
224 break;
225 }
226 }
227
228 if (ext_image_external) {
229 SetupTextureDestructionExpectations(
230 gl, GL_TEXTURE_EXTERNAL_OES, use_default_textures);
231 }
232 if (arb_texture_rectangle) {
233 SetupTextureDestructionExpectations(
234 gl, GL_TEXTURE_RECTANGLE_ARB, use_default_textures);
235 }
236
237 EXPECT_CALL(*gl, DeleteTextures(4, _))
238 .Times(1)
239 .RetiresOnSaturation();
240 }
241
SetupContextGroupInitExpectations(::gfx::MockGLInterface * gl,const DisallowedFeatures & disallowed_features,const char * extensions,const char * gl_version,bool bind_generates_resource)242 void TestHelper::SetupContextGroupInitExpectations(
243 ::gfx::MockGLInterface* gl,
244 const DisallowedFeatures& disallowed_features,
245 const char* extensions,
246 const char* gl_version,
247 bool bind_generates_resource) {
248 InSequence sequence;
249
250 SetupFeatureInfoInitExpectationsWithGLVersion(gl, extensions, "", gl_version);
251
252 std::string l_version(StringToLowerASCII(std::string(gl_version)));
253 bool is_es3 = (l_version.substr(0, 12) == "opengl es 3.");
254
255 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_RENDERBUFFER_SIZE, _))
256 .WillOnce(SetArgumentPointee<1>(kMaxRenderbufferSize))
257 .RetiresOnSaturation();
258 if (strstr(extensions, "GL_EXT_framebuffer_multisample") ||
259 strstr(extensions, "GL_EXT_multisampled_render_to_texture") || is_es3) {
260 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_SAMPLES, _))
261 .WillOnce(SetArgumentPointee<1>(kMaxSamples))
262 .RetiresOnSaturation();
263 } else if (strstr(extensions, "GL_IMG_multisampled_render_to_texture")) {
264 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_SAMPLES_IMG, _))
265 .WillOnce(SetArgumentPointee<1>(kMaxSamples))
266 .RetiresOnSaturation();
267 }
268 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_ATTRIBS, _))
269 .WillOnce(SetArgumentPointee<1>(kNumVertexAttribs))
270 .RetiresOnSaturation();
271 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, _))
272 .WillOnce(SetArgumentPointee<1>(kNumTextureUnits))
273 .RetiresOnSaturation();
274 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_TEXTURE_SIZE, _))
275 .WillOnce(SetArgumentPointee<1>(kMaxTextureSize))
276 .RetiresOnSaturation();
277 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, _))
278 .WillOnce(SetArgumentPointee<1>(kMaxCubeMapTextureSize))
279 .RetiresOnSaturation();
280 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, _))
281 .WillOnce(SetArgumentPointee<1>(kMaxTextureImageUnits))
282 .RetiresOnSaturation();
283 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, _))
284 .WillOnce(SetArgumentPointee<1>(kMaxVertexTextureImageUnits))
285 .RetiresOnSaturation();
286 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, _))
287 .WillOnce(SetArgumentPointee<1>(kMaxFragmentUniformComponents))
288 .RetiresOnSaturation();
289 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VARYING_FLOATS, _))
290 .WillOnce(SetArgumentPointee<1>(kMaxVaryingFloats))
291 .RetiresOnSaturation();
292 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, _))
293 .WillOnce(SetArgumentPointee<1>(kMaxVertexUniformComponents))
294 .RetiresOnSaturation();
295
296 bool use_default_textures = bind_generates_resource;
297 SetupTextureManagerInitExpectations(gl, extensions, use_default_textures);
298 }
299
SetupFeatureInfoInitExpectations(::gfx::MockGLInterface * gl,const char * extensions)300 void TestHelper::SetupFeatureInfoInitExpectations(
301 ::gfx::MockGLInterface* gl, const char* extensions) {
302 SetupFeatureInfoInitExpectationsWithGLVersion(gl, extensions, "", "");
303 }
304
SetupFeatureInfoInitExpectationsWithGLVersion(::gfx::MockGLInterface * gl,const char * extensions,const char * gl_renderer,const char * gl_version)305 void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(
306 ::gfx::MockGLInterface* gl,
307 const char* extensions,
308 const char* gl_renderer,
309 const char* gl_version) {
310 InSequence sequence;
311
312 EXPECT_CALL(*gl, GetString(GL_EXTENSIONS))
313 .WillOnce(Return(reinterpret_cast<const uint8*>(extensions)))
314 .RetiresOnSaturation();
315 EXPECT_CALL(*gl, GetString(GL_RENDERER))
316 .WillOnce(Return(reinterpret_cast<const uint8*>(gl_renderer)))
317 .RetiresOnSaturation();
318 EXPECT_CALL(*gl, GetString(GL_VERSION))
319 .WillOnce(Return(reinterpret_cast<const uint8*>(gl_version)))
320 .RetiresOnSaturation();
321
322 std::string l_version(StringToLowerASCII(std::string(gl_version)));
323 bool is_es3 = (l_version.substr(0, 12) == "opengl es 3.");
324
325 if (strstr(extensions, "GL_ARB_texture_float") ||
326 (is_es3 && strstr(extensions, "GL_EXT_color_buffer_float"))) {
327 static const GLuint gl_ids[] = {101, 102};
328 const GLsizei width = 16;
329 EXPECT_CALL(*gl, GetIntegerv(GL_FRAMEBUFFER_BINDING, _))
330 .WillOnce(SetArgumentPointee<1>(gl_ids[0]))
331 .RetiresOnSaturation();
332 EXPECT_CALL(*gl, GetIntegerv(GL_TEXTURE_BINDING_2D, _))
333 .WillOnce(SetArgumentPointee<1>(gl_ids[0]))
334 .RetiresOnSaturation();
335 EXPECT_CALL(*gl, GenTextures(1, _))
336 .WillOnce(SetArrayArgument<1>(gl_ids + 1, gl_ids + 2))
337 .RetiresOnSaturation();
338 EXPECT_CALL(*gl, GenFramebuffersEXT(1, _))
339 .WillOnce(SetArrayArgument<1>(gl_ids + 1, gl_ids + 2))
340 .RetiresOnSaturation();
341 EXPECT_CALL(*gl, BindTexture(GL_TEXTURE_2D, gl_ids[1]))
342 .Times(1)
343 .RetiresOnSaturation();
344 EXPECT_CALL(*gl, TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
345 GL_NEAREST))
346 .Times(1)
347 .RetiresOnSaturation();
348 EXPECT_CALL(*gl, TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, width, 0,
349 GL_RGBA, GL_FLOAT, _))
350 .Times(1)
351 .RetiresOnSaturation();
352 EXPECT_CALL(*gl, BindFramebufferEXT(GL_FRAMEBUFFER, gl_ids[1]))
353 .Times(1)
354 .RetiresOnSaturation();
355 EXPECT_CALL(*gl, FramebufferTexture2DEXT(GL_FRAMEBUFFER,
356 GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl_ids[1], 0))
357 .Times(1)
358 .RetiresOnSaturation();
359 EXPECT_CALL(*gl, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
360 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
361 .RetiresOnSaturation();
362 EXPECT_CALL(*gl, TexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, width, 0,
363 GL_RGB, GL_FLOAT, _))
364 .Times(1)
365 .RetiresOnSaturation();
366 if (is_es3) {
367 EXPECT_CALL(*gl, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
368 .WillOnce(Return(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT))
369 .RetiresOnSaturation();
370 } else {
371 EXPECT_CALL(*gl, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
372 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
373 .RetiresOnSaturation();
374 }
375 EXPECT_CALL(*gl, DeleteFramebuffersEXT(1, _))
376 .Times(1)
377 .RetiresOnSaturation();
378 EXPECT_CALL(*gl, DeleteTextures(1, _))
379 .Times(1)
380 .RetiresOnSaturation();
381 EXPECT_CALL(*gl, BindFramebufferEXT(GL_FRAMEBUFFER, gl_ids[0]))
382 .Times(1)
383 .RetiresOnSaturation();
384 EXPECT_CALL(*gl, BindTexture(GL_TEXTURE_2D, gl_ids[0]))
385 .Times(1)
386 .RetiresOnSaturation();
387 #if DCHECK_IS_ON
388 EXPECT_CALL(*gl, GetError())
389 .WillOnce(Return(GL_NO_ERROR))
390 .RetiresOnSaturation();
391 #endif
392 }
393 }
394
SetupExpectationsForClearingUniforms(::gfx::MockGLInterface * gl,UniformInfo * uniforms,size_t num_uniforms)395 void TestHelper::SetupExpectationsForClearingUniforms(
396 ::gfx::MockGLInterface* gl, UniformInfo* uniforms, size_t num_uniforms) {
397 for (size_t ii = 0; ii < num_uniforms; ++ii) {
398 const UniformInfo& info = uniforms[ii];
399 switch (info.type) {
400 case GL_FLOAT:
401 EXPECT_CALL(*gl, Uniform1fv(info.real_location, info.size, _))
402 .Times(1)
403 .RetiresOnSaturation();
404 break;
405 case GL_FLOAT_VEC2:
406 EXPECT_CALL(*gl, Uniform2fv(info.real_location, info.size, _))
407 .Times(1)
408 .RetiresOnSaturation();
409 break;
410 case GL_FLOAT_VEC3:
411 EXPECT_CALL(*gl, Uniform3fv(info.real_location, info.size, _))
412 .Times(1)
413 .RetiresOnSaturation();
414 break;
415 case GL_FLOAT_VEC4:
416 EXPECT_CALL(*gl, Uniform4fv(info.real_location, info.size, _))
417 .Times(1)
418 .RetiresOnSaturation();
419 break;
420 case GL_INT:
421 case GL_BOOL:
422 case GL_SAMPLER_2D:
423 case GL_SAMPLER_CUBE:
424 case GL_SAMPLER_EXTERNAL_OES:
425 case GL_SAMPLER_3D_OES:
426 case GL_SAMPLER_2D_RECT_ARB:
427 EXPECT_CALL(*gl, Uniform1iv(info.real_location, info.size, _))
428 .Times(1)
429 .RetiresOnSaturation();
430 break;
431 case GL_INT_VEC2:
432 case GL_BOOL_VEC2:
433 EXPECT_CALL(*gl, Uniform2iv(info.real_location, info.size, _))
434 .Times(1)
435 .RetiresOnSaturation();
436 break;
437 case GL_INT_VEC3:
438 case GL_BOOL_VEC3:
439 EXPECT_CALL(*gl, Uniform3iv(info.real_location, info.size, _))
440 .Times(1)
441 .RetiresOnSaturation();
442 break;
443 case GL_INT_VEC4:
444 case GL_BOOL_VEC4:
445 EXPECT_CALL(*gl, Uniform4iv(info.real_location, info.size, _))
446 .Times(1)
447 .RetiresOnSaturation();
448 break;
449 case GL_FLOAT_MAT2:
450 EXPECT_CALL(*gl, UniformMatrix2fv(
451 info.real_location, info.size, false, _))
452 .Times(1)
453 .RetiresOnSaturation();
454 break;
455 case GL_FLOAT_MAT3:
456 EXPECT_CALL(*gl, UniformMatrix3fv(
457 info.real_location, info.size, false, _))
458 .Times(1)
459 .RetiresOnSaturation();
460 break;
461 case GL_FLOAT_MAT4:
462 EXPECT_CALL(*gl, UniformMatrix4fv(
463 info.real_location, info.size, false, _))
464 .Times(1)
465 .RetiresOnSaturation();
466 break;
467 default:
468 NOTREACHED();
469 break;
470 }
471 }
472 }
473
SetupProgramSuccessExpectations(::gfx::MockGLInterface * gl,AttribInfo * attribs,size_t num_attribs,UniformInfo * uniforms,size_t num_uniforms,GLuint service_id)474 void TestHelper::SetupProgramSuccessExpectations(
475 ::gfx::MockGLInterface* gl,
476 AttribInfo* attribs, size_t num_attribs,
477 UniformInfo* uniforms, size_t num_uniforms,
478 GLuint service_id) {
479 EXPECT_CALL(*gl,
480 GetProgramiv(service_id, GL_LINK_STATUS, _))
481 .WillOnce(SetArgumentPointee<2>(1))
482 .RetiresOnSaturation();
483 EXPECT_CALL(*gl,
484 GetProgramiv(service_id, GL_INFO_LOG_LENGTH, _))
485 .WillOnce(SetArgumentPointee<2>(0))
486 .RetiresOnSaturation();
487 EXPECT_CALL(*gl,
488 GetProgramiv(service_id, GL_ACTIVE_ATTRIBUTES, _))
489 .WillOnce(SetArgumentPointee<2>(num_attribs))
490 .RetiresOnSaturation();
491 size_t max_attrib_len = 0;
492 for (size_t ii = 0; ii < num_attribs; ++ii) {
493 size_t len = strlen(attribs[ii].name) + 1;
494 max_attrib_len = std::max(max_attrib_len, len);
495 }
496 EXPECT_CALL(*gl,
497 GetProgramiv(service_id, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, _))
498 .WillOnce(SetArgumentPointee<2>(max_attrib_len))
499 .RetiresOnSaturation();
500
501 for (size_t ii = 0; ii < num_attribs; ++ii) {
502 const AttribInfo& info = attribs[ii];
503 EXPECT_CALL(*gl,
504 GetActiveAttrib(service_id, ii,
505 max_attrib_len, _, _, _, _))
506 .WillOnce(DoAll(
507 SetArgumentPointee<3>(strlen(info.name)),
508 SetArgumentPointee<4>(info.size),
509 SetArgumentPointee<5>(info.type),
510 SetArrayArgument<6>(info.name,
511 info.name + strlen(info.name) + 1)))
512 .RetiresOnSaturation();
513 if (!ProgramManager::IsInvalidPrefix(info.name, strlen(info.name))) {
514 EXPECT_CALL(*gl, GetAttribLocation(service_id, StrEq(info.name)))
515 .WillOnce(Return(info.location))
516 .RetiresOnSaturation();
517 }
518 }
519 EXPECT_CALL(*gl,
520 GetProgramiv(service_id, GL_ACTIVE_UNIFORMS, _))
521 .WillOnce(SetArgumentPointee<2>(num_uniforms))
522 .RetiresOnSaturation();
523
524 size_t max_uniform_len = 0;
525 for (size_t ii = 0; ii < num_uniforms; ++ii) {
526 size_t len = strlen(uniforms[ii].name) + 1;
527 max_uniform_len = std::max(max_uniform_len, len);
528 }
529 EXPECT_CALL(*gl,
530 GetProgramiv(service_id, GL_ACTIVE_UNIFORM_MAX_LENGTH, _))
531 .WillOnce(SetArgumentPointee<2>(max_uniform_len))
532 .RetiresOnSaturation();
533 for (size_t ii = 0; ii < num_uniforms; ++ii) {
534 const UniformInfo& info = uniforms[ii];
535 EXPECT_CALL(*gl,
536 GetActiveUniform(service_id, ii,
537 max_uniform_len, _, _, _, _))
538 .WillOnce(DoAll(
539 SetArgumentPointee<3>(strlen(info.name)),
540 SetArgumentPointee<4>(info.size),
541 SetArgumentPointee<5>(info.type),
542 SetArrayArgument<6>(info.name,
543 info.name + strlen(info.name) + 1)))
544 .RetiresOnSaturation();
545 }
546
547 for (int pass = 0; pass < 2; ++pass) {
548 for (size_t ii = 0; ii < num_uniforms; ++ii) {
549 const UniformInfo& info = uniforms[ii];
550 if (ProgramManager::IsInvalidPrefix(info.name, strlen(info.name))) {
551 continue;
552 }
553 if (pass == 0) {
554 EXPECT_CALL(*gl, GetUniformLocation(service_id, StrEq(info.name)))
555 .WillOnce(Return(info.real_location))
556 .RetiresOnSaturation();
557 }
558 if ((pass == 0 && info.desired_location >= 0) ||
559 (pass == 1 && info.desired_location < 0)) {
560 if (info.size > 1) {
561 std::string base_name = info.name;
562 size_t array_pos = base_name.rfind("[0]");
563 if (base_name.size() > 3 && array_pos == base_name.size() - 3) {
564 base_name = base_name.substr(0, base_name.size() - 3);
565 }
566 for (GLsizei jj = 1; jj < info.size; ++jj) {
567 std::string element_name(
568 std::string(base_name) + "[" + base::IntToString(jj) + "]");
569 EXPECT_CALL(*gl, GetUniformLocation(
570 service_id, StrEq(element_name)))
571 .WillOnce(Return(info.real_location + jj * 2))
572 .RetiresOnSaturation();
573 }
574 }
575 }
576 }
577 }
578 }
579
SetupShader(::gfx::MockGLInterface * gl,AttribInfo * attribs,size_t num_attribs,UniformInfo * uniforms,size_t num_uniforms,GLuint service_id)580 void TestHelper::SetupShader(
581 ::gfx::MockGLInterface* gl,
582 AttribInfo* attribs, size_t num_attribs,
583 UniformInfo* uniforms, size_t num_uniforms,
584 GLuint service_id) {
585 InSequence s;
586
587 EXPECT_CALL(*gl,
588 LinkProgram(service_id))
589 .Times(1)
590 .RetiresOnSaturation();
591
592 SetupProgramSuccessExpectations(
593 gl, attribs, num_attribs, uniforms, num_uniforms, service_id);
594 }
595
DoBufferData(::gfx::MockGLInterface * gl,MockErrorState * error_state,BufferManager * manager,Buffer * buffer,GLsizeiptr size,GLenum usage,const GLvoid * data,GLenum error)596 void TestHelper::DoBufferData(
597 ::gfx::MockGLInterface* gl, MockErrorState* error_state,
598 BufferManager* manager, Buffer* buffer, GLsizeiptr size, GLenum usage,
599 const GLvoid* data, GLenum error) {
600 EXPECT_CALL(*error_state, CopyRealGLErrorsToWrapper(_, _, _))
601 .Times(1)
602 .RetiresOnSaturation();
603 if (manager->IsUsageClientSideArray(usage)) {
604 EXPECT_CALL(*gl, BufferData(
605 buffer->target(), 0, _, usage))
606 .Times(1)
607 .RetiresOnSaturation();
608 } else {
609 EXPECT_CALL(*gl, BufferData(
610 buffer->target(), size, _, usage))
611 .Times(1)
612 .RetiresOnSaturation();
613 }
614 EXPECT_CALL(*error_state, PeekGLError(_, _, _))
615 .WillOnce(Return(error))
616 .RetiresOnSaturation();
617 manager->DoBufferData(error_state, buffer, size, usage, data);
618 }
619
SetTexParameteriWithExpectations(::gfx::MockGLInterface * gl,MockErrorState * error_state,TextureManager * manager,TextureRef * texture_ref,GLenum pname,GLint value,GLenum error)620 void TestHelper::SetTexParameteriWithExpectations(
621 ::gfx::MockGLInterface* gl, MockErrorState* error_state,
622 TextureManager* manager, TextureRef* texture_ref,
623 GLenum pname, GLint value, GLenum error) {
624 if (error == GL_NO_ERROR) {
625 if (pname != GL_TEXTURE_POOL_CHROMIUM) {
626 EXPECT_CALL(*gl, TexParameteri(texture_ref->texture()->target(),
627 pname, value))
628 .Times(1)
629 .RetiresOnSaturation();
630 }
631 } else if (error == GL_INVALID_ENUM) {
632 EXPECT_CALL(*error_state, SetGLErrorInvalidEnum(_, _, _, value, _))
633 .Times(1)
634 .RetiresOnSaturation();
635 } else {
636 EXPECT_CALL(*error_state, SetGLErrorInvalidParami(_, _, error, _, _, _))
637 .Times(1)
638 .RetiresOnSaturation();
639 }
640 manager->SetParameteri("", error_state, texture_ref, pname, value);
641 }
642
ScopedGLImplementationSetter(gfx::GLImplementation implementation)643 ScopedGLImplementationSetter::ScopedGLImplementationSetter(
644 gfx::GLImplementation implementation)
645 : old_implementation_(gfx::GetGLImplementation()) {
646 gfx::SetGLImplementation(implementation);
647 }
648
~ScopedGLImplementationSetter()649 ScopedGLImplementationSetter::~ScopedGLImplementationSetter() {
650 gfx::SetGLImplementation(old_implementation_);
651 }
652
653 } // namespace gles2
654 } // namespace gpu
655
656