1 // Copyright 2012 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.
5 #ifndef CC_TILES_TILE_MANAGER_H_
6 #define CC_TILES_TILE_MANAGER_H_
13 #include <unordered_map>
17 #include "base/macros.h"
18 #include "base/sequenced_task_runner.h"
19 #include "base/values.h"
20 #include "cc/base/unique_notifier.h"
21 #include "cc/paint/color_space_transfer_cache_entry.h"
22 #include "cc/raster/raster_buffer_provider.h"
23 #include "cc/raster/raster_source.h"
24 #include "cc/resources/memory_history.h"
25 #include "cc/resources/resource_pool.h"
26 #include "cc/tiles/checker_image_tracker.h"
27 #include "cc/tiles/decoded_image_tracker.h"
28 #include "cc/tiles/eviction_tile_priority_queue.h"
29 #include "cc/tiles/image_controller.h"
30 #include "cc/tiles/raster_tile_priority_queue.h"
31 #include "cc/tiles/tile.h"
32 #include "cc/tiles/tile_draw_info.h"
33 #include "cc/tiles/tile_manager_settings.h"
34 #include "cc/tiles/tile_task_manager.h"
37 namespace trace_event {
38 class ConvertableToTraceFormat;
44 class ImageDecodeCache;
46 class CC_EXPORT TileManagerClient {
48 // Called when all tiles marked as required for activation are ready to draw.
49 virtual void NotifyReadyToActivate() = 0;
51 // Called when all tiles marked as required for draw are ready to draw.
52 virtual void NotifyReadyToDraw() = 0;
54 // Called when all tile tasks started by the most recent call to PrepareTiles
56 virtual void NotifyAllTileTasksCompleted() = 0;
58 // Called when the visible representation of a tile might have changed. Some
60 // - Tile version initialized.
61 // - Tile resources freed.
62 // - Tile marked for on-demand raster.
63 virtual void NotifyTileStateChanged(const Tile* tile) = 0;
65 // Given an empty raster tile priority queue, this will build a priority queue
66 // that will return tiles in order in which they should be rasterized.
67 // Note if the queue was previous built, Reset must be called on it.
68 virtual std::unique_ptr<RasterTilePriorityQueue> BuildRasterQueue(
69 TreePriority tree_priority,
70 RasterTilePriorityQueue::Type type) = 0;
72 // Given an empty eviction tile priority queue, this will build a priority
73 // queue that will return tiles in order in which they should be evicted.
74 // Note if the queue was previous built, Reset must be called on it.
75 virtual std::unique_ptr<EvictionTilePriorityQueue> BuildEvictionQueue(
76 TreePriority tree_priority) = 0;
78 // Informs the client that due to the currently rasterizing (or scheduled to
79 // be rasterized) tiles, we will be in a position that will likely require a
80 // draw. This can be used to preemptively start a frame.
81 virtual void SetIsLikelyToRequireADraw(bool is_likely_to_require_a_draw) = 0;
83 // Requests the color space into which tiles should be rasterized.
84 virtual RasterColorSpace GetRasterColorSpace() const = 0;
86 // Requests that a pending tree be scheduled to invalidate content on the
87 // pending on active tree. This is currently used when tiles that are
88 // rasterized with missing images need to be invalidated.
89 virtual void RequestImplSideInvalidationForCheckerImagedTiles() = 0;
91 virtual size_t GetFrameIndexForImage(const PaintImage& paint_image,
92 WhichTree tree) const = 0;
95 virtual ~TileManagerClient() {}
98 struct RasterTaskCompletionStats {
99 RasterTaskCompletionStats();
101 size_t completed_count;
102 size_t canceled_count;
104 std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
105 RasterTaskCompletionStatsAsValue(const RasterTaskCompletionStats& stats);
107 // This class manages tiles, deciding which should get rasterized and which
108 // should no longer have any memory assigned to them. Tile objects are "owned"
109 // by layers; they automatically register with the manager when they are
110 // created, and unregister from the manager when they are deleted.
112 // The TileManager coordinates scheduling of prioritized raster and decode work
113 // across 2 different subsystems, namely the TaskGraphRunner used primarily for
114 // raster work and images which must be decoded before rasterization of a tile
115 // can proceed, and the CheckerImageTracker used for images decoded
116 // asynchronously from raster using the |image_worker_task_runner|. The order in
117 // which work is scheduled across these systems is as follows:
119 // 1) RequiredForActivation/Draw Tiles: These are the highest priority tiles
120 // which block scheduling of any decode work for checkered-images.
122 // 2) Pre-paint Tiles: These are offscreen tiles which fall within the
123 // pre-raster distance. The work for these tiles continues in parallel with the
124 // decode work for checkered images from visible/pre-paint tiles.
126 // 3) Pre-decode Tiles: These are offscreen tiles which are outside the
127 // pre-raster distance but have their images pre-decoded and locked. Finishing
128 // work for these tiles on the TaskGraph blocks starting decode work for
129 // checker-imaged pre-decode tiles.
131 class CC_EXPORT TileManager : CheckerImageTrackerClient {
133 TileManager(TileManagerClient* client,
134 base::SequencedTaskRunner* origin_task_runner,
135 scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner,
136 size_t scheduled_raster_task_limit,
137 const TileManagerSettings& tile_manager_settings);
138 ~TileManager() override;
140 // Assigns tile memory and schedules work to prepare tiles for drawing.
141 // - Runs client_->NotifyReadyToActivate() when all tiles required for
142 // activation are prepared, or failed to prepare due to OOM.
143 // - Runs client_->NotifyReadyToDraw() when all tiles required draw are
144 // prepared, or failed to prepare due to OOM.
145 bool PrepareTiles(const GlobalStateThatImpactsTilePriority& state);
147 // Synchronously finish any in progress work, cancel the rest, and clean up as
148 // much resources as possible. Also, prevents any future work until a
149 // SetResources call.
150 void FinishTasksAndCleanUp();
152 // Set the new given resource pool and tile task runner. Note that
153 // FinishTasksAndCleanUp must be called in between consecutive calls to
155 void SetResources(ResourcePool* resource_pool,
156 ImageDecodeCache* image_decode_cache,
157 TaskGraphRunner* task_graph_runner,
158 RasterBufferProvider* raster_buffer_provider,
159 bool use_gpu_rasterization);
161 // This causes any completed raster work to finalize, so that tiles get up to
162 // date draw information.
163 void CheckForCompletedTasks();
165 // Called when the required-for-activation/required-for-draw state of tiles
167 void DidModifyTilePriorities();
169 std::unique_ptr<Tile> CreateTile(const Tile::CreateInfo& info,
171 int source_frame_number,
173 bool can_use_lcd_text);
175 bool IsReadyToActivate() const;
176 bool IsReadyToDraw() const;
178 const PaintImageIdFlatSet& TakeImagesToInvalidateOnSyncTree();
179 void DidActivateSyncTree();
180 void ClearCheckerImageTracking(bool can_clear_decode_policy_tracking);
181 void SetCheckerImagingForceDisabled(bool force_disable);
183 std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
184 BasicStateAsValue() const;
185 void BasicStateAsValueInto(base::trace_event::TracedValue* dict) const;
186 const MemoryHistory::Entry& memory_stats_from_last_assign() const {
187 return memory_stats_from_last_assign_;
190 // Public methods for testing.
191 void InitializeTilesWithResourcesForTesting(const std::vector<Tile*>& tiles) {
192 for (size_t i = 0; i < tiles.size(); ++i) {
193 TileDrawInfo& draw_info = tiles[i]->draw_info();
194 ResourcePool::InUsePoolResource resource =
195 resource_pool_->AcquireResource(
196 tiles[i]->desired_texture_size(),
197 raster_buffer_provider_->GetResourceFormat(),
198 client_->GetRasterColorSpace().color_space);
199 raster_buffer_provider_->AcquireBufferForRaster(resource, 0, 0);
200 // The raster here never really happened, cuz tests. So just add an
201 // arbitrary sync token.
202 if (resource.gpu_backing()) {
203 resource.gpu_backing()->mailbox_sync_token.Set(
204 gpu::GPU_IO, gpu::CommandBufferId::FromUnsafeValue(1), 1);
206 resource_pool_->PrepareForExport(resource);
207 draw_info.SetResource(std::move(resource), false, false, false);
208 draw_info.set_resource_ready_for_draw();
212 void ReleaseTileResourcesForTesting(const std::vector<Tile*>& tiles) {
213 for (size_t i = 0; i < tiles.size(); ++i) {
214 Tile* tile = tiles[i];
215 FreeResourcesForTile(tile);
219 void SetGlobalStateForTesting(
220 const GlobalStateThatImpactsTilePriority& state) {
221 global_state_ = state;
224 void SetTileTaskManagerForTesting(
225 std::unique_ptr<TileTaskManager> tile_task_manager) {
226 tile_task_manager_ = std::move(tile_task_manager);
229 void SetRasterBufferProviderForTesting(
230 RasterBufferProvider* raster_buffer_provider) {
231 raster_buffer_provider_ = raster_buffer_provider;
234 std::vector<Tile*> AllTilesForTesting() const {
235 std::vector<Tile*> tiles;
236 for (auto& tile_pair : tiles_)
237 tiles.push_back(tile_pair.second);
241 void SetScheduledRasterTaskLimitForTesting(size_t limit) {
242 scheduled_raster_task_limit_ = limit;
245 void CheckIfMoreTilesNeedToBePreparedForTesting() {
246 CheckIfMoreTilesNeedToBePrepared();
249 void SetMoreTilesNeedToBeRasterizedForTesting() {
250 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false;
253 void ResetSignalsForTesting();
255 bool HasScheduledTileTasksForTesting() const {
256 return has_scheduled_tile_tasks_;
259 void OnRasterTaskCompleted(Tile::Id tile_id,
260 ResourcePool::InUsePoolResource resource,
263 // CheckerImageTrackerClient implementation.
264 void NeedsInvalidationForCheckerImagedTiles() override;
266 // This method can only be used for debugging information, since it performs a
267 // non trivial amount of work.
268 std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
269 ActivationStateAsValue();
271 void ActivationStateAsValueInto(base::trace_event::TracedValue* state);
272 int num_of_tiles_with_checker_images() const {
273 return num_of_tiles_with_checker_images_;
276 CheckerImageTracker& checker_image_tracker() {
277 return checker_image_tracker_;
279 DecodedImageTracker& decoded_image_tracker() {
280 return decoded_image_tracker_;
283 const std::vector<DrawImage>& decode_tasks_for_testing(Tile::Id id) {
284 return scheduled_draw_images_[id];
289 // Must be called by tile during destruction.
290 void Release(Tile* tile);
291 Tile::Id GetUniqueTileId() { return ++next_tile_id_; }
297 MemoryUsage(size_t memory_bytes, size_t resource_count);
299 static MemoryUsage FromConfig(const gfx::Size& size,
300 viz::ResourceFormat format);
301 static MemoryUsage FromTile(const Tile* tile);
303 MemoryUsage& operator+=(const MemoryUsage& other);
304 MemoryUsage& operator-=(const MemoryUsage& other);
305 MemoryUsage operator-(const MemoryUsage& other);
307 bool Exceeds(const MemoryUsage& limit) const;
308 int64_t memory_bytes() const { return memory_bytes_; }
311 int64_t memory_bytes_;
316 bool activate_tile_tasks_completed = false;
317 bool draw_tile_tasks_completed = false;
318 bool all_tile_tasks_completed = false;
320 bool activate_gpu_work_completed = false;
321 bool draw_gpu_work_completed = false;
323 bool did_notify_ready_to_activate = false;
324 bool did_notify_ready_to_draw = false;
325 bool did_notify_all_tile_tasks_completed = false;
328 struct PrioritizedWorkToSchedule {
329 PrioritizedWorkToSchedule();
330 PrioritizedWorkToSchedule(PrioritizedWorkToSchedule&& other);
331 ~PrioritizedWorkToSchedule();
333 std::vector<PrioritizedTile> tiles_to_raster;
334 std::vector<PrioritizedTile> tiles_to_process_for_images;
335 // A vector of additional images to be decoded for prepaint, but that
336 // are not necessarily associated with any tile.
337 std::vector<DrawImage> extra_prepaint_images;
338 CheckerImageTracker::ImageDecodeQueue checker_image_decode_queue;
341 void FreeResourcesForTile(Tile* tile);
342 void FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(Tile* tile);
343 scoped_refptr<TileTask> CreateRasterTask(
344 const PrioritizedTile& prioritized_tile,
345 const RasterColorSpace& raster_color_space,
346 PrioritizedWorkToSchedule* work_to_schedule);
348 std::unique_ptr<EvictionTilePriorityQueue>
349 FreeTileResourcesUntilUsageIsWithinLimit(
350 std::unique_ptr<EvictionTilePriorityQueue> eviction_priority_queue,
351 const MemoryUsage& limit,
353 std::unique_ptr<EvictionTilePriorityQueue>
354 FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit(
355 std::unique_ptr<EvictionTilePriorityQueue> eviction_priority_queue,
356 const MemoryUsage& limit,
357 const TilePriority& oother_priority,
359 bool TilePriorityViolatesMemoryPolicy(const TilePriority& priority);
360 bool AreRequiredTilesReadyToDraw(RasterTilePriorityQueue::Type type) const;
361 void CheckIfMoreTilesNeedToBePrepared();
362 void MarkTilesOutOfMemory(
363 std::unique_ptr<RasterTilePriorityQueue> queue) const;
365 viz::ResourceFormat DetermineResourceFormat(const Tile* tile) const;
367 void DidFinishRunningTileTasksRequiredForActivation();
368 void DidFinishRunningTileTasksRequiredForDraw();
369 void DidFinishRunningAllTileTasks();
371 scoped_refptr<TileTask> CreateTaskSetFinishedTask(
372 void (TileManager::*callback)());
373 PrioritizedWorkToSchedule AssignGpuMemoryToTiles();
374 void ScheduleTasks(PrioritizedWorkToSchedule work_to_schedule);
376 void PartitionImagesForCheckering(
377 const PrioritizedTile& prioritized_tile,
378 const gfx::ColorSpace& raster_color_space,
379 std::vector<DrawImage>* sync_decoded_images,
380 std::vector<PaintImage>* checkered_images,
381 const gfx::Rect* invalidated_rect,
382 base::flat_map<PaintImage::Id, size_t>* image_to_frame_index = nullptr);
383 void AddCheckeredImagesToDecodeQueue(
384 const PrioritizedTile& prioritized_tile,
385 const gfx::ColorSpace& raster_color_space,
386 CheckerImageTracker::DecodeType decode_type,
387 CheckerImageTracker::ImageDecodeQueue* image_decode_queue);
389 std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
390 ScheduledTasksStateAsValue() const;
392 bool UsePartialRaster() const;
394 void FlushAndIssueSignals();
395 void CheckPendingGpuWorkAndIssueSignals();
398 TileManagerClient* client_;
399 base::SequencedTaskRunner* task_runner_;
400 ResourcePool* resource_pool_;
401 std::unique_ptr<TileTaskManager> tile_task_manager_;
402 RasterBufferProvider* raster_buffer_provider_;
403 GlobalStateThatImpactsTilePriority global_state_;
404 size_t scheduled_raster_task_limit_;
406 const TileManagerSettings tile_manager_settings_;
407 bool use_gpu_rasterization_;
409 std::unordered_map<Tile::Id, Tile*> tiles_;
411 bool all_tiles_that_need_to_be_rasterized_are_scheduled_;
412 MemoryHistory::Entry memory_stats_from_last_assign_;
414 bool did_check_for_completed_tasks_since_last_schedule_tasks_;
415 bool did_oom_on_last_assign_;
417 ImageController image_controller_;
418 DecodedImageTracker decoded_image_tracker_;
419 CheckerImageTracker checker_image_tracker_;
421 RasterTaskCompletionStats raster_task_completion_stats_;
425 UniqueNotifier more_tiles_need_prepare_check_notifier_;
429 UniqueNotifier signals_check_notifier_;
431 bool has_scheduled_tile_tasks_;
433 uint64_t prepare_tiles_count_;
434 uint64_t next_tile_id_;
436 std::unordered_set<Tile*> pending_gpu_work_tiles_;
437 uint64_t pending_required_for_activation_callback_id_ = 0;
438 uint64_t pending_required_for_draw_callback_id_ = 0;
439 // If true, we should re-compute tile requirements in
440 // CheckPendingGpuWorkAndIssueSignals.
441 bool pending_tile_requirements_dirty_ = false;
443 std::unordered_map<Tile::Id, std::vector<DrawImage>> scheduled_draw_images_;
444 std::vector<scoped_refptr<TileTask>> locked_image_tasks_;
446 // Number of tiles with a checker-imaged resource or active raster tasks which
447 // will create a checker-imaged resource.
448 int num_of_tiles_with_checker_images_ = 0;
450 // We need two WeakPtrFactory objects as the invalidation pattern of each is
451 // different. The |task_set_finished_weak_ptr_factory_| is invalidated any
452 // time new tasks are scheduled, preventing a race when the callback has
453 // been scheduled but not yet executed.
454 base::WeakPtrFactory<TileManager> task_set_finished_weak_ptr_factory_;
455 // The |ready_to_draw_callback_weak_ptr_factory_| is never invalidated.
456 base::WeakPtrFactory<TileManager> ready_to_draw_callback_weak_ptr_factory_;
458 DISALLOW_COPY_AND_ASSIGN(TileManager);
463 #endif // CC_TILES_TILE_MANAGER_H_