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 373 374 375 376 377 378 379 380 381 382 383
|
// 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) {
if (is_backdrop_filter_mask_ == is_backdrop_filter_mask) {
return;
}
is_backdrop_filter_mask_ = is_backdrop_filter_mask;
SetNeedsPushProperties();
}
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(const AppendQuadsContext& context,
viz::CompositorRenderPass* render_pass,
AppendQuadsData* append_quads_data) override;
void NotifyTileStateChanged(const Tile* tile, bool update_damage) 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) {
if (gpu_raster_max_texture_size_ == gpu_raster_max_texture_size) {
return;
}
gpu_raster_max_texture_size_ = gpu_raster_max_texture_size;
SetNeedsPushProperties();
}
gfx::Size gpu_raster_max_texture_size() {
return gpu_raster_max_texture_size_;
}
void UpdateRasterSource(scoped_refptr<RasterSource> raster_source,
Region* new_invalidation);
void SetRasterSourceForTesting(scoped_refptr<RasterSource> raster_source,
const Region& invalidation = Region());
void RegenerateDiscardableImageMap();
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();
bool IsDirectlyCompositedImage() const;
bool nearest_neighbor() const { return nearest_neighbor_; }
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 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 DiscardableImageMap::PaintWorkletInputs& 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;
// Tracks tiles changed since the last call to TakeUpdatedTiles().
TileUpdateSet updated_tiles_;
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 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 produced_tile_last_append_quads_ : 1 = true;
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_;
};
} // namespace cc
#endif // CC_LAYERS_PICTURE_LAYER_IMPL_H_
|