| 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 static const int kMaxCacheItems = 2000; |
| 39 static const int kMaxCacheItemsThrottled = 100; |
| 39 | 40 |
| 40 // Returns true if an image would not be drawn and should therefore be | 41 // Returns true if an image would not be drawn and should therefore be |
| 41 // skipped rather than decoded. | 42 // skipped rather than decoded. |
| 42 bool SkipImage(const DrawImage& draw_image) { | 43 bool SkipImage(const DrawImage& draw_image) { |
| 43 if (!SkIRect::Intersects(draw_image.src_rect(), draw_image.image()->bounds())) | 44 if (!SkIRect::Intersects(draw_image.src_rect(), draw_image.image()->bounds())) |
| 44 return true; | 45 return true; |
| 45 if (std::abs(draw_image.scale().width()) < | 46 if (std::abs(draw_image.scale().width()) < |
| 46 std::numeric_limits<float>::epsilon() || | 47 std::numeric_limits<float>::epsilon() || |
| 47 std::abs(draw_image.scale().height()) < | 48 std::abs(draw_image.scale().height()) < |
| 48 std::numeric_limits<float>::epsilon()) { | 49 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. | 321 // be freed with the GL context lock held. |
| 321 DCHECK(!upload.image()); | 322 DCHECK(!upload.image()); |
| 322 } | 323 } |
| 323 | 324 |
| 324 GpuImageDecodeController::GpuImageDecodeController(ContextProvider* context, | 325 GpuImageDecodeController::GpuImageDecodeController(ContextProvider* context, |
| 325 ResourceFormat decode_format, | 326 ResourceFormat decode_format, |
| 326 size_t max_gpu_image_bytes) | 327 size_t max_gpu_image_bytes) |
| 327 : format_(decode_format), | 328 : format_(decode_format), |
| 328 context_(context), | 329 context_(context), |
| 329 persistent_cache_(PersistentCache::NO_AUTO_EVICT), | 330 persistent_cache_(PersistentCache::NO_AUTO_EVICT), |
| 330 cached_items_limit_(kMaxDiscardableItems), | |
| 331 cached_bytes_limit_(max_gpu_image_bytes), | |
| 332 bytes_used_(0), | |
| 333 max_gpu_image_bytes_(max_gpu_image_bytes) { | 331 max_gpu_image_bytes_(max_gpu_image_bytes) { |
| 334 // Acquire the context_lock so that we can safely retrieve the | 332 // Acquire the context_lock so that we can safely retrieve the |
| 335 // GrContextThreadSafeProxy. This proxy can then be used with no lock held. | 333 // GrContextThreadSafeProxy. This proxy can then be used with no lock held. |
| 336 { | 334 { |
| 337 ContextProvider::ScopedContextLock context_lock(context_); | 335 ContextProvider::ScopedContextLock context_lock(context_); |
| 338 context_threadsafe_proxy_ = sk_sp<GrContextThreadSafeProxy>( | 336 context_threadsafe_proxy_ = sk_sp<GrContextThreadSafeProxy>( |
| 339 context->GrContext()->threadSafeProxy()); | 337 context->GrContext()->threadSafeProxy()); |
| 340 } | 338 } |
| 341 | 339 |
| 342 // In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview). | 340 // In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview). |
| (...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 902 } | 900 } |
| 903 | 901 |
| 904 // Preferred count is only used as a guideline when triming the cache. Allow | 902 // 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. | 903 // new elements to be added as long as we are below our size limit. |
| 906 return CanFitSize(required_size); | 904 return CanFitSize(required_size); |
| 907 } | 905 } |
| 908 | 906 |
| 909 bool GpuImageDecodeController::CanFitSize(size_t size) const { | 907 bool GpuImageDecodeController::CanFitSize(size_t size) const { |
| 910 lock_.AssertAcquired(); | 908 lock_.AssertAcquired(); |
| 911 | 909 |
| 910 size_t bytes_limit; |
| 911 if (memory_state_ == base::MemoryState::NORMAL) { |
| 912 bytes_limit = cached_bytes_limit_; |
| 913 } else if (memory_state_ == base::MemoryState::THROTTLED) { |
| 914 bytes_limit = cached_bytes_limit_ / 2; |
| 915 } else { |
| 916 DCHECK_EQ(base::MemoryState::SUSPENDED, memory_state_); |
| 917 bytes_limit = 0; |
| 918 } |
| 919 |
| 912 base::CheckedNumeric<uint32_t> new_size(bytes_used_); | 920 base::CheckedNumeric<uint32_t> new_size(bytes_used_); |
| 913 new_size += size; | 921 new_size += size; |
| 914 return new_size.IsValid() && new_size.ValueOrDie() <= cached_bytes_limit_; | 922 return new_size.IsValid() && new_size.ValueOrDie() <= bytes_limit; |
| 915 } | 923 } |
| 916 | 924 |
| 917 bool GpuImageDecodeController::ExceedsPreferredCount() const { | 925 bool GpuImageDecodeController::ExceedsPreferredCount() const { |
| 918 lock_.AssertAcquired(); | 926 lock_.AssertAcquired(); |
| 919 | 927 |
| 920 return persistent_cache_.size() > cached_items_limit_; | 928 size_t items_limit; |
| 929 if (memory_state_ == base::MemoryState::NORMAL) { |
| 930 items_limit = kMaxCacheItems; |
| 931 } else if (memory_state_ == base::MemoryState::THROTTLED) { |
| 932 items_limit = kMaxCacheItemsThrottled; |
| 933 } else { |
| 934 DCHECK_EQ(base::MemoryState::SUSPENDED, memory_state_); |
| 935 items_limit = 0; |
| 936 } |
| 937 |
| 938 return persistent_cache_.size() > items_limit; |
| 921 } | 939 } |
| 922 | 940 |
| 923 void GpuImageDecodeController::DecodeImageIfNecessary( | 941 void GpuImageDecodeController::DecodeImageIfNecessary( |
| 924 const DrawImage& draw_image, | 942 const DrawImage& draw_image, |
| 925 ImageData* image_data) { | 943 ImageData* image_data) { |
| 926 lock_.AssertAcquired(); | 944 lock_.AssertAcquired(); |
| 927 | 945 |
| 928 DCHECK_GT(image_data->decode.ref_count, 0u); | 946 DCHECK_GT(image_data->decode.ref_count, 0u); |
| 929 | 947 |
| 930 if (image_data->decode.decode_failure) { | 948 if (image_data->decode.decode_failure) { |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1170 base::AutoLock lock(lock_); | 1188 base::AutoLock lock(lock_); |
| 1171 auto found = persistent_cache_.Peek(image.image()->uniqueID()); | 1189 auto found = persistent_cache_.Peek(image.image()->uniqueID()); |
| 1172 DCHECK(found != persistent_cache_.end()); | 1190 DCHECK(found != persistent_cache_.end()); |
| 1173 ImageData* image_data = found->second.get(); | 1191 ImageData* image_data = found->second.get(); |
| 1174 return image_data->decode.is_locked(); | 1192 return image_data->decode.is_locked(); |
| 1175 } | 1193 } |
| 1176 | 1194 |
| 1177 void GpuImageDecodeController::OnMemoryStateChange(base::MemoryState state) { | 1195 void GpuImageDecodeController::OnMemoryStateChange(base::MemoryState state) { |
| 1178 switch (state) { | 1196 switch (state) { |
| 1179 case base::MemoryState::NORMAL: | 1197 case base::MemoryState::NORMAL: |
| 1180 // TODO(tasak): go back to normal state. | 1198 memory_state_ = state; |
| 1181 break; | 1199 break; |
| 1182 case base::MemoryState::THROTTLED: | 1200 case base::MemoryState::THROTTLED: |
| 1183 // TODO(tasak): make the limits of this component's caches smaller to | 1201 case base::MemoryState::SUSPENDED: { |
| 1184 // save memory usage. | 1202 memory_state_ = state; |
| 1203 |
| 1204 // We've just changed our memory state to a (potentially) more |
| 1205 // restrictive one. Re-enforce cache limits. |
| 1206 base::AutoLock lock(lock_); |
| 1207 EnsureCapacity(0); |
| 1185 break; | 1208 break; |
| 1186 case base::MemoryState::SUSPENDED: | 1209 } |
| 1187 // TODO(tasak): free this component's caches as much as possible before | |
| 1188 // suspending renderer. | |
| 1189 break; | |
| 1190 case base::MemoryState::UNKNOWN: | 1210 case base::MemoryState::UNKNOWN: |
| 1191 // NOT_REACHED. | 1211 // NOT_REACHED. |
| 1192 break; | 1212 break; |
| 1193 } | 1213 } |
| 1194 } | 1214 } |
| 1195 | 1215 |
| 1196 } // namespace cc | 1216 } // namespace cc |
| OLD | NEW |