1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  182
  183
  184
  185
  186
  187
  188
  189
  190
  191
  192
  193
  194
  195
  196
  197
  198
  199
  200
  201
  202
  203
  204
  205
  206
  207
  208
  209
  210
  211
  212
  213
  214
  215
  216
  217
  218
  219
  220
  221
  222
  223
  224
  225
  226
  227
  228

cc / tiles / tiling_set_raster_queue_all.h [blame]

// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CC_TILES_TILING_SET_RASTER_QUEUE_ALL_H_
#define CC_TILES_TILING_SET_RASTER_QUEUE_ALL_H_

#include <stddef.h>

#include <array>
#include <memory>
#include <optional>

#include "base/notreached.h"
#include "cc/cc_export.h"
#include "cc/tiles/prioritized_tile.h"
#include "cc/tiles/tile.h"
#include "cc/tiles/tile_priority.h"
#include "third_party/abseil-cpp/absl/container/inlined_vector.h"

namespace cc {

class PictureLayerTilingSet;

// This queue returns all tiles required to be rasterized from HIGH_RESOLUTION
// and LOW_RESOLUTION tilings.
class CC_EXPORT TilingSetRasterQueueAll {
 public:
  static std::unique_ptr<TilingSetRasterQueueAll> Create(
      PictureLayerTilingSet* tiling_set,
      bool prioritize_low_res,
      bool is_drawing_layer);

  TilingSetRasterQueueAll(const TilingSetRasterQueueAll&) = delete;
  ~TilingSetRasterQueueAll();

  TilingSetRasterQueueAll& operator=(const TilingSetRasterQueueAll&) = delete;

  const PrioritizedTile& Top() const;
  void Pop();
  bool IsEmpty() const;
  bool is_drawing_layer() const { return is_drawing_layer_; }

 private:
  // Helper base class for individual region iterators.
  class OnePriorityRectIterator {
   public:
    OnePriorityRectIterator();
    OnePriorityRectIterator(
        PictureLayerTiling* tiling,
        TilingData* tiling_data,
        PictureLayerTiling::PriorityRectType priority_rect_type);

    bool done() const { return !current_tile_.tile(); }
    const PrioritizedTile& operator*() const { return current_tile_; }

   protected:
    ~OnePriorityRectIterator() = default;

    template <typename TilingIteratorType>
    void AdvanceToNextTile(TilingIteratorType* iterator);
    template <typename TilingIteratorType>
    bool GetFirstTileAndCheckIfValid(TilingIteratorType* iterator);

    enum IsTileValidResult {
      kTileNotValid,
      kTileNeedsRaster,
      kTileNeedsCheckerImageReraster
    };
    IsTileValidResult IsTileValid(const Tile* tile) const;

    PrioritizedTile current_tile_;

    // `tiling_` and `tiling_data_` are not a raw_ptr<...> for performance
    // reasons (based on analysis of sampling profiler data and
    // tab_search:top100:2020).
    RAW_PTR_EXCLUSION PictureLayerTiling* tiling_;
    RAW_PTR_EXCLUSION TilingData* tiling_data_;

    PictureLayerTiling::PriorityRectType priority_rect_type_;
    gfx::Rect pending_visible_rect_;
  };

  // Iterates over visible rect only, left to right top to bottom order.
  class VisibleTilingIterator : public OnePriorityRectIterator {
   public:
    VisibleTilingIterator() = default;
    VisibleTilingIterator(PictureLayerTiling* tiling, TilingData* tiling_data);

    VisibleTilingIterator& operator++();

   private:
    TilingData::Iterator iterator_;
  };

  class PendingVisibleTilingIterator : public OnePriorityRectIterator {
   public:
    PendingVisibleTilingIterator() = default;
    PendingVisibleTilingIterator(PictureLayerTiling* tiling,
                                 TilingData* tiling_data);

    PendingVisibleTilingIterator& operator++();

   private:
    TilingData::DifferenceIterator iterator_;
  };

