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 #ifndef GPU_COMMAND_BUFFER_SERVICE_PROGRAM_CACHE_H_ 6 #define GPU_COMMAND_BUFFER_SERVICE_PROGRAM_CACHE_H_ 7 8 #include <stddef.h> 9 10 #include <map> 11 #include <string> 12 #include <unordered_map> 13 #include <unordered_set> 14 15 #include "base/hash/sha1.h" 16 #include "base/macros.h" 17 #include "base/memory/memory_pressure_listener.h" 18 #include "gpu/command_buffer/common/gl2_types.h" 19 #include "gpu/gpu_gles2_export.h" 20 21 namespace gpu { 22 23 class DecoderClient; 24 25 namespace gles2 { 26 27 class Shader; 28 29 // Program cache base class for caching linked gpu programs 30 class GPU_GLES2_EXPORT ProgramCache { 31 public: 32 static const size_t kHashLength = base::kSHA1Length; 33 34 typedef std::map<std::string, GLint> LocationMap; 35 using CacheProgramCallback = 36 ::base::RepeatingCallback<void(const std::string&, const std::string&)>; 37 38 enum LinkedProgramStatus { 39 LINK_UNKNOWN, 40 LINK_SUCCEEDED 41 }; 42 43 enum ProgramLoadResult { 44 PROGRAM_LOAD_FAILURE, 45 PROGRAM_LOAD_SUCCESS 46 }; 47 48 class GPU_GLES2_EXPORT ScopedCacheUse { 49 public: 50 ScopedCacheUse(ProgramCache* cache, CacheProgramCallback callback); 51 ~ScopedCacheUse(); 52 53 ScopedCacheUse(ScopedCacheUse&&) = default; 54 ScopedCacheUse& operator=(ScopedCacheUse&& other) = default; 55 56 private: 57 ProgramCache* cache_; 58 }; 59 60 explicit ProgramCache(size_t max_cache_size_bytes); 61 virtual ~ProgramCache(); 62 63 bool HasSuccessfullyCompiledShader(const std::string& shader_signature) const; 64 65 LinkedProgramStatus GetLinkedProgramStatus( 66 const std::string& shader_signature_a, 67 const std::string& shader_signature_b, 68 const LocationMap* bind_attrib_location_map, 69 const std::vector<std::string>& transform_feedback_varyings, 70 GLenum transform_feedback_buffer_mode) const; 71 72 // Loads the linked program from the cache. If the program is not found or 73 // there was an error, PROGRAM_LOAD_FAILURE should be returned. 74 virtual ProgramLoadResult LoadLinkedProgram( 75 GLuint program, 76 Shader* shader_a, 77 Shader* shader_b, 78 const LocationMap* bind_attrib_location_map, 79 const std::vector<std::string>& transform_feedback_varyings, 80 GLenum transform_feedback_buffer_mode, 81 DecoderClient* client) = 0; 82 83 // Saves the program into the cache. If successful, the implementation should 84 // call LinkedProgramCacheSuccess. 85 virtual void SaveLinkedProgram( 86 GLuint program, 87 const Shader* shader_a, 88 const Shader* shader_b, 89 const LocationMap* bind_attrib_location_map, 90 const std::vector<std::string>& transform_feedback_varyings, 91 GLenum transform_feedback_buffer_mode, 92 DecoderClient* client) = 0; 93 94 virtual void LoadProgram(const std::string& key, 95 const std::string& program) = 0; 96 97 // clears the cache 98 void Clear(); 99 100 // Only for testing 101 void LinkedProgramCacheSuccess(const std::string& shader_signature_a, 102 const std::string& shader_signature_b, 103 const LocationMap* bind_attrib_location_map, 104 const std::vector<std::string>& transform_feedback_varyings, 105 GLenum transform_feedback_buffer_mode); 106 107 // Discards excess cache contents to a fixed upper limit. 108 // Returns the number of bytes of memory freed. 109 virtual size_t Trim(size_t limit) = 0; 110 111 // Reduces cache usage based on the given MemoryPressureLevel 112 void HandleMemoryPressure( 113 base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level); 114 115 protected: max_size_bytes()116 size_t max_size_bytes() const { return max_size_bytes_; } 117 118 // called by implementing class after a shader was successfully cached 119 void LinkedProgramCacheSuccess(const std::string& program_hash); 120 121 void CompiledShaderCacheSuccess(const std::string& shader_hash); 122 123 // result is not null terminated 124 void ComputeShaderHash(const std::string& shader, 125 char* result) const; 126 127 // result is not null terminated. hashed shaders are expected to be 128 // kHashLength in length 129 void ComputeProgramHash( 130 const char* hashed_shader_0, 131 const char* hashed_shader_1, 132 const LocationMap* bind_attrib_location_map, 133 const std::vector<std::string>& transform_feedback_varyings, 134 GLenum transform_feedback_buffer_mode, 135 char* result) const; 136 137 void Evict(const std::string& program_hash, 138 const std::string& shader_0_hash, 139 const std::string& shader_1_hash); 140 141 // Used by the passthrough program cache to notify when a new blob is 142 // inserted. 143 CacheProgramCallback cache_program_callback_; 144 145 private: 146 typedef std::unordered_map<std::string, LinkedProgramStatus> LinkStatusMap; 147 typedef std::unordered_set<std::string> CachedCompiledShaderSet; 148 149 // called to clear the backend cache 150 virtual void ClearBackend() = 0; 151 152 const size_t max_size_bytes_; 153 LinkStatusMap link_status_; 154 // only cache the hash of successfully compiled shaders 155 CachedCompiledShaderSet compiled_shaders_; 156 157 DISALLOW_COPY_AND_ASSIGN(ProgramCache); 158 }; 159 160 } // namespace gles2 161 } // namespace gpu 162 163 #endif // GPU_COMMAND_BUFFER_SERVICE_PROGRAM_CACHE_H_ 164