[M108 Migration][VD] Avoid pending frame counter becoming negative
[platform/framework/web/chromium-efl.git] / cc / tiles / tile_manager.h
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.
4
5 #ifndef CC_TILES_TILE_MANAGER_H_
6 #define CC_TILES_TILE_MANAGER_H_
7
8 #include <stddef.h>
9 #include <stdint.h>
10
11 #include <memory>
12 #include <set>
13 #include <unordered_map>
14 #include <unordered_set>
15 #include <utility>
16 #include <vector>
17
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"
38 #include "url/gurl.h"
39
40 namespace base {
41 namespace trace_event {
42 class ConvertableToTraceFormat;
43 class TracedValue;
44 }
45 }
46
47 namespace cc {
48 class ImageDecodeCache;
49 class TilesWithResourceIterator;
50
51 class CC_EXPORT TileManagerClient {
52  public:
53   // Called when all tiles marked as required for activation are ready to draw.
54   virtual void NotifyReadyToActivate() = 0;
55
56   // Called when all tiles marked as required for draw are ready to draw.
57   virtual void NotifyReadyToDraw() = 0;
58
59   // Called when all tile tasks started by the most recent call to PrepareTiles
60   // are completed.
61   virtual void NotifyAllTileTasksCompleted() = 0;
62
63   // Called when the visible representation of a tile might have changed. Some
64   // examples are:
65   // - Tile version initialized.
66   // - Tile resources freed.
67   // - Tile marked for on-demand raster.
68   virtual void NotifyTileStateChanged(const Tile* tile) = 0;
69
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;
76
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;
82
83   // Returns an iterator over all the tiles that have a resource.
84   virtual std::unique_ptr<TilesWithResourceIterator>
85   CreateTilesWithResourceIterator() = 0;
86
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;
91
92   // Requests the color parameters in which the tiles should be rasterized.
93   virtual TargetColorParams GetTargetColorParams(
94       gfx::ContentColorUsage content_color_usage) const = 0;
95
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;
100
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;
104
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;
108
109   // True if there is a pending tree.
110   virtual bool HasPendingTree() = 0;
111
112  protected:
113   virtual ~TileManagerClient() {}
114 };
115
116 struct RasterTaskCompletionStats {
117   RasterTaskCompletionStats();
118
119   size_t completed_count;
120   size_t canceled_count;
121 };
122 std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
123 RasterTaskCompletionStatsAsValue(const RasterTaskCompletionStats& stats);
124
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.
129 //
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:
136 //
137 // 1) RequiredForActivation/Draw Tiles: These are the highest priority tiles
138 // which block scheduling of any decode work for checkered-images.
139 //
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.
143 //
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.
148
149 class CC_EXPORT TileManager : CheckerImageTrackerClient {
150  public:
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);
156
157   TileManager(const TileManager&) = delete;
158   ~TileManager() override;
159
160   TileManager& operator=(const TileManager&) = delete;
161
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.
165   //
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);
171
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();
176
177   // Set the new given resource pool and tile task runner. Note that
178   // FinishTasksAndCleanUp must be called in between consecutive calls to
179   // SetResources.
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);
186
187   // This causes any completed raster work to finalize, so that tiles get up to
188   // date draw information.
189   void CheckForCompletedTasks();
190
191   // Called when the required-for-activation/required-for-draw state of tiles
192   // may have changed.
193   void DidModifyTilePriorities();
194
195   std::unique_ptr<Tile> CreateTile(const Tile::CreateInfo& info,
196                                    int layer_id,
197                                    int source_frame_number,
198                                    int flags);
199
200   bool IsReadyToActivate() const;
201   bool IsReadyToDraw() const;
202
203   const PaintImageIdFlatSet& TakeImagesToInvalidateOnSyncTree();
204   void DidActivateSyncTree();
205   void ClearCheckerImageTracking(bool can_clear_decode_policy_tracking);
206   void SetCheckerImagingForceDisabled(bool force_disable);
207
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_;
213   }
214
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)
224                   .color_space);
225       raster_buffer_provider_->AcquireBufferForRaster(
226           resource, 0, 0,
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);
236       }
237       bool exported = resource_pool_->PrepareForExport(resource);
238       DCHECK(exported);
239       draw_info.SetResource(std::move(resource), false, false);
240       draw_info.set_resource_ready_for_draw();
241     }
242   }
243
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);
248     }
249   }
250
251   void SetGlobalStateForTesting(
252       const GlobalStateThatImpactsTilePriority& state) {
253     global_state_ = state;
254   }
255
256   void SetTileTaskManagerForTesting(
257       std::unique_ptr<TileTaskManager> tile_task_manager) {
258     tile_task_manager_ = std::move(tile_task_manager);
259   }
260
261   void SetRasterBufferProviderForTesting(
262       RasterBufferProvider* raster_buffer_provider) {
263     raster_buffer_provider_ = raster_buffer_provider;
264   }
265
266   void SetPendingRasterQueriesForTesting(
267       RasterQueryQueue* pending_raster_queries) {
268     pending_raster_queries_ = pending_raster_queries;
269   }
270
271   std::vector<Tile*> AllTilesForTesting() const {
272     std::vector<Tile*> tiles;
273     for (auto& tile_pair : tiles_)
274       tiles.push_back(tile_pair.second);
275     return tiles;
276   }
277
278   void SetScheduledRasterTaskLimitForTesting(size_t limit) {
279     scheduled_raster_task_limit_ = limit;
280   }
281
282   void CheckIfMoreTilesNeedToBePreparedForTesting() {
283     CheckIfMoreTilesNeedToBePrepared();
284   }
285
286   void SetMoreTilesNeedToBeRasterizedForTesting() {
287     all_tiles_that_need_to_be_rasterized_are_scheduled_ = false;
288   }
289
290   void ResetSignalsForTesting();
291
292   bool HasScheduledTileTasksForTesting() const {
293     return has_scheduled_tile_tasks_;
294   }
295
296   void OnRasterTaskCompleted(Tile::Id tile_id,
297                              ResourcePool::InUsePoolResource resource,
298                              bool was_canceled);
299
300   // CheckerImageTrackerClient implementation.
301   void NeedsInvalidationForCheckerImagedTiles() override;
302
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();
307
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_;
311   }
312
313   CheckerImageTracker& checker_image_tracker() {
314     return checker_image_tracker_;
315   }
316   DecodedImageTracker& decoded_image_tracker() {
317     return decoded_image_tracker_;
318   }
319
320   const std::vector<DrawImage>& decode_tasks_for_testing(Tile::Id id) {
321     return scheduled_draw_images_[id];
322   }
323
324   void set_active_url(const GURL& url) { active_url_ = url; }
325
326  protected:
327   friend class Tile;
328   // Must be called by tile during destruction.
329   void Release(Tile* tile);
330   Tile::Id GetUniqueTileId() { return ++next_tile_id_; }
331
332  private:
333   class MemoryUsage {
334    public:
335     MemoryUsage();
336     MemoryUsage(size_t memory_bytes, size_t resource_count);
337
338     static MemoryUsage FromConfig(const gfx::Size& size,
339                                   viz::ResourceFormat format);
340     static MemoryUsage FromTile(const Tile* tile);
341
342     MemoryUsage& operator+=(const MemoryUsage& other);
343     MemoryUsage& operator-=(const MemoryUsage& other);
344     MemoryUsage operator-(const MemoryUsage& other);
345
346     bool Exceeds(const MemoryUsage& limit) const;
347     int64_t memory_bytes() const { return memory_bytes_; }
348
349    private:
350     int64_t memory_bytes_;
351     int resource_count_;
352   };
353
354   struct Signals {
355     bool activate_tile_tasks_completed = false;
356     bool draw_tile_tasks_completed = false;
357     bool all_tile_tasks_completed = false;
358
359     bool activate_gpu_work_completed = false;
360     bool draw_gpu_work_completed = false;
361
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;
365   };
366
367   struct PrioritizedWorkToSchedule {
368     PrioritizedWorkToSchedule();
369     PrioritizedWorkToSchedule(PrioritizedWorkToSchedule&& other);
370     ~PrioritizedWorkToSchedule();
371
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;
378   };
379
380   // Frees the resources of all occluded tiles.
381   void FreeResourcesForOccludedTiles();
382
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);
389
390   std::unique_ptr<EvictionTilePriorityQueue>
391   FreeTileResourcesUntilUsageIsWithinLimit(
392       std::unique_ptr<EvictionTilePriorityQueue> eviction_priority_queue,
393       const MemoryUsage& limit,
394       MemoryUsage* usage);
395   std::unique_ptr<EvictionTilePriorityQueue>
396   FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit(
397       std::unique_ptr<EvictionTilePriorityQueue> eviction_priority_queue,
398       const MemoryUsage& limit,
399       const TilePriority& oother_priority,
400       MemoryUsage* usage);
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;
406
407   viz::ResourceFormat DetermineResourceFormat(const Tile* tile) const;
408
409   void DidFinishRunningTileTasksRequiredForActivation();
410   void DidFinishRunningTileTasksRequiredForDraw();
411   void DidFinishRunningAllTileTasks(bool has_pending_queries);
412
413   scoped_refptr<TileTask> CreateTaskSetFinishedTask(
414       void (TileManager::*callback)());
415   PrioritizedWorkToSchedule AssignGpuMemoryToTiles();
416   void ScheduleTasks(PrioritizedWorkToSchedule work_to_schedule);
417
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);
430
431   std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
432   ScheduledTasksStateAsValue() const;
433
434   bool UsePartialRaster(int msaa_sample_count) const;
435
436   void FlushAndIssueSignals();
437   void CheckPendingGpuWorkAndIssueSignals();
438   void IssueSignals();
439   void ScheduleCheckRasterFinishedQueries();
440   void CheckRasterFinishedQueries();
441
442   bool ShouldRasterOccludedTiles() const;
443
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_;
451
452   const TileManagerSettings tile_manager_settings_;
453   bool use_gpu_rasterization_;
454   raw_ptr<RasterQueryQueue> pending_raster_queries_ = nullptr;
455
456   std::unordered_map<Tile::Id, Tile*> tiles_;
457
458   bool all_tiles_that_need_to_be_rasterized_are_scheduled_;
459   MemoryHistory::Entry memory_stats_from_last_assign_;
460
461   bool did_check_for_completed_tasks_since_last_schedule_tasks_;
462   bool did_oom_on_last_assign_;
463
464   ImageController image_controller_;
465   DecodedImageTracker decoded_image_tracker_;
466   CheckerImageTracker checker_image_tracker_;
467
468   RasterTaskCompletionStats raster_task_completion_stats_;
469
470   TaskGraph graph_;
471
472   UniqueNotifier more_tiles_need_prepare_check_notifier_;
473
474   Signals signals_;
475
476   UniqueNotifier signals_check_notifier_;
477
478   bool has_scheduled_tile_tasks_;
479
480   uint64_t prepare_tiles_count_;
481   uint64_t next_tile_id_;
482
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;
489
490   std::unordered_map<Tile::Id, std::vector<DrawImage>> scheduled_draw_images_;
491   std::vector<scoped_refptr<TileTask>> locked_image_tasks_;
492
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;
496
497   GURL active_url_;
498
499   // The callback scheduled to poll whether the GPU side work for pending tiles
500   // has completed.
501   bool has_pending_queries_ = false;
502   base::CancelableOnceClosure check_pending_tile_queries_callback_;
503
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_;
511
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_{
519       this};
520 };
521
522 }  // namespace cc
523
524 #endif  // CC_TILES_TILE_MANAGER_H_