Chromium Code Reviews| 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..fd4943e352d0edbda8d3b6d2a2cad287e61d4eb3 |
| --- /dev/null |
| +++ b/gpu/command_buffer/service/memory_program_cache.cc |
| @@ -0,0 +1,141 @@ |
| +// 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/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) && |
| + size >= 0) { |
| + return size; |
| + } |
| + return gpu::gles2::MemoryProgramCache::kDefaultMaxProgramCacheMemoryBytes; |
| +} |
| +} // anonymous namespace |
| + |
| +namespace gpu { |
| +namespace gles2 { |
| + |
| +MemoryProgramCache::MemoryProgramCache() : max_size_bytes_(GetCacheSize()), |
|
greggman
2012/07/10 21:43:30
style: If they can't fit one one line the style is
dmurph
2012/07/11 23:32:52
Done.
|
| + curr_size_bytes_(0) { } |
| + |
| +void MemoryProgramCache::ClearBackend() { |
| + curr_size_bytes_ = 0; |
| + store_.clear(); |
| + eviction_helper_.Clear(); |
| +} |
| + |
| +ProgramCache::ProgramLoadResult MemoryProgramCache::LoadLinkedProgram( |
| + const 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->source(), a_sha); |
| + ComputeShaderHash(*shader_b->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); |
| + shader_a->SetAttribMap(value->attrib_map_0); |
| + shader_a->SetUniformMap(value->uniform_map_0); |
| + shader_b->SetAttribMap(value->attrib_map_1); |
| + shader_b->SetUniformMap(value->uniform_map_1); |
| + return PROGRAM_LOAD_SUCCESS; |
| +} |
| + |
| +void MemoryProgramCache::SaveLinkedProgram( |
| + const 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->source(), a_sha); |
| + ComputeShaderHash(*shader_b->source(), b_sha); |
| + |
| + scoped_refptr<ProgramCacheValue> value( |
| + 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())); |
| + char sha[kHashLength]; |
| + ComputeProgramHash(a_sha, |
| + b_sha, |
| + bind_attrib_location_map, |
| + sha); |
| + const std::string sha_string(sha, kHashLength); |
|
greggman
2012/07/10 21:43:30
how about
const std::string sha_string(sha, sizeof
dmurph
2012/07/11 23:32:52
Sure, done.
|
| + |
| + 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] = value; |
| + curr_size_bytes_ += length; |
| + eviction_helper_.KeyUsed(sha_string); |
| + LinkedProgramCacheSuccess(sha_string, |
| + std::string(a_sha, kHashLength), |
| + std::string(b_sha, kHashLength)); |
| +} |
| + |
| +} // namespace gles2 |
| +} // namespace gpu |