OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "cc/resources/resource_pool.h" | 5 #include "cc/resources/resource_pool.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
11 #include <utility> | 11 #include <utility> |
12 | 12 |
13 #include "base/format_macros.h" | 13 #include "base/format_macros.h" |
14 #include "base/memory/memory_coordinator_client_registry.h" | 14 #include "base/memory/memory_coordinator_client_registry.h" |
15 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
16 #include "base/threading/thread_task_runner_handle.h" | 16 #include "base/threading/thread_task_runner_handle.h" |
17 #include "base/trace_event/memory_dump_manager.h" | 17 #include "base/trace_event/memory_dump_manager.h" |
18 #include "cc/base/container_util.h" | 18 #include "cc/base/container_util.h" |
19 #include "cc/resources/resource_provider.h" | 19 #include "cc/resources/resource_provider.h" |
20 #include "cc/resources/resource_util.h" | 20 #include "cc/resources/resource_util.h" |
21 #include "cc/resources/scoped_resource.h" | 21 #include "cc/resources/scoped_resource.h" |
22 | 22 |
23 using base::trace_event::MemoryAllocatorDump; | 23 using base::trace_event::MemoryAllocatorDump; |
24 using base::trace_event::MemoryDumpLevelOfDetail; | 24 using base::trace_event::MemoryDumpLevelOfDetail; |
25 | 25 |
26 namespace cc { | 26 namespace cc { |
| 27 namespace { |
| 28 bool ResourceMeetsSizeRequirements(const gfx::Size& requested_size, |
| 29 const gfx::Size& actual_size, |
| 30 bool disallow_non_exact_reuse) { |
| 31 const float kReuseThreshold = 2.0f; |
| 32 |
| 33 if (disallow_non_exact_reuse) |
| 34 return requested_size == actual_size; |
| 35 |
| 36 // Allocating new resources is expensive, and we'd like to re-use our |
| 37 // existing ones within reason. Allow a larger resource to be used for a |
| 38 // smaller request. |
| 39 if (actual_size.width() < requested_size.width() || |
| 40 actual_size.height() < requested_size.height()) |
| 41 return false; |
| 42 |
| 43 // GetArea will crash on overflow, however all sizes in use are tile sizes. |
| 44 // These are capped at ResourceProvider::max_texture_size(), and will not |
| 45 // overflow. |
| 46 float actual_area = actual_size.GetArea(); |
| 47 float requested_area = requested_size.GetArea(); |
| 48 // Don't use a resource that is more than |kReuseThreshold| times the |
| 49 // requested pixel area, as we want to free unnecessarily large resources. |
| 50 if (actual_area / requested_area > kReuseThreshold) |
| 51 return false; |
| 52 |
| 53 return true; |
| 54 } |
| 55 |
| 56 } // namespace |
| 57 |
27 base::TimeDelta ResourcePool::kDefaultExpirationDelay = | 58 base::TimeDelta ResourcePool::kDefaultExpirationDelay = |
28 base::TimeDelta::FromSeconds(1); | 59 base::TimeDelta::FromSeconds(5); |
29 | 60 |
30 void ResourcePool::PoolResource::OnMemoryDump( | 61 void ResourcePool::PoolResource::OnMemoryDump( |
31 base::trace_event::ProcessMemoryDump* pmd, | 62 base::trace_event::ProcessMemoryDump* pmd, |
32 const ResourceProvider* resource_provider, | 63 const ResourceProvider* resource_provider, |
33 bool is_free) const { | 64 bool is_free) const { |
34 // Resource IDs are not process-unique, so log with the ResourceProvider's | 65 // Resource IDs are not process-unique, so log with the ResourceProvider's |
35 // unique id. | 66 // unique id. |
36 std::string parent_node = | 67 std::string parent_node = |
37 base::StringPrintf("cc/resource_memory/provider_%d/resource_%d", | 68 base::StringPrintf("cc/resource_memory/provider_%d/resource_%d", |
38 resource_provider->tracing_id(), id()); | 69 resource_provider->tracing_id(), id()); |
(...skipping 10 matching lines...) Expand all Loading... |
49 MemoryAllocatorDump::kUnitsBytes, total_bytes); | 80 MemoryAllocatorDump::kUnitsBytes, total_bytes); |
50 | 81 |
51 if (is_free) { | 82 if (is_free) { |
52 dump->AddScalar("free_size", MemoryAllocatorDump::kUnitsBytes, total_bytes); | 83 dump->AddScalar("free_size", MemoryAllocatorDump::kUnitsBytes, total_bytes); |
53 } | 84 } |
54 } | 85 } |
55 | 86 |
56 ResourcePool::ResourcePool(ResourceProvider* resource_provider, | 87 ResourcePool::ResourcePool(ResourceProvider* resource_provider, |
57 base::SingleThreadTaskRunner* task_runner, | 88 base::SingleThreadTaskRunner* task_runner, |
58 gfx::BufferUsage usage, | 89 gfx::BufferUsage usage, |
59 const base::TimeDelta& expiration_delay) | 90 const base::TimeDelta& expiration_delay, |
| 91 bool disallow_non_exact_reuse) |
60 : resource_provider_(resource_provider), | 92 : resource_provider_(resource_provider), |
61 use_gpu_memory_buffers_(true), | 93 use_gpu_memory_buffers_(true), |
62 usage_(usage), | 94 usage_(usage), |
63 task_runner_(task_runner), | 95 task_runner_(task_runner), |
64 resource_expiration_delay_(expiration_delay), | 96 resource_expiration_delay_(expiration_delay), |
| 97 disallow_non_exact_reuse_(disallow_non_exact_reuse), |
65 weak_ptr_factory_(this) { | 98 weak_ptr_factory_(this) { |
66 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( | 99 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( |
67 this, "cc::ResourcePool", task_runner_.get()); | 100 this, "cc::ResourcePool", task_runner_.get()); |
68 | 101 |
69 // Register this component with base::MemoryCoordinatorClientRegistry. | 102 // Register this component with base::MemoryCoordinatorClientRegistry. |
70 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(this); | 103 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(this); |
71 } | 104 } |
72 | 105 |
73 ResourcePool::ResourcePool(ResourceProvider* resource_provider, | 106 ResourcePool::ResourcePool(ResourceProvider* resource_provider, |
74 base::SingleThreadTaskRunner* task_runner, | 107 base::SingleThreadTaskRunner* task_runner, |
75 ResourceProvider::TextureHint hint, | 108 ResourceProvider::TextureHint hint, |
76 const base::TimeDelta& expiration_delay) | 109 const base::TimeDelta& expiration_delay, |
| 110 bool disallow_non_exact_reuse) |
77 : resource_provider_(resource_provider), | 111 : resource_provider_(resource_provider), |
78 use_gpu_memory_buffers_(false), | 112 use_gpu_memory_buffers_(false), |
79 hint_(hint), | 113 hint_(hint), |
80 task_runner_(task_runner), | 114 task_runner_(task_runner), |
81 resource_expiration_delay_(expiration_delay), | 115 resource_expiration_delay_(expiration_delay), |
| 116 disallow_non_exact_reuse_(disallow_non_exact_reuse), |
82 weak_ptr_factory_(this) { | 117 weak_ptr_factory_(this) { |
83 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( | 118 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( |
84 this, "cc::ResourcePool", task_runner_.get()); | 119 this, "cc::ResourcePool", task_runner_.get()); |
85 | 120 |
86 // Register this component with base::MemoryCoordinatorClientRegistry. | 121 // Register this component with base::MemoryCoordinatorClientRegistry. |
87 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(this); | 122 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(this); |
88 } | 123 } |
89 | 124 |
90 ResourcePool::~ResourcePool() { | 125 ResourcePool::~ResourcePool() { |
91 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( | 126 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( |
(...skipping 20 matching lines...) Expand all Loading... |
112 // Finding resources in |unused_resources_| from MRU to LRU direction, touches | 147 // Finding resources in |unused_resources_| from MRU to LRU direction, touches |
113 // LRU resources only if needed, which increases possibility of expiring more | 148 // LRU resources only if needed, which increases possibility of expiring more |
114 // LRU resources within kResourceExpirationDelayMs. | 149 // LRU resources within kResourceExpirationDelayMs. |
115 for (ResourceDeque::iterator it = unused_resources_.begin(); | 150 for (ResourceDeque::iterator it = unused_resources_.begin(); |
116 it != unused_resources_.end(); ++it) { | 151 it != unused_resources_.end(); ++it) { |
117 ScopedResource* resource = it->get(); | 152 ScopedResource* resource = it->get(); |
118 DCHECK(resource_provider_->CanLockForWrite(resource->id())); | 153 DCHECK(resource_provider_->CanLockForWrite(resource->id())); |
119 | 154 |
120 if (resource->format() != format) | 155 if (resource->format() != format) |
121 continue; | 156 continue; |
122 if (resource->size() != size) | 157 if (!ResourceMeetsSizeRequirements(size, resource->size(), |
| 158 disallow_non_exact_reuse_)) |
123 continue; | 159 continue; |
124 if (resource->color_space() != color_space) | 160 if (resource->color_space() != color_space) |
125 continue; | 161 continue; |
126 | 162 |
127 // Transfer resource to |in_use_resources_|. | 163 // Transfer resource to |in_use_resources_|. |
128 in_use_resources_[resource->id()] = std::move(*it); | 164 in_use_resources_[resource->id()] = std::move(*it); |
129 unused_resources_.erase(it); | 165 unused_resources_.erase(it); |
130 in_use_memory_usage_bytes_ += ResourceUtil::UncheckedSizeInBytes<size_t>( | 166 in_use_memory_usage_bytes_ += ResourceUtil::UncheckedSizeInBytes<size_t>( |
131 resource->size(), resource->format()); | 167 resource->size(), resource->format()); |
132 return resource; | 168 return resource; |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 } | 516 } |
481 return true; | 517 return true; |
482 } | 518 } |
483 | 519 |
484 void ResourcePool::OnPurgeMemory() { | 520 void ResourcePool::OnPurgeMemory() { |
485 // Release all resources, regardless of how recently they were used. | 521 // Release all resources, regardless of how recently they were used. |
486 EvictResourcesNotUsedSince(base::TimeTicks() + base::TimeDelta::Max()); | 522 EvictResourcesNotUsedSince(base::TimeTicks() + base::TimeDelta::Max()); |
487 } | 523 } |
488 | 524 |
489 } // namespace cc | 525 } // namespace cc |
OLD | NEW |