 Chromium Code Reviews
 Chromium Code Reviews Issue 2814583002:
  Service/ClientDiscardableManager  (Closed)
    
  
    Issue 2814583002:
  Service/ClientDiscardableManager  (Closed) 
  | Index: gpu/command_buffer/service/service_discardable_manager.cc | 
| diff --git a/gpu/command_buffer/service/service_discardable_manager.cc b/gpu/command_buffer/service/service_discardable_manager.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..6a0eb2f5012ac5e389092c0d4268cf6692925096 | 
| --- /dev/null | 
| +++ b/gpu/command_buffer/service/service_discardable_manager.cc | 
| @@ -0,0 +1,82 @@ | 
| +// Copyright (c) 2017 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/service_discardable_manager.h" | 
| + | 
| +#include "base/memory/singleton.h" | 
| +#include "gpu/command_buffer/service/texture_manager.h" | 
| + | 
| +namespace gpu { | 
| +namespace { | 
| +// TODO(ericrk): Arbitrary limit, refine this once we actually use this class in | 
| +// production. crbug.com/706456 | 
| +const size_t kMaxSize = 256 * 1024 * 1024; | 
| +} | 
| + | 
| +ServiceDiscardableManager::ServiceDiscardableManager() | 
| + : entries_(EntryCache::NO_AUTO_EVICT) {} | 
| +ServiceDiscardableManager::~ServiceDiscardableManager() = default; | 
| + | 
| +void ServiceDiscardableManager::InsertLockedTexture( | 
| + uint32_t texture_id, | 
| + size_t texture_size, | 
| + gles2::ContextGroup* context_group, | 
| + ServiceDiscardableHandle handle) { | 
| + total_size_ += texture_size; | 
| + entries_.Put({texture_id, context_group}, | 
| + GpuDiscardableEntry{handle, texture_size}); | 
| + EnforceLimits(); | 
| +} | 
| + | 
| +bool ServiceDiscardableManager::UnlockTexture( | 
| + uint32_t texture_id, | 
| + const gles2::ContextGroup* context_group) { | 
| + auto found = entries_.Get({texture_id, context_group}); | 
| + if (found == entries_.end()) | 
| + return false; | 
| + | 
| + found->second.handle.Unlock(); | 
| + EnforceLimits(); | 
| + return true; | 
| +} | 
| + | 
| +void ServiceDiscardableManager::OnTextureDeleted( | 
| + uint32_t texture_id, | 
| + const gles2::ContextGroup* context_group) { | 
| 
piman
2017/05/02 22:21:03
You probably also need a call when the whole conte
 
ericrk
2017/05/10 21:36:03
Updated to handle this in TextureManager.
 | 
| + auto found = entries_.Get({texture_id, context_group}); | 
| + if (found == entries_.end()) | 
| + return; | 
| + | 
| + found->second.handle.ForceDelete(); | 
| + total_size_ -= found->second.size; | 
| + entries_.Erase(found); | 
| +} | 
| + | 
| +void ServiceDiscardableManager::EnforceLimits() { | 
| + for (auto it = entries_.rbegin(); it != entries_.rend();) { | 
| + if (total_size_ <= kMaxSize) { | 
| + return; | 
| + } | 
| + if (!it->second.handle.Delete()) { | 
| + ++it; | 
| + continue; | 
| + } | 
| + | 
| + total_size_ -= it->second.size; | 
| + it->first.context_group->texture_manager()->RemoveTexture( | 
| + it->first.texture_id); | 
| 
piman
2017/05/02 22:21:03
I think that for consistency, we should do somethi
 
ericrk
2017/05/10 21:36:02
Makes perfect sense. I *think* I have achieved thi
 | 
| + it = entries_.Erase(it); | 
| + } | 
| +} | 
| + | 
| +bool ServiceDiscardableManager::IsEntryLockedForTesting( | 
| + uint32_t texture_id, | 
| + const gles2::ContextGroup* context_group) const { | 
| + auto found = entries_.Peek({texture_id, context_group}); | 
| + DCHECK(found != entries_.end()); | 
| + | 
| + return found->second.handle.IsLockedForTesting(); | 
| +} | 
| + | 
| +} // namespace gpu |