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