  // Iterates over skewport only, spiral around the visible rect.
  class SkewportTilingIterator : public OnePriorityRectIterator {
   public:
    SkewportTilingIterator() = default;
    SkewportTilingIterator(PictureLayerTiling* tiling, TilingData* tiling_data);

    SkewportTilingIterator& operator++();

   private:
    TilingData::SpiralDifferenceIterator iterator_;
  };

  // Iterates over soon border only, spiral around the visible rect.
  class SoonBorderTilingIterator : public OnePriorityRectIterator {
   public:
    SoonBorderTilingIterator() = default;
    SoonBorderTilingIterator(PictureLayerTiling* tiling,
                             TilingData* tiling_data);

    SoonBorderTilingIterator& operator++();

   private:
    TilingData::SpiralDifferenceIterator iterator_;
  };

  // Iterates over eventually rect only, spiral around the soon rect.
  class EventuallyTilingIterator : public OnePriorityRectIterator {
   public:
    EventuallyTilingIterator() = default;
    EventuallyTilingIterator(PictureLayerTiling* tiling,
                             TilingData* tiling_data);

    EventuallyTilingIterator& operator++();

   private:
    TilingData::SpiralDifferenceIterator iterator_;
  };

  // Iterates over all of the above phases in the following order: visible,
  // skewport, soon border, eventually.
  class TilingIterator {
   public:
    TilingIterator();
    TilingIterator(PictureLayerTiling* tiling, TilingData* tiling_data);
    ~TilingIterator();

    bool done() const { return !current_tile_.tile(); }
    const PrioritizedTile& operator*() const { return current_tile_; }
    TilePriority::PriorityBin type() const {
      switch (phase_) {
        case Phase::VISIBLE_RECT:
          return TilePriority::NOW;
        case Phase::PENDING_VISIBLE_RECT:
        case Phase::SKEWPORT_RECT:
        case Phase::SOON_BORDER_RECT:
          return TilePriority::SOON;
        case Phase::EVENTUALLY_RECT:
          return TilePriority::EVENTUALLY;
      }
      NOTREACHED();
    }

    TilingIterator& operator++();

   private:
    using Phase = PictureLayerTiling::PriorityRectType;

    void AdvancePhase();

    // `tiling_` and `tiling_data_` are not a raw_ptr<...> for performance
    // reasons (based on analysis of sampling profiler data and
    // tab_search:top100:2020).
    // These fields are not raw_ptr<> for performance based on sampling profiler
    // data and tab_search:top100:2020 profiler data.
    RAW_PTR_EXCLUSION PictureLayerTiling* tiling_;
    RAW_PTR_EXCLUSION TilingData* tiling_data_;

    Phase phase_;

    PrioritizedTile current_tile_;
    VisibleTilingIterator visible_iterator_;
    PendingVisibleTilingIterator pending_visible_iterator_;
    SkewportTilingIterator skewport_iterator_;
    SoonBorderTilingIterator soon_border_iterator_;
    EventuallyTilingIterator eventually_iterator_;
  };

  enum IteratorType {
    LOW_RES,
    HIGH_RES,
    ACTIVE_NON_IDEAL_PENDING_HIGH_RES,
    NUM_ITERATORS
  };

  TilingSetRasterQueueAll(
      PictureLayerTiling* high_res_tiling,
      PictureLayerTiling* low_res_tiling,
      PictureLayerTiling* active_non_ideal_pending_high_res_tiling,
      bool is_drawing_layer);

  void MakeTilingIterator(IteratorType type, PictureLayerTiling* tiling);
  void AdvanceToNextStage();

  struct IterationStage {
    IterationStage(IteratorType type, TilePriority::PriorityBin bin);
    IteratorType iterator_type;
    TilePriority::PriorityBin tile_type;
  };

  size_t current_stage_;

  // The max number of stages is 6: 1 low res, 3 high res, and 2 active non
  // ideal pending high res.
  absl::InlinedVector<IterationStage, 6> stages_;
  std::array<std::optional<TilingIterator>, NUM_ITERATORS> iterators_;
  bool is_drawing_layer_ = false;
};

}  // namespace cc

#endif  // CC_TILES_TILING_SET_RASTER_QUEUE_ALL_H_