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 |