• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/program_cache.h"
6 
7 #include "base/memory/scoped_ptr.h"
8 #include "gpu/command_buffer/service/mocks.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 
11 using ::testing::Return;
12 
13 namespace gpu {
14 namespace gles2 {
15 
16 class NoBackendProgramCache : public ProgramCache {
17  public:
LoadLinkedProgram(GLuint,Shader *,const ShaderTranslatorInterface *,Shader *,const ShaderTranslatorInterface *,const LocationMap *,const ShaderCacheCallback &)18   virtual ProgramLoadResult LoadLinkedProgram(
19       GLuint /* program */,
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;
27   }
SaveLinkedProgram(GLuint,const Shader *,const ShaderTranslatorInterface *,const Shader *,const ShaderTranslatorInterface *,const LocationMap *,const ShaderCacheCallback &)28   virtual void SaveLinkedProgram(
29       GLuint /* program */,
30       const Shader* /* shader_a */,
31       const ShaderTranslatorInterface* /* translator_b */,
32       const Shader* /* shader_b */,
33       const ShaderTranslatorInterface* /* translator_b */,
34       const LocationMap* /* bind_attrib_location_map */,
35       const ShaderCacheCallback& /* callback */) OVERRIDE { }
36 
LoadProgram(const std::string &)37   virtual void LoadProgram(const std::string& /* program */) OVERRIDE {}
38 
ClearBackend()39   virtual void ClearBackend() OVERRIDE {}
40 
SaySuccessfullyCached(const std::string & shader1,const ShaderTranslatorInterface * translator_1,const std::string & shader2,const ShaderTranslatorInterface * translator_2,std::map<std::string,GLint> * attrib_map)41   void SaySuccessfullyCached(const std::string& shader1,
42                              const ShaderTranslatorInterface* translator_1,
43                              const std::string& shader2,
44                              const ShaderTranslatorInterface* translator_2,
45                              std::map<std::string, GLint>* attrib_map) {
46     char a_sha[kHashLength];
47     char b_sha[kHashLength];
48     ComputeShaderHash(shader1, translator_1, a_sha);
49     ComputeShaderHash(shader2, translator_2, b_sha);
50 
51     char sha[kHashLength];
52     ComputeProgramHash(a_sha,
53                        b_sha,
54                        attrib_map,
55                        sha);
56     const std::string shaString(sha, kHashLength);
57 
58     LinkedProgramCacheSuccess(shaString);
59   }
60 
ComputeShaderHash(const std::string & shader,const ShaderTranslatorInterface * translator,char * result) const61   void ComputeShaderHash(const std::string& shader,
62                          const ShaderTranslatorInterface* translator,
63                          char* result) const {
64     ProgramCache::ComputeShaderHash(shader, translator, result);
65   }
66 
ComputeProgramHash(const char * hashed_shader_0,const char * hashed_shader_1,const LocationMap * bind_attrib_location_map,char * result) const67   void ComputeProgramHash(const char* hashed_shader_0,
68                           const char* hashed_shader_1,
69                           const LocationMap* bind_attrib_location_map,
70                           char* result) const {
71     ProgramCache::ComputeProgramHash(hashed_shader_0,
72                                      hashed_shader_1,
73                                      bind_attrib_location_map,
74                                      result);
75   }
76 
Evict(const std::string & program_hash)77   void Evict(const std::string& program_hash) {
78     ProgramCache::Evict(program_hash);
79   }
80 };
81 
82 class ProgramCacheTest : public testing::Test {
83  public:
ProgramCacheTest()84   ProgramCacheTest() :
85     cache_(new NoBackendProgramCache()) { }
86 
87  protected:
88   scoped_ptr<NoBackendProgramCache> cache_;
89 };
90 
TEST_F(ProgramCacheTest,LinkStatusSave)91 TEST_F(ProgramCacheTest, LinkStatusSave) {
92   const std::string shader1 = "abcd1234";
93   const std::string shader2 = "abcda sda b1~#4 bbbbb1234";
94   {
95     std::string shader_a = shader1;
96     std::string shader_b = shader2;
97     EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
98               cache_->GetLinkedProgramStatus(
99                   shader_a, NULL, shader_b, NULL, NULL));
100     cache_->SaySuccessfullyCached(shader_a, NULL, shader_b, NULL, NULL);
101 
102     shader_a.clear();
103     shader_b.clear();
104   }
105   // make sure it was copied
106   EXPECT_EQ(ProgramCache::LINK_SUCCEEDED,
107             cache_->GetLinkedProgramStatus(
108                 shader1, NULL, shader2, NULL, NULL));
109 }
110 
TEST_F(ProgramCacheTest,LinkUnknownOnFragmentSourceChange)111 TEST_F(ProgramCacheTest, LinkUnknownOnFragmentSourceChange) {
112   const std::string shader1 = "abcd1234";
113   std::string shader2 = "abcda sda b1~#4 bbbbb1234";
114   cache_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL);
115 
116   shader2 = "different!";
117   EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
118             cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL));
119 }
120 
TEST_F(ProgramCacheTest,LinkUnknownOnVertexSourceChange)121 TEST_F(ProgramCacheTest, LinkUnknownOnVertexSourceChange) {
122   std::string shader1 = "abcd1234";
123   const std::string shader2 = "abcda sda b1~#4 bbbbb1234";
124   cache_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL);
125 
126   shader1 = "different!";
127   EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
128             cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL));
129 }
130 
TEST_F(ProgramCacheTest,StatusEviction)131 TEST_F(ProgramCacheTest, StatusEviction) {
132   const std::string shader1 = "abcd1234";
133   const std::string shader2 = "abcda sda b1~#4 bbbbb1234";
134   cache_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL);
135   char a_sha[ProgramCache::kHashLength];
136   char b_sha[ProgramCache::kHashLength];
137   cache_->ComputeShaderHash(shader1, NULL, a_sha);
138   cache_->ComputeShaderHash(shader2, NULL, b_sha);
139 
140   char sha[ProgramCache::kHashLength];
141   cache_->ComputeProgramHash(a_sha,
142                              b_sha,
143                              NULL,
144                              sha);
145   cache_->Evict(std::string(sha, ProgramCache::kHashLength));
146   EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
147             cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL));
148 }
149 
TEST_F(ProgramCacheTest,EvictionWithReusedShader)150 TEST_F(ProgramCacheTest, EvictionWithReusedShader) {
151   const std::string shader1 = "abcd1234";
152   const std::string shader2 = "abcda sda b1~#4 bbbbb1234";
153   const std::string shader3 = "asbjbbjj239a";
154   cache_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL);
155   cache_->SaySuccessfullyCached(shader1, NULL, shader3, NULL, NULL);
156 
157   char a_sha[ProgramCache::kHashLength];
158   char b_sha[ProgramCache::kHashLength];
159   char c_sha[ProgramCache::kHashLength];
160   cache_->ComputeShaderHash(shader1, NULL, a_sha);
161   cache_->ComputeShaderHash(shader2, NULL, b_sha);
162   cache_->ComputeShaderHash(shader3, NULL, c_sha);
163 
164   char sha[ProgramCache::kHashLength];
165   cache_->ComputeProgramHash(a_sha,
166                              b_sha,
167                              NULL,
168                              sha);
169   cache_->Evict(std::string(sha, ProgramCache::kHashLength));
170   EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
171             cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL));
172   EXPECT_EQ(ProgramCache::LINK_SUCCEEDED,
173             cache_->GetLinkedProgramStatus(shader1, NULL, shader3, NULL, NULL));
174 
175 
176   cache_->ComputeProgramHash(a_sha,
177                              c_sha,
178                              NULL,
179                              sha);
180   cache_->Evict(std::string(sha, ProgramCache::kHashLength));
181   EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
182             cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL));
183   EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
184             cache_->GetLinkedProgramStatus(shader1, NULL, shader3, NULL, NULL));
185 }
186 
TEST_F(ProgramCacheTest,StatusClear)187 TEST_F(ProgramCacheTest, StatusClear) {
188   const std::string shader1 = "abcd1234";
189   const std::string shader2 = "abcda sda b1~#4 bbbbb1234";
190   const std::string shader3 = "asbjbbjj239a";
191   cache_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL);
192   cache_->SaySuccessfullyCached(shader1, NULL, shader3, NULL, NULL);
193   cache_->Clear();
194   EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
195             cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL));
196   EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
197             cache_->GetLinkedProgramStatus(shader1, NULL, shader3, NULL, NULL));
198 }
199 
200 }  // namespace gles2
201 }  // namespace gpu
202