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 const ShaderTranslatorInterface* /* translator_a */,
22 Shader* /* shader_b */,
23 const ShaderTranslatorInterface* /* translator_b */,
24 const LocationMap* /* bind_attrib_location_map */,
25 const ShaderCacheCallback& /* callback */) override {
26 return PROGRAM_LOAD_SUCCESS;
28 void SaveLinkedProgram(GLuint /* program */,
29 const Shader* /* shader_a */,
30 const ShaderTranslatorInterface* /* translator_b */,
31 const Shader* /* shader_b */,
32 const ShaderTranslatorInterface* /* translator_b */,
33 const LocationMap* /* bind_attrib_location_map */,
34 const ShaderCacheCallback& /* callback */) override {}
36 void LoadProgram(const std::string& /* program */) override {}
38 void ClearBackend() override {}
40 void SaySuccessfullyCached(const std::string& shader1,
41 const ShaderTranslatorInterface* translator_1,
42 const std::string& shader2,
43 const ShaderTranslatorInterface* translator_2,
44 std::map<std::string, GLint>* attrib_map) {
45 char a_sha[kHashLength];
46 char b_sha[kHashLength];
47 ComputeShaderHash(shader1, translator_1, a_sha);
48 ComputeShaderHash(shader2, translator_2, b_sha);
50 char sha[kHashLength];
51 ComputeProgramHash(a_sha,
55 const std::string shaString(sha, kHashLength);
57 LinkedProgramCacheSuccess(shaString);
60 void ComputeShaderHash(const std::string& shader,
61 const ShaderTranslatorInterface* translator,
63 ProgramCache::ComputeShaderHash(shader, translator, result);
66 void ComputeProgramHash(const char* hashed_shader_0,
67 const char* hashed_shader_1,
68 const LocationMap* bind_attrib_location_map,
70 ProgramCache::ComputeProgramHash(hashed_shader_0,
72 bind_attrib_location_map,
76 void Evict(const std::string& program_hash) {
77 ProgramCache::Evict(program_hash);
81 class ProgramCacheTest : public testing::Test {
84 cache_(new NoBackendProgramCache()) { }
87 scoped_ptr<NoBackendProgramCache> cache_;
90 TEST_F(ProgramCacheTest, LinkStatusSave) {
91 const std::string shader1 = "abcd1234";
92 const std::string shader2 = "abcda sda b1~#4 bbbbb1234";
94 std::string shader_a = shader1;
95 std::string shader_b = shader2;
96 EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
97 cache_->GetLinkedProgramStatus(
98 shader_a, NULL, shader_b, NULL, NULL));
99 cache_->SaySuccessfullyCached(shader_a, NULL, shader_b, NULL, NULL);
104 // make sure it was copied
105 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED,
106 cache_->GetLinkedProgramStatus(
107 shader1, NULL, shader2, NULL, NULL));
110 TEST_F(ProgramCacheTest, LinkUnknownOnFragmentSourceChange) {
111 const std::string shader1 = "abcd1234";
112 std::string shader2 = "abcda sda b1~#4 bbbbb1234";
113 cache_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL);
115 shader2 = "different!";
116 EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
117 cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL));
120 TEST_F(ProgramCacheTest, LinkUnknownOnVertexSourceChange) {
121 std::string shader1 = "abcd1234";
122 const std::string shader2 = "abcda sda b1~#4 bbbbb1234";
123 cache_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL);
125 shader1 = "different!";
126 EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
127 cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL));
130 TEST_F(ProgramCacheTest, StatusEviction) {
131 const std::string shader1 = "abcd1234";
132 const std::string shader2 = "abcda sda b1~#4 bbbbb1234";
133 cache_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL);
134 char a_sha[ProgramCache::kHashLength];
135 char b_sha[ProgramCache::kHashLength];
136 cache_->ComputeShaderHash(shader1, NULL, a_sha);
137 cache_->ComputeShaderHash(shader2, NULL, b_sha);
139 char sha[ProgramCache::kHashLength];
140 cache_->ComputeProgramHash(a_sha,
144 cache_->Evict(std::string(sha, ProgramCache::kHashLength));
145 EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
146 cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL));
149 TEST_F(ProgramCacheTest, EvictionWithReusedShader) {
150 const std::string shader1 = "abcd1234";
151 const std::string shader2 = "abcda sda b1~#4 bbbbb1234";
152 const std::string shader3 = "asbjbbjj239a";
153 cache_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL);
154 cache_->SaySuccessfullyCached(shader1, NULL, shader3, NULL, NULL);
156 char a_sha[ProgramCache::kHashLength];
157 char b_sha[ProgramCache::kHashLength];
158 char c_sha[ProgramCache::kHashLength];
159 cache_->ComputeShaderHash(shader1, NULL, a_sha);
160 cache_->ComputeShaderHash(shader2, NULL, b_sha);
161 cache_->ComputeShaderHash(shader3, NULL, c_sha);
163 char sha[ProgramCache::kHashLength];
164 cache_->ComputeProgramHash(a_sha,
168 cache_->Evict(std::string(sha, ProgramCache::kHashLength));
169 EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
170 cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL));
171 EXPECT_EQ(ProgramCache::LINK_SUCCEEDED,
172 cache_->GetLinkedProgramStatus(shader1, NULL, shader3, NULL, NULL));
175 cache_->ComputeProgramHash(a_sha,
179 cache_->Evict(std::string(sha, ProgramCache::kHashLength));
180 EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
181 cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL));
182 EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
183 cache_->GetLinkedProgramStatus(shader1, NULL, shader3, NULL, NULL));
186 TEST_F(ProgramCacheTest, StatusClear) {
187 const std::string shader1 = "abcd1234";
188 const std::string shader2 = "abcda sda b1~#4 bbbbb1234";
189 const std::string shader3 = "asbjbbjj239a";
190 cache_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL);
191 cache_->SaySuccessfullyCached(shader1, NULL, shader3, NULL, NULL);
193 EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
194 cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL));
195 EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
196 cache_->GetLinkedProgramStatus(shader1, NULL, shader3, NULL, NULL));