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