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
  229
  230
  231
  232
  233
  234
  235
  236
  237
  238
  239
  240
  241
  242
  243
  244
  245
  246
  247
  248
  249
  250
  251
  252
  253
  254
  255
  256
  257
  258
  259
  260
  261
  262
  263
  264
  265
  266
  267
  268
  269
  270
  271
  272
  273
  274
  275
  276
  277
  278
  279
  280
  281
  282
  283
  284
  285
  286
  287
  288
  289
  290
  291
  292
  293
  294
  295
  296
  297
  298
  299
  300
  301
  302
  303
  304
  305
  306
  307
  308
  309
  310
  311
  312
  313
  314
  315
  316
  317
  318
  319
  320
  321
  322
  323
  324
  325
  326
  327
  328
  329
  330
  331
  332
  333
  334
  335
  336
  337
  338
  339
  340
  341
  342
  343
  344
  345
  346
  347
  348
  349
  350
  351
  352
  353
  354
  355
  356
  357
  358
  359
  360
  361
  362
  363
  364
  365
  366
  367
  368
  369
  370
  371
  372

cc / layers / picture_layer_impl.h [blame]

// Copyright 2012 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_LAYERS_PICTURE_LAYER_IMPL_H_
#define CC_LAYERS_PICTURE_LAYER_IMPL_H_

#include <stddef.h>

#include <algorithm>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>

#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/raw_ptr_exclusion.h"
#include "cc/cc_export.h"
#include "cc/layers/layer.h"
#include "cc/layers/layer_impl.h"
#include "cc/layers/tile_size_calculator.h"
#include "cc/paint/discardable_image_map.h"
#include "cc/paint/image_id.h"
#include "cc/raster/lcd_text_disallowed_reason.h"
#include "cc/tiles/picture_layer_tiling.h"
#include "cc/tiles/picture_layer_tiling_set.h"
#include "cc/tiles/tile_index.h"
#include "cc/tiles/tile_priority.h"
#include "cc/tiles/tiling_set_eviction_queue.h"
#include "cc/trees/image_animation_controller.h"

