blob: a225a3cc8c170712002704afcf77b7e22433c5ce [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// 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/shader_manager.h"
6
7#include "base/memory/scoped_ptr.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +00008#include "gpu/command_buffer/service/mocks.h"
9#include "testing/gtest/include/gtest/gtest.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000010#include "ui/gl/gl_mock.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000011
12using ::testing::Return;
13using ::testing::ReturnRef;
14
15namespace gpu {
16namespace gles2 {
17
18class ShaderManagerTest : public testing::Test {
19 public:
20 ShaderManagerTest() {
21 }
22
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000023 virtual ~ShaderManagerTest() {
Torne (Richard Coles)58218062012-11-14 11:43:16 +000024 manager_.Destroy(false);
25 }
26
27 protected:
28 virtual void SetUp() {
29 gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>());
30 ::gfx::GLInterface::SetGLInterface(gl_.get());
31 }
32
33 virtual void TearDown() {
34 ::gfx::GLInterface::SetGLInterface(NULL);
35 gl_.reset();
36 }
37
38 // Use StrictMock to make 100% sure we know how GL will be called.
39 scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_;
40 ShaderManager manager_;
41};
42
43TEST_F(ShaderManagerTest, Basic) {
44 const GLuint kClient1Id = 1;
45 const GLuint kService1Id = 11;
46 const GLenum kShader1Type = GL_VERTEX_SHADER;
47 const GLuint kClient2Id = 2;
48 // Check we can create shader.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000049 Shader* info0 = manager_.CreateShader(
Torne (Richard Coles)58218062012-11-14 11:43:16 +000050 kClient1Id, kService1Id, kShader1Type);
51 // Check shader got created.
52 ASSERT_TRUE(info0 != NULL);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000053 Shader* shader1 = manager_.GetShader(kClient1Id);
54 ASSERT_EQ(info0, shader1);
Torne (Richard Coles)58218062012-11-14 11:43:16 +000055 // Check we get nothing for a non-existent shader.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000056 EXPECT_TRUE(manager_.GetShader(kClient2Id) == NULL);
Torne (Richard Coles)58218062012-11-14 11:43:16 +000057 // Check we can't get the shader after we remove it.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000058 manager_.MarkAsDeleted(shader1);
59 EXPECT_TRUE(manager_.GetShader(kClient1Id) == NULL);
Torne (Richard Coles)58218062012-11-14 11:43:16 +000060}
61
62TEST_F(ShaderManagerTest, Destroy) {
63 const GLuint kClient1Id = 1;
64 const GLuint kService1Id = 11;
65 const GLenum kShader1Type = GL_VERTEX_SHADER;
66 // Check we can create shader.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000067 Shader* shader1 = manager_.CreateShader(
Torne (Richard Coles)58218062012-11-14 11:43:16 +000068 kClient1Id, kService1Id, kShader1Type);
69 // Check shader got created.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000070 ASSERT_TRUE(shader1 != NULL);
Torne (Richard Coles)58218062012-11-14 11:43:16 +000071 EXPECT_CALL(*gl_, DeleteShader(kService1Id))
72 .Times(1)
73 .RetiresOnSaturation();
74 manager_.Destroy(true);
75 // Check that resources got freed.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000076 shader1 = manager_.GetShader(kClient1Id);
77 ASSERT_TRUE(shader1 == NULL);
Torne (Richard Coles)58218062012-11-14 11:43:16 +000078}
79
80TEST_F(ShaderManagerTest, DeleteBug) {
81 const GLuint kClient1Id = 1;
82 const GLuint kClient2Id = 2;
83 const GLuint kService1Id = 11;
84 const GLuint kService2Id = 12;
85 const GLenum kShaderType = GL_VERTEX_SHADER;
86 // Check we can create shader.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000087 scoped_refptr<Shader> shader1(
88 manager_.CreateShader(kClient1Id, kService1Id, kShaderType));
89 scoped_refptr<Shader> shader2(
90 manager_.CreateShader(kClient2Id, kService2Id, kShaderType));
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010091 ASSERT_TRUE(shader1.get());
92 ASSERT_TRUE(shader2.get());
93 manager_.UseShader(shader1.get());
94 manager_.MarkAsDeleted(shader1.get());
95 manager_.MarkAsDeleted(shader2.get());
96 EXPECT_TRUE(manager_.IsOwned(shader1.get()));
97 EXPECT_FALSE(manager_.IsOwned(shader2.get()));
Torne (Richard Coles)58218062012-11-14 11:43:16 +000098}
99
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000100TEST_F(ShaderManagerTest, Shader) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000101 const GLuint kClient1Id = 1;
102 const GLuint kService1Id = 11;
103 const GLenum kShader1Type = GL_VERTEX_SHADER;
104 const char* kClient1Source = "hello world";
105 // Check we can create shader.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000106 Shader* shader1 = manager_.CreateShader(
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000107 kClient1Id, kService1Id, kShader1Type);
108 // Check shader got created.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000109 ASSERT_TRUE(shader1 != NULL);
110 EXPECT_EQ(kService1Id, shader1->service_id());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000111 // Check if the shader has correct type.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000112 EXPECT_EQ(kShader1Type, shader1->shader_type());
113 EXPECT_FALSE(shader1->IsValid());
114 EXPECT_FALSE(shader1->InUse());
115 EXPECT_TRUE(shader1->source() == NULL);
116 EXPECT_TRUE(shader1->log_info() == NULL);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000117 const char* kLog = "foo";
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000118 shader1->SetStatus(true, kLog, NULL);
119 EXPECT_TRUE(shader1->IsValid());
120 EXPECT_STREQ(kLog, shader1->log_info()->c_str());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000121 // Check we can set its source.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000122 shader1->UpdateSource(kClient1Source);
123 EXPECT_STREQ(kClient1Source, shader1->source()->c_str());
124 EXPECT_EQ(NULL, shader1->translated_source());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000125 // Check we can set its translated source.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000126 shader1->UpdateTranslatedSource(kClient1Source);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000127 EXPECT_STREQ(kClient1Source,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000128 shader1->translated_source()->c_str());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000129}
130
131TEST_F(ShaderManagerTest, GetInfo) {
132 const GLuint kClient1Id = 1;
133 const GLuint kService1Id = 11;
134 const GLenum kShader1Type = GL_VERTEX_SHADER;
135 const GLenum kAttrib1Type = GL_FLOAT_VEC2;
136 const GLsizei kAttrib1Size = 2;
137 const char* kAttrib1Name = "attr1";
138 const GLenum kAttrib2Type = GL_FLOAT_VEC3;
139 const GLsizei kAttrib2Size = 4;
140 const char* kAttrib2Name = "attr2";
141 const GLenum kUniform1Type = GL_FLOAT_MAT2;
142 const GLsizei kUniform1Size = 3;
143 const char* kUniform1Name = "uni1";
144 const GLenum kUniform2Type = GL_FLOAT_MAT3;
145 const GLsizei kUniform2Size = 5;
146 const char* kUniform2Name = "uni2";
147 MockShaderTranslator shader_translator;
148 ShaderTranslator::VariableMap attrib_map;
149 attrib_map[kAttrib1Name] = ShaderTranslatorInterface::VariableInfo(
150 kAttrib1Type, kAttrib1Size, kAttrib1Name);
151 attrib_map[kAttrib2Name] = ShaderTranslatorInterface::VariableInfo(
152 kAttrib2Type, kAttrib2Size, kAttrib2Name);
153 ShaderTranslator::VariableMap uniform_map;
154 uniform_map[kUniform1Name] = ShaderTranslatorInterface::VariableInfo(
155 kUniform1Type, kUniform1Size, kUniform1Name);
156 uniform_map[kUniform2Name] = ShaderTranslatorInterface::VariableInfo(
157 kUniform2Type, kUniform2Size, kUniform2Name);
158 EXPECT_CALL(shader_translator, attrib_map())
159 .WillRepeatedly(ReturnRef(attrib_map));
160 EXPECT_CALL(shader_translator, uniform_map())
161 .WillRepeatedly(ReturnRef(uniform_map));
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000162 ShaderTranslator::NameMap name_map;
163 EXPECT_CALL(shader_translator, name_map())
164 .WillRepeatedly(ReturnRef(name_map));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000165 // Check we can create shader.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000166 Shader* shader1 = manager_.CreateShader(
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000167 kClient1Id, kService1Id, kShader1Type);
168 // Check shader got created.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000169 ASSERT_TRUE(shader1 != NULL);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000170 // Set Status
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000171 shader1->SetStatus(true, "", &shader_translator);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000172 // Check attrib and uniform infos got copied.
173 for (ShaderTranslator::VariableMap::const_iterator it = attrib_map.begin();
174 it != attrib_map.end(); ++it) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000175 const Shader::VariableInfo* variable_info =
176 shader1->GetAttribInfo(it->first);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000177 ASSERT_TRUE(variable_info != NULL);
178 EXPECT_EQ(it->second.type, variable_info->type);
179 EXPECT_EQ(it->second.size, variable_info->size);
180 EXPECT_EQ(it->second.name, variable_info->name);
181 }
182 for (ShaderTranslator::VariableMap::const_iterator it = uniform_map.begin();
183 it != uniform_map.end(); ++it) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000184 const Shader::VariableInfo* variable_info =
185 shader1->GetUniformInfo(it->first);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000186 ASSERT_TRUE(variable_info != NULL);
187 EXPECT_EQ(it->second.type, variable_info->type);
188 EXPECT_EQ(it->second.size, variable_info->size);
189 EXPECT_EQ(it->second.name, variable_info->name);
190 }
191 // Check attrib and uniform get cleared.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000192 shader1->SetStatus(true, NULL, NULL);
193 EXPECT_TRUE(shader1->log_info() == NULL);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000194 for (ShaderTranslator::VariableMap::const_iterator it = attrib_map.begin();
195 it != attrib_map.end(); ++it) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000196 const Shader::VariableInfo* variable_info =
197 shader1->GetAttribInfo(it->first);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000198 EXPECT_TRUE(variable_info == NULL);
199 }
200 for (ShaderTranslator::VariableMap::const_iterator it = uniform_map.begin();
201 it != uniform_map.end(); ++it) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000202 const Shader::VariableInfo* variable_info =
203 shader1->GetUniformInfo(it->first);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000204 ASSERT_TRUE(variable_info == NULL);
205 }
206}
207
208TEST_F(ShaderManagerTest, ShaderInfoUseCount) {
209 const GLuint kClient1Id = 1;
210 const GLuint kService1Id = 11;
211 const GLenum kShader1Type = GL_VERTEX_SHADER;
212 // Check we can create shader.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000213 Shader* shader1 = manager_.CreateShader(
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000214 kClient1Id, kService1Id, kShader1Type);
215 // Check shader got created.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000216 ASSERT_TRUE(shader1 != NULL);
217 EXPECT_FALSE(shader1->InUse());
218 EXPECT_FALSE(shader1->IsDeleted());
219 manager_.UseShader(shader1);
220 EXPECT_TRUE(shader1->InUse());
221 manager_.UseShader(shader1);
222 EXPECT_TRUE(shader1->InUse());
223 manager_.MarkAsDeleted(shader1);
224 EXPECT_TRUE(shader1->IsDeleted());
225 Shader* shader2 = manager_.GetShader(kClient1Id);
226 EXPECT_EQ(shader1, shader2);
227 manager_.UnuseShader(shader1);
228 EXPECT_TRUE(shader1->InUse());
229 manager_.UnuseShader(shader1); // this should delete the info.
230 shader2 = manager_.GetShader(kClient1Id);
231 EXPECT_TRUE(shader2 == NULL);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000232
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000233 shader1 = manager_.CreateShader(kClient1Id, kService1Id, kShader1Type);
234 ASSERT_TRUE(shader1 != NULL);
235 EXPECT_FALSE(shader1->InUse());
236 manager_.UseShader(shader1);
237 EXPECT_TRUE(shader1->InUse());
238 manager_.UseShader(shader1);
239 EXPECT_TRUE(shader1->InUse());
240 manager_.UnuseShader(shader1);
241 EXPECT_TRUE(shader1->InUse());
242 manager_.UnuseShader(shader1);
243 EXPECT_FALSE(shader1->InUse());
244 shader2 = manager_.GetShader(kClient1Id);
245 EXPECT_EQ(shader1, shader2);
246 manager_.MarkAsDeleted(shader1); // this should delete the shader.
247 shader2 = manager_.GetShader(kClient1Id);
248 EXPECT_TRUE(shader2 == NULL);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000249}
250
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000251} // namespace gles2
252} // namespace gpu