OLD | NEW |
(Empty) | |
| 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/memory_program_cache.h" |
| 6 |
| 7 #include "base/command_line.h" |
| 8 #include "base/metrics/histogram.h" |
| 9 #include "base/sha1.h" |
| 10 #include "base/string_number_conversions.h" |
| 11 #include "gpu/command_buffer/service/gl_utils.h" |
| 12 #include "gpu/command_buffer/service/gpu_switches.h" |
| 13 #include "ui/gl/gl_bindings.h" |
| 14 |
| 15 namespace { |
| 16 size_t GetCacheSize() { |
| 17 size_t size; |
| 18 const CommandLine* command_line = CommandLine::ForCurrentProcess(); |
| 19 if (command_line->HasSwitch(switches::kGpuProgramCacheSizeKb) && |
| 20 base::StringToSizeT(command_line->GetSwitchValueNative( |
| 21 switches::kGpuProgramCacheSizeKb), |
| 22 &size)) { |
| 23 return size; |
| 24 } |
| 25 return gpu::gles2::MemoryProgramCache::kDefaultMaxProgramCacheMemoryBytes; |
| 26 } |
| 27 } // anonymous namespace |
| 28 |
| 29 namespace gpu { |
| 30 namespace gles2 { |
| 31 |
| 32 MemoryProgramCache::MemoryProgramCache() |
| 33 : max_size_bytes_(GetCacheSize()), |
| 34 curr_size_bytes_(0) { } |
| 35 |
| 36 MemoryProgramCache::MemoryProgramCache(const size_t max_cache_size_bytes) |
| 37 : max_size_bytes_(max_cache_size_bytes), |
| 38 curr_size_bytes_(0) {} |
| 39 |
| 40 MemoryProgramCache::~MemoryProgramCache() {} |
| 41 |
| 42 void MemoryProgramCache::ClearBackend() { |
| 43 curr_size_bytes_ = 0; |
| 44 store_.clear(); |
| 45 eviction_helper_.Clear(); |
| 46 } |
| 47 |
| 48 ProgramCache::ProgramLoadResult MemoryProgramCache::LoadLinkedProgram( |
| 49 GLuint program, |
| 50 ShaderManager::ShaderInfo* shader_a, |
| 51 ShaderManager::ShaderInfo* shader_b, |
| 52 const LocationMap* bind_attrib_location_map) const { |
| 53 char a_sha[kHashLength]; |
| 54 char b_sha[kHashLength]; |
| 55 ComputeShaderHash(*shader_a->deferred_compilation_source(), a_sha); |
| 56 ComputeShaderHash(*shader_b->deferred_compilation_source(), b_sha); |
| 57 |
| 58 char sha[kHashLength]; |
| 59 ComputeProgramHash(a_sha, |
| 60 b_sha, |
| 61 bind_attrib_location_map, |
| 62 sha); |
| 63 const std::string sha_string(sha, kHashLength); |
| 64 |
| 65 StoreMap::const_iterator found = store_.find(sha_string); |
| 66 if (found == store_.end()) { |
| 67 return PROGRAM_LOAD_FAILURE; |
| 68 } |
| 69 const scoped_refptr<ProgramCacheValue> value = found->second; |
| 70 glProgramBinary(program, |
| 71 value->format, |
| 72 static_cast<const GLvoid*>(value->data.get()), |
| 73 value->length); |
| 74 GLint success = 0; |
| 75 glGetProgramiv(program, GL_LINK_STATUS, &success); |
| 76 if (success == GL_FALSE) { |
| 77 return PROGRAM_LOAD_FAILURE; |
| 78 } |
| 79 shader_a->set_attrib_map(value->attrib_map_0); |
| 80 shader_a->set_uniform_map(value->uniform_map_0); |
| 81 shader_b->set_attrib_map(value->attrib_map_1); |
| 82 shader_b->set_uniform_map(value->uniform_map_1); |
| 83 return PROGRAM_LOAD_SUCCESS; |
| 84 } |
| 85 |
| 86 void MemoryProgramCache::SaveLinkedProgram( |
| 87 GLuint program, |
| 88 const ShaderManager::ShaderInfo* shader_a, |
| 89 const ShaderManager::ShaderInfo* shader_b, |
| 90 const LocationMap* bind_attrib_location_map) { |
| 91 GLsizei length; |
| 92 GLenum format; |
| 93 GLsizei buffer_length = 0; |
| 94 glGetProgramiv(program, GL_PROGRAM_BINARY_LENGTH_OES, &buffer_length); |
| 95 if (static_cast<unsigned int>(buffer_length) > max_size_bytes_) { |
| 96 return; |
| 97 } |
| 98 scoped_array<char> binary(new char[buffer_length]); |
| 99 glGetProgramBinary(program, |
| 100 buffer_length, |
| 101 &length, |
| 102 &format, |
| 103 binary.get()); |
| 104 if (length == 0) { |
| 105 return; |
| 106 } |
| 107 |
| 108 char a_sha[kHashLength]; |
| 109 char b_sha[kHashLength]; |
| 110 ComputeShaderHash(*shader_a->deferred_compilation_source(), a_sha); |
| 111 ComputeShaderHash(*shader_b->deferred_compilation_source(), b_sha); |
| 112 |
| 113 char sha[kHashLength]; |
| 114 ComputeProgramHash(a_sha, |
| 115 b_sha, |
| 116 bind_attrib_location_map, |
| 117 sha); |
| 118 const std::string sha_string(sha, sizeof(sha)); |
| 119 |
| 120 if (store_.find(sha_string) != store_.end()) { |
| 121 return; |
| 122 } |
| 123 |
| 124 while (curr_size_bytes_ + length > max_size_bytes_) { |
| 125 DCHECK(!eviction_helper_.IsEmpty()); |
| 126 const std::string* program = eviction_helper_.PeekKey(); |
| 127 const StoreMap::iterator found = store_.find(*program); |
| 128 const ProgramCacheValue* evicting = found->second.get(); |
| 129 curr_size_bytes_ -= evicting->length; |
| 130 Evict(*program, evicting->shader_0_hash, evicting->shader_1_hash); |
| 131 store_.erase(found); |
| 132 eviction_helper_.PopKey(); |
| 133 } |
| 134 store_[sha_string] = new ProgramCacheValue(length, |
| 135 format, |
| 136 binary.release(), |
| 137 a_sha, |
| 138 shader_a->attrib_map(), |
| 139 shader_a->uniform_map(), |
| 140 b_sha, |
| 141 shader_b->attrib_map(), |
| 142 shader_b->uniform_map()); |
| 143 curr_size_bytes_ += length; |
| 144 eviction_helper_.KeyUsed(sha_string); |
| 145 LinkedProgramCacheSuccess(sha_string, |
| 146 std::string(a_sha, kHashLength), |
| 147 std::string(b_sha, kHashLength)); |
| 148 } |
| 149 |
| 150 MemoryProgramCache::ProgramCacheValue::ProgramCacheValue( |
| 151 GLsizei _length, |
| 152 GLenum _format, |
| 153 const char* _data, |
| 154 const char* _shader_0_hash, |
| 155 const ShaderTranslator::VariableMap& _attrib_map_0, |
| 156 const ShaderTranslator::VariableMap& _uniform_map_0, |
| 157 const char* _shader_1_hash, |
| 158 const ShaderTranslator::VariableMap& _attrib_map_1, |
| 159 const ShaderTranslator::VariableMap& _uniform_map_1) |
| 160 : length(_length), |
| 161 format(_format), |
| 162 data(_data), |
| 163 shader_0_hash(_shader_0_hash, kHashLength), |
| 164 attrib_map_0(_attrib_map_0), |
| 165 uniform_map_0(_uniform_map_0), |
| 166 shader_1_hash(_shader_1_hash, kHashLength), |
| 167 attrib_map_1(_attrib_map_1), |
| 168 uniform_map_1(_uniform_map_1) {} |
| 169 |
| 170 MemoryProgramCache::ProgramCacheValue::~ProgramCacheValue() {} |
| 171 |
| 172 } // namespace gles2 |
| 173 } // namespace gpu |
OLD | NEW |