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/program_cache.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "gpu/command_buffer/service/mocks.h"
9 #include "testing/gtest/include/gtest/gtest.h"
11 using ::testing::Return
;
16 class NoBackendProgramCache
: public ProgramCache
{
18 ProgramLoadResult
LoadLinkedProgram(
20 Shader
* /* shader_a */,
21 Shader
* /* shader_b */,
22 const LocationMap
* /* bind_attrib_location_map */,
23 const std::vector
<std::string
>& /* transform_feedback_varyings */,
24 GLenum
/* transform_feedback_buffer_mode */,
25 const ShaderCacheCallback
& /* callback */) override
{
26 return PROGRAM_LOAD_SUCCESS
;
28 void SaveLinkedProgram(
30 const Shader
* /* shader_a */,
31 const Shader
* /* shader_b */,
32 const LocationMap
* /* bind_attrib_location_map */,
33 const std::vector
<std::string
>& /* transform_feedback_varyings */,
34 GLenum
/* transform_feedback_buffer_mode */,
35 const ShaderCacheCallback
& /* callback */) override
{}
37 void LoadProgram(const std::string
& /* program */) override
{}
39 void ClearBackend() override
{}
41 void SaySuccessfullyCached(const std::string
& shader1
,
42 const std::string
& shader2
,
43 std::map
<std::string
, GLint
>* attrib_map
,
44 const std::vector
<std::string
>& varyings
,
46 char a_sha
[kHashLength
];
47 char b_sha
[kHashLength
];
48 ComputeShaderHash(shader1
, a_sha
);
49 ComputeShaderHash(shader2
, b_sha
);
51 char sha
[kHashLength
];
52 ComputeProgramHash(a_sha
,
58 const std::string
shaString(sha
, kHashLength
);
60 LinkedProgramCacheSuccess(shaString
);
63 void ComputeShaderHash(const std::string
& shader
,
65 ProgramCache::ComputeShaderHash(shader
, result
);
68 void ComputeProgramHash(
69 const char* hashed_shader_0
,
70 const char* hashed_shader_1
,
71 const LocationMap
* bind_attrib_location_map
,
72 const std::vector
<std::string
>& transform_feedback_varyings
,
73 GLenum transform_feedback_buffer_mode
,
75 ProgramCache::ComputeProgramHash(hashed_shader_0
,
77 bind_attrib_location_map
,
78 transform_feedback_varyings
,
79 transform_feedback_buffer_mode
,
83 void Evict(const std::string
& program_hash
) {
84 ProgramCache::Evict(program_hash
);
88 class ProgramCacheTest
: public testing::Test
{
91 cache_(new NoBackendProgramCache()) { }
94 scoped_ptr
<NoBackendProgramCache
> cache_
;
95 std::vector
<std::string
> varyings_
;
98 TEST_F(ProgramCacheTest
, LinkStatusSave
) {
99 const std::string shader1
= "abcd1234";
100 const std::string shader2
= "abcda sda b1~#4 bbbbb1234";
102 std::string shader_a
= shader1
;
103 std::string shader_b
= shader2
;
104 EXPECT_EQ(ProgramCache::LINK_UNKNOWN
,
105 cache_
->GetLinkedProgramStatus(
106 shader_a
, shader_b
, NULL
, varyings_
, GL_NONE
));
107 cache_
->SaySuccessfullyCached(shader_a
, shader_b
, NULL
, varyings_
, GL_NONE
);
112 // make sure it was copied
113 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED
,
114 cache_
->GetLinkedProgramStatus(
115 shader1
, shader2
, NULL
, varyings_
, GL_NONE
));
118 TEST_F(ProgramCacheTest
, LinkUnknownOnFragmentSourceChange
) {
119 const std::string shader1
= "abcd1234";
120 std::string shader2
= "abcda sda b1~#4 bbbbb1234";
121 cache_
->SaySuccessfullyCached(shader1
, shader2
, NULL
, varyings_
, GL_NONE
);
123 shader2
= "different!";
124 EXPECT_EQ(ProgramCache::LINK_UNKNOWN
,
125 cache_
->GetLinkedProgramStatus(shader1
, shader2
, NULL
,
126 varyings_
, GL_NONE
));
129 TEST_F(ProgramCacheTest
, LinkUnknownOnVertexSourceChange
) {
130 std::string shader1
= "abcd1234";
131 const std::string shader2
= "abcda sda b1~#4 bbbbb1234";
132 cache_
->SaySuccessfullyCached(shader1
, shader2
, NULL
, varyings_
, GL_NONE
);
134 shader1
= "different!";
135 EXPECT_EQ(ProgramCache::LINK_UNKNOWN
,
136 cache_
->GetLinkedProgramStatus(shader1
, shader2
, NULL
,
137 varyings_
, GL_NONE
));
140 TEST_F(ProgramCacheTest
, StatusEviction
) {
141 const std::string shader1
= "abcd1234";
142 const std::string shader2
= "abcda sda b1~#4 bbbbb1234";
143 cache_
->SaySuccessfullyCached(shader1
, shader2
, NULL
, varyings_
, GL_NONE
);
144 char a_sha
[ProgramCache::kHashLength
];
145 char b_sha
[ProgramCache::kHashLength
];
146 cache_
->ComputeShaderHash(shader1
, a_sha
);
147 cache_
->ComputeShaderHash(shader2
, b_sha
);
149 char sha
[ProgramCache::kHashLength
];
150 cache_
->ComputeProgramHash(a_sha
,
156 cache_
->Evict(std::string(sha
, ProgramCache::kHashLength
));
157 EXPECT_EQ(ProgramCache::LINK_UNKNOWN
,
158 cache_
->GetLinkedProgramStatus(shader1
, shader2
, NULL
,
159 varyings_
, GL_NONE
));
162 TEST_F(ProgramCacheTest
, EvictionWithReusedShader
) {
163 const std::string shader1
= "abcd1234";
164 const std::string shader2
= "abcda sda b1~#4 bbbbb1234";
165 const std::string shader3
= "asbjbbjj239a";
166 cache_
->SaySuccessfullyCached(shader1
, shader2
, NULL
, varyings_
, GL_NONE
);
167 cache_
->SaySuccessfullyCached(shader1
, shader3
, NULL
, varyings_
, GL_NONE
);
169 char a_sha
[ProgramCache::kHashLength
];
170 char b_sha
[ProgramCache::kHashLength
];
171 char c_sha
[ProgramCache::kHashLength
];
172 cache_
->ComputeShaderHash(shader1
, a_sha
);
173 cache_
->ComputeShaderHash(shader2
, b_sha
);
174 cache_
->ComputeShaderHash(shader3
, c_sha
);
176 char sha
[ProgramCache::kHashLength
];
177 cache_
->ComputeProgramHash(a_sha
,
183 cache_
->Evict(std::string(sha
, ProgramCache::kHashLength
));
184 EXPECT_EQ(ProgramCache::LINK_UNKNOWN
,
185 cache_
->GetLinkedProgramStatus(shader1
, shader2
, NULL
,
186 varyings_
, GL_NONE
));
187 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED
,
188 cache_
->GetLinkedProgramStatus(shader1
, shader3
, NULL
,
189 varyings_
, GL_NONE
));
192 cache_
->ComputeProgramHash(a_sha
,
198 cache_
->Evict(std::string(sha
, ProgramCache::kHashLength
));
199 EXPECT_EQ(ProgramCache::LINK_UNKNOWN
,
200 cache_
->GetLinkedProgramStatus(shader1
, shader2
, NULL
,
201 varyings_
, GL_NONE
));
202 EXPECT_EQ(ProgramCache::LINK_UNKNOWN
,
203 cache_
->GetLinkedProgramStatus(shader1
, shader3
, NULL
,
204 varyings_
, GL_NONE
));
207 TEST_F(ProgramCacheTest
, StatusClear
) {
208 const std::string shader1
= "abcd1234";
209 const std::string shader2
= "abcda sda b1~#4 bbbbb1234";
210 const std::string shader3
= "asbjbbjj239a";
211 cache_
->SaySuccessfullyCached(shader1
, shader2
, NULL
, varyings_
, GL_NONE
);
212 cache_
->SaySuccessfullyCached(shader1
, shader3
, NULL
, varyings_
, GL_NONE
);
214 EXPECT_EQ(ProgramCache::LINK_UNKNOWN
,
215 cache_
->GetLinkedProgramStatus(shader1
, shader2
, NULL
,
216 varyings_
, GL_NONE
));
217 EXPECT_EQ(ProgramCache::LINK_UNKNOWN
,
218 cache_
->GetLinkedProgramStatus(shader1
, shader3
, NULL
,
219 varyings_
, GL_NONE
));
222 TEST_F(ProgramCacheTest
, LinkUnknownOnTransformFeedbackChange
) {
223 const std::string shader1
= "abcd1234";
224 std::string shader2
= "abcda sda b1~#4 bbbbb1234";
225 varyings_
.push_back("a");
226 cache_
->SaySuccessfullyCached(shader1
, shader2
, NULL
, varyings_
,
227 GL_INTERLEAVED_ATTRIBS
);
229 EXPECT_EQ(ProgramCache::LINK_UNKNOWN
,
230 cache_
->GetLinkedProgramStatus(shader1
, shader2
, NULL
,
231 varyings_
, GL_SEPARATE_ATTRIBS
));
233 varyings_
.push_back("b");
234 EXPECT_EQ(ProgramCache::LINK_UNKNOWN
,
235 cache_
->GetLinkedProgramStatus(shader1
, shader2
, NULL
,
236 varyings_
, GL_INTERLEAVED_ATTRIBS
));