Chromium Code Reviews| 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 #ifndef CC_TILES_GPU_IMAGE_DECODE_CONTROLLER_H_ | 5 #ifndef CC_TILES_GPU_IMAGE_DECODE_CONTROLLER_H_ |
| 6 #define CC_TILES_GPU_IMAGE_DECODE_CONTROLLER_H_ | 6 #define CC_TILES_GPU_IMAGE_DECODE_CONTROLLER_H_ |
| 7 | 7 |
| 8 #include <list> | |
| 8 #include <unordered_map> | 9 #include <unordered_map> |
| 9 #include <unordered_set> | 10 #include <unordered_set> |
| 11 #include <vector> | |
| 10 | 12 |
| 13 #include "base/containers/mru_cache.h" | |
| 14 #include "base/memory/discardable_memory.h" | |
| 15 #include "base/memory/scoped_ptr.h" | |
| 11 #include "base/synchronization/lock.h" | 16 #include "base/synchronization/lock.h" |
| 17 #include "base/trace_event/memory_dump_provider.h" | |
| 12 #include "cc/base/cc_export.h" | 18 #include "cc/base/cc_export.h" |
| 13 #include "cc/tiles/image_decode_controller.h" | 19 #include "cc/tiles/image_decode_controller.h" |
| 20 #include "skia/ext/refptr.h" | |
| 21 | |
| 22 class SkImageTextureData; | |
| 14 | 23 |
| 15 namespace cc { | 24 namespace cc { |
| 16 | 25 |
| 26 class ContextProvider; | |
| 27 | |
| 28 // GpuImageDecodeController handles the decode and upload of images that will | |
| 29 // be used by Skia's GPU raster path. It also maintains a cache of these | |
| 30 // decoded/ uploaded images for later re-use. | |
| 31 // | |
| 32 // Generally, when an image is required for raster, GpuImageDecodeController | |
| 33 // creates two tasks, one to decode the image, and one to upload the image to | |
| 34 // the GPU. These tasks are completed before the raster task which depends on | |
| 35 // the image. We need to seperate decode and upload tasks, as decode can occur | |
| 36 // simultaneously on multiple threads, while upload requires the GL context | |
| 37 // lockmust happen on our non-concurrent raster thread. | |
| 38 // | |
| 39 // Decoded and Uploaded image data share a single cache entry. Depending on how | |
| 40 // far we've progressed, this cache entry may contain CPU-side decoded data, | |
| 41 // GPU-side uploaded data, or both. Because CPU-side decoded data is stored in | |
| 42 // discardable memory, and is only locked for short periods of time (until the | |
| 43 // upload completes), this memory is not counted against our sized cache | |
| 44 // limits. Uploaded GPU memory, being non- discardable, always counts against | |
| 45 // our limits. | |
| 46 // | |
| 47 // In cases where the number of images needed exceeds our cache limits, we | |
| 48 // operate in an "at-raster" mode. In this mode, there are no decode/upload | |
| 49 // tasks, and images are decoded/uploaded as needed, immediately before being | |
| 50 // used in raster. Cache entries for at-raster tasks are marked as such, which | |
| 51 // prevents future tasks from taking a dependency on them and extending their | |
| 52 // lifetime longer than is necessary. | |
| 17 class CC_EXPORT GpuImageDecodeController : public ImageDecodeController { | 53 class CC_EXPORT GpuImageDecodeController : public ImageDecodeController { |
| 18 public: | 54 public: |
| 19 GpuImageDecodeController(); | 55 explicit GpuImageDecodeController(ContextProvider* context); |
| 20 ~GpuImageDecodeController() override; | 56 ~GpuImageDecodeController() override; |
| 21 | 57 |
| 22 // ImageDecodeController overrides. | 58 // ImageDecodeController overrides. |
| 23 bool GetTaskForImageAndRef(const DrawImage& image, | 59 bool GetTaskForImageAndRef(const DrawImage& image, |
| 24 uint64_t prepare_tiles_id, | 60 uint64_t prepare_tiles_id, |
| 25 scoped_refptr<ImageDecodeTask>* task) override; | 61 scoped_refptr<ImageDecodeTask>* task) override; |
| 26 void UnrefImage(const DrawImage& image) override; | 62 void UnrefImage(const DrawImage& image) override; |
| 27 DecodedDrawImage GetDecodedImageForDraw(const DrawImage& draw_image) override; | 63 DecodedDrawImage GetDecodedImageForDraw(const DrawImage& draw_image) override; |
| 28 void DrawWithImageFinished(const DrawImage& image, | 64 void DrawWithImageFinished(const DrawImage& image, |
| 29 const DecodedDrawImage& decoded_image) override; | 65 const DecodedDrawImage& decoded_image) override; |
| 30 void ReduceCacheUsage() override; | 66 void ReduceCacheUsage() override; |
| 31 | 67 |
| 68 // Called by Decode / Upload tasks. | |
| 32 void DecodeImage(const DrawImage& image); | 69 void DecodeImage(const DrawImage& image); |
| 70 void UploadImage(const DrawImage& image); | |
| 71 void RemovePendingDecodeTaskForImage(const DrawImage& image); | |
| 72 void RemovePendingUploadTaskForImage(const DrawImage& image); | |
| 73 scoped_refptr<ImageDecodeTask> GetImageDecodeTaskAndRefLocked( | |
|
vmpstr
2016/03/25 22:37:30
Can you put a separate comment here. I'm not sure
ericrk
2016/03/28 22:10:52
This was called by the upload task, which was cons
| |
| 74 const DrawImage& image, | |
| 75 uint64_t prepare_tiles_id); | |
| 76 void UnrefImageDecode(const DrawImage& draw_image); | |
| 33 | 77 |
| 34 void RemovePendingTaskForImage(const DrawImage& image); | 78 // For testing only. |
| 79 void SetCachedItemLimit(size_t limit) { cached_items_limit_ = limit; } | |
|
vmpstr
2016/03/25 22:37:30
These have to be named with ForTesting at the end
ericrk
2016/03/28 22:10:53
Done.
| |
| 80 void SetCachedBytesLimit(size_t limit) { cached_bytes_limit_ = limit; } | |
| 81 size_t GetBytesUsedForTesting() const { return bytes_used_; } | |
| 35 | 82 |
| 36 private: | 83 private: |
| 84 class ScopedRefImageLocked; | |
| 85 | |
| 86 enum DecodedDataMode { DECODED_DATA_MODE_GPU, DECODED_DATA_MODE_CPU }; | |
|
vmpstr
2016/03/25 22:37:30
Can you do an enum class and call the values GPU a
ericrk
2016/03/28 22:10:52
yup - forgot that we could use these.
| |
| 87 | |
| 88 struct ImageData { | |
| 89 ImageData(DecodedDataMode mode, size_t size); | |
| 90 ~ImageData(); | |
| 91 const DecodedDataMode mode; | |
|
vmpstr
2016/03/25 22:37:30
nit: blank line before this one please
ericrk
2016/03/28 22:10:53
Done.
| |
| 92 const size_t size; | |
| 93 | |
| 94 // May be null if image not yet decoded. | |
|
vmpstr
2016/03/25 22:37:30
The cpu side and the gpu side seem logically to be
ericrk
2016/03/28 22:10:53
Sure, I think I like that better as well.
| |
| 95 scoped_ptr<base::DiscardableMemory> decoded_data; | |
| 96 uint32_t decoded_data_ref_count; | |
| 97 bool decoded_data_is_locked; | |
| 98 | |
| 99 // May be null if image not yet uploaded / prepared. | |
| 100 skia::RefPtr<SkImage> uploaded_image; | |
| 101 // True if the image is pending upload, in which case it counts against our | |
| 102 // memory budget even though the uploaded_image may not yet exist. | |
| 103 bool image_pending; | |
| 104 uint32_t image_ref_count; | |
| 105 | |
| 106 bool is_at_raster; | |
| 107 }; | |
| 108 | |
| 109 void RefImageDecodeLocked(const DrawImage& draw_image); | |
| 110 void UnrefImageDecodeLocked(const DrawImage& draw_image); | |
| 111 void RefImageLocked(const DrawImage& draw_image); | |
| 112 void UnrefImageLocked(const DrawImage& draw_image); | |
| 113 bool EnsureCapacityLocked(size_t new_size); | |
|
vmpstr
2016/03/25 22:37:30
This function needs a comment. Not sure what it do
ericrk
2016/03/28 22:10:53
Done.
| |
| 114 | |
| 115 bool CanFitSize(size_t size) const; | |
| 116 bool CanFitCount(size_t num_elements) const; | |
| 117 | |
| 118 void DecodeImageIfNecessaryLocked(const DrawImage& draw_image, | |
| 119 ImageData* image_data); | |
| 120 void UploadImageIfNecessaryLocked(const DrawImage& draw_image, | |
| 121 ImageData* image_data); | |
| 122 | |
| 123 scoped_ptr<GpuImageDecodeController::ImageData> NewImageData( | |
| 124 const DrawImage& image); | |
| 125 | |
| 126 void RemovePendingUploadTaskForImageLocked(const DrawImage& draw_image); | |
| 127 void RemovePendingDecodeTaskForImageLocked(const DrawImage& draw_image); | |
| 128 | |
| 129 void DeletePendingImagesLocked(); | |
| 130 | |
| 37 base::Lock lock_; | 131 base::Lock lock_; |
| 38 | 132 |
| 39 std::unordered_set<uint32_t> prerolled_images_; | |
| 40 std::unordered_map<uint32_t, scoped_refptr<ImageDecodeTask>> | 133 std::unordered_map<uint32_t, scoped_refptr<ImageDecodeTask>> |
| 41 pending_image_tasks_; | 134 pending_image_upload_tasks_; |
| 135 std::unordered_map<uint32_t, scoped_refptr<ImageDecodeTask>> | |
| 136 pending_image_decode_tasks_; | |
| 137 | |
| 138 base::MRUCache<uint32_t, scoped_ptr<ImageData>> image_data_; | |
| 139 | |
| 140 size_t cached_items_limit_; | |
| 141 size_t cached_bytes_limit_; | |
| 142 size_t bytes_used_; | |
| 143 ContextProvider* context_; | |
| 144 GrContextThreadSafeProxy* context_threadsafe_proxy_; | |
| 145 | |
| 146 // We can't release GPU backed SkImages without holding the Skia context lock, | |
| 147 // so we add them to this list and defer deletion until the next time the lock | |
| 148 // is held. | |
| 149 std::vector<skia::RefPtr<SkImage>> images_pending_deletion_; | |
| 42 }; | 150 }; |
| 43 | 151 |
| 44 } // namespace cc | 152 } // namespace cc |
| 45 | 153 |
| 46 #endif // CC_TILES_GPU_IMAGE_DECODE_CONTROLLER_H_ | 154 #endif // CC_TILES_GPU_IMAGE_DECODE_CONTROLLER_H_ |
| OLD | NEW |