• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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