Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Side by Side Diff: gpu/command_buffer/service/memory_program_cache_unittest.cc

Issue 10534173: GPU Program Caching (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Style fixes, thorough tests Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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/memory_program_cache.h"
6
7 #include "gpu/command_buffer/common/gl_mock.h"
8 #include "gpu/command_buffer/common/gles2_cmd_format.h"
9 #include "gpu/command_buffer/service/gl_utils.h"
10 #include "gpu/command_buffer/service/shader_translator.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "ui/gl/gl_bindings.h"
13
14 using ::testing::_;
15 using ::testing::SetArgPointee;
16 using ::testing::SetArrayArgument;
17 using ::testing::ElementsAreArray;
18
19 namespace gpu {
20 namespace gles2 {
21
22 // custom mock interface due to limitations of gmock with void*
greggman 2012/07/10 21:43:30 What is the limitation of gmock with void*? You c
dmurph 2012/07/11 23:32:52 Awesome, I was digging around forever to figure ou
23 class GLMockWithProgramBinary : public ::gfx::MockGLInterface {
24 public:
25 virtual void GetProgramBinary(GLuint program,
26 GLsizei bufSize,
greggman 2012/07/10 21:43:30 style: arguments are under_score
dmurph 2012/07/11 23:32:52 Done.
27 GLsizei* length,
28 GLenum* binaryFormat,
greggman 2012/07/10 21:43:30 style: arguments are under_score
dmurph 2012/07/11 23:32:52 Done.
29 GLvoid* binary) OVERRIDE {
30 EXPECT_EQ(program_, program);
31 EXPECT_EQ(length_, bufSize);
32 *length = length_;
33 *binaryFormat = format_;
34 memcpy(binary, binary_, length_);
35 get_called_ = true;
36 }
37
38 virtual void ProgramBinary(GLuint program,
39 GLenum format,
40 const GLvoid* binary,
41 GLsizei length) OVERRIDE {
42 const char* charBinary = static_cast<const char*>(binary);
43 EXPECT_EQ(program_, program);
44 EXPECT_EQ(format_, format);
45 EXPECT_EQ(length_, length);
46 for (int i = 0; i < length; i++) {
47 char expected = binary_[i];
48 EXPECT_EQ(expected, charBinary[i]);
49 }
50 binary_called_ = true;
51 }
52
53 void ExpectAndPopulateProgramBinaryCalls(GLuint program,
54 GLsizei length,
55 GLenum format,
56 char* binary) {
57 program_ = program;
58 length_ = length;
59 format_ = format;
60 binary_ = binary;
61 get_called_ = binary_called_ = false;
62 }
63
64 bool get_called() const {
65 return get_called_;
66 }
67
68 bool binary_called() const {
69 return binary_called_;
70 }
71
72 private:
73 bool get_called_;
74 bool binary_called_;
75 GLuint program_;
76 GLsizei length_;
77 GLenum format_;
78 char* binary_;
79 };
80
81 class MemoryProgramCacheTest : public testing::Test {
82 public:
83 static const size_t kCacheSizeBytes = 1024;
84 static const GLuint kVertexShaderClientId = 90;
85 static const GLuint kVertexShaderServiceId = 100;
86 static const GLuint kFragmentShaderClientId = 91;
87 static const GLuint kFragmentShaderServiceId = 100;
88
89 MemoryProgramCacheTest()
90 : cache_(new MemoryProgramCache(kCacheSizeBytes)),
91 vertex_shader_(NULL),
92 fragment_shader_(NULL) { }
93 ~MemoryProgramCacheTest() {
94 shader_manager_.Destroy(false);
95 }
96
97 protected:
98 virtual void SetUp() {
99 gl_.reset(new ::testing::StrictMock<GLMockWithProgramBinary>());
100 ::gfx::GLInterface::SetGLInterface(gl_.get());
101
102 vertex_shader_ = shader_manager_.CreateShaderInfo(kVertexShaderClientId,
103 kVertexShaderServiceId,
104 GL_VERTEX_SHADER);
105 fragment_shader_ = shader_manager_.CreateShaderInfo(
106 kFragmentShaderClientId,
107 kFragmentShaderServiceId,
108 GL_FRAGMENT_SHADER);
109 ASSERT_TRUE(vertex_shader_ != NULL);
110 ASSERT_TRUE(fragment_shader_ != NULL);
111 typedef ShaderTranslatorInterface::VariableInfo VariableInfo;
112 typedef ShaderTranslator::VariableMap VariableMap;
113 VariableMap vertex_attrib_map;
114 VariableMap vertex_uniform_map;
115 VariableMap fragment_attrib_map;
116 VariableMap fragment_uniform_map;
117
118 vertex_attrib_map["a"] = VariableInfo(1, 34, "a");
119 vertex_uniform_map["a"] = VariableInfo(0, 10, "a");
120 vertex_uniform_map["b"] = VariableInfo(2, 3114, "b");
121 fragment_attrib_map["jjjbb"] = VariableInfo(463, 1114, "jjjbb");
122 fragment_uniform_map["k"] = VariableInfo(10, 34413, "k");
123
124 vertex_shader_->SetAttribMap(vertex_attrib_map);
125 vertex_shader_->SetUniformMap(vertex_uniform_map);
126 fragment_shader_->SetAttribMap(vertex_attrib_map);
127 fragment_shader_->SetUniformMap(vertex_uniform_map);
128
129 vertex_shader_->UpdateSource("bbbalsldkdkdkd");
130 fragment_shader_->UpdateSource("bbbal sldkdkdkas 134 ad");
131
132 vertex_shader_->SetStatus(true, NULL, NULL);
133 fragment_shader_->SetStatus(true, NULL, NULL);
134 }
135
136 virtual void TearDown() {
137 ::gfx::GLInterface::SetGLInterface(NULL);
138 gl_.reset();
139 }
140 // Use StrictMock to make 100% sure we know how GL will be called.
141 scoped_ptr< ::testing::StrictMock<GLMockWithProgramBinary> > gl_;
142 scoped_ptr<MemoryProgramCache> cache_;
143 ShaderManager shader_manager_;
144 ShaderManager::ShaderInfo* vertex_shader_;
145 ShaderManager::ShaderInfo* fragment_shader_;
146 };
147
148 TEST_F(MemoryProgramCacheTest, MemoryProgramCacheSave) {
149 const GLenum kFormat = 1;
150 const int kProgramId = 10;
151 const int kBinaryLength = 20;
152 char testBinary[kBinaryLength];
153 for (int i = 0; i < kBinaryLength; ++i) {
154 testBinary[i] = i;
155 }
156 EXPECT_CALL(*gl_.get(),
157 GetProgramiv(kProgramId, GL_PROGRAM_BINARY_LENGTH_OES, _))
158 .WillOnce(SetArgPointee<2>(kBinaryLength));
159 gl_->ExpectAndPopulateProgramBinaryCalls(kProgramId,
greggman 2012/07/10 21:43:30 Is seems better to use gmock for all this?
dmurph 2012/07/11 23:32:52 Definitely. Thanks for the tip above.
160 kBinaryLength,
161 kFormat,
162 testBinary);
163
164 cache_->SaveLinkedProgram(kProgramId, vertex_shader_, fragment_shader_, NULL);
165 EXPECT_TRUE(gl_->get_called());
166
167 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus(
168 *vertex_shader_->source(),
169 *fragment_shader_->source(),
170 NULL));
171 }
172
173 TEST_F(MemoryProgramCacheTest, MemoryProgramCacheLoad) {
174 typedef ShaderTranslator::VariableMap VariableMap;
175 const GLenum kFormat = 1;
176 const int kProgramId = 10;
177 const int kBinaryLength = 20;
178 char testBinary[kBinaryLength];
179 for (int i = 0; i < kBinaryLength; ++i) {
180 testBinary[i] = i;
181 }
182 EXPECT_CALL(*gl_.get(),
183 GetProgramiv(kProgramId, GL_PROGRAM_BINARY_LENGTH_OES, _))
184 .WillOnce(SetArgPointee<2>(kBinaryLength));
185 gl_->ExpectAndPopulateProgramBinaryCalls(kProgramId,
186 kBinaryLength,
187 kFormat,
188 testBinary);
189
190 cache_->SaveLinkedProgram(kProgramId, vertex_shader_, fragment_shader_, NULL);
191
192 VariableMap vertex_attrib_map = vertex_shader_->attrib_map();
193 VariableMap vertex_uniform_map = vertex_shader_->uniform_map();
194 VariableMap fragment_attrib_map = fragment_shader_->attrib_map();
195 VariableMap fragment_uniform_map = fragment_shader_->uniform_map();
196
197 vertex_shader_->SetAttribMap(VariableMap());
198 vertex_shader_->SetUniformMap(VariableMap());
199 fragment_shader_->SetAttribMap(VariableMap());
200 fragment_shader_->SetUniformMap(VariableMap());
201
202 ProgramCache::ProgramLoadResult result = cache_->LoadLinkedProgram(
203 kProgramId,
204 vertex_shader_,
205 fragment_shader_,
206 NULL);
207
208 EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS, result);
209 EXPECT_EQ(vertex_attrib_map, vertex_shader_->attrib_map());
210
211 EXPECT_TRUE(gl_->binary_called());
212 }
greggman 2012/07/10 21:43:30 Should there be a checks that *) The binary saved
dmurph 2012/07/11 23:32:52 Implemented. Also, I list all of my tests in the
213
214 TEST_F(MemoryProgramCacheTest, MemoryProgramCacheEviction) {
215 typedef ShaderTranslator::VariableMap VariableMap;
216 const GLenum kFormat = 1;
217 const int kProgramId = 10;
218 const int kBinaryLength = 20;
219 char testBinary[kBinaryLength];
220 for (int i = 0; i < kBinaryLength; ++i) {
221 testBinary[i] = i;
222 }
223 EXPECT_CALL(*gl_.get(),
224 GetProgramiv(kProgramId, GL_PROGRAM_BINARY_LENGTH_OES, _))
225 .WillOnce(SetArgPointee<2>(kBinaryLength));
226 gl_->ExpectAndPopulateProgramBinaryCalls(kProgramId,
227 kBinaryLength,
228 kFormat,
229 testBinary);
230
231 cache_->SaveLinkedProgram(kProgramId, vertex_shader_, fragment_shader_, NULL);
232
233 const int kEvictingProgramId = 11;
234 const size_t kEvictingBinaryLength = kCacheSizeBytes - kBinaryLength + 1;
235
236 // save old source and modify for new program
237 std::string old_source(*vertex_shader_->source());
238 vertex_shader_->UpdateSource("alkjdk");
239
240 scoped_array<char> bigTestBinary =
241 scoped_array<char>(new char[kEvictingBinaryLength]);
242 for (size_t i = 0; i < kEvictingBinaryLength; ++i) {
243 bigTestBinary[i] = i % 250;
244 }
245 EXPECT_CALL(*gl_.get(),
246 GetProgramiv(kEvictingProgramId, GL_PROGRAM_BINARY_LENGTH_OES, _))
247 .WillOnce(SetArgPointee<2>(kEvictingBinaryLength));
248 gl_->ExpectAndPopulateProgramBinaryCalls(kEvictingProgramId,
249 kEvictingBinaryLength,
250 kFormat,
251 bigTestBinary.get());
252 cache_->SaveLinkedProgram(kEvictingProgramId,
253 vertex_shader_,
254 fragment_shader_,
255 NULL);
256 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus(
257 *vertex_shader_->source(),
258 *fragment_shader_->source(),
259 NULL));
260 EXPECT_EQ(ProgramCache::LINK_UNKNOWN, cache_->GetLinkedProgramStatus(
261 old_source,
262 *fragment_shader_->source(),
263 NULL));
264 }
265
266 } // namespace gles2
267 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698