| Index: cc/tiles/gpu_image_decode_controller.cc
|
| diff --git a/cc/tiles/gpu_image_decode_controller.cc b/cc/tiles/gpu_image_decode_controller.cc
|
| index 83ce4c4cf1c4677c5945f3d228bdb12b3e03dd28..0ebc1940673444ea6673554daee17383686f4649 100644
|
| --- a/cc/tiles/gpu_image_decode_controller.cc
|
| +++ b/cc/tiles/gpu_image_decode_controller.cc
|
| @@ -35,7 +35,8 @@
|
| namespace cc {
|
| namespace {
|
|
|
| -static const int kMaxDiscardableItems = 2000;
|
| +static const int kMaxCacheItems = 2000;
|
| +static const int kMaxCacheItemsThrottled = 100;
|
|
|
| // Returns true if an image would not be drawn and should therefore be
|
| // skipped rather than decoded.
|
| @@ -327,9 +328,6 @@ GpuImageDecodeController::GpuImageDecodeController(ContextProvider* context,
|
| : format_(decode_format),
|
| context_(context),
|
| persistent_cache_(PersistentCache::NO_AUTO_EVICT),
|
| - cached_items_limit_(kMaxDiscardableItems),
|
| - cached_bytes_limit_(max_gpu_image_bytes),
|
| - bytes_used_(0),
|
| max_gpu_image_bytes_(max_gpu_image_bytes) {
|
| // Acquire the context_lock so that we can safely retrieve the
|
| // GrContextThreadSafeProxy. This proxy can then be used with no lock held.
|
| @@ -909,15 +907,35 @@ bool GpuImageDecodeController::EnsureCapacity(size_t required_size) {
|
| bool GpuImageDecodeController::CanFitSize(size_t size) const {
|
| lock_.AssertAcquired();
|
|
|
| + size_t bytes_limit;
|
| + if (memory_state_ == base::MemoryState::NORMAL) {
|
| + bytes_limit = cached_bytes_limit_;
|
| + } else if (memory_state_ == base::MemoryState::THROTTLED) {
|
| + bytes_limit = cached_bytes_limit_ / 2;
|
| + } else {
|
| + DCHECK_EQ(base::MemoryState::SUSPENDED, memory_state_);
|
| + bytes_limit = 0;
|
| + }
|
| +
|
| base::CheckedNumeric<uint32_t> new_size(bytes_used_);
|
| new_size += size;
|
| - return new_size.IsValid() && new_size.ValueOrDie() <= cached_bytes_limit_;
|
| + return new_size.IsValid() && new_size.ValueOrDie() <= bytes_limit;
|
| }
|
|
|
| bool GpuImageDecodeController::ExceedsPreferredCount() const {
|
| lock_.AssertAcquired();
|
|
|
| - return persistent_cache_.size() > cached_items_limit_;
|
| + size_t items_limit;
|
| + if (memory_state_ == base::MemoryState::NORMAL) {
|
| + items_limit = kMaxCacheItems;
|
| + } else if (memory_state_ == base::MemoryState::THROTTLED) {
|
| + items_limit = kMaxCacheItemsThrottled;
|
| + } else {
|
| + DCHECK_EQ(base::MemoryState::SUSPENDED, memory_state_);
|
| + items_limit = 0;
|
| + }
|
| +
|
| + return persistent_cache_.size() > items_limit;
|
| }
|
|
|
| void GpuImageDecodeController::DecodeImageIfNecessary(
|
| @@ -1177,16 +1195,18 @@ bool GpuImageDecodeController::DiscardableIsLockedForTesting(
|
| void GpuImageDecodeController::OnMemoryStateChange(base::MemoryState state) {
|
| switch (state) {
|
| case base::MemoryState::NORMAL:
|
| - // TODO(tasak): go back to normal state.
|
| + memory_state_ = state;
|
| break;
|
| case base::MemoryState::THROTTLED:
|
| - // TODO(tasak): make the limits of this component's caches smaller to
|
| - // save memory usage.
|
| - break;
|
| - case base::MemoryState::SUSPENDED:
|
| - // TODO(tasak): free this component's caches as much as possible before
|
| - // suspending renderer.
|
| + case base::MemoryState::SUSPENDED: {
|
| + memory_state_ = state;
|
| +
|
| + // We've just changed our memory state to a (potentially) more
|
| + // restrictive one. Re-enforce cache limits.
|
| + base::AutoLock lock(lock_);
|
| + EnsureCapacity(0);
|
| break;
|
| + }
|
| case base::MemoryState::UNKNOWN:
|
| // NOT_REACHED.
|
| break;
|
|
|