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

cc / tiles / tiling_set_eviction_queue.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_EVICTION_QUEUE_H_
#define CC_TILES_TILING_SET_EVICTION_QUEUE_H_

#include <stddef.h>

#include <vector>

#include "base/memory/raw_ptr_exclusion.h"
#include "cc/cc_export.h"
#include "cc/tiles/picture_layer_tiling_set.h"
#include "cc/tiles/prioritized_tile.h"

namespace cc {

// This eviction queue returned tiles from all tilings in a tiling set in
// the order in which the tiles should be evicted. It can be thought of as the
// following:
//  for all phases:
//    for all ordered tilings:
//      yield the next tile for the given phase from the given tiling
//
// Phases are the following (in order in which they are processed):
// EVENTUALLY_RECT - Tiles in the eventually region of the tiling.
// SOON_BORDER_RECT - Tiles in the prepainting skirt of the tiling.
// SKEWPORT_RECT - Tiles in the skewport of the tiling.
// PENDING_VISIBLE_RECT - Tiles that will be visible upon activation, not
//     required for activation.
// PENDING_VISIBLE_RECT_REQUIRED_FOR_ACTIVATION - Tiles that will be visible
//     upon activation, required for activation.
// VISIBLE_RECT_OCCLUDED - Occluded, not required for activation, visible tiles.
// VISIBLE_RECT_UNOCCLUDED - Unoccluded, not required for activation, visible
//     tiles.
// VISIBLE_RECT_REQUIRED_FOR_ACTIVATION_OCCLUDED - Occluded, but required for
//     activation, visible tiles. This can happen when an active tree tile is
//     occluded, but is not occluded on the pending tree (and is required for
//     activation).
// VISIBLE_RECT_REQUIRED_FOR_ACTIVATION_UNOCCLUDED - Unoccluded, required for
//     activation, tiles.
//
// The tilings are ordered as follows. Suppose we have tilings with the scales
// below:
// 2.0   1.5   1.0(HR)   0.8   0.5   0.25(LR)   0.2   0.1
// With HR referring to high res tiling and LR referring to low res tiling,
// then tilings are processed in this order:
// 2.0   1.5   0.1   0.2   0.5   0.8   0.25(LR)   1.0(HR).
//
// To put it differently:
//  1. Process the highest scale tiling down to, but not including, high res
//     tiling.
//  2. Process the lowest scale tiling up to, but not including, the low res
//     tiling. In cases without a low res tiling, this is an empty set.
//  3. Process low res tiling up to high res tiling, including neither high
//     nor low res tilings. In cases without a low res tiling, this set
//     includes all tilings with a lower scale than the high res tiling.
//  4. Process the low res tiling.
//  5. Process the high res tiling.
//
// Additional notes:
// Since eventually the tiles are considered to have the priority which is the
// higher of the two trees, we might visit a tile that should actually be
// returned by its twin. In those situations, the tiles are not returned. That
// is, since the twin has higher priority, it should return it when it gets to
// it. This ensures that we don't block raster because we've returned a tile
// with low priority on one tree, but high combined priority.
class CC_EXPORT TilingSetEvictionQueue {
 public:
  explicit TilingSetEvictionQueue(PictureLayerTilingSet* tiling_set,
                                  bool is_drawing_layer);
  ~TilingSetEvictionQueue();

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

 private:
  enum Phase {
    EVENTUALLY_RECT,
    SOON_BORDER_RECT,
    SKEWPORT_RECT,
    PENDING_VISIBLE_RECT,
    PENDING_VISIBLE_RECT_REQUIRED_FOR_ACTIVATION,
    VISIBLE_RECT_OCCLUDED,
    VISIBLE_RECT_UNOCCLUDED,
    VISIBLE_RECT_REQUIRED_FOR_ACTIVATION_OCCLUDED,
    VISIBLE_RECT_REQUIRED_FOR_ACTIVATION_UNOCCLUDED
  };

  void GenerateTilingOrder(PictureLayerTilingSet* tiling_set);

  // Helper base class for individual region iterators.
  class EvictionRectIterator {
   public:
    EvictionRectIterator();
    EvictionRectIterator(
        std::vector<PictureLayerTiling*>* tilings,
        WhichTree tree,
        PictureLayerTiling::PriorityRectType priority_rect_type);

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

   protected:
    ~EvictionRectIterator() = default;

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

    PrioritizedTile prioritized_tile_;

    // `tilings_` is not a raw_ptr<...> for performance reasons (based on
    // analysis of sampling profiler data and tab_search:top100:2020).
    RAW_PTR_EXCLUSION std::vector<PictureLayerTiling*>* tilings_;

    WhichTree tree_;
    PictureLayerTiling::PriorityRectType priority_rect_type_;
    size_t tiling_index_;
  };

  class PendingVisibleTilingIterator : public EvictionRectIterator {
   public:
    PendingVisibleTilingIterator() = default;
    PendingVisibleTilingIterator(std::vector<PictureLayerTiling*>* tilings,
                                 WhichTree tree,
                                 bool return_required_for_activation_tiles);

    PendingVisibleTilingIterator& operator++();

   private:
    bool TileMatchesRequiredFlags(const PrioritizedTile& tile) const;

    TilingData::DifferenceIterator iterator_;
    bool return_required_for_activation_tiles_;
  };

  class VisibleTilingIterator : public EvictionRectIterator {
   public:
    VisibleTilingIterator() = default;
    VisibleTilingIterator(std::vector<PictureLayerTiling*>* tilings,
                          WhichTree tree,
                          bool return_occluded_tiles,
                          bool return_required_for_activation_tiles);

    VisibleTilingIterator& operator++();

   private:
    bool TileMatchesRequiredFlags(const PrioritizedTile& tile) const;

    TilingData::Iterator iterator_;
    bool return_occluded_tiles_;
    bool return_required_for_activation_tiles_;
  };

  class SkewportTilingIterator : public EvictionRectIterator {
   public:
    SkewportTilingIterator() = default;
    SkewportTilingIterator(std::vector<PictureLayerTiling*>* tilings,
                           WhichTree tree);

    SkewportTilingIterator& operator++();

   private:
    TilingData::ReverseSpiralDifferenceIterator iterator_;
  };

  class SoonBorderTilingIterator : public EvictionRectIterator {
   public:
    SoonBorderTilingIterator() = default;
    SoonBorderTilingIterator(std::vector<PictureLayerTiling*>* tilings,
                             WhichTree tree);

    SoonBorderTilingIterator& operator++();

   private:
    TilingData::ReverseSpiralDifferenceIterator iterator_;
  };

  class EventuallyTilingIterator : public EvictionRectIterator {
   public:
    EventuallyTilingIterator() = default;
    EventuallyTilingIterator(std::vector<PictureLayerTiling*>* tilings,
                             WhichTree tree);

    EventuallyTilingIterator& operator++();

   private:
    TilingData::ReverseSpiralDifferenceIterator iterator_;
  };

  void AdvancePhase();

  WhichTree tree_;
  Phase phase_;
  PrioritizedTile current_tile_;
  std::vector<PictureLayerTiling*> tilings_;

  EventuallyTilingIterator eventually_iterator_;
  SoonBorderTilingIterator soon_iterator_;
  SkewportTilingIterator skewport_iterator_;
  PendingVisibleTilingIterator pending_visible_iterator_;
  VisibleTilingIterator visible_iterator_;
  bool is_drawing_layer_;
};

}  // namespace cc

#endif  // CC_TILES_TILING_SET_EVICTION_QUEUE_H_