Home | History | Annotate | Download | only in service
      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:
     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   }
     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 
     37   virtual void LoadProgram(const std::string& /* program */) OVERRIDE {}
     38 
     39   virtual void ClearBackend() OVERRIDE {}
     40 
     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 
     61   void ComputeShaderHash(const std::string& shader,
     62                          const ShaderTranslatorInterface* translator,
     63                          char* result) const {
     64     ProgramCache::ComputeShaderHash(shader, translator, result);
     65   }
     66 
     67   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 
     77   void Evict(const std::string& program_hash) {
     78     ProgramCache::Evict(program_hash);
     79   }
     80 };
     81 
     82 class ProgramCacheTest : public testing::Test {
     83  public:
     84   ProgramCacheTest() :
     85     cache_(new NoBackendProgramCache()) { }
     86 
     87  protected:
     88   scoped_ptr<NoBackendProgramCache> cache_;
     89 };
     90 
     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 
    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 
    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 
    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 
    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 
    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