Elim cr-checkbox
[chromium-blink-merge.git] / gpu / command_buffer / service / test_helper.cc
blob4b8d8fc9e6e35f5a82d7b128cacf059544b7c283
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "gpu/command_buffer/service/test_helper.h"
7 #include <algorithm>
8 #include <string>
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_split.h"
12 #include "base/strings/string_tokenizer.h"
13 #include "gpu/command_buffer/service/buffer_manager.h"
14 #include "gpu/command_buffer/service/error_state_mock.h"
15 #include "gpu/command_buffer/service/gl_utils.h"
16 #include "gpu/command_buffer/service/gpu_switches.h"
17 #include "gpu/command_buffer/service/mocks.h"
18 #include "gpu/command_buffer/service/program_manager.h"
19 #include "gpu/command_buffer/service/texture_manager.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "ui/gl/gl_mock.h"
22 #include "ui/gl/gl_version_info.h"
24 using ::testing::_;
25 using ::testing::DoAll;
26 using ::testing::InSequence;
27 using ::testing::MatcherCast;
28 using ::testing::Pointee;
29 using ::testing::NotNull;
30 using ::testing::Return;
31 using ::testing::SetArrayArgument;
32 using ::testing::SetArgumentPointee;
33 using ::testing::StrEq;
34 using ::testing::StrictMock;
36 namespace gpu {
37 namespace gles2 {
39 namespace {
41 template<typename T>
42 T ConstructShaderVariable(
43 GLenum type, GLint array_size, GLenum precision,
44 bool static_use, const std::string& name) {
45 T var;
46 var.type = type;
47 var.arraySize = array_size;
48 var.precision = precision;
49 var.staticUse = static_use;
50 var.name = name;
51 var.mappedName = name; // No name hashing.
52 return var;
55 } // namespace anonymous
57 // GCC requires these declarations, but MSVC requires they not be present
58 #ifndef COMPILER_MSVC
59 const GLuint TestHelper::kServiceBlackTexture2dId;
60 const GLuint TestHelper::kServiceDefaultTexture2dId;
61 const GLuint TestHelper::kServiceBlackTexture3dId;
62 const GLuint TestHelper::kServiceDefaultTexture3dId;
63 const GLuint TestHelper::kServiceBlackTexture2dArrayId;
64 const GLuint TestHelper::kServiceDefaultTexture2dArrayId;
65 const GLuint TestHelper::kServiceBlackTextureCubemapId;
66 const GLuint TestHelper::kServiceDefaultTextureCubemapId;
67 const GLuint TestHelper::kServiceBlackExternalTextureId;
68 const GLuint TestHelper::kServiceDefaultExternalTextureId;
69 const GLuint TestHelper::kServiceBlackRectangleTextureId;
70 const GLuint TestHelper::kServiceDefaultRectangleTextureId;
72 const GLint TestHelper::kMaxSamples;
73 const GLint TestHelper::kMaxRenderbufferSize;
74 const GLint TestHelper::kMaxTextureSize;
75 const GLint TestHelper::kMaxCubeMapTextureSize;
76 const GLint TestHelper::kMaxRectangleTextureSize;
77 const GLint TestHelper::kMax3DTextureSize;
78 const GLint TestHelper::kNumVertexAttribs;
79 const GLint TestHelper::kNumTextureUnits;
80 const GLint TestHelper::kMaxTextureImageUnits;
81 const GLint TestHelper::kMaxVertexTextureImageUnits;
82 const GLint TestHelper::kMaxFragmentUniformVectors;
83 const GLint TestHelper::kMaxFragmentUniformComponents;
84 const GLint TestHelper::kMaxVaryingVectors;
85 const GLint TestHelper::kMaxVaryingFloats;
86 const GLint TestHelper::kMaxVertexUniformVectors;
87 const GLint TestHelper::kMaxVertexUniformComponents;
88 #endif
90 std::vector<std::string> TestHelper::split_extensions_;
92 void TestHelper::SetupTextureInitializationExpectations(
93 ::gfx::MockGLInterface* gl,
94 GLenum target,
95 bool use_default_textures) {
96 InSequence sequence;
98 bool needs_initialization = (target != GL_TEXTURE_EXTERNAL_OES);
99 bool needs_faces = (target == GL_TEXTURE_CUBE_MAP);
100 bool is_3d_or_2d_array_target = (target == GL_TEXTURE_3D ||
101 target == GL_TEXTURE_2D_ARRAY);
103 static GLuint texture_2d_ids[] = {
104 kServiceBlackTexture2dId,
105 kServiceDefaultTexture2dId };
106 static GLuint texture_3d_ids[] = {
107 kServiceBlackTexture3dId,
108 kServiceDefaultTexture3dId };
109 static GLuint texture_2d_array_ids[] = {
110 kServiceBlackTexture2dArrayId,
111 kServiceDefaultTexture2dArrayId };
112 static GLuint texture_cube_map_ids[] = {
113 kServiceBlackTextureCubemapId,
114 kServiceDefaultTextureCubemapId };
115 static GLuint texture_external_oes_ids[] = {
116 kServiceBlackExternalTextureId,
117 kServiceDefaultExternalTextureId };
118 static GLuint texture_rectangle_arb_ids[] = {
119 kServiceBlackRectangleTextureId,
120 kServiceDefaultRectangleTextureId };
122 const GLuint* texture_ids = NULL;
123 switch (target) {
124 case GL_TEXTURE_2D:
125 texture_ids = &texture_2d_ids[0];
126 break;
127 case GL_TEXTURE_3D:
128 texture_ids = &texture_3d_ids[0];
129 break;
130 case GL_TEXTURE_2D_ARRAY:
131 texture_ids = &texture_2d_array_ids[0];
132 break;
133 case GL_TEXTURE_CUBE_MAP:
134 texture_ids = &texture_cube_map_ids[0];
135 break;
136 case GL_TEXTURE_EXTERNAL_OES:
137 texture_ids = &texture_external_oes_ids[0];
138 break;
139 case GL_TEXTURE_RECTANGLE_ARB:
140 texture_ids = &texture_rectangle_arb_ids[0];
141 break;
142 default:
143 NOTREACHED();
146 int array_size = use_default_textures ? 2 : 1;
148 EXPECT_CALL(*gl, GenTextures(array_size, _))
149 .WillOnce(SetArrayArgument<1>(texture_ids,
150 texture_ids + array_size))
151 .RetiresOnSaturation();
152 for (int ii = 0; ii < array_size; ++ii) {
153 EXPECT_CALL(*gl, BindTexture(target, texture_ids[ii]))
154 .Times(1)
155 .RetiresOnSaturation();
156 if (needs_initialization) {
157 if (needs_faces) {
158 static GLenum faces[] = {
159 GL_TEXTURE_CUBE_MAP_POSITIVE_X,
160 GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
161 GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
162 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
163 GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
164 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
166 for (size_t ii = 0; ii < arraysize(faces); ++ii) {
167 EXPECT_CALL(*gl, TexImage2D(faces[ii], 0, GL_RGBA, 1, 1, 0, GL_RGBA,
168 GL_UNSIGNED_BYTE, _))
169 .Times(1)
170 .RetiresOnSaturation();
172 } else {
173 if (is_3d_or_2d_array_target) {
174 EXPECT_CALL(*gl, TexImage3D(target, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA,
175 GL_UNSIGNED_BYTE, _))
176 .Times(1)
177 .RetiresOnSaturation();
178 } else {
179 EXPECT_CALL(*gl, TexImage2D(target, 0, GL_RGBA, 1, 1, 0, GL_RGBA,
180 GL_UNSIGNED_BYTE, _))
181 .Times(1)
182 .RetiresOnSaturation();
187 EXPECT_CALL(*gl, BindTexture(target, 0))
188 .Times(1)
189 .RetiresOnSaturation();
192 void TestHelper::SetupTextureManagerInitExpectations(
193 ::gfx::MockGLInterface* gl,
194 bool is_es3_enabled,
195 const char* extensions,
196 bool use_default_textures) {
197 InSequence sequence;
199 SetupTextureInitializationExpectations(
200 gl, GL_TEXTURE_2D, use_default_textures);
201 SetupTextureInitializationExpectations(
202 gl, GL_TEXTURE_CUBE_MAP, use_default_textures);
204 if (is_es3_enabled) {
205 SetupTextureInitializationExpectations(
206 gl, GL_TEXTURE_3D, use_default_textures);
207 SetupTextureInitializationExpectations(
208 gl, GL_TEXTURE_2D_ARRAY, use_default_textures);
211 bool ext_image_external = false;
212 bool arb_texture_rectangle = false;
213 base::CStringTokenizer t(extensions, extensions + strlen(extensions), " ");
214 while (t.GetNext()) {
215 if (t.token() == "GL_OES_EGL_image_external") {
216 ext_image_external = true;
217 break;
219 if (t.token() == "GL_ARB_texture_rectangle") {
220 arb_texture_rectangle = true;
221 break;
225 if (ext_image_external) {
226 SetupTextureInitializationExpectations(
227 gl, GL_TEXTURE_EXTERNAL_OES, use_default_textures);
229 if (arb_texture_rectangle) {
230 SetupTextureInitializationExpectations(
231 gl, GL_TEXTURE_RECTANGLE_ARB, use_default_textures);
235 void TestHelper::SetupTextureDestructionExpectations(
236 ::gfx::MockGLInterface* gl,
237 GLenum target,
238 bool use_default_textures) {
239 if (!use_default_textures)
240 return;
242 GLuint texture_id = 0;
243 switch (target) {
244 case GL_TEXTURE_2D:
245 texture_id = kServiceDefaultTexture2dId;
246 break;
247 case GL_TEXTURE_3D:
248 texture_id = kServiceDefaultTexture3dId;
249 break;
250 case GL_TEXTURE_2D_ARRAY:
251 texture_id = kServiceDefaultTexture2dArrayId;
252 break;
253 case GL_TEXTURE_CUBE_MAP:
254 texture_id = kServiceDefaultTextureCubemapId;
255 break;
256 case GL_TEXTURE_EXTERNAL_OES:
257 texture_id = kServiceDefaultExternalTextureId;
258 break;
259 case GL_TEXTURE_RECTANGLE_ARB:
260 texture_id = kServiceDefaultRectangleTextureId;
261 break;
262 default:
263 NOTREACHED();
266 EXPECT_CALL(*gl, DeleteTextures(1, Pointee(texture_id)))
267 .Times(1)
268 .RetiresOnSaturation();
271 void TestHelper::SetupTextureManagerDestructionExpectations(
272 ::gfx::MockGLInterface* gl,
273 bool is_es3_enabled,
274 const char* extensions,
275 bool use_default_textures) {
276 SetupTextureDestructionExpectations(gl, GL_TEXTURE_2D, use_default_textures);
277 SetupTextureDestructionExpectations(
278 gl, GL_TEXTURE_CUBE_MAP, use_default_textures);
280 if (is_es3_enabled) {
281 SetupTextureDestructionExpectations(
282 gl, GL_TEXTURE_3D, use_default_textures);
283 SetupTextureDestructionExpectations(
284 gl, GL_TEXTURE_2D_ARRAY,use_default_textures);
287 bool ext_image_external = false;
288 bool arb_texture_rectangle = false;
289 base::CStringTokenizer t(extensions, extensions + strlen(extensions), " ");
290 while (t.GetNext()) {
291 if (t.token() == "GL_OES_EGL_image_external") {
292 ext_image_external = true;
293 break;
295 if (t.token() == "GL_ARB_texture_rectangle") {
296 arb_texture_rectangle = true;
297 break;
301 if (ext_image_external) {
302 SetupTextureDestructionExpectations(
303 gl, GL_TEXTURE_EXTERNAL_OES, use_default_textures);
305 if (arb_texture_rectangle) {
306 SetupTextureDestructionExpectations(
307 gl, GL_TEXTURE_RECTANGLE_ARB, use_default_textures);
310 EXPECT_CALL(*gl, DeleteTextures(TextureManager::kNumDefaultTextures, _))
311 .Times(1)
312 .RetiresOnSaturation();
315 void TestHelper::SetupContextGroupInitExpectations(
316 ::gfx::MockGLInterface* gl,
317 const DisallowedFeatures& disallowed_features,
318 const char* extensions,
319 const char* gl_version,
320 bool bind_generates_resource) {
321 InSequence sequence;
323 SetupFeatureInfoInitExpectationsWithGLVersion(gl, extensions, "", gl_version);
325 gfx::GLVersionInfo gl_info(gl_version, "", extensions);
327 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_RENDERBUFFER_SIZE, _))
328 .WillOnce(SetArgumentPointee<1>(kMaxRenderbufferSize))
329 .RetiresOnSaturation();
330 if (strstr(extensions, "GL_EXT_framebuffer_multisample") ||
331 strstr(extensions, "GL_EXT_multisampled_render_to_texture") ||
332 gl_info.is_es3) {
333 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_SAMPLES, _))
334 .WillOnce(SetArgumentPointee<1>(kMaxSamples))
335 .RetiresOnSaturation();
336 } else if (strstr(extensions, "GL_IMG_multisampled_render_to_texture")) {
337 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_SAMPLES_IMG, _))
338 .WillOnce(SetArgumentPointee<1>(kMaxSamples))
339 .RetiresOnSaturation();
341 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_ATTRIBS, _))
342 .WillOnce(SetArgumentPointee<1>(kNumVertexAttribs))
343 .RetiresOnSaturation();
344 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, _))
345 .WillOnce(SetArgumentPointee<1>(kNumTextureUnits))
346 .RetiresOnSaturation();
347 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_TEXTURE_SIZE, _))
348 .WillOnce(SetArgumentPointee<1>(kMaxTextureSize))
349 .RetiresOnSaturation();
350 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, _))
351 .WillOnce(SetArgumentPointee<1>(kMaxCubeMapTextureSize))
352 .RetiresOnSaturation();
353 if (gl_info.IsES3Capable()) {
354 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_3D_TEXTURE_SIZE, _))
355 .WillOnce(SetArgumentPointee<1>(kMax3DTextureSize))
356 .RetiresOnSaturation();
358 if (strstr(extensions, "GL_ARB_texture_rectangle")) {
359 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE, _))
360 .WillOnce(SetArgumentPointee<1>(kMaxRectangleTextureSize))
361 .RetiresOnSaturation();
363 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, _))
364 .WillOnce(SetArgumentPointee<1>(kMaxTextureImageUnits))
365 .RetiresOnSaturation();
366 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, _))
367 .WillOnce(SetArgumentPointee<1>(kMaxVertexTextureImageUnits))
368 .RetiresOnSaturation();
370 if (gl_info.is_es) {
371 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, _))
372 .WillOnce(SetArgumentPointee<1>(kMaxFragmentUniformVectors))
373 .RetiresOnSaturation();
374 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VARYING_VECTORS, _))
375 .WillOnce(SetArgumentPointee<1>(kMaxVaryingVectors))
376 .RetiresOnSaturation();
377 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, _))
378 .WillOnce(SetArgumentPointee<1>(kMaxVertexUniformVectors))
379 .RetiresOnSaturation();
380 } else {
381 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, _))
382 .WillOnce(SetArgumentPointee<1>(kMaxFragmentUniformComponents))
383 .RetiresOnSaturation();
384 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VARYING_FLOATS, _))
385 .WillOnce(SetArgumentPointee<1>(kMaxVaryingFloats))
386 .RetiresOnSaturation();
387 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, _))
388 .WillOnce(SetArgumentPointee<1>(kMaxVertexUniformComponents))
389 .RetiresOnSaturation();
392 bool use_default_textures = bind_generates_resource;
393 SetupTextureManagerInitExpectations(
394 gl, false, extensions, use_default_textures);
397 void TestHelper::SetupFeatureInfoInitExpectations(
398 ::gfx::MockGLInterface* gl, const char* extensions) {
399 SetupFeatureInfoInitExpectationsWithGLVersion(gl, extensions, "", "");
402 void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(
403 ::gfx::MockGLInterface* gl,
404 const char* extensions,
405 const char* gl_renderer,
406 const char* gl_version) {
407 InSequence sequence;
409 EXPECT_CALL(*gl, GetString(GL_VERSION))
410 .WillOnce(Return(reinterpret_cast<const uint8*>(gl_version)))
411 .RetiresOnSaturation();
413 // Persistent storage is needed for the split extension string.
414 split_extensions_.clear();
415 if (extensions) {
416 split_extensions_ = base::SplitString(
417 extensions, " ", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
420 gfx::GLVersionInfo gl_info(gl_version, gl_renderer, extensions);
421 if (!gl_info.is_es && gl_info.major_version >= 3) {
422 EXPECT_CALL(*gl, GetIntegerv(GL_NUM_EXTENSIONS, _))
423 .WillOnce(SetArgumentPointee<1>(split_extensions_.size()))
424 .RetiresOnSaturation();
425 for (size_t ii = 0; ii < split_extensions_.size(); ++ii) {
426 EXPECT_CALL(*gl, GetStringi(GL_EXTENSIONS, ii))
427 .WillOnce(Return(reinterpret_cast<const uint8*>(
428 split_extensions_[ii].c_str())))
429 .RetiresOnSaturation();
431 } else {
432 EXPECT_CALL(*gl, GetString(GL_EXTENSIONS))
433 .WillOnce(Return(reinterpret_cast<const uint8*>(extensions)))
434 .RetiresOnSaturation();
437 EXPECT_CALL(*gl, GetString(GL_VERSION))
438 .WillOnce(Return(reinterpret_cast<const uint8*>(gl_version)))
439 .RetiresOnSaturation();
440 EXPECT_CALL(*gl, GetString(GL_RENDERER))
441 .WillOnce(Return(reinterpret_cast<const uint8*>(gl_renderer)))
442 .RetiresOnSaturation();
444 if (strstr(extensions, "GL_ARB_texture_float") ||
445 (gl_info.is_es3 && strstr(extensions, "GL_EXT_color_buffer_float"))) {
446 static const GLuint tx_ids[] = {101, 102};
447 static const GLuint fb_ids[] = {103, 104};
448 const GLsizei width = 16;
449 EXPECT_CALL(*gl, GetIntegerv(GL_FRAMEBUFFER_BINDING, _))
450 .WillOnce(SetArgumentPointee<1>(fb_ids[0]))
451 .RetiresOnSaturation();
452 EXPECT_CALL(*gl, GetIntegerv(GL_TEXTURE_BINDING_2D, _))
453 .WillOnce(SetArgumentPointee<1>(tx_ids[0]))
454 .RetiresOnSaturation();
455 EXPECT_CALL(*gl, GenTextures(1, _))
456 .WillOnce(SetArrayArgument<1>(tx_ids + 1, tx_ids + 2))
457 .RetiresOnSaturation();
458 EXPECT_CALL(*gl, GenFramebuffersEXT(1, _))
459 .WillOnce(SetArrayArgument<1>(fb_ids + 1, fb_ids + 2))
460 .RetiresOnSaturation();
461 EXPECT_CALL(*gl, BindTexture(GL_TEXTURE_2D, tx_ids[1]))
462 .Times(1)
463 .RetiresOnSaturation();
464 EXPECT_CALL(*gl, TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
465 GL_NEAREST))
466 .Times(1)
467 .RetiresOnSaturation();
468 EXPECT_CALL(*gl, TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, width, 0,
469 GL_RGBA, GL_FLOAT, _))
470 .Times(1)
471 .RetiresOnSaturation();
472 EXPECT_CALL(*gl, BindFramebufferEXT(GL_FRAMEBUFFER, fb_ids[1]))
473 .Times(1)
474 .RetiresOnSaturation();
475 EXPECT_CALL(*gl, FramebufferTexture2DEXT(GL_FRAMEBUFFER,
476 GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tx_ids[1], 0))
477 .Times(1)
478 .RetiresOnSaturation();
479 EXPECT_CALL(*gl, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
480 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
481 .RetiresOnSaturation();
482 EXPECT_CALL(*gl, TexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, width, 0,
483 GL_RGB, GL_FLOAT, _))
484 .Times(1)
485 .RetiresOnSaturation();
486 if (gl_info.is_es3) {
487 EXPECT_CALL(*gl, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
488 .WillOnce(Return(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT))
489 .RetiresOnSaturation();
490 } else {
491 EXPECT_CALL(*gl, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
492 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
493 .RetiresOnSaturation();
495 EXPECT_CALL(*gl, DeleteFramebuffersEXT(1, _))
496 .Times(1)
497 .RetiresOnSaturation();
498 EXPECT_CALL(*gl, DeleteTextures(1, _))
499 .Times(1)
500 .RetiresOnSaturation();
501 EXPECT_CALL(*gl, BindFramebufferEXT(GL_FRAMEBUFFER, fb_ids[0]))
502 .Times(1)
503 .RetiresOnSaturation();
504 EXPECT_CALL(*gl, BindTexture(GL_TEXTURE_2D, tx_ids[0]))
505 .Times(1)
506 .RetiresOnSaturation();
507 #if DCHECK_IS_ON()
508 EXPECT_CALL(*gl, GetError())
509 .WillOnce(Return(GL_NO_ERROR))
510 .RetiresOnSaturation();
511 #endif
514 if (strstr(extensions, "GL_EXT_draw_buffers") ||
515 strstr(extensions, "GL_ARB_draw_buffers") ||
516 (gl_info.is_es3 && strstr(extensions, "GL_NV_draw_buffers"))) {
517 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, _))
518 .WillOnce(SetArgumentPointee<1>(8))
519 .RetiresOnSaturation();
520 EXPECT_CALL(*gl, GetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, _))
521 .WillOnce(SetArgumentPointee<1>(8))
522 .RetiresOnSaturation();
525 if (gl_info.is_es3 || strstr(extensions, "GL_EXT_texture_rg") ||
526 (strstr(extensions, "GL_ARB_texture_rg"))) {
527 static const GLuint tx_ids[] = {101, 102};
528 static const GLuint fb_ids[] = {103, 104};
529 const GLsizei width = 1;
530 EXPECT_CALL(*gl, GetIntegerv(GL_FRAMEBUFFER_BINDING, _))
531 .WillOnce(SetArgumentPointee<1>(fb_ids[0]))
532 .RetiresOnSaturation();
533 EXPECT_CALL(*gl, GetIntegerv(GL_TEXTURE_BINDING_2D, _))
534 .WillOnce(SetArgumentPointee<1>(tx_ids[0]))
535 .RetiresOnSaturation();
536 EXPECT_CALL(*gl, GenTextures(1, _))
537 .WillOnce(SetArrayArgument<1>(tx_ids + 1, tx_ids + 2))
538 .RetiresOnSaturation();
539 EXPECT_CALL(*gl, BindTexture(GL_TEXTURE_2D, tx_ids[1]))
540 .Times(1)
541 .RetiresOnSaturation();
542 EXPECT_CALL(*gl, TexImage2D(GL_TEXTURE_2D, 0, _, width, width, 0,
543 GL_RED_EXT, GL_UNSIGNED_BYTE, _))
544 .Times(1)
545 .RetiresOnSaturation();
546 EXPECT_CALL(*gl, GenFramebuffersEXT(1, _))
547 .WillOnce(SetArrayArgument<1>(fb_ids + 1, fb_ids + 2))
548 .RetiresOnSaturation();
549 EXPECT_CALL(*gl, BindFramebufferEXT(GL_FRAMEBUFFER, fb_ids[1]))
550 .Times(1)
551 .RetiresOnSaturation();
552 EXPECT_CALL(*gl, FramebufferTexture2DEXT(GL_FRAMEBUFFER,
553 GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tx_ids[1], 0))
554 .Times(1)
555 .RetiresOnSaturation();
556 EXPECT_CALL(*gl, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
557 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
558 .RetiresOnSaturation();
559 EXPECT_CALL(*gl, DeleteFramebuffersEXT(1, _))
560 .Times(1)
561 .RetiresOnSaturation();
562 EXPECT_CALL(*gl, DeleteTextures(1, _))
563 .Times(1)
564 .RetiresOnSaturation();
565 EXPECT_CALL(*gl, BindFramebufferEXT(GL_FRAMEBUFFER, fb_ids[0]))
566 .Times(1)
567 .RetiresOnSaturation();
568 EXPECT_CALL(*gl, BindTexture(GL_TEXTURE_2D, tx_ids[0]))
569 .Times(1)
570 .RetiresOnSaturation();
571 #if DCHECK_IS_ON()
572 EXPECT_CALL(*gl, GetError())
573 .WillOnce(Return(GL_NO_ERROR))
574 .RetiresOnSaturation();
575 #endif
579 void TestHelper::SetupExpectationsForClearingUniforms(
580 ::gfx::MockGLInterface* gl, UniformInfo* uniforms, size_t num_uniforms) {
581 for (size_t ii = 0; ii < num_uniforms; ++ii) {
582 const UniformInfo& info = uniforms[ii];
583 switch (info.type) {
584 case GL_FLOAT:
585 EXPECT_CALL(*gl, Uniform1fv(info.real_location, info.size, _))
586 .Times(1)
587 .RetiresOnSaturation();
588 break;
589 case GL_FLOAT_VEC2:
590 EXPECT_CALL(*gl, Uniform2fv(info.real_location, info.size, _))
591 .Times(1)
592 .RetiresOnSaturation();
593 break;
594 case GL_FLOAT_VEC3:
595 EXPECT_CALL(*gl, Uniform3fv(info.real_location, info.size, _))
596 .Times(1)
597 .RetiresOnSaturation();
598 break;
599 case GL_FLOAT_VEC4:
600 EXPECT_CALL(*gl, Uniform4fv(info.real_location, info.size, _))
601 .Times(1)
602 .RetiresOnSaturation();
603 break;
604 case GL_INT:
605 case GL_BOOL:
606 case GL_SAMPLER_2D:
607 case GL_SAMPLER_CUBE:
608 case GL_SAMPLER_EXTERNAL_OES:
609 case GL_SAMPLER_3D_OES:
610 case GL_SAMPLER_2D_RECT_ARB:
611 case GL_SAMPLER_2D_ARRAY:
612 EXPECT_CALL(*gl, Uniform1iv(info.real_location, info.size, _))
613 .Times(1)
614 .RetiresOnSaturation();
615 break;
616 case GL_UNSIGNED_INT:
617 EXPECT_CALL(*gl, Uniform1uiv(info.real_location, info.size, _))
618 .Times(1)
619 .RetiresOnSaturation();
620 break;
621 case GL_INT_VEC2:
622 case GL_BOOL_VEC2:
623 EXPECT_CALL(*gl, Uniform2iv(info.real_location, info.size, _))
624 .Times(1)
625 .RetiresOnSaturation();
626 break;
627 case GL_UNSIGNED_INT_VEC2:
628 EXPECT_CALL(*gl, Uniform2uiv(info.real_location, info.size, _))
629 .Times(1)
630 .RetiresOnSaturation();
631 break;
632 case GL_INT_VEC3:
633 case GL_BOOL_VEC3:
634 EXPECT_CALL(*gl, Uniform3iv(info.real_location, info.size, _))
635 .Times(1)
636 .RetiresOnSaturation();
637 break;
638 case GL_UNSIGNED_INT_VEC3:
639 EXPECT_CALL(*gl, Uniform3uiv(info.real_location, info.size, _))
640 .Times(1)
641 .RetiresOnSaturation();
642 break;
643 case GL_INT_VEC4:
644 case GL_BOOL_VEC4:
645 EXPECT_CALL(*gl, Uniform4iv(info.real_location, info.size, _))
646 .Times(1)
647 .RetiresOnSaturation();
648 break;
649 case GL_UNSIGNED_INT_VEC4:
650 EXPECT_CALL(*gl, Uniform4uiv(info.real_location, info.size, _))
651 .Times(1)
652 .RetiresOnSaturation();
653 break;
654 case GL_FLOAT_MAT2:
655 EXPECT_CALL(*gl, UniformMatrix2fv(
656 info.real_location, info.size, false, _))
657 .Times(1)
658 .RetiresOnSaturation();
659 break;
660 case GL_FLOAT_MAT3:
661 EXPECT_CALL(*gl, UniformMatrix3fv(
662 info.real_location, info.size, false, _))
663 .Times(1)
664 .RetiresOnSaturation();
665 break;
666 case GL_FLOAT_MAT4:
667 EXPECT_CALL(*gl, UniformMatrix4fv(
668 info.real_location, info.size, false, _))
669 .Times(1)
670 .RetiresOnSaturation();
671 break;
672 default:
673 NOTREACHED();
674 break;
679 void TestHelper::SetupProgramSuccessExpectations(
680 ::gfx::MockGLInterface* gl,
681 AttribInfo* attribs, size_t num_attribs,
682 UniformInfo* uniforms, size_t num_uniforms,
683 GLuint service_id) {
684 EXPECT_CALL(*gl,
685 GetProgramiv(service_id, GL_LINK_STATUS, _))
686 .WillOnce(SetArgumentPointee<2>(1))
687 .RetiresOnSaturation();
688 EXPECT_CALL(*gl,
689 GetProgramiv(service_id, GL_INFO_LOG_LENGTH, _))
690 .WillOnce(SetArgumentPointee<2>(0))
691 .RetiresOnSaturation();
692 EXPECT_CALL(*gl,
693 GetProgramiv(service_id, GL_ACTIVE_ATTRIBUTES, _))
694 .WillOnce(SetArgumentPointee<2>(num_attribs))
695 .RetiresOnSaturation();
696 size_t max_attrib_len = 0;
697 for (size_t ii = 0; ii < num_attribs; ++ii) {
698 size_t len = strlen(attribs[ii].name) + 1;
699 max_attrib_len = std::max(max_attrib_len, len);
701 EXPECT_CALL(*gl,
702 GetProgramiv(service_id, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, _))
703 .WillOnce(SetArgumentPointee<2>(max_attrib_len))
704 .RetiresOnSaturation();
706 for (size_t ii = 0; ii < num_attribs; ++ii) {
707 const AttribInfo& info = attribs[ii];
708 EXPECT_CALL(*gl,
709 GetActiveAttrib(service_id, ii,
710 max_attrib_len, _, _, _, _))
711 .WillOnce(DoAll(
712 SetArgumentPointee<3>(strlen(info.name)),
713 SetArgumentPointee<4>(info.size),
714 SetArgumentPointee<5>(info.type),
715 SetArrayArgument<6>(info.name,
716 info.name + strlen(info.name) + 1)))
717 .RetiresOnSaturation();
718 if (!ProgramManager::IsInvalidPrefix(info.name, strlen(info.name))) {
719 EXPECT_CALL(*gl, GetAttribLocation(service_id, StrEq(info.name)))
720 .WillOnce(Return(info.location))
721 .RetiresOnSaturation();
724 EXPECT_CALL(*gl,
725 GetProgramiv(service_id, GL_ACTIVE_UNIFORMS, _))
726 .WillOnce(SetArgumentPointee<2>(num_uniforms))
727 .RetiresOnSaturation();
729 size_t max_uniform_len = 0;
730 for (size_t ii = 0; ii < num_uniforms; ++ii) {
731 size_t len = strlen(uniforms[ii].name) + 1;
732 max_uniform_len = std::max(max_uniform_len, len);
734 EXPECT_CALL(*gl,
735 GetProgramiv(service_id, GL_ACTIVE_UNIFORM_MAX_LENGTH, _))
736 .WillOnce(SetArgumentPointee<2>(max_uniform_len))
737 .RetiresOnSaturation();
738 for (size_t ii = 0; ii < num_uniforms; ++ii) {
739 const UniformInfo& info = uniforms[ii];
740 EXPECT_CALL(*gl,
741 GetActiveUniform(service_id, ii,
742 max_uniform_len, _, _, _, _))
743 .WillOnce(DoAll(
744 SetArgumentPointee<3>(strlen(info.name)),
745 SetArgumentPointee<4>(info.size),
746 SetArgumentPointee<5>(info.type),
747 SetArrayArgument<6>(info.name,
748 info.name + strlen(info.name) + 1)))
749 .RetiresOnSaturation();
752 for (int pass = 0; pass < 2; ++pass) {
753 for (size_t ii = 0; ii < num_uniforms; ++ii) {
754 const UniformInfo& info = uniforms[ii];
755 if (pass == 0 && info.real_location != -1) {
756 EXPECT_CALL(*gl, GetUniformLocation(service_id, StrEq(info.name)))
757 .WillOnce(Return(info.real_location))
758 .RetiresOnSaturation();
760 if ((pass == 0 && info.desired_location >= 0) ||
761 (pass == 1 && info.desired_location < 0)) {
762 if (info.size > 1) {
763 std::string base_name = info.name;
764 size_t array_pos = base_name.rfind("[0]");
765 if (base_name.size() > 3 && array_pos == base_name.size() - 3) {
766 base_name = base_name.substr(0, base_name.size() - 3);
768 for (GLsizei jj = 1; jj < info.size; ++jj) {
769 std::string element_name(
770 std::string(base_name) + "[" + base::IntToString(jj) + "]");
771 EXPECT_CALL(*gl, GetUniformLocation(
772 service_id, StrEq(element_name)))
773 .WillOnce(Return(info.real_location + jj * 2))
774 .RetiresOnSaturation();
782 void TestHelper::SetupShader(
783 ::gfx::MockGLInterface* gl,
784 AttribInfo* attribs, size_t num_attribs,
785 UniformInfo* uniforms, size_t num_uniforms,
786 GLuint service_id) {
787 InSequence s;
789 EXPECT_CALL(*gl,
790 LinkProgram(service_id))
791 .Times(1)
792 .RetiresOnSaturation();
794 SetupProgramSuccessExpectations(
795 gl, attribs, num_attribs, uniforms, num_uniforms, service_id);
798 void TestHelper::DoBufferData(
799 ::gfx::MockGLInterface* gl, MockErrorState* error_state,
800 BufferManager* manager, Buffer* buffer, GLenum target, GLsizeiptr size,
801 GLenum usage, const GLvoid* data, GLenum error) {
802 EXPECT_CALL(*error_state, CopyRealGLErrorsToWrapper(_, _, _))
803 .Times(1)
804 .RetiresOnSaturation();
805 if (manager->IsUsageClientSideArray(usage)) {
806 EXPECT_CALL(*gl, BufferData(target, 0, _, usage))
807 .Times(1)
808 .RetiresOnSaturation();
809 } else {
810 EXPECT_CALL(*gl, BufferData(target, size, _, usage))
811 .Times(1)
812 .RetiresOnSaturation();
814 EXPECT_CALL(*error_state, PeekGLError(_, _, _))
815 .WillOnce(Return(error))
816 .RetiresOnSaturation();
817 manager->DoBufferData(error_state, buffer, target, size, usage, data);
820 void TestHelper::SetTexParameteriWithExpectations(
821 ::gfx::MockGLInterface* gl, MockErrorState* error_state,
822 TextureManager* manager, TextureRef* texture_ref,
823 GLenum pname, GLint value, GLenum error) {
824 if (error == GL_NO_ERROR) {
825 if (pname != GL_TEXTURE_POOL_CHROMIUM) {
826 EXPECT_CALL(*gl, TexParameteri(texture_ref->texture()->target(),
827 pname, value))
828 .Times(1)
829 .RetiresOnSaturation();
831 } else if (error == GL_INVALID_ENUM) {
832 EXPECT_CALL(*error_state, SetGLErrorInvalidEnum(_, _, _, value, _))
833 .Times(1)
834 .RetiresOnSaturation();
835 } else {
836 EXPECT_CALL(*error_state, SetGLErrorInvalidParami(_, _, error, _, _, _))
837 .Times(1)
838 .RetiresOnSaturation();
840 manager->SetParameteri("", error_state, texture_ref, pname, value);
843 // static
844 void TestHelper::SetShaderStates(
845 ::gfx::MockGLInterface* gl, Shader* shader,
846 bool expected_valid,
847 const std::string* const expected_log_info,
848 const std::string* const expected_translated_source,
849 const int* const expected_shader_version,
850 const AttributeMap* const expected_attrib_map,
851 const UniformMap* const expected_uniform_map,
852 const VaryingMap* const expected_varying_map,
853 const NameMap* const expected_name_map) {
854 const std::string empty_log_info;
855 const std::string* log_info = (expected_log_info && !expected_valid) ?
856 expected_log_info : &empty_log_info;
857 const std::string empty_translated_source;
858 const std::string* translated_source =
859 (expected_translated_source && expected_valid) ?
860 expected_translated_source : &empty_translated_source;
861 int default_shader_version = 100;
862 const int* shader_version = (expected_shader_version && expected_valid) ?
863 expected_shader_version : &default_shader_version;
864 const AttributeMap empty_attrib_map;
865 const AttributeMap* attrib_map = (expected_attrib_map && expected_valid) ?
866 expected_attrib_map : &empty_attrib_map;
867 const UniformMap empty_uniform_map;
868 const UniformMap* uniform_map = (expected_uniform_map && expected_valid) ?
869 expected_uniform_map : &empty_uniform_map;
870 const VaryingMap empty_varying_map;
871 const VaryingMap* varying_map = (expected_varying_map && expected_valid) ?
872 expected_varying_map : &empty_varying_map;
873 const NameMap empty_name_map;
874 const NameMap* name_map = (expected_name_map && expected_valid) ?
875 expected_name_map : &empty_name_map;
877 MockShaderTranslator* mock_translator = new MockShaderTranslator;
878 scoped_refptr<ShaderTranslatorInterface> translator(mock_translator);
879 EXPECT_CALL(*mock_translator, Translate(_,
880 NotNull(), // log_info
881 NotNull(), // translated_source
882 NotNull(), // shader_version
883 NotNull(), // attrib_map
884 NotNull(), // uniform_map
885 NotNull(), // varying_map
886 NotNull())) // name_map
887 .WillOnce(DoAll(SetArgumentPointee<1>(*log_info),
888 SetArgumentPointee<2>(*translated_source),
889 SetArgumentPointee<3>(*shader_version),
890 SetArgumentPointee<4>(*attrib_map),
891 SetArgumentPointee<5>(*uniform_map),
892 SetArgumentPointee<6>(*varying_map),
893 SetArgumentPointee<7>(*name_map),
894 Return(expected_valid)))
895 .RetiresOnSaturation();
896 if (expected_valid) {
897 EXPECT_CALL(*gl, ShaderSource(shader->service_id(), 1, _, NULL))
898 .Times(1)
899 .RetiresOnSaturation();
900 EXPECT_CALL(*gl, CompileShader(shader->service_id()))
901 .Times(1)
902 .RetiresOnSaturation();
903 EXPECT_CALL(*gl, GetShaderiv(shader->service_id(),
904 GL_COMPILE_STATUS,
905 NotNull())) // status
906 .WillOnce(SetArgumentPointee<2>(GL_TRUE))
907 .RetiresOnSaturation();
909 shader->RequestCompile(translator, Shader::kGL);
910 shader->DoCompile();
913 // static
914 void TestHelper::SetShaderStates(
915 ::gfx::MockGLInterface* gl, Shader* shader, bool valid) {
916 SetShaderStates(gl, shader, valid, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
919 // static
920 sh::Attribute TestHelper::ConstructAttribute(
921 GLenum type, GLint array_size, GLenum precision,
922 bool static_use, const std::string& name) {
923 return ConstructShaderVariable<sh::Attribute>(
924 type, array_size, precision, static_use, name);
927 // static
928 sh::Uniform TestHelper::ConstructUniform(
929 GLenum type, GLint array_size, GLenum precision,
930 bool static_use, const std::string& name) {
931 return ConstructShaderVariable<sh::Uniform>(
932 type, array_size, precision, static_use, name);
935 // static
936 sh::Varying TestHelper::ConstructVarying(
937 GLenum type, GLint array_size, GLenum precision,
938 bool static_use, const std::string& name) {
939 return ConstructShaderVariable<sh::Varying>(
940 type, array_size, precision, static_use, name);
943 ScopedGLImplementationSetter::ScopedGLImplementationSetter(
944 gfx::GLImplementation implementation)
945 : old_implementation_(gfx::GetGLImplementation()) {
946 gfx::SetGLImplementation(implementation);
949 ScopedGLImplementationSetter::~ScopedGLImplementationSetter() {
950 gfx::SetGLImplementation(old_implementation_);
953 } // namespace gles2
954 } // namespace gpu