namespace cc {

class AppendQuadsData;
class MicroBenchmarkImpl;
class Tile;

class CC_EXPORT PictureLayerImpl
    : public LayerImpl,
      public PictureLayerTilingClient,
      public ImageAnimationController::AnimationDriver {
 public:
  static std::unique_ptr<PictureLayerImpl> Create(LayerTreeImpl* tree_impl,
                                                  int id) {
    return base::WrapUnique(new PictureLayerImpl(tree_impl, id));
  }
  PictureLayerImpl(const PictureLayerImpl&) = delete;
  ~PictureLayerImpl() override;

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

  void SetIsBackdropFilterMask(bool is_backdrop_filter_mask) {
    is_backdrop_filter_mask_ = is_backdrop_filter_mask;
  }
  bool is_backdrop_filter_mask() const { return is_backdrop_filter_mask_; }

  // LayerImpl overrides.
  mojom::LayerType GetLayerType() const override;
  std::unique_ptr<LayerImpl> CreateLayerImpl(
      LayerTreeImpl* tree_impl) const override;
  void PushPropertiesTo(LayerImpl* layer) override;
  void AppendQuads(viz::CompositorRenderPass* render_pass,
                   AppendQuadsData* append_quads_data) override;
  void NotifyTileStateChanged(const Tile* tile) override;
  gfx::Rect GetDamageRect() const override;
  void ResetChangeTracking() override;
  void ResetRasterScale();
  void DidBeginTracing() override;
  void ReleaseResources() override;
  void ReleaseTileResources() override;
  void RecreateTileResources() override;
  Region GetInvalidationRegionForDebugging() override;
  gfx::Rect GetEnclosingVisibleRectInTargetSpace() const override;
  gfx::ContentColorUsage GetContentColorUsage() const override;
  DamageReasonSet GetDamageReasons() const override;

  // PictureLayerTilingClient overrides.
  std::unique_ptr<Tile> CreateTile(const Tile::CreateInfo& info) override;
  gfx::Size CalculateTileSize(const gfx::Size& content_bounds) override;
  const Region* GetPendingInvalidation() override;
  const PictureLayerTiling* GetPendingOrActiveTwinTiling(
      const PictureLayerTiling* tiling) const override;
  bool HasValidTilePriorities() const override;
  bool RequiresHighResToDraw() const override;
  const PaintWorkletRecordMap& GetPaintWorkletRecords() const override;
  std::vector<const DrawImage*> GetDiscardableImagesInRect(
      const gfx::Rect& rect) const override;
  ScrollOffsetMap GetRasterInducingScrollOffsets() const override;
  const GlobalStateThatImpactsTilePriority& global_tile_state() const override;

  // ImageAnimationController::AnimationDriver overrides.
  bool ShouldAnimate(PaintImage::Id paint_image_id) const override;

  void set_gpu_raster_max_texture_size(gfx::Size gpu_raster_max_texture_size) {
    gpu_raster_max_texture_size_ = gpu_raster_max_texture_size;
  }

  gfx::Size gpu_raster_max_texture_size() {
    return gpu_raster_max_texture_size_;
  }

  void UpdateRasterSource(scoped_refptr<RasterSource> raster_source,
                          Region* new_invalidation);
  bool UpdateTiles();

  // Mask-related functions.
  void GetContentsResourceId(viz::ResourceId* resource_id,
                             gfx::Size* resource_size,
                             gfx::SizeF* resource_uv_size) const override;

  size_t GPUMemoryUsageInBytes() const override;

  void RunMicroBenchmark(MicroBenchmarkImpl* benchmark) override;

  bool CanHaveTilings() const;

  PictureLayerTilingSet* picture_layer_tiling_set() { return tilings_.get(); }

  // Functions used by tile manager.
  PictureLayerImpl* GetPendingOrActiveTwinLayer() const;
  bool IsOnActiveOrPendingTree() const;

  // Used for benchmarking
  RasterSource* GetRasterSource() const { return raster_source_.get(); }

  // This enum is the return value of the InvalidateRegionForImages() call. The
  // possible values represent the fact that there are no images on this layer
  // (kNoImages), the fact that the invalidation images don't cause an
  // invalidation on this layer (kNoInvalidation), or the fact that the layer
  // was invalidated (kInvalidated).
  enum class ImageInvalidationResult {
    kNoImages,
    kNoInvalidation,
    kInvalidated,
  };

  ImageInvalidationResult InvalidateRegionForImages(
      const PaintImageIdFlatSet& images_to_invalidate);

  void InvalidateRasterInducingScrolls(
      const base::flat_set<ElementId>& scrolls_to_invalidate);

  bool can_use_lcd_text() const {
    return lcd_text_disallowed_reason_ == LCDTextDisallowedReason::kNone;
  }
  LCDTextDisallowedReason lcd_text_disallowed_reason() const {
    return lcd_text_disallowed_reason_;
  }
  LCDTextDisallowedReason ComputeLCDTextDisallowedReasonForTesting() const;

  const Region& InvalidationForTesting() const { return invalidation_; }

  // Set the paint result (PaintRecord) for a given PaintWorkletInput.
  void SetPaintWorkletRecord(scoped_refptr<const PaintWorkletInput>,
                             PaintRecord);

  // Retrieve the map of PaintWorkletInputs to their painted results
  // (PaintRecords). If a PaintWorkletInput has not been painted yet, it will
  // map to nullptr.
  const PaintWorkletRecordMap& GetPaintWorkletRecordMap() const {
    return paint_worklet_records_;
  }

  // Invalidates all PaintWorklets in this layer who depend on the given
  // property to be painted. Used when the value for the property is changed by
  // an animation, at which point the PaintWorklet must be re-painted.
  void InvalidatePaintWorklets(const PaintWorkletInput::PropertyKey& key,
                               const PaintWorkletInput::PropertyValue& prev,
                               const PaintWorkletInput::PropertyValue& next);

  void SetContentsScaleForTesting(float scale) {
    ideal_contents_scale_ = raster_contents_scale_ =
        gfx::Vector2dF(scale, scale);
  }

  void AddLastAppendQuadsTilingForTesting(PictureLayerTiling* tiling) {
    last_append_quads_tilings_.push_back(tiling);
  }

  void set_has_non_animated_image_update_rect() {
    has_non_animated_image_update_rect_ = true;
  }

  // Returns the set of tiles which have been updated since the last call to
  // this method. This returns tile indices for each updated tile, grouped by
  // the scale key of their respective tiling. Beware that this is not pruned,
  // so tilings or tiles identified within may no longer exist.
  using TileUpdateSet = std::map<float, std::set<TileIndex>>;
  TileUpdateSet TakeUpdatedTiles();

 protected:
  friend class RasterizeAndRecordBenchmarkImpl;

  PictureLayerImpl(LayerTreeImpl* tree_impl, int id);
  PictureLayerTiling* AddTiling(const gfx::AxisTransform2d& contents_transform);
  void RemoveAllTilings();
  bool CanRecreateHighResTilingForLCDTextAndRasterTransform(
      const PictureLayerTiling& high_res) const;
  void UpdateTilingsForRasterScaleAndTranslation(bool adjusted_raster_scale);
  void AddLowResolutionTilingIfNeeded();
  bool ShouldAdjustRasterScale() const;
  void RecalculateRasterScales();
  void AdjustRasterScaleForTransformAnimation(
      const gfx::Vector2dF& preserved_raster_contents_scale);
  float MinimumRasterContentsScaleForWillChangeTransform() const;
  // Returns false if raster translation is not applicable.
  bool CalculateRasterTranslation(gfx::Vector2dF& raster_translation) const;
  void CleanUpTilingsOnActiveLayer(
      const std::vector<raw_ptr<PictureLayerTiling, VectorExperimental>>&
          used_tilings);
  float MinimumContentsScale() const;
  float MaximumContentsScale() const;
  void UpdateViewportRectForTilePriorityInContentSpace();
  PictureLayerImpl* GetRecycledTwinLayer() const;
  bool ShouldDirectlyCompositeImage(float raster_scale) const;

  // Returns the raster scale that should be used for a directly composited
  // image. This takes into account the ideal contents scale to ensure we don't
  // use too much memory for layers that are small due to contents scale
  // factors, and bumps up the reduced scale if those layers end up increasing
  // their contents scale.
  float CalculateDirectlyCompositedImageRasterScale() const;

  void UpdateRasterSourceInternal(
      scoped_refptr<RasterSource> raster_source,
      Region* new_invalidation,
      const PictureLayerTilingSet* pending_set,
      const PaintWorkletRecordMap* pending_paint_worklet_records,
      const DiscardableImageMap* pending_discardable_image_map);
  void RegenerateDiscardableImageMap();

  bool IsDirectlyCompositedImage() const;
  void UpdateDirectlyCompositedImageFromRasterSource();

  void SanityCheckTilingState() const;

  void GetDebugBorderProperties(SkColor4f* color, float* width) const override;
  void GetAllPrioritizedTilesForTracing(
      std::vector<PrioritizedTile>* prioritized_tiles) const override;
  void AsValueInto(base::trace_event::TracedValue* dict) const override;

  void UpdateIdealScales();
  float MaximumTilingContentsScale() const;
  std::unique_ptr<PictureLayerTilingSet> CreatePictureLayerTilingSet();

  void RegisterAnimatedImages();
  void UnregisterAnimatedImages();

  // Set the collection of PaintWorkletInput as well as their PaintImageId that
  // are part of this layer.
  void SetPaintWorkletInputs(
      const std::vector<DiscardableImageMap::PaintWorkletInputWithImageId>&
          inputs);

  LCDTextDisallowedReason ComputeLCDTextDisallowedReason(
      bool raster_translation_aligns_pixels) const;
  void UpdateCanUseLCDText(bool raster_translation_aligns_pixels);

  // Whether the transform node for this layer, or any ancestor transform
  // node, has a will-change hint for one of the transform properties.
  bool AffectedByWillChangeTransformHint() const;

  // RAW_PTR_EXCLUSION: Performance reasons (based on analysis of speedometer3).
  RAW_PTR_EXCLUSION PictureLayerImpl* twin_layer_ = nullptr;

  std::unique_ptr<PictureLayerTilingSet> tilings_ =
      CreatePictureLayerTilingSet();
  scoped_refptr<RasterSource> raster_source_;
  Region invalidation_;
  scoped_refptr<const DiscardableImageMap> discardable_image_map_;

  // Ideal scales are calcuated from the transforms applied to the layer. They
  // represent the best known scale from the layer to the final output.
  // Page scale is from user pinch/zoom.
  float ideal_page_scale_ = 0.f;
  // Device scale is from screen dpi, and it comes from device scale facter.
  float ideal_device_scale_ = 0.f;
  // Source scale comes from javascript css scale.
  gfx::Vector2dF ideal_source_scale_;
  // Contents scale = device scale * page scale * source scale.
  gfx::Vector2dF ideal_contents_scale_;

  // Raster scales are set from ideal scales. They are scales we choose to
  // raster at. They may not match the ideal scales at times to avoid raster for
  // performance reasons.
  float raster_page_scale_ = 0.f;
  float raster_device_scale_ = 0.f;
  gfx::Vector2dF raster_source_scale_;
  gfx::Vector2dF raster_contents_scale_;
  float low_res_raster_contents_scale_ = 0.f;

  float ideal_source_scale_key() const {
    return std::max(ideal_source_scale_.x(), ideal_source_scale_.y());
  }
  float ideal_contents_scale_key() const {
    return std::max(ideal_contents_scale_.x(), ideal_contents_scale_.y());
  }
  float raster_source_scale_key() const {
    return std::max(raster_source_scale_.x(), raster_source_scale_.y());
  }
  float raster_contents_scale_key() const {
    return std::max(raster_contents_scale_.x(), raster_contents_scale_.y());
  }

  bool is_backdrop_filter_mask_ : 1 = false;

  bool was_screen_space_transform_animating_ : 1 = false;
  bool only_used_low_res_last_append_quads_ : 1 = false;

  bool nearest_neighbor_ : 1 = false;

  // This is set by UpdateRasterSource() on change of raster source size. It's
  // used to recalculate raster scale for will-chagne:transform. It's reset to
  // false after raster scale update.
  bool raster_source_size_changed_ : 1 = false;

  bool directly_composited_image_default_raster_scale_changed_ : 1 = false;

  // Keep track of if a non-empty update_rect is due to animated image or other
  // reasons.
  bool has_animated_image_update_rect_ : 1 = false;
  bool has_non_animated_image_update_rect_ : 1 = false;

  LCDTextDisallowedReason lcd_text_disallowed_reason_ =
      LCDTextDisallowedReason::kNoText;

  // If this scale is not zero, it indicates that this layer is a directly
  // composited image layer (i.e. the only thing drawn into this layer is an
  // image). The rasterized pixels will be the same as the image's original
  // pixels if this scale is used as the raster scale.
  // To avoid re-raster on scale changes, this may be different than the used
  // raster scale, see: |RecalculateRasterScales()| and
  // |CalculateDirectlyCompositedImageRasterScale()|.
  // TODO(crbug.com/40176440): Support 2D scales in directly composited images.
  float directly_composited_image_default_raster_scale_ = 0;

  // Use this instead of |visible_layer_rect()| for tiling calculations. This
  // takes external viewport and transform for tile priority into account.
  gfx::Rect viewport_rect_for_tile_priority_in_content_space_;

  gfx::Size gpu_raster_max_texture_size_;

  // List of tilings that were used last time we appended quads. This can be
  // used as an optimization not to remove tilings if they are still being
  // drawn. Note that accessing this vector should only be done in the context
  // of comparing pointers, since objects pointed to are not guaranteed to
  // exist.
  std::vector<raw_ptr<PictureLayerTiling, VectorExperimental>>
      last_append_quads_tilings_;

  // The set of PaintWorkletInputs that are part of this PictureLayerImpl, and
  // their painted results (if any). During commit, Blink hands us a set of
  // PaintWorkletInputs that are part of this layer. These are then painted
  // asynchronously on a worklet thread, triggered from
  // |LayerTreeHostImpl::UpdateSyncTreeAfterCommitOrImplSideInvalidation|.
  PaintWorkletRecordMap paint_worklet_records_;

  TileSizeCalculator tile_size_calculator_{this};

  // Denotes an area that is damaged and needs redraw. This is in the layer's
  // space.
  gfx::Rect damage_rect_;

  // Tracks tiles changed since the last call to TakeUpdatedTiles().
  TileUpdateSet updated_tiles_;
};

}  // namespace cc

#endif  // CC_LAYERS_PICTURE_LAYER_IMPL_H_