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/shader_manager.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "gpu/command_buffer/service/gpu_service_test.h"
9 #include "gpu/command_buffer/service/mocks.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "ui/gl/gl_mock.h"
13 using ::testing::Return
;
14 using ::testing::ReturnRef
;
19 class ShaderManagerTest
: public GpuServiceTest
{
24 virtual ~ShaderManagerTest() {
25 manager_
.Destroy(false);
29 ShaderManager manager_
;
32 TEST_F(ShaderManagerTest
, Basic
) {
33 const GLuint kClient1Id
= 1;
34 const GLuint kService1Id
= 11;
35 const GLenum kShader1Type
= GL_VERTEX_SHADER
;
36 const GLuint kClient2Id
= 2;
37 // Check we can create shader.
38 Shader
* info0
= manager_
.CreateShader(
39 kClient1Id
, kService1Id
, kShader1Type
);
40 // Check shader got created.
41 ASSERT_TRUE(info0
!= NULL
);
42 Shader
* shader1
= manager_
.GetShader(kClient1Id
);
43 ASSERT_EQ(info0
, shader1
);
44 // Check we get nothing for a non-existent shader.
45 EXPECT_TRUE(manager_
.GetShader(kClient2Id
) == NULL
);
46 // Check we can't get the shader after we remove it.
47 manager_
.MarkAsDeleted(shader1
);
48 EXPECT_TRUE(manager_
.GetShader(kClient1Id
) == NULL
);
51 TEST_F(ShaderManagerTest
, Destroy
) {
52 const GLuint kClient1Id
= 1;
53 const GLuint kService1Id
= 11;
54 const GLenum kShader1Type
= GL_VERTEX_SHADER
;
55 // Check we can create shader.
56 Shader
* shader1
= manager_
.CreateShader(
57 kClient1Id
, kService1Id
, kShader1Type
);
58 // Check shader got created.
59 ASSERT_TRUE(shader1
!= NULL
);
60 EXPECT_CALL(*gl_
, DeleteShader(kService1Id
))
62 .RetiresOnSaturation();
63 manager_
.Destroy(true);
64 // Check that resources got freed.
65 shader1
= manager_
.GetShader(kClient1Id
);
66 ASSERT_TRUE(shader1
== NULL
);
69 TEST_F(ShaderManagerTest
, DeleteBug
) {
70 const GLuint kClient1Id
= 1;
71 const GLuint kClient2Id
= 2;
72 const GLuint kService1Id
= 11;
73 const GLuint kService2Id
= 12;
74 const GLenum kShaderType
= GL_VERTEX_SHADER
;
75 // Check we can create shader.
76 scoped_refptr
<Shader
> shader1(
77 manager_
.CreateShader(kClient1Id
, kService1Id
, kShaderType
));
78 scoped_refptr
<Shader
> shader2(
79 manager_
.CreateShader(kClient2Id
, kService2Id
, kShaderType
));
80 ASSERT_TRUE(shader1
.get());
81 ASSERT_TRUE(shader2
.get());
82 manager_
.UseShader(shader1
.get());
83 manager_
.MarkAsDeleted(shader1
.get());
84 manager_
.MarkAsDeleted(shader2
.get());
85 EXPECT_TRUE(manager_
.IsOwned(shader1
.get()));
86 EXPECT_FALSE(manager_
.IsOwned(shader2
.get()));
89 TEST_F(ShaderManagerTest
, Shader
) {
90 const GLuint kClient1Id
= 1;
91 const GLuint kService1Id
= 11;
92 const GLenum kShader1Type
= GL_VERTEX_SHADER
;
93 const char* kClient1Source
= "hello world";
94 // Check we can create shader.
95 Shader
* shader1
= manager_
.CreateShader(
96 kClient1Id
, kService1Id
, kShader1Type
);
97 // Check shader got created.
98 ASSERT_TRUE(shader1
!= NULL
);
99 EXPECT_EQ(kService1Id
, shader1
->service_id());
100 // Check if the shader has correct type.
101 EXPECT_EQ(kShader1Type
, shader1
->shader_type());
102 EXPECT_FALSE(shader1
->IsValid());
103 EXPECT_FALSE(shader1
->InUse());
104 EXPECT_TRUE(shader1
->source() == NULL
);
105 EXPECT_TRUE(shader1
->log_info() == NULL
);
106 const char* kLog
= "foo";
107 shader1
->SetStatus(true, kLog
, NULL
);
108 EXPECT_TRUE(shader1
->IsValid());
109 EXPECT_STREQ(kLog
, shader1
->log_info()->c_str());
110 // Check we can set its source.
111 shader1
->UpdateSource(kClient1Source
);
112 EXPECT_STREQ(kClient1Source
, shader1
->source()->c_str());
113 EXPECT_EQ(NULL
, shader1
->translated_source());
114 // Check we can set its translated source.
115 shader1
->UpdateTranslatedSource(kClient1Source
);
116 EXPECT_STREQ(kClient1Source
,
117 shader1
->translated_source()->c_str());
120 TEST_F(ShaderManagerTest
, GetInfo
) {
121 const GLuint kClient1Id
= 1;
122 const GLuint kService1Id
= 11;
123 const GLenum kShader1Type
= GL_VERTEX_SHADER
;
124 const GLenum kAttrib1Type
= GL_FLOAT_VEC2
;
125 const GLsizei kAttrib1Size
= 2;
126 const int kAttrib1Precision
= SH_PRECISION_MEDIUMP
;
127 const char* kAttrib1Name
= "attr1";
128 const GLenum kAttrib2Type
= GL_FLOAT_VEC3
;
129 const GLsizei kAttrib2Size
= 4;
130 const int kAttrib2Precision
= SH_PRECISION_HIGHP
;
131 const char* kAttrib2Name
= "attr2";
132 const int kAttribStaticUse
= 0;
133 const GLenum kUniform1Type
= GL_FLOAT_MAT2
;
134 const GLsizei kUniform1Size
= 3;
135 const int kUniform1Precision
= SH_PRECISION_LOWP
;
136 const int kUniform1StaticUse
= 1;
137 const char* kUniform1Name
= "uni1";
138 const GLenum kUniform2Type
= GL_FLOAT_MAT3
;
139 const GLsizei kUniform2Size
= 5;
140 const int kUniform2Precision
= SH_PRECISION_MEDIUMP
;
141 const int kUniform2StaticUse
= 0;
142 const char* kUniform2Name
= "uni2";
144 MockShaderTranslator shader_translator
;
145 ShaderTranslator::VariableMap attrib_map
;
146 attrib_map
[kAttrib1Name
] = ShaderTranslatorInterface::VariableInfo(
147 kAttrib1Type
, kAttrib1Size
, kAttrib1Precision
,
148 kAttribStaticUse
, kAttrib1Name
);
149 attrib_map
[kAttrib2Name
] = ShaderTranslatorInterface::VariableInfo(
150 kAttrib2Type
, kAttrib2Size
, kAttrib2Precision
,
151 kAttribStaticUse
, kAttrib2Name
);
152 ShaderTranslator::VariableMap uniform_map
;
153 uniform_map
[kUniform1Name
] = ShaderTranslatorInterface::VariableInfo(
154 kUniform1Type
, kUniform1Size
, kUniform1Precision
,
155 kUniform1StaticUse
, kUniform1Name
);
156 uniform_map
[kUniform2Name
] = ShaderTranslatorInterface::VariableInfo(
157 kUniform2Type
, kUniform2Size
, kUniform2Precision
,
158 kUniform2StaticUse
, kUniform2Name
);
159 EXPECT_CALL(shader_translator
, attrib_map())
160 .WillRepeatedly(ReturnRef(attrib_map
));
161 EXPECT_CALL(shader_translator
, uniform_map())
162 .WillRepeatedly(ReturnRef(uniform_map
));
163 ShaderTranslator::VariableMap varying_map
;
164 EXPECT_CALL(shader_translator
, varying_map())
165 .WillRepeatedly(ReturnRef(varying_map
));
166 ShaderTranslator::NameMap name_map
;
167 EXPECT_CALL(shader_translator
, name_map())
168 .WillRepeatedly(ReturnRef(name_map
));
169 // Check we can create shader.
170 Shader
* shader1
= manager_
.CreateShader(
171 kClient1Id
, kService1Id
, kShader1Type
);
172 // Check shader got created.
173 ASSERT_TRUE(shader1
!= NULL
);
175 shader1
->SetStatus(true, "", &shader_translator
);
176 // Check attrib and uniform infos got copied.
177 for (ShaderTranslator::VariableMap::const_iterator it
= attrib_map
.begin();
178 it
!= attrib_map
.end(); ++it
) {
179 const Shader::VariableInfo
* variable_info
=
180 shader1
->GetAttribInfo(it
->first
);
181 ASSERT_TRUE(variable_info
!= NULL
);
182 EXPECT_EQ(it
->second
.type
, variable_info
->type
);
183 EXPECT_EQ(it
->second
.size
, variable_info
->size
);
184 EXPECT_EQ(it
->second
.precision
, variable_info
->precision
);
185 EXPECT_EQ(it
->second
.static_use
, variable_info
->static_use
);
186 EXPECT_EQ(it
->second
.name
, variable_info
->name
);
188 for (ShaderTranslator::VariableMap::const_iterator it
= uniform_map
.begin();
189 it
!= uniform_map
.end(); ++it
) {
190 const Shader::VariableInfo
* variable_info
=
191 shader1
->GetUniformInfo(it
->first
);
192 ASSERT_TRUE(variable_info
!= NULL
);
193 EXPECT_EQ(it
->second
.type
, variable_info
->type
);
194 EXPECT_EQ(it
->second
.size
, variable_info
->size
);
195 EXPECT_EQ(it
->second
.precision
, variable_info
->precision
);
196 EXPECT_EQ(it
->second
.static_use
, variable_info
->static_use
);
197 EXPECT_EQ(it
->second
.name
, variable_info
->name
);
199 // Check attrib and uniform get cleared.
200 shader1
->SetStatus(true, NULL
, NULL
);
201 EXPECT_TRUE(shader1
->log_info() == NULL
);
202 for (ShaderTranslator::VariableMap::const_iterator it
= attrib_map
.begin();
203 it
!= attrib_map
.end(); ++it
) {
204 const Shader::VariableInfo
* variable_info
=
205 shader1
->GetAttribInfo(it
->first
);
206 EXPECT_TRUE(variable_info
== NULL
);
208 for (ShaderTranslator::VariableMap::const_iterator it
= uniform_map
.begin();
209 it
!= uniform_map
.end(); ++it
) {
210 const Shader::VariableInfo
* variable_info
=
211 shader1
->GetUniformInfo(it
->first
);
212 ASSERT_TRUE(variable_info
== NULL
);
216 TEST_F(ShaderManagerTest
, ShaderInfoUseCount
) {
217 const GLuint kClient1Id
= 1;
218 const GLuint kService1Id
= 11;
219 const GLenum kShader1Type
= GL_VERTEX_SHADER
;
220 // Check we can create shader.
221 Shader
* shader1
= manager_
.CreateShader(
222 kClient1Id
, kService1Id
, kShader1Type
);
223 // Check shader got created.
224 ASSERT_TRUE(shader1
!= NULL
);
225 EXPECT_FALSE(shader1
->InUse());
226 EXPECT_FALSE(shader1
->IsDeleted());
227 manager_
.UseShader(shader1
);
228 EXPECT_TRUE(shader1
->InUse());
229 manager_
.UseShader(shader1
);
230 EXPECT_TRUE(shader1
->InUse());
231 manager_
.MarkAsDeleted(shader1
);
232 EXPECT_TRUE(shader1
->IsDeleted());
233 Shader
* shader2
= manager_
.GetShader(kClient1Id
);
234 EXPECT_EQ(shader1
, shader2
);
235 manager_
.UnuseShader(shader1
);
236 EXPECT_TRUE(shader1
->InUse());
237 manager_
.UnuseShader(shader1
); // this should delete the info.
238 shader2
= manager_
.GetShader(kClient1Id
);
239 EXPECT_TRUE(shader2
== NULL
);
241 shader1
= manager_
.CreateShader(kClient1Id
, kService1Id
, kShader1Type
);
242 ASSERT_TRUE(shader1
!= NULL
);
243 EXPECT_FALSE(shader1
->InUse());
244 manager_
.UseShader(shader1
);
245 EXPECT_TRUE(shader1
->InUse());
246 manager_
.UseShader(shader1
);
247 EXPECT_TRUE(shader1
->InUse());
248 manager_
.UnuseShader(shader1
);
249 EXPECT_TRUE(shader1
->InUse());
250 manager_
.UnuseShader(shader1
);
251 EXPECT_FALSE(shader1
->InUse());
252 shader2
= manager_
.GetShader(kClient1Id
);
253 EXPECT_EQ(shader1
, shader2
);
254 manager_
.MarkAsDeleted(shader1
); // this should delete the shader.
255 shader2
= manager_
.GetShader(kClient1Id
);
256 EXPECT_TRUE(shader2
== NULL
);