blob: 32b2b4c240fca4af4e5ed385e9db278b60810b69 [file] [log] [blame]
vmpstr64cdba32016-03-03 00:38:401// Copyright 2016 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CC_TILES_GPU_IMAGE_DECODE_CONTROLLER_H_
6#define CC_TILES_GPU_IMAGE_DECODE_CONTROLLER_H_
7
ericrkd2ff2a132016-04-11 22:16:008#include <memory>
vmpstr64cdba32016-03-03 00:38:409#include <unordered_map>
ericrkd2ff2a132016-04-11 22:16:0010#include <vector>
vmpstr64cdba32016-03-03 00:38:4011
ericrkd2ff2a132016-04-11 22:16:0012#include "base/containers/mru_cache.h"
13#include "base/memory/discardable_memory.h"
vmpstr64cdba32016-03-03 00:38:4014#include "base/synchronization/lock.h"
ericrkd2ff2a132016-04-11 22:16:0015#include "base/trace_event/memory_dump_provider.h"
vmpstr64cdba32016-03-03 00:38:4016#include "cc/base/cc_export.h"
ericrkd2ff2a132016-04-11 22:16:0017#include "cc/resources/resource_format.h"
vmpstr64cdba32016-03-03 00:38:4018#include "cc/tiles/image_decode_controller.h"
ericrkd2ff2a132016-04-11 22:16:0019#include "skia/ext/refptr.h"
20
21class SkImageTextureData;
vmpstr64cdba32016-03-03 00:38:4022
23namespace cc {
24
ericrkd2ff2a132016-04-11 22:16:0025class ContextProvider;
26
27// GpuImageDecodeController handles the decode and upload of images that will
28// be used by Skia's GPU raster path. It also maintains a cache of these
29// decoded/uploaded images for later re-use.
30//
31// Generally, when an image is required for raster, GpuImageDecodeController
32// creates two tasks, one to decode the image, and one to upload the image to
33// the GPU. These tasks are completed before the raster task which depends on
34// the image. We need to seperate decode and upload tasks, as decode can occur
35// simultaneously on multiple threads, while upload requires the GL context
36// lock must happen on our non-concurrent raster thread.
37//
38// Decoded and Uploaded image data share a single cache entry. Depending on how
39// far we've progressed, this cache entry may contain CPU-side decoded data,
40// GPU-side uploaded data, or both. Because CPU-side decoded data is stored in
41// discardable memory, and is only locked for short periods of time (until the
42// upload completes), this memory is not counted against our sized cache
43// limits. Uploaded GPU memory, being non-discardable, always counts against
44// our limits.
45//
46// In cases where the number of images needed exceeds our cache limits, we
47// operate in an "at-raster" mode. In this mode, there are no decode/upload
48// tasks, and images are decoded/uploaded as needed, immediately before being
49// used in raster. Cache entries for at-raster tasks are marked as such, which
50// prevents future tasks from taking a dependency on them and extending their
51// lifetime longer than is necessary.
vmpstr64cdba32016-03-03 00:38:4052class CC_EXPORT GpuImageDecodeController : public ImageDecodeController {
53 public:
ericrkd2ff2a132016-04-11 22:16:0054 explicit GpuImageDecodeController(ContextProvider* context,
55 ResourceFormat decode_format);
vmpstr64cdba32016-03-03 00:38:4056 ~GpuImageDecodeController() override;
57
58 // ImageDecodeController overrides.
ericrkd2ff2a132016-04-11 22:16:0059
60 // Finds the existing uploaded image for the provided DrawImage. Creates an
61 // upload task to upload the image if an exsiting image does not exist.
vmpstr64cdba32016-03-03 00:38:4062 bool GetTaskForImageAndRef(const DrawImage& image,
63 uint64_t prepare_tiles_id,
prashant.n49b3e64652016-04-19 07:04:4964 scoped_refptr<TileTask>* task) override;
vmpstr64cdba32016-03-03 00:38:4065 void UnrefImage(const DrawImage& image) override;
66 DecodedDrawImage GetDecodedImageForDraw(const DrawImage& draw_image) override;
67 void DrawWithImageFinished(const DrawImage& image,
68 const DecodedDrawImage& decoded_image) override;
69 void ReduceCacheUsage() override;
ericrkd2ff2a132016-04-11 22:16:0070 void SetShouldAggressivelyFreeResources(
71 bool aggressively_free_resources) override;
vmpstr64cdba32016-03-03 00:38:4072
ericrkd2ff2a132016-04-11 22:16:0073 // Called by Decode / Upload tasks.
vmpstr64cdba32016-03-03 00:38:4074 void DecodeImage(const DrawImage& image);
ericrkd2ff2a132016-04-11 22:16:0075 void UploadImage(const DrawImage& image);
76 void DecodeTaskCompleted(const DrawImage& image);
77 void UploadTaskCompleted(const DrawImage& image);
vmpstr64cdba32016-03-03 00:38:4078
ericrkd2ff2a132016-04-11 22:16:0079 // For testing only.
80 void SetCachedItemLimitForTesting(size_t limit) {
81 cached_items_limit_ = limit;
82 }
83 void SetCachedBytesLimitForTesting(size_t limit) {
84 cached_bytes_limit_ = limit;
85 }
86 size_t GetBytesUsedForTesting() const { return bytes_used_; }
vmpstr64cdba32016-03-03 00:38:4087
88 private:
ericrkd2ff2a132016-04-11 22:16:0089 enum class DecodedDataMode { GPU, CPU };
90
91 // Stores the CPU-side decoded bits of an image and supporting fields.
92 struct DecodedImageData {
93 DecodedImageData();
94 ~DecodedImageData();
95
96 // May be null if image not yet decoded.
97 std::unique_ptr<base::DiscardableMemory> data;
98 uint32_t ref_count;
99 bool is_locked;
100
101 // Set to true if the image was corrupt and could not be decoded.
102 bool decode_failure;
103 };
104
105 // Stores the GPU-side image and supporting fields.
106 struct UploadedImageData {
107 UploadedImageData();
108 ~UploadedImageData();
109
110 // May be null if image not yet uploaded / prepared.
111 skia::RefPtr<SkImage> image;
112 // True if the image is counting against our memory limits.
113 bool budgeted;
114 uint32_t ref_count;
115 };
116
117 struct ImageData {
118 ImageData(DecodedDataMode mode, size_t size);
119 ~ImageData();
120
121 const DecodedDataMode mode;
122 const size_t size;
123 bool is_at_raster;
124
125 DecodedImageData decode;
126 UploadedImageData upload;
127 };
128
129 using ImageDataMRUCache =
130 base::MRUCache<uint32_t, std::unique_ptr<ImageData>>;
131
132 // All private functions should only be called while holding |lock_|. Some
133 // functions also require the |context_| lock. These are indicated by
134 // additional comments.
135
136 // Similar to GetTaskForImageAndRef, but gets the dependent decode task
137 // rather than the upload task, if necessary.
prashant.n49b3e64652016-04-19 07:04:49138 scoped_refptr<TileTask> GetImageDecodeTaskAndRef(const DrawImage& image,
139 uint64_t prepare_tiles_id);
ericrkd2ff2a132016-04-11 22:16:00140
141 void RefImageDecode(const DrawImage& draw_image);
142 void UnrefImageDecode(const DrawImage& draw_image);
143 void RefImage(const DrawImage& draw_image);
144 void UnrefImageInternal(const DrawImage& draw_image);
145 void RefCountChanged(ImageData* image_data);
146
147 // Ensures that the cache can hold an element of |required_size|, freeing
148 // unreferenced cache entries if necessary to make room.
149 bool EnsureCapacity(size_t required_size);
150 bool CanFitSize(size_t size) const;
151 bool ExceedsPreferredCount() const;
152
153 void DecodeImageIfNecessary(const DrawImage& draw_image,
154 ImageData* image_data);
155
156 std::unique_ptr<GpuImageDecodeController::ImageData> CreateImageData(
157 const DrawImage& image);
158 SkImageInfo CreateImageInfoForDrawImage(const DrawImage& draw_image) const;
159
160 // The following two functions also require the |context_| lock to be held.
161 void UploadImageIfNecessary(const DrawImage& draw_image,
162 ImageData* image_data);
163 void DeletePendingImages();
164
165 const ResourceFormat format_;
166 ContextProvider* context_;
167 skia::RefPtr<GrContextThreadSafeProxy> context_threadsafe_proxy_;
168
169 // All members below this point must only be accessed while holding |lock_|.
vmpstr64cdba32016-03-03 00:38:40170 base::Lock lock_;
171
prashant.n49b3e64652016-04-19 07:04:49172 std::unordered_map<uint32_t, scoped_refptr<TileTask>>
ericrkd2ff2a132016-04-11 22:16:00173 pending_image_upload_tasks_;
prashant.n49b3e64652016-04-19 07:04:49174 std::unordered_map<uint32_t, scoped_refptr<TileTask>>
ericrkd2ff2a132016-04-11 22:16:00175 pending_image_decode_tasks_;
176
177 ImageDataMRUCache image_data_;
178
179 size_t cached_items_limit_;
180 size_t cached_bytes_limit_;
181 size_t bytes_used_;
182
183 // We can't release GPU backed SkImages without holding the context lock,
184 // so we add them to this list and defer deletion until the next time the lock
185 // is held.
186 std::vector<skia::RefPtr<SkImage>> images_pending_deletion_;
vmpstr64cdba32016-03-03 00:38:40187};
188
189} // namespace cc
190
191#endif // CC_TILES_GPU_IMAGE_DECODE_CONTROLLER_H_