Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(203)

Unified Diff: gpu/command_buffer/service/memory_program_cache.cc

Issue 10797055: gpu in-memory program cache implementation with a memory limit + lru eviction. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: simplified binary loading logic Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: gpu/command_buffer/service/memory_program_cache.cc
diff --git a/gpu/command_buffer/service/memory_program_cache.cc b/gpu/command_buffer/service/memory_program_cache.cc
new file mode 100644
index 0000000000000000000000000000000000000000..0a061cb1ed430edd7374cbf93781ec1195e818eb
--- /dev/null
+++ b/gpu/command_buffer/service/memory_program_cache.cc
@@ -0,0 +1,173 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gpu/command_buffer/service/memory_program_cache.h"
+
+#include "base/command_line.h"
+#include "base/metrics/histogram.h"
+#include "base/sha1.h"
+#include "base/string_number_conversions.h"
+#include "gpu/command_buffer/service/gl_utils.h"
+#include "gpu/command_buffer/service/gpu_switches.h"
+#include "ui/gl/gl_bindings.h"
+
+namespace {
+size_t GetCacheSize() {
+ size_t size;
+ const CommandLine* command_line = CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(switches::kGpuProgramCacheSizeKb) &&
+ base::StringToSizeT(command_line->GetSwitchValueNative(
+ switches::kGpuProgramCacheSizeKb),
+ &size)) {
+ return size;
+ }
+ return gpu::gles2::MemoryProgramCache::kDefaultMaxProgramCacheMemoryBytes;
+}
+} // anonymous namespace
+
+namespace gpu {
+namespace gles2 {
+
+MemoryProgramCache::MemoryProgramCache()
+ : max_size_bytes_(GetCacheSize()),
+ curr_size_bytes_(0) { }
+
+MemoryProgramCache::MemoryProgramCache(const size_t max_cache_size_bytes)
+ : max_size_bytes_(max_cache_size_bytes),
+ curr_size_bytes_(0) {}
+
+MemoryProgramCache::~MemoryProgramCache() {}
+
+void MemoryProgramCache::ClearBackend() {
+ curr_size_bytes_ = 0;
+ store_.clear();
+ eviction_helper_.Clear();
+}
+
+ProgramCache::ProgramLoadResult MemoryProgramCache::LoadLinkedProgram(
+ GLuint program,
+ ShaderManager::ShaderInfo* shader_a,
+ ShaderManager::ShaderInfo* shader_b,
+ const LocationMap* bind_attrib_location_map) const {
+ char a_sha[kHashLength];
+ char b_sha[kHashLength];
+ ComputeShaderHash(*shader_a->deferred_compilation_source(), a_sha);
+ ComputeShaderHash(*shader_b->deferred_compilation_source(), b_sha);
+
+ char sha[kHashLength];
+ ComputeProgramHash(a_sha,
+ b_sha,
+ bind_attrib_location_map,
+ sha);
+ const std::string sha_string(sha, kHashLength);
+
+ StoreMap::const_iterator found = store_.find(sha_string);
+ if (found == store_.end()) {
+ return PROGRAM_LOAD_FAILURE;
+ }
+ const scoped_refptr<ProgramCacheValue> value = found->second;
+ glProgramBinary(program,
+ value->format,
+ static_cast<const GLvoid*>(value->data.get()),
+ value->length);
+ GLint success = 0;
+ glGetProgramiv(program, GL_LINK_STATUS, &success);
+ if (success == GL_FALSE) {
+ return PROGRAM_LOAD_FAILURE;
+ }
+ shader_a->set_attrib_map(value->attrib_map_0);
+ shader_a->set_uniform_map(value->uniform_map_0);
+ shader_b->set_attrib_map(value->attrib_map_1);
+ shader_b->set_uniform_map(value->uniform_map_1);
+ return PROGRAM_LOAD_SUCCESS;
+}
+
+void MemoryProgramCache::SaveLinkedProgram(
+ GLuint program,
+ const ShaderManager::ShaderInfo* shader_a,
+ const ShaderManager::ShaderInfo* shader_b,
+ const LocationMap* bind_attrib_location_map) {
+ GLsizei length;
+ GLenum format;
+ GLsizei buffer_length = 0;
+ glGetProgramiv(program, GL_PROGRAM_BINARY_LENGTH_OES, &buffer_length);
+ if (static_cast<unsigned int>(buffer_length) > max_size_bytes_) {
+ return;
+ }
+ scoped_array<char> binary(new char[buffer_length]);
+ glGetProgramBinary(program,
+ buffer_length,
+ &length,
+ &format,
+ binary.get());
+ if (length == 0) {
+ return;
+ }
+
+ char a_sha[kHashLength];
+ char b_sha[kHashLength];
+ ComputeShaderHash(*shader_a->deferred_compilation_source(), a_sha);
+ ComputeShaderHash(*shader_b->deferred_compilation_source(), b_sha);
+
+ char sha[kHashLength];
+ ComputeProgramHash(a_sha,
+ b_sha,
+ bind_attrib_location_map,
+ sha);
+ const std::string sha_string(sha, sizeof(sha));
+
+ if (store_.find(sha_string) != store_.end()) {
+ return;
+ }
+
+ while (curr_size_bytes_ + length > max_size_bytes_) {
+ DCHECK(!eviction_helper_.IsEmpty());
+ const std::string* program = eviction_helper_.PeekKey();
+ const StoreMap::iterator found = store_.find(*program);
+ const ProgramCacheValue* evicting = found->second.get();
+ curr_size_bytes_ -= evicting->length;
+ Evict(*program, evicting->shader_0_hash, evicting->shader_1_hash);
+ store_.erase(found);
+ eviction_helper_.PopKey();
+ }
+ store_[sha_string] = new ProgramCacheValue(length,
+ format,
+ binary.release(),
+ a_sha,
+ shader_a->attrib_map(),
+ shader_a->uniform_map(),
+ b_sha,
+ shader_b->attrib_map(),
+ shader_b->uniform_map());
+ curr_size_bytes_ += length;
+ eviction_helper_.KeyUsed(sha_string);
+ LinkedProgramCacheSuccess(sha_string,
+ std::string(a_sha, kHashLength),
+ std::string(b_sha, kHashLength));
+}
+
+MemoryProgramCache::ProgramCacheValue::ProgramCacheValue(
+ GLsizei _length,
+ GLenum _format,
+ const char* _data,
+ const char* _shader_0_hash,
+ const ShaderTranslator::VariableMap& _attrib_map_0,
+ const ShaderTranslator::VariableMap& _uniform_map_0,
+ const char* _shader_1_hash,
+ const ShaderTranslator::VariableMap& _attrib_map_1,
+ const ShaderTranslator::VariableMap& _uniform_map_1)
+ : length(_length),
+ format(_format),
+ data(_data),
+ shader_0_hash(_shader_0_hash, kHashLength),
+ attrib_map_0(_attrib_map_0),
+ uniform_map_0(_uniform_map_0),
+ shader_1_hash(_shader_1_hash, kHashLength),
+ attrib_map_1(_attrib_map_1),
+ uniform_map_1(_uniform_map_1) {}
+
+MemoryProgramCache::ProgramCacheValue::~ProgramCacheValue() {}
+
+} // namespace gles2
+} // namespace gpu

Powered by Google App Engine
This is Rietveld 408576698