1 // Copyright 2012 The Chromium Authors
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>
14 #include <unordered_set>
18 #include "base/memory/raw_ptr.h"
19 #include "base/synchronization/waitable_event.h"
20 #include "base/task/sequenced_task_runner.h"
21 #include "cc/base/unique_notifier.h"
22 #include "cc/paint/target_color_params.h"
23 #include "cc/raster/raster_buffer_provider.h"
24 #include "cc/raster/raster_query_queue.h"
25 #include "cc/raster/raster_source.h"
26 #include "cc/resources/memory_history.h"
27 #include "cc/resources/resource_pool.h"
28 #include "cc/tiles/checker_image_tracker.h"
29 #include "cc/tiles/decoded_image_tracker.h"
30 #include "cc/tiles/eviction_tile_priority_queue.h"
31 #include "cc/tiles/image_controller.h"
32 #include "cc/tiles/raster_tile_priority_queue.h"
33 #include "cc/tiles/tile.h"
34 #include "cc/tiles/tile_draw_info.h"
35 #include "cc/tiles/tile_manager_settings.h"
36 #include "cc/tiles/tile_task_manager.h"
37 #include "ui/gfx/display_color_spaces.h"
41 namespace trace_event {
42 class ConvertableToTraceFormat;
48 class ImageDecodeCache;
49 class TilesWithResourceIterator;
51 class CC_EXPORT TileManagerClient {
53 // Called when all tiles marked as required for activation are ready to draw.
54 virtual void NotifyReadyToActivate() = 0;
56 // Called when all tiles marked as required for draw are ready to draw.
57 virtual void NotifyReadyToDraw() = 0;
59 // Called when all tile tasks started by the most recent call to PrepareTiles
61 virtual void NotifyAllTileTasksCompleted() = 0;
63 // Called when the visible representation of a tile might have changed. Some
65 // - Tile version initialized.
66 // - Tile resources freed.
67 // - Tile marked for on-demand raster.
68 virtual void NotifyTileStateChanged(const Tile* tile) = 0;
70 // Given an empty raster tile priority queue, this will build a priority queue
71 // that will return tiles in the order in which they should be rasterized.
72 // Note if the queue was previously built, Reset must be called on it.
73 virtual std::unique_ptr<RasterTilePriorityQueue> BuildRasterQueue(
74 TreePriority tree_priority,
75 RasterTilePriorityQueue::Type type) = 0;
77 // Given an empty eviction tile priority queue, this will build a priority
78 // queue that will return tiles in the order in which they should be evicted.
79 // Note if the queue was previously built, Reset must be called on it.
80 virtual std::unique_ptr<EvictionTilePriorityQueue> BuildEvictionQueue(
81 TreePriority tree_priority) = 0;
83 // Returns an iterator over all the tiles that have a resource.
84 virtual std::unique_ptr<TilesWithResourceIterator>
85 CreateTilesWithResourceIterator() = 0;
87 // Informs the client that due to the currently rasterizing (or scheduled to
88 // be rasterized) tiles, we will be in a position that will likely require a
89 // draw. This can be used to preemptively start a frame.
90 virtual void SetIsLikelyToRequireADraw(bool is_likely_to_require_a_draw) = 0;
92 // Requests the color parameters in which the tiles should be rasterized.
93 virtual TargetColorParams GetTargetColorParams(
94 gfx::ContentColorUsage content_color_usage) const = 0;
96 // Requests that a pending tree be scheduled to invalidate content on the
97 // pending on active tree. This is currently used when tiles that are
98 // rasterized with missing images need to be invalidated.
99 virtual void RequestImplSideInvalidationForCheckerImagedTiles() = 0;
101 // Returns the frame index to display for the given image on the given tree.
102 virtual size_t GetFrameIndexForImage(const PaintImage& paint_image,
103 WhichTree tree) const = 0;
105 // Returns the sample count to use if MSAA is enabled for a tile.
106 virtual int GetMSAASampleCountForRaster(
107 const scoped_refptr<DisplayItemList>& display_list) = 0;
109 // True if there is a pending tree.
110 virtual bool HasPendingTree() = 0;
113 virtual ~TileManagerClient() {}
116 struct RasterTaskCompletionStats {
117 RasterTaskCompletionStats();
119 size_t completed_count;
120 size_t canceled_count;
122 std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
123 RasterTaskCompletionStatsAsValue(const RasterTaskCompletionStats& stats);
125 // This class manages tiles, deciding which should get rasterized and which
126 // should no longer have any memory assigned to them. Tile objects are "owned"
127 // by layers; they automatically register with the manager when they are
128 // created, and unregister from the manager when they are deleted.
130 // The TileManager coordinates scheduling of prioritized raster and decode work
131 // across 2 different subsystems, namely the TaskGraphRunner used primarily for
132 // raster work and images which must be decoded before rasterization of a tile
133 // can proceed, and the CheckerImageTracker used for images decoded
134 // asynchronously from raster using the |image_worker_task_runner|. The order in
135 // which work is scheduled across these systems is as follows:
137 // 1) RequiredForActivation/Draw Tiles: These are the highest priority tiles
138 // which block scheduling of any decode work for checkered-images.
140 // 2) Pre-paint Tiles: These are offscreen tiles which fall within the
141 // pre-raster distance. The work for these tiles continues in parallel with the
142 // decode work for checkered images from visible/pre-paint tiles.
144 // 3) Pre-decode Tiles: These are offscreen tiles which are outside the
145 // pre-raster distance but have their images pre-decoded and locked. Finishing
146 // work for these tiles on the TaskGraph blocks starting decode work for
147 // checker-imaged pre-decode tiles.
149 class CC_EXPORT TileManager : CheckerImageTrackerClient {
151 TileManager(TileManagerClient* client,
152 base::SequencedTaskRunner* origin_task_runner,
153 scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner,
154 size_t scheduled_raster_task_limit,
155 const TileManagerSettings& tile_manager_settings);
157 TileManager(const TileManager&) = delete;
158 ~TileManager() override;
160 TileManager& operator=(const TileManager&) = delete;
162 // Assigns tile memory and schedules work to prepare tiles for drawing.
163 // This step occurs after Commit and at most once per BeginFrame. It can be
164 // called on its own, that is, outside of Commit.
166 // - Runs client_->NotifyReadyToActivate() when all tiles required for
167 // activation are prepared, or failed to prepare due to OOM.
168 // - Runs client_->NotifyReadyToDraw() when all tiles required draw are
169 // prepared, or failed to prepare due to OOM.
170 bool PrepareTiles(const GlobalStateThatImpactsTilePriority& state);
172 // Synchronously finish any in progress work, cancel the rest, and clean up as
173 // much resources as possible. Also, prevents any future work until a
174 // SetResources call.
175 void FinishTasksAndCleanUp();
177 // Set the new given resource pool and tile task runner. Note that
178 // FinishTasksAndCleanUp must be called in between consecutive calls to
180 void SetResources(ResourcePool* resource_pool,
181 ImageDecodeCache* image_decode_cache,
182 TaskGraphRunner* task_graph_runner,
183 RasterBufferProvider* raster_buffer_provider,
184 bool use_gpu_rasterization,
185 RasterQueryQueue* pending_raster_queries);
187 // This causes any completed raster work to finalize, so that tiles get up to
188 // date draw information.
189 void CheckForCompletedTasks();
191 // Called when the required-for-activation/required-for-draw state of tiles
193 void DidModifyTilePriorities();
195 std::unique_ptr<Tile> CreateTile(const Tile::CreateInfo& info,
197 int source_frame_number,
200 bool IsReadyToActivate() const;
201 bool IsReadyToDraw() const;
203 const PaintImageIdFlatSet& TakeImagesToInvalidateOnSyncTree();
204 void DidActivateSyncTree();
205 void ClearCheckerImageTracking(bool can_clear_decode_policy_tracking);
206 void SetCheckerImagingForceDisabled(bool force_disable);
208 std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
209 BasicStateAsValue() const;
210 void BasicStateAsValueInto(base::trace_event::TracedValue* dict) const;
211 const MemoryHistory::Entry& memory_stats_from_last_assign() const {
212 return memory_stats_from_last_assign_;
215 // Public methods for testing.
216 void InitializeTilesWithResourcesForTesting(const std::vector<Tile*>& tiles) {
217 for (size_t i = 0; i < tiles.size(); ++i) {
218 TileDrawInfo& draw_info = tiles[i]->draw_info();
219 ResourcePool::InUsePoolResource resource =
220 resource_pool_->AcquireResource(
221 tiles[i]->desired_texture_size(),
222 raster_buffer_provider_->GetResourceFormat(),
223 client_->GetTargetColorParams(gfx::ContentColorUsage::kSRGB)
225 raster_buffer_provider_->AcquireBufferForRaster(
227 /*depends_on_at_raster_decodes=*/false,
228 /*depends_on_hardware_accelerated_jpeg_candidates=*/false,
229 /*depends_on_hardware_accelerated_webp_candidates=*/false);
230 // The raster here never really happened, cuz tests. So just add an
231 // arbitrary sync token.
232 if (resource.gpu_backing()) {
233 resource.gpu_backing()->mailbox = gpu::Mailbox::Generate();
234 resource.gpu_backing()->mailbox_sync_token.Set(
235 gpu::GPU_IO, gpu::CommandBufferId::FromUnsafeValue(1), 1);
237 bool exported = resource_pool_->PrepareForExport(resource);
239 draw_info.SetResource(std::move(resource), false, false);
240 draw_info.set_resource_ready_for_draw();
244 void ReleaseTileResourcesForTesting(const std::vector<Tile*>& tiles) {
245 for (size_t i = 0; i < tiles.size(); ++i) {
246 Tile* tile = tiles[i];
247 FreeResourcesForTile(tile);
251 void SetGlobalStateForTesting(
252 const GlobalStateThatImpactsTilePriority& state) {
253 global_state_ = state;
256 void SetTileTaskManagerForTesting(
257 std::unique_ptr<TileTaskManager> tile_task_manager) {
258 tile_task_manager_ = std::move(tile_task_manager);
261 void SetRasterBufferProviderForTesting(
262 RasterBufferProvider* raster_buffer_provider) {
263 raster_buffer_provider_ = raster_buffer_provider;
266 void SetPendingRasterQueriesForTesting(
267 RasterQueryQueue* pending_raster_queries) {
268 pending_raster_queries_ = pending_raster_queries;
271 std::vector<Tile*> AllTilesForTesting() const {
272 std::vector<Tile*> tiles;
273 for (auto& tile_pair : tiles_)
274 tiles.push_back(tile_pair.second);
278 void SetScheduledRasterTaskLimitForTesting(size_t limit) {
279 scheduled_raster_task_limit_ = limit;
282 void CheckIfMoreTilesNeedToBePreparedForTesting() {
283 CheckIfMoreTilesNeedToBePrepared();
286 void SetMoreTilesNeedToBeRasterizedForTesting() {
287 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false;
290 void ResetSignalsForTesting();
292 bool HasScheduledTileTasksForTesting() const {
293 return has_scheduled_tile_tasks_;
296 void OnRasterTaskCompleted(Tile::Id tile_id,
297 ResourcePool::InUsePoolResource resource,
300 // CheckerImageTrackerClient implementation.
301 void NeedsInvalidationForCheckerImagedTiles() override;
303 // This method can only be used for debugging information, since it performs a
304 // non trivial amount of work.
305 std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
306 ActivationStateAsValue();
308 void ActivationStateAsValueInto(base::trace_event::TracedValue* state);
309 int num_of_tiles_with_checker_images() const {
310 return num_of_tiles_with_checker_images_;
313 CheckerImageTracker& checker_image_tracker() {
314 return checker_image_tracker_;
316 DecodedImageTracker& decoded_image_tracker() {
317 return decoded_image_tracker_;
320 const std::vector<DrawImage>& decode_tasks_for_testing(Tile::Id id) {
321 return scheduled_draw_images_[id];
324 void set_active_url(const GURL& url) { active_url_ = url; }
328 // Must be called by tile during destruction.
329 void Release(Tile* tile);
330 Tile::Id GetUniqueTileId() { return ++next_tile_id_; }
336 MemoryUsage(size_t memory_bytes, size_t resource_count);
338 static MemoryUsage FromConfig(const gfx::Size& size,
339 viz::ResourceFormat format);
340 static MemoryUsage FromTile(const Tile* tile);
342 MemoryUsage& operator+=(const MemoryUsage& other);
343 MemoryUsage& operator-=(const MemoryUsage& other);
344 MemoryUsage operator-(const MemoryUsage& other);
346 bool Exceeds(const MemoryUsage& limit) const;
347 int64_t memory_bytes() const { return memory_bytes_; }
350 int64_t memory_bytes_;
355 bool activate_tile_tasks_completed = false;
356 bool draw_tile_tasks_completed = false;
357 bool all_tile_tasks_completed = false;
359 bool activate_gpu_work_completed = false;
360 bool draw_gpu_work_completed = false;
362 bool did_notify_ready_to_activate = false;
363 bool did_notify_ready_to_draw = false;
364 bool did_notify_all_tile_tasks_completed = false;
367 struct PrioritizedWorkToSchedule {
368 PrioritizedWorkToSchedule();
369 PrioritizedWorkToSchedule(PrioritizedWorkToSchedule&& other);
370 ~PrioritizedWorkToSchedule();
372 std::vector<PrioritizedTile> tiles_to_raster;
373 std::vector<PrioritizedTile> tiles_to_process_for_images;
374 // A vector of additional images to be decoded for prepaint, but that
375 // are not necessarily associated with any tile.
376 std::vector<DrawImage> extra_prepaint_images;
377 CheckerImageTracker::ImageDecodeQueue checker_image_decode_queue;
380 // Frees the resources of all occluded tiles.
381 void FreeResourcesForOccludedTiles();
383 void FreeResourcesForTile(Tile* tile);
384 void FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(Tile* tile);
385 scoped_refptr<TileTask> CreateRasterTask(
386 const PrioritizedTile& prioritized_tile,
387 const TargetColorParams& target_color_params,
388 PrioritizedWorkToSchedule* work_to_schedule);
390 std::unique_ptr<EvictionTilePriorityQueue>
391 FreeTileResourcesUntilUsageIsWithinLimit(
392 std::unique_ptr<EvictionTilePriorityQueue> eviction_priority_queue,
393 const MemoryUsage& limit,
395 std::unique_ptr<EvictionTilePriorityQueue>
396 FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit(
397 std::unique_ptr<EvictionTilePriorityQueue> eviction_priority_queue,
398 const MemoryUsage& limit,
399 const TilePriority& oother_priority,
401 bool TilePriorityViolatesMemoryPolicy(const TilePriority& priority);
402 bool AreRequiredTilesReadyToDraw(RasterTilePriorityQueue::Type type) const;
403 void CheckIfMoreTilesNeedToBePrepared();
404 void MarkTilesOutOfMemory(
405 std::unique_ptr<RasterTilePriorityQueue> queue) const;
407 viz::ResourceFormat DetermineResourceFormat(const Tile* tile) const;
409 void DidFinishRunningTileTasksRequiredForActivation();
410 void DidFinishRunningTileTasksRequiredForDraw();
411 void DidFinishRunningAllTileTasks(bool has_pending_queries);
413 scoped_refptr<TileTask> CreateTaskSetFinishedTask(
414 void (TileManager::*callback)());
415 PrioritizedWorkToSchedule AssignGpuMemoryToTiles();
416 void ScheduleTasks(PrioritizedWorkToSchedule work_to_schedule);
418 void PartitionImagesForCheckering(
419 const PrioritizedTile& prioritized_tile,
420 const TargetColorParams& target_color_params,
421 std::vector<DrawImage>* sync_decoded_images,
422 std::vector<PaintImage>* checkered_images,
423 const gfx::Rect* invalidated_rect,
424 base::flat_map<PaintImage::Id, size_t>* image_to_frame_index = nullptr);
425 void AddCheckeredImagesToDecodeQueue(
426 const PrioritizedTile& prioritized_tile,
427 const TargetColorParams& target_color_params,
428 CheckerImageTracker::DecodeType decode_type,
429 CheckerImageTracker::ImageDecodeQueue* image_decode_queue);
431 std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
432 ScheduledTasksStateAsValue() const;
434 bool UsePartialRaster(int msaa_sample_count) const;
436 void FlushAndIssueSignals();
437 void CheckPendingGpuWorkAndIssueSignals();
439 void ScheduleCheckRasterFinishedQueries();
440 void CheckRasterFinishedQueries();
442 bool ShouldRasterOccludedTiles() const;
444 raw_ptr<TileManagerClient, DanglingUntriaged> client_;
445 raw_ptr<base::SequencedTaskRunner> task_runner_;
446 raw_ptr<ResourcePool, DanglingUntriaged> resource_pool_;
447 std::unique_ptr<TileTaskManager> tile_task_manager_;
448 raw_ptr<RasterBufferProvider, DanglingUntriaged> raster_buffer_provider_;
449 GlobalStateThatImpactsTilePriority global_state_;
450 size_t scheduled_raster_task_limit_;
452 const TileManagerSettings tile_manager_settings_;
453 bool use_gpu_rasterization_;
454 raw_ptr<RasterQueryQueue> pending_raster_queries_ = nullptr;
456 std::unordered_map<Tile::Id, Tile*> tiles_;
458 bool all_tiles_that_need_to_be_rasterized_are_scheduled_;
459 MemoryHistory::Entry memory_stats_from_last_assign_;
461 bool did_check_for_completed_tasks_since_last_schedule_tasks_;
462 bool did_oom_on_last_assign_;
464 ImageController image_controller_;
465 DecodedImageTracker decoded_image_tracker_;
466 CheckerImageTracker checker_image_tracker_;
468 RasterTaskCompletionStats raster_task_completion_stats_;
472 UniqueNotifier more_tiles_need_prepare_check_notifier_;
476 UniqueNotifier signals_check_notifier_;
478 bool has_scheduled_tile_tasks_;
480 uint64_t prepare_tiles_count_;
481 uint64_t next_tile_id_;
483 std::unordered_set<Tile*> pending_gpu_work_tiles_;
484 uint64_t pending_required_for_activation_callback_id_ = 0;
485 uint64_t pending_required_for_draw_callback_id_ = 0;
486 // If true, we should re-compute tile requirements in
487 // CheckPendingGpuWorkAndIssueSignals.
488 bool pending_tile_requirements_dirty_ = false;
490 std::unordered_map<Tile::Id, std::vector<DrawImage>> scheduled_draw_images_;
491 std::vector<scoped_refptr<TileTask>> locked_image_tasks_;
493 // Number of tiles with a checker-imaged resource or active raster tasks which
494 // will create a checker-imaged resource.
495 int num_of_tiles_with_checker_images_ = 0;
499 // The callback scheduled to poll whether the GPU side work for pending tiles
501 bool has_pending_queries_ = false;
502 base::CancelableOnceClosure check_pending_tile_queries_callback_;
504 // Signaled inside FinishTasksAndCleanUp() to avoid deadlock.
505 // FinishTasksAndCleanUp() may block waiting for worker thread tasks to finish
506 // and worker thread tasks may block on this thread causing deadlock. Worker
507 // thread tasks can use WaitableEvent::WaitMany() to wait on two events, one
508 // for the original task completion plus this event to cancel waiting on
509 // completion when FinishTasksAndCleanUp() runs.
510 base::WaitableEvent shutdown_event_;
512 // We need two WeakPtrFactory objects as the invalidation pattern of each is
513 // different. The |task_set_finished_weak_ptr_factory_| is invalidated any
514 // time new tasks are scheduled, preventing a race when the callback has
515 // been scheduled but not yet executed.
516 base::WeakPtrFactory<TileManager> task_set_finished_weak_ptr_factory_{this};
517 // The |ready_to_draw_callback_weak_ptr_factory_| is never invalidated.
518 base::WeakPtrFactory<TileManager> ready_to_draw_callback_weak_ptr_factory_{
524 #endif // CC_TILES_TILE_MANAGER_H_