| 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
|
|
|