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"
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"
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
;
42 T
ConstructShaderVariable(
43 GLenum type
, GLint array_size
, GLenum precision
,
44 bool static_use
, const std::string
& name
) {
47 var
.arraySize
= array_size
;
48 var
.precision
= precision
;
49 var
.staticUse
= static_use
;
51 var
.mappedName
= name
; // No name hashing.
55 } // namespace anonymous
57 // GCC requires these declarations, but MSVC requires they not be present
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
;
90 std::vector
<std::string
> TestHelper::split_extensions_
;
92 void TestHelper::SetupTextureInitializationExpectations(
93 ::gfx::MockGLInterface
* gl
,
95 bool use_default_textures
) {
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
;
125 texture_ids
= &texture_2d_ids
[0];
128 texture_ids
= &texture_3d_ids
[0];
130 case GL_TEXTURE_2D_ARRAY
:
131 texture_ids
= &texture_2d_array_ids
[0];
133 case GL_TEXTURE_CUBE_MAP
:
134 texture_ids
= &texture_cube_map_ids
[0];
136 case GL_TEXTURE_EXTERNAL_OES
:
137 texture_ids
= &texture_external_oes_ids
[0];
139 case GL_TEXTURE_RECTANGLE_ARB
:
140 texture_ids
= &texture_rectangle_arb_ids
[0];
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
]))
155 .RetiresOnSaturation();
156 if (needs_initialization
) {
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
, _
))
170 .RetiresOnSaturation();
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
, _
))
177 .RetiresOnSaturation();
179 EXPECT_CALL(*gl
, TexImage2D(target
, 0, GL_RGBA
, 1, 1, 0, GL_RGBA
,
180 GL_UNSIGNED_BYTE
, _
))
182 .RetiresOnSaturation();
187 EXPECT_CALL(*gl
, BindTexture(target
, 0))
189 .RetiresOnSaturation();
192 void TestHelper::SetupTextureManagerInitExpectations(
193 ::gfx::MockGLInterface
* gl
,
195 const char* extensions
,
196 bool use_default_textures
) {
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;
219 if (t
.token() == "GL_ARB_texture_rectangle") {
220 arb_texture_rectangle
= true;
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
,
238 bool use_default_textures
) {
239 if (!use_default_textures
)
242 GLuint texture_id
= 0;
245 texture_id
= kServiceDefaultTexture2dId
;
248 texture_id
= kServiceDefaultTexture3dId
;
250 case GL_TEXTURE_2D_ARRAY
:
251 texture_id
= kServiceDefaultTexture2dArrayId
;
253 case GL_TEXTURE_CUBE_MAP
:
254 texture_id
= kServiceDefaultTextureCubemapId
;
256 case GL_TEXTURE_EXTERNAL_OES
:
257 texture_id
= kServiceDefaultExternalTextureId
;
259 case GL_TEXTURE_RECTANGLE_ARB
:
260 texture_id
= kServiceDefaultRectangleTextureId
;
266 EXPECT_CALL(*gl
, DeleteTextures(1, Pointee(texture_id
)))
268 .RetiresOnSaturation();
271 void TestHelper::SetupTextureManagerDestructionExpectations(
272 ::gfx::MockGLInterface
* gl
,
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;
295 if (t
.token() == "GL_ARB_texture_rectangle") {
296 arb_texture_rectangle
= true;
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
, _
))
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
) {
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") ||
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();
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();
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
) {
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();
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();
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]))
463 .RetiresOnSaturation();
464 EXPECT_CALL(*gl
, TexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
,
467 .RetiresOnSaturation();
468 EXPECT_CALL(*gl
, TexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA32F
, width
, width
, 0,
469 GL_RGBA
, GL_FLOAT
, _
))
471 .RetiresOnSaturation();
472 EXPECT_CALL(*gl
, BindFramebufferEXT(GL_FRAMEBUFFER
, fb_ids
[1]))
474 .RetiresOnSaturation();
475 EXPECT_CALL(*gl
, FramebufferTexture2DEXT(GL_FRAMEBUFFER
,
476 GL_COLOR_ATTACHMENT0
, GL_TEXTURE_2D
, tx_ids
[1], 0))
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
, _
))
485 .RetiresOnSaturation();
486 if (gl_info
.is_es3
) {
487 EXPECT_CALL(*gl
, CheckFramebufferStatusEXT(GL_FRAMEBUFFER
))
488 .WillOnce(Return(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
))
489 .RetiresOnSaturation();
491 EXPECT_CALL(*gl
, CheckFramebufferStatusEXT(GL_FRAMEBUFFER
))
492 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE
))
493 .RetiresOnSaturation();
495 EXPECT_CALL(*gl
, DeleteFramebuffersEXT(1, _
))
497 .RetiresOnSaturation();
498 EXPECT_CALL(*gl
, DeleteTextures(1, _
))
500 .RetiresOnSaturation();
501 EXPECT_CALL(*gl
, BindFramebufferEXT(GL_FRAMEBUFFER
, fb_ids
[0]))
503 .RetiresOnSaturation();
504 EXPECT_CALL(*gl
, BindTexture(GL_TEXTURE_2D
, tx_ids
[0]))
506 .RetiresOnSaturation();
508 EXPECT_CALL(*gl
, GetError())
509 .WillOnce(Return(GL_NO_ERROR
))
510 .RetiresOnSaturation();
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]))
541 .RetiresOnSaturation();
542 EXPECT_CALL(*gl
, TexImage2D(GL_TEXTURE_2D
, 0, _
, width
, width
, 0,
543 GL_RED_EXT
, GL_UNSIGNED_BYTE
, _
))
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]))
551 .RetiresOnSaturation();
552 EXPECT_CALL(*gl
, FramebufferTexture2DEXT(GL_FRAMEBUFFER
,
553 GL_COLOR_ATTACHMENT0
, GL_TEXTURE_2D
, tx_ids
[1], 0))
555 .RetiresOnSaturation();
556 EXPECT_CALL(*gl
, CheckFramebufferStatusEXT(GL_FRAMEBUFFER
))
557 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE
))
558 .RetiresOnSaturation();
559 EXPECT_CALL(*gl
, DeleteFramebuffersEXT(1, _
))
561 .RetiresOnSaturation();
562 EXPECT_CALL(*gl
, DeleteTextures(1, _
))
564 .RetiresOnSaturation();
565 EXPECT_CALL(*gl
, BindFramebufferEXT(GL_FRAMEBUFFER
, fb_ids
[0]))
567 .RetiresOnSaturation();
568 EXPECT_CALL(*gl
, BindTexture(GL_TEXTURE_2D
, tx_ids
[0]))
570 .RetiresOnSaturation();
572 EXPECT_CALL(*gl
, GetError())
573 .WillOnce(Return(GL_NO_ERROR
))
574 .RetiresOnSaturation();
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
];
585 EXPECT_CALL(*gl
, Uniform1fv(info
.real_location
, info
.size
, _
))
587 .RetiresOnSaturation();
590 EXPECT_CALL(*gl
, Uniform2fv(info
.real_location
, info
.size
, _
))
592 .RetiresOnSaturation();
595 EXPECT_CALL(*gl
, Uniform3fv(info
.real_location
, info
.size
, _
))
597 .RetiresOnSaturation();
600 EXPECT_CALL(*gl
, Uniform4fv(info
.real_location
, info
.size
, _
))
602 .RetiresOnSaturation();
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
, _
))
614 .RetiresOnSaturation();
616 case GL_UNSIGNED_INT
:
617 EXPECT_CALL(*gl
, Uniform1uiv(info
.real_location
, info
.size
, _
))
619 .RetiresOnSaturation();
623 EXPECT_CALL(*gl
, Uniform2iv(info
.real_location
, info
.size
, _
))
625 .RetiresOnSaturation();
627 case GL_UNSIGNED_INT_VEC2
:
628 EXPECT_CALL(*gl
, Uniform2uiv(info
.real_location
, info
.size
, _
))
630 .RetiresOnSaturation();
634 EXPECT_CALL(*gl
, Uniform3iv(info
.real_location
, info
.size
, _
))
636 .RetiresOnSaturation();
638 case GL_UNSIGNED_INT_VEC3
:
639 EXPECT_CALL(*gl
, Uniform3uiv(info
.real_location
, info
.size
, _
))
641 .RetiresOnSaturation();
645 EXPECT_CALL(*gl
, Uniform4iv(info
.real_location
, info
.size
, _
))
647 .RetiresOnSaturation();
649 case GL_UNSIGNED_INT_VEC4
:
650 EXPECT_CALL(*gl
, Uniform4uiv(info
.real_location
, info
.size
, _
))
652 .RetiresOnSaturation();
655 EXPECT_CALL(*gl
, UniformMatrix2fv(
656 info
.real_location
, info
.size
, false, _
))
658 .RetiresOnSaturation();
661 EXPECT_CALL(*gl
, UniformMatrix3fv(
662 info
.real_location
, info
.size
, false, _
))
664 .RetiresOnSaturation();
667 EXPECT_CALL(*gl
, UniformMatrix4fv(
668 info
.real_location
, info
.size
, false, _
))
670 .RetiresOnSaturation();
679 void TestHelper::SetupProgramSuccessExpectations(
680 ::gfx::MockGLInterface
* gl
,
681 AttribInfo
* attribs
, size_t num_attribs
,
682 UniformInfo
* uniforms
, size_t num_uniforms
,
685 GetProgramiv(service_id
, GL_LINK_STATUS
, _
))
686 .WillOnce(SetArgumentPointee
<2>(1))
687 .RetiresOnSaturation();
689 GetProgramiv(service_id
, GL_INFO_LOG_LENGTH
, _
))
690 .WillOnce(SetArgumentPointee
<2>(0))
691 .RetiresOnSaturation();
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
);
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
];
709 GetActiveAttrib(service_id
, ii
,
710 max_attrib_len
, _
, _
, _
, _
))
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();
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
);
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
];
741 GetActiveUniform(service_id
, ii
,
742 max_uniform_len
, _
, _
, _
, _
))
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)) {
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
,
790 LinkProgram(service_id
))
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(_
, _
, _
))
804 .RetiresOnSaturation();
805 if (manager
->IsUsageClientSideArray(usage
)) {
806 EXPECT_CALL(*gl
, BufferData(target
, 0, _
, usage
))
808 .RetiresOnSaturation();
810 EXPECT_CALL(*gl
, BufferData(target
, size
, _
, usage
))
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(),
829 .RetiresOnSaturation();
831 } else if (error
== GL_INVALID_ENUM
) {
832 EXPECT_CALL(*error_state
, SetGLErrorInvalidEnum(_
, _
, _
, value
, _
))
834 .RetiresOnSaturation();
836 EXPECT_CALL(*error_state
, SetGLErrorInvalidParami(_
, _
, error
, _
, _
, _
))
838 .RetiresOnSaturation();
840 manager
->SetParameteri("", error_state
, texture_ref
, pname
, value
);
844 void TestHelper::SetShaderStates(
845 ::gfx::MockGLInterface
* gl
, Shader
* shader
,
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
))
899 .RetiresOnSaturation();
900 EXPECT_CALL(*gl
, CompileShader(shader
->service_id()))
902 .RetiresOnSaturation();
903 EXPECT_CALL(*gl
, GetShaderiv(shader
->service_id(),
905 NotNull())) // status
906 .WillOnce(SetArgumentPointee
<2>(GL_TRUE
))
907 .RetiresOnSaturation();
909 shader
->RequestCompile(translator
, Shader::kGL
);
914 void TestHelper::SetShaderStates(
915 ::gfx::MockGLInterface
* gl
, Shader
* shader
, bool valid
) {
916 SetShaderStates(gl
, shader
, valid
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
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
);
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
);
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_
);