| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/tiles/gpu_image_decode_controller.h" | 5 #include "cc/tiles/gpu_image_decode_controller.h" |
| 6 | 6 |
| 7 #include <inttypes.h> | 7 #include <inttypes.h> |
| 8 | 8 |
| 9 #include "base/debug/alias.h" | 9 #include "base/debug/alias.h" |
| 10 #include "base/memory/discardable_memory_allocator.h" | 10 #include "base/memory/discardable_memory_allocator.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 #include "third_party/skia/include/core/SkRefCnt.h" | 28 #include "third_party/skia/include/core/SkRefCnt.h" |
| 29 #include "third_party/skia/include/core/SkSurface.h" | 29 #include "third_party/skia/include/core/SkSurface.h" |
| 30 #include "third_party/skia/include/gpu/GrContext.h" | 30 #include "third_party/skia/include/gpu/GrContext.h" |
| 31 #include "third_party/skia/include/gpu/GrTexture.h" | 31 #include "third_party/skia/include/gpu/GrTexture.h" |
| 32 #include "ui/gfx/skia_util.h" | 32 #include "ui/gfx/skia_util.h" |
| 33 #include "ui/gl/trace_util.h" | 33 #include "ui/gl/trace_util.h" |
| 34 | 34 |
| 35 namespace cc { | 35 namespace cc { |
| 36 namespace { | 36 namespace { |
| 37 | 37 |
| 38 static const int kMaxDiscardableItems = 2000; | 38 // The number or entries to keep in the cache, depending on the memory state of |
| 39 // the system. This limit can be breached by in-use cache items, which cannot |
| 40 // be deleted. |
| 41 static const int kNormalMaxItemsInCache = 2000; |
| 42 static const int kThrottledMaxItemsInCache = 100; |
| 43 static const int kSuspendedMaxItemsInCache = 0; |
| 44 |
| 45 // The factor by which to reduce the GPU memory size of the cache when in the |
| 46 // THROTTLED memory state. |
| 47 static const int kThrottledCacheSizeReductionFactor = 2; |
| 48 |
| 49 // The maximum size in bytes of GPU memory in the cache while SUSPENDED or not |
| 50 // visible. This limit can be breached by in-use cache items, which cannot be |
| 51 // deleted. |
| 52 static const int kSuspendedOrInvisibleMaxGpuImageBytes = 0; |
| 39 | 53 |
| 40 // Returns true if an image would not be drawn and should therefore be | 54 // Returns true if an image would not be drawn and should therefore be |
| 41 // skipped rather than decoded. | 55 // skipped rather than decoded. |
| 42 bool SkipImage(const DrawImage& draw_image) { | 56 bool SkipImage(const DrawImage& draw_image) { |
| 43 if (!SkIRect::Intersects(draw_image.src_rect(), draw_image.image()->bounds())) | 57 if (!SkIRect::Intersects(draw_image.src_rect(), draw_image.image()->bounds())) |
| 44 return true; | 58 return true; |
| 45 if (std::abs(draw_image.scale().width()) < | 59 if (std::abs(draw_image.scale().width()) < |
| 46 std::numeric_limits<float>::epsilon() || | 60 std::numeric_limits<float>::epsilon() || |
| 47 std::abs(draw_image.scale().height()) < | 61 std::abs(draw_image.scale().height()) < |
| 48 std::numeric_limits<float>::epsilon()) { | 62 std::numeric_limits<float>::epsilon()) { |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 320 // be freed with the GL context lock held. | 334 // be freed with the GL context lock held. |
| 321 DCHECK(!upload.image()); | 335 DCHECK(!upload.image()); |
| 322 } | 336 } |
| 323 | 337 |
| 324 GpuImageDecodeController::GpuImageDecodeController(ContextProvider* context, | 338 GpuImageDecodeController::GpuImageDecodeController(ContextProvider* context, |
| 325 ResourceFormat decode_format, | 339 ResourceFormat decode_format, |
| 326 size_t max_gpu_image_bytes) | 340 size_t max_gpu_image_bytes) |
| 327 : format_(decode_format), | 341 : format_(decode_format), |
| 328 context_(context), | 342 context_(context), |
| 329 persistent_cache_(PersistentCache::NO_AUTO_EVICT), | 343 persistent_cache_(PersistentCache::NO_AUTO_EVICT), |
| 330 cached_items_limit_(kMaxDiscardableItems), | 344 normal_max_gpu_image_bytes_(max_gpu_image_bytes) { |
| 331 cached_bytes_limit_(max_gpu_image_bytes), | |
| 332 bytes_used_(0), | |
| 333 max_gpu_image_bytes_(max_gpu_image_bytes) { | |
| 334 // Acquire the context_lock so that we can safely retrieve the | 345 // Acquire the context_lock so that we can safely retrieve the |
| 335 // GrContextThreadSafeProxy. This proxy can then be used with no lock held. | 346 // GrContextThreadSafeProxy. This proxy can then be used with no lock held. |
| 336 { | 347 { |
| 337 ContextProvider::ScopedContextLock context_lock(context_); | 348 ContextProvider::ScopedContextLock context_lock(context_); |
| 338 context_threadsafe_proxy_ = sk_sp<GrContextThreadSafeProxy>( | 349 context_threadsafe_proxy_ = sk_sp<GrContextThreadSafeProxy>( |
| 339 context->GrContext()->threadSafeProxy()); | 350 context->GrContext()->threadSafeProxy()); |
| 340 } | 351 } |
| 341 | 352 |
| 342 // In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview). | 353 // In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview). |
| 343 // Don't register a dump provider in these cases. | 354 // Don't register a dump provider in these cases. |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 515 void GpuImageDecodeController::SetShouldAggressivelyFreeResources( | 526 void GpuImageDecodeController::SetShouldAggressivelyFreeResources( |
| 516 bool aggressively_free_resources) { | 527 bool aggressively_free_resources) { |
| 517 TRACE_EVENT1("disabled-by-default-cc.debug", | 528 TRACE_EVENT1("disabled-by-default-cc.debug", |
| 518 "GpuImageDecodeController::SetShouldAggressivelyFreeResources", | 529 "GpuImageDecodeController::SetShouldAggressivelyFreeResources", |
| 519 "agressive_free_resources", aggressively_free_resources); | 530 "agressive_free_resources", aggressively_free_resources); |
| 520 if (aggressively_free_resources) { | 531 if (aggressively_free_resources) { |
| 521 ContextProvider::ScopedContextLock context_lock(context_); | 532 ContextProvider::ScopedContextLock context_lock(context_); |
| 522 base::AutoLock lock(lock_); | 533 base::AutoLock lock(lock_); |
| 523 // We want to keep as little in our cache as possible. Set our memory limit | 534 // We want to keep as little in our cache as possible. Set our memory limit |
| 524 // to zero and EnsureCapacity to clean up memory. | 535 // to zero and EnsureCapacity to clean up memory. |
| 525 cached_bytes_limit_ = 0; | 536 cached_bytes_limit_ = kSuspendedOrInvisibleMaxGpuImageBytes; |
| 526 EnsureCapacity(0); | 537 EnsureCapacity(0); |
| 527 | 538 |
| 528 // We are holding the context lock, so finish cleaning up deleted images | 539 // We are holding the context lock, so finish cleaning up deleted images |
| 529 // now. | 540 // now. |
| 530 DeletePendingImages(); | 541 DeletePendingImages(); |
| 531 } else { | 542 } else { |
| 532 base::AutoLock lock(lock_); | 543 base::AutoLock lock(lock_); |
| 533 cached_bytes_limit_ = max_gpu_image_bytes_; | 544 cached_bytes_limit_ = normal_max_gpu_image_bytes_; |
| 534 } | 545 } |
| 535 } | 546 } |
| 536 | 547 |
| 537 bool GpuImageDecodeController::OnMemoryDump( | 548 bool GpuImageDecodeController::OnMemoryDump( |
| 538 const base::trace_event::MemoryDumpArgs& args, | 549 const base::trace_event::MemoryDumpArgs& args, |
| 539 base::trace_event::ProcessMemoryDump* pmd) { | 550 base::trace_event::ProcessMemoryDump* pmd) { |
| 540 TRACE_EVENT0("disabled-by-default-cc.debug", | 551 TRACE_EVENT0("disabled-by-default-cc.debug", |
| 541 "GpuImageDecodeController::OnMemoryDump"); | 552 "GpuImageDecodeController::OnMemoryDump"); |
| 542 for (const auto& image_pair : persistent_cache_) { | 553 for (const auto& image_pair : persistent_cache_) { |
| 543 const ImageData* image_data = image_pair.second.get(); | 554 const ImageData* image_data = image_pair.second.get(); |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 902 } | 913 } |
| 903 | 914 |
| 904 // Preferred count is only used as a guideline when triming the cache. Allow | 915 // Preferred count is only used as a guideline when triming the cache. Allow |
| 905 // new elements to be added as long as we are below our size limit. | 916 // new elements to be added as long as we are below our size limit. |
| 906 return CanFitSize(required_size); | 917 return CanFitSize(required_size); |
| 907 } | 918 } |
| 908 | 919 |
| 909 bool GpuImageDecodeController::CanFitSize(size_t size) const { | 920 bool GpuImageDecodeController::CanFitSize(size_t size) const { |
| 910 lock_.AssertAcquired(); | 921 lock_.AssertAcquired(); |
| 911 | 922 |
| 923 size_t bytes_limit; |
| 924 if (memory_state_ == base::MemoryState::NORMAL) { |
| 925 bytes_limit = cached_bytes_limit_; |
| 926 } else if (memory_state_ == base::MemoryState::THROTTLED) { |
| 927 bytes_limit = cached_bytes_limit_ / kThrottledCacheSizeReductionFactor; |
| 928 } else { |
| 929 DCHECK_EQ(base::MemoryState::SUSPENDED, memory_state_); |
| 930 bytes_limit = kSuspendedOrInvisibleMaxGpuImageBytes; |
| 931 } |
| 932 |
| 912 base::CheckedNumeric<uint32_t> new_size(bytes_used_); | 933 base::CheckedNumeric<uint32_t> new_size(bytes_used_); |
| 913 new_size += size; | 934 new_size += size; |
| 914 return new_size.IsValid() && new_size.ValueOrDie() <= cached_bytes_limit_; | 935 return new_size.IsValid() && new_size.ValueOrDie() <= bytes_limit; |
| 915 } | 936 } |
| 916 | 937 |
| 917 bool GpuImageDecodeController::ExceedsPreferredCount() const { | 938 bool GpuImageDecodeController::ExceedsPreferredCount() const { |
| 918 lock_.AssertAcquired(); | 939 lock_.AssertAcquired(); |
| 919 | 940 |
| 920 return persistent_cache_.size() > cached_items_limit_; | 941 size_t items_limit; |
| 942 if (memory_state_ == base::MemoryState::NORMAL) { |
| 943 items_limit = kNormalMaxItemsInCache; |
| 944 } else if (memory_state_ == base::MemoryState::THROTTLED) { |
| 945 items_limit = kThrottledMaxItemsInCache; |
| 946 } else { |
| 947 DCHECK_EQ(base::MemoryState::SUSPENDED, memory_state_); |
| 948 items_limit = kSuspendedMaxItemsInCache; |
| 949 } |
| 950 |
| 951 return persistent_cache_.size() > items_limit; |
| 921 } | 952 } |
| 922 | 953 |
| 923 void GpuImageDecodeController::DecodeImageIfNecessary( | 954 void GpuImageDecodeController::DecodeImageIfNecessary( |
| 924 const DrawImage& draw_image, | 955 const DrawImage& draw_image, |
| 925 ImageData* image_data) { | 956 ImageData* image_data) { |
| 926 lock_.AssertAcquired(); | 957 lock_.AssertAcquired(); |
| 927 | 958 |
| 928 DCHECK_GT(image_data->decode.ref_count, 0u); | 959 DCHECK_GT(image_data->decode.ref_count, 0u); |
| 929 | 960 |
| 930 if (image_data->decode.decode_failure) { | 961 if (image_data->decode.decode_failure) { |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1170 base::AutoLock lock(lock_); | 1201 base::AutoLock lock(lock_); |
| 1171 auto found = persistent_cache_.Peek(image.image()->uniqueID()); | 1202 auto found = persistent_cache_.Peek(image.image()->uniqueID()); |
| 1172 DCHECK(found != persistent_cache_.end()); | 1203 DCHECK(found != persistent_cache_.end()); |
| 1173 ImageData* image_data = found->second.get(); | 1204 ImageData* image_data = found->second.get(); |
| 1174 return image_data->decode.is_locked(); | 1205 return image_data->decode.is_locked(); |
| 1175 } | 1206 } |
| 1176 | 1207 |
| 1177 void GpuImageDecodeController::OnMemoryStateChange(base::MemoryState state) { | 1208 void GpuImageDecodeController::OnMemoryStateChange(base::MemoryState state) { |
| 1178 switch (state) { | 1209 switch (state) { |
| 1179 case base::MemoryState::NORMAL: | 1210 case base::MemoryState::NORMAL: |
| 1180 // TODO(tasak): go back to normal state. | 1211 memory_state_ = state; |
| 1181 break; | 1212 break; |
| 1182 case base::MemoryState::THROTTLED: | 1213 case base::MemoryState::THROTTLED: |
| 1183 // TODO(tasak): make the limits of this component's caches smaller to | 1214 case base::MemoryState::SUSPENDED: { |
| 1184 // save memory usage. | 1215 memory_state_ = state; |
| 1216 |
| 1217 // We've just changed our memory state to a (potentially) more |
| 1218 // restrictive one. Re-enforce cache limits. |
| 1219 base::AutoLock lock(lock_); |
| 1220 EnsureCapacity(0); |
| 1185 break; | 1221 break; |
| 1186 case base::MemoryState::SUSPENDED: | 1222 } |
| 1187 // TODO(tasak): free this component's caches as much as possible before | |
| 1188 // suspending renderer. | |
| 1189 break; | |
| 1190 case base::MemoryState::UNKNOWN: | 1223 case base::MemoryState::UNKNOWN: |
| 1191 // NOT_REACHED. | 1224 // NOT_REACHED. |
| 1192 break; | 1225 break; |
| 1193 } | 1226 } |
| 1194 } | 1227 } |
| 1195 | 1228 |
| 1196 } // namespace cc | 1229 } // namespace cc |
| OLD | NEW |