1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "cc/layers/picture_layer_impl.h"
6 
7 #include <stddef.h>
8 #include <stdint.h>
9 
10 #include <algorithm>
11 #include <cmath>
12 #include <limits>
13 #include <set>
14 
15 #include "base/metrics/histogram_macros.h"
16 #include "base/no_destructor.h"
17 #include "base/numerics/ranges.h"
18 #include "base/time/time.h"
19 #include "base/trace_event/traced_value.h"
20 #include "build/build_config.h"
21 #include "cc/base/math_util.h"
22 #include "cc/benchmarks/micro_benchmark_impl.h"
23 #include "cc/debug/debug_colors.h"
24 #include "cc/layers/append_quads_data.h"
25 #include "cc/layers/solid_color_layer_impl.h"
26 #include "cc/paint/display_item_list.h"
27 #include "cc/tiles/tile_manager.h"
28 #include "cc/tiles/tiling_set_raster_queue_all.h"
29 #include "cc/trees/effect_node.h"
30 #include "cc/trees/layer_tree_impl.h"
31 #include "cc/trees/occlusion.h"
32 #include "components/viz/common/frame_sinks/begin_frame_args.h"
33 #include "components/viz/common/quads/debug_border_draw_quad.h"
34 #include "components/viz/common/quads/picture_draw_quad.h"
35 #include "components/viz/common/quads/solid_color_draw_quad.h"
36 #include "components/viz/common/quads/tile_draw_quad.h"
37 #include "components/viz/common/traced_value.h"
38 #include "ui/gfx/geometry/quad_f.h"
39 #include "ui/gfx/geometry/rect_conversions.h"
40 #include "ui/gfx/geometry/size_conversions.h"
41 
42 namespace cc {
43 namespace {
44 // This must be > 1 as we multiply or divide by this to find a new raster
45 // scale during pinch.
46 const float kMaxScaleRatioDuringPinch = 2.0f;
47 
48 // When creating a new tiling during pinch, snap to an existing
49 // tiling's scale if the desired scale is within this ratio.
50 const float kSnapToExistingTilingRatio = 1.2f;
51 
52 // Large contents scale can cause overflow issues. Cap the ideal contents scale
53 // by this constant, since scales larger than this are usually not correct or
54 // their scale doesn't matter as long as it's large. Content scales usually
55 // closely match the default device-scale factor (so it's usually <= 5). See
56 // Renderer4.IdealContentsScale UMA (deprecated) for distribution of content
57 // scales.
58 const float kMaxIdealContentsScale = 10000.f;
59 
60 // Intersect rects which may have right() and bottom() that overflow integer
61 // boundaries. This code is similar to gfx::Rect::Intersect with the exception
62 // that the types are promoted to int64_t when there is a chance of overflow.
SafeIntersectRects(const gfx::Rect & one,const gfx::Rect & two)63 gfx::Rect SafeIntersectRects(const gfx::Rect& one, const gfx::Rect& two) {
64   if (one.IsEmpty() || two.IsEmpty())
65     return gfx::Rect();
66 
67   int rx = std::max(one.x(), two.x());
68   int ry = std::max(one.y(), two.y());
69   int64_t rr = std::min(static_cast<int64_t>(one.x()) + one.width(),
70                         static_cast<int64_t>(two.x()) + two.width());
71   int64_t rb = std::min(static_cast<int64_t>(one.y()) + one.height(),
72                         static_cast<int64_t>(two.y()) + two.height());
73   if (rx > rr || ry > rb)
74     return gfx::Rect();
75   return gfx::Rect(rx, ry, static_cast<int>(rr - rx),
76                    static_cast<int>(rb - ry));
77 }
78 
79 }  // namespace
80 
PictureLayerImpl(LayerTreeImpl * tree_impl,int id)81 PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl, int id)
82     : LayerImpl(tree_impl, id, /*will_always_push_properties=*/true),
83       twin_layer_(nullptr),
84       tilings_(CreatePictureLayerTilingSet()),
85       ideal_page_scale_(0.f),
86       ideal_device_scale_(0.f),
87       ideal_source_scale_(0.f),
88       ideal_contents_scale_(0.f),
89       raster_page_scale_(0.f),
90       raster_device_scale_(0.f),
91       raster_source_scale_(0.f),
92       raster_contents_scale_(0.f),
93       low_res_raster_contents_scale_(0.f),
94       is_backdrop_filter_mask_(false),
95       was_screen_space_transform_animating_(false),
96       only_used_low_res_last_append_quads_(false),
97       nearest_neighbor_(false),
98       use_transformed_rasterization_(false),
99       can_use_lcd_text_(true),
100       directly_composited_image_size_(base::nullopt),
101       tile_size_calculator_(this) {
102   layer_tree_impl()->RegisterPictureLayerImpl(this);
103 }
104 
~PictureLayerImpl()105 PictureLayerImpl::~PictureLayerImpl() {
106   if (twin_layer_)
107     twin_layer_->twin_layer_ = nullptr;
108 
109   // We only track PaintWorklet-containing PictureLayerImpls on the pending
110   // tree. However this deletion may happen outside the commit flow when we are
111   // on the recycle tree instead, so just check !IsActiveTree().
112   if (!paint_worklet_records_.empty() && !layer_tree_impl()->IsActiveTree())
113     layer_tree_impl()->NotifyLayerHasPaintWorkletsChanged(this, false);
114 
115   // Similarly, AnimatedPaintWorkletTracker is only valid on the pending tree.
116   if (!layer_tree_impl()->IsActiveTree()) {
117     layer_tree_impl()
118         ->paint_worklet_tracker()
119         .UpdatePaintWorkletInputProperties({}, this);
120   }
121 
122   layer_tree_impl()->UnregisterPictureLayerImpl(this);
123 
124   // Unregister for all images on the current raster source.
125   UnregisterAnimatedImages();
126 }
127 
LayerTypeAsString() const128 const char* PictureLayerImpl::LayerTypeAsString() const {
129   return "cc::PictureLayerImpl";
130 }
131 
CreateLayerImpl(LayerTreeImpl * tree_impl)132 std::unique_ptr<LayerImpl> PictureLayerImpl::CreateLayerImpl(
133     LayerTreeImpl* tree_impl) {
134   return PictureLayerImpl::Create(tree_impl, id());
135 }
136 
PushPropertiesTo(LayerImpl * base_layer)137 void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) {
138   PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer);
139 
140 
141   LayerImpl::PushPropertiesTo(base_layer);
142 
143   // Twin relationships should never change once established.
144   DCHECK(!twin_layer_ || twin_layer_ == layer_impl);
145   DCHECK(!twin_layer_ || layer_impl->twin_layer_ == this);
146   // The twin relationship does not need to exist before the first
147   // PushPropertiesTo from pending to active layer since before that the active
148   // layer can not have a pile or tilings, it has only been created and inserted
149   // into the tree at that point.
150   twin_layer_ = layer_impl;
151   layer_impl->twin_layer_ = this;
152 
153   layer_impl->SetNearestNeighbor(nearest_neighbor_);
154   layer_impl->SetUseTransformedRasterization(use_transformed_rasterization_);
155   layer_impl->SetDirectlyCompositedImageSize(directly_composited_image_size_);
156   layer_impl->SetIsBackdropFilterMask(is_backdrop_filter_mask_);
157 
158   // Solid color layers have no tilings.
159   DCHECK(!raster_source_->IsSolidColor() || tilings_->num_tilings() == 0);
160   // The pending tree should only have a high res (and possibly low res) tiling.
161   DCHECK_LE(tilings_->num_tilings(),
162             layer_tree_impl()->create_low_res_tiling() ? 2u : 1u);
163 
164   layer_impl->set_gpu_raster_max_texture_size(gpu_raster_max_texture_size_);
165   layer_impl->UpdateRasterSource(raster_source_, &invalidation_, tilings_.get(),
166                                  &paint_worklet_records_);
167   DCHECK(invalidation_.IsEmpty());
168 
169   // After syncing a solid color layer, the active layer has no tilings.
170   DCHECK(!raster_source_->IsSolidColor() ||
171          layer_impl->tilings_->num_tilings() == 0);
172 
173   layer_impl->raster_page_scale_ = raster_page_scale_;
174   layer_impl->raster_device_scale_ = raster_device_scale_;
175   layer_impl->raster_source_scale_ = raster_source_scale_;
176   layer_impl->raster_contents_scale_ = raster_contents_scale_;
177   layer_impl->low_res_raster_contents_scale_ = low_res_raster_contents_scale_;
178   // Simply push the value to the active tree without any extra invalidations,
179   // since the pending tree tiles would have this handled. This is here to
180   // ensure the state is consistent for future raster.
181   layer_impl->can_use_lcd_text_ = can_use_lcd_text_;
182 
183   layer_impl->SanityCheckTilingState();
184 }
185 
AppendQuads(viz::RenderPass * render_pass,AppendQuadsData * append_quads_data)186 void PictureLayerImpl::AppendQuads(viz::RenderPass* render_pass,
187                                    AppendQuadsData* append_quads_data) {
188   // RenderSurfaceImpl::AppendQuads sets mask properties in the DrawQuad for
189   // the masked surface, which will apply to both the backdrop filter and the
190   // contents of the masked surface, so we should not append quads of the mask
191   // layer in DstIn blend mode which would apply the mask in another codepath.
192   if (is_backdrop_filter_mask_)
193     return;
194 
195   // The bounds and the pile size may differ if the pile wasn't updated (ie.
196   // PictureLayer::Update didn't happen). In that case the pile will be empty.
197   DCHECK(raster_source_->GetSize().IsEmpty() ||
198          bounds() == raster_source_->GetSize())
199       << " bounds " << bounds().ToString() << " pile "
200       << raster_source_->GetSize().ToString();
201 
202   viz::SharedQuadState* shared_quad_state =
203       render_pass->CreateAndAppendSharedQuadState();
204 
205   if (raster_source_->IsSolidColor()) {
206     // TODO(979672): This is still hard-coded at 1.0. This has some history:
207     //  - for crbug.com/769319, the contents scale was allowed to change, to
208     //    avoid blurring on high-dpi screens.
209     //  - for crbug.com/796558, the max device scale was hard-coded back to 1.0
210     //    for single-tile masks, to avoid problems with transforms.
211     // To avoid those transform/scale bugs, this is currently left at 1.0. See
212     // crbug.com/979672 for more context and test links.
213     float max_contents_scale = 1;
214 
215     // The downstream CA layers use shared_quad_state to generate resources of
216     // the right size even if it is a solid color picture layer.
217     PopulateScaledSharedQuadState(shared_quad_state, max_contents_scale,
218                                   contents_opaque());
219 
220     AppendDebugBorderQuad(render_pass, gfx::Rect(bounds()), shared_quad_state,
221                           append_quads_data);
222 
223     gfx::Rect scaled_visible_layer_rect =
224         shared_quad_state->visible_quad_layer_rect;
225     Occlusion occlusion = draw_properties().occlusion_in_content_space;
226 
227     EffectNode* effect_node = GetEffectTree().Node(effect_tree_index());
228     SolidColorLayerImpl::AppendSolidQuads(
229         render_pass, occlusion, shared_quad_state, scaled_visible_layer_rect,
230         raster_source_->GetSolidColor(),
231         !layer_tree_impl()->settings().enable_edge_anti_aliasing,
232         effect_node->blend_mode, append_quads_data);
233     return;
234   }
235 
236   float device_scale_factor = layer_tree_impl()->device_scale_factor();
237   // If we don't have tilings, we're likely going to append a checkerboard quad
238   // the size of the layer. In that case, use scale 1 for more stable
239   // to-screen-space mapping.
240   float max_contents_scale =
241       tilings_->num_tilings() ? MaximumTilingContentsScale() : 1.f;
242   PopulateScaledSharedQuadState(shared_quad_state, max_contents_scale,
243                                 contents_opaque());
244   Occlusion scaled_occlusion =
245       draw_properties()
246           .occlusion_in_content_space.GetOcclusionWithGivenDrawTransform(
247               shared_quad_state->quad_to_target_transform);
248 
249   if (current_draw_mode_ == DRAW_MODE_RESOURCELESS_SOFTWARE) {
250     DCHECK(shared_quad_state->quad_layer_rect.origin() == gfx::Point(0, 0));
251     AppendDebugBorderQuad(
252         render_pass, shared_quad_state->quad_layer_rect, shared_quad_state,
253         append_quads_data, DebugColors::DirectPictureBorderColor(),
254         DebugColors::DirectPictureBorderWidth(device_scale_factor));
255 
256     gfx::Rect geometry_rect = shared_quad_state->visible_quad_layer_rect;
257     gfx::Rect visible_geometry_rect =
258         scaled_occlusion.GetUnoccludedContentRect(geometry_rect);
259     bool needs_blending = !contents_opaque();
260 
261     // The raster source may not be valid over the entire visible rect,
262     // and rastering outside of that may cause incorrect pixels.
263     gfx::Rect scaled_recorded_viewport = gfx::ScaleToEnclosingRect(
264         raster_source_->RecordedViewport(), max_contents_scale);
265     geometry_rect.Intersect(scaled_recorded_viewport);
266     visible_geometry_rect.Intersect(scaled_recorded_viewport);
267 
268     if (visible_geometry_rect.IsEmpty())
269       return;
270 
271     DCHECK(raster_source_->HasRecordings());
272     gfx::Rect quad_content_rect = shared_quad_state->visible_quad_layer_rect;
273     gfx::Size texture_size = quad_content_rect.size();
274     gfx::RectF texture_rect = gfx::RectF(gfx::SizeF(texture_size));
275 
276     viz::PictureDrawQuad::ImageAnimationMap image_animation_map;
277     const auto* controller = layer_tree_impl()->image_animation_controller();
278     WhichTree tree = layer_tree_impl()->IsPendingTree()
279                          ? WhichTree::PENDING_TREE
280                          : WhichTree::ACTIVE_TREE;
281     for (const auto& image_data : raster_source_->GetDisplayItemList()
282                                       ->discardable_image_map()
283                                       .animated_images_metadata()) {
284       image_animation_map[image_data.paint_image_id] =
285           controller->GetFrameIndexForImage(image_data.paint_image_id, tree);
286     }
287 
288     auto* quad = render_pass->CreateAndAppendDrawQuad<viz::PictureDrawQuad>();
289     quad->SetNew(shared_quad_state, geometry_rect, visible_geometry_rect,
290                  needs_blending, texture_rect, texture_size, nearest_neighbor_,
291                  viz::RGBA_8888, quad_content_rect, max_contents_scale,
292                  std::move(image_animation_map),
293                  raster_source_->GetDisplayItemList());
294     ValidateQuadResources(quad);
295     return;
296   }
297 
298   // If we're doing a regular AppendQuads (ie, not solid color or resourceless
299   // software draw, and if the visible rect is scrolled far enough away, then we
300   // may run into a floating point precision in AA calculations in the renderer.
301   // See crbug.com/765297. In order to avoid this, we shift the quads up from
302   // where they logically reside and adjust the shared_quad_state's transform
303   // instead. We only do this in a scale/translate matrices to ensure the math
304   // is correct.
305   gfx::Vector2d quad_offset;
306   if (shared_quad_state->quad_to_target_transform.IsScaleOrTranslation()) {
307     const auto& visible_rect = shared_quad_state->visible_quad_layer_rect;
308     quad_offset = gfx::Vector2d(-visible_rect.x(), -visible_rect.y());
309   }
310 
311   gfx::Rect debug_border_rect(shared_quad_state->quad_layer_rect);
312   debug_border_rect.Offset(quad_offset);
313   AppendDebugBorderQuad(render_pass, debug_border_rect, shared_quad_state,
314                         append_quads_data);
315 
316   if (ShowDebugBorders(DebugBorderType::LAYER)) {
317     for (PictureLayerTilingSet::CoverageIterator iter(
318              tilings_.get(), max_contents_scale,
319              shared_quad_state->visible_quad_layer_rect, ideal_contents_scale_);
320          iter; ++iter) {
321       SkColor color;
322       float width;
323       if (*iter && iter->draw_info().IsReadyToDraw()) {
324         TileDrawInfo::Mode mode = iter->draw_info().mode();
325         if (mode == TileDrawInfo::SOLID_COLOR_MODE) {
326           color = DebugColors::SolidColorTileBorderColor();
327           width = DebugColors::SolidColorTileBorderWidth(device_scale_factor);
328         } else if (mode == TileDrawInfo::OOM_MODE) {
329           color = DebugColors::OOMTileBorderColor();
330           width = DebugColors::OOMTileBorderWidth(device_scale_factor);
331         } else if (iter.resolution() == HIGH_RESOLUTION) {
332           color = DebugColors::HighResTileBorderColor();
333           width = DebugColors::HighResTileBorderWidth(device_scale_factor);
334         } else if (iter.resolution() == LOW_RESOLUTION) {
335           color = DebugColors::LowResTileBorderColor();
336           width = DebugColors::LowResTileBorderWidth(device_scale_factor);
337         } else if (iter->contents_scale_key() > max_contents_scale) {
338           color = DebugColors::ExtraHighResTileBorderColor();
339           width = DebugColors::ExtraHighResTileBorderWidth(device_scale_factor);
340         } else {
341           color = DebugColors::ExtraLowResTileBorderColor();
342           width = DebugColors::ExtraLowResTileBorderWidth(device_scale_factor);
343         }
344       } else {
345         color = DebugColors::MissingTileBorderColor();
346         width = DebugColors::MissingTileBorderWidth(device_scale_factor);
347       }
348 
349       auto* debug_border_quad =
350           render_pass->CreateAndAppendDrawQuad<viz::DebugBorderDrawQuad>();
351       gfx::Rect geometry_rect = iter.geometry_rect();
352       geometry_rect.Offset(quad_offset);
353       gfx::Rect visible_geometry_rect = geometry_rect;
354       debug_border_quad->SetNew(shared_quad_state,
355                                 geometry_rect,
356                                 visible_geometry_rect,
357                                 color,
358                                 width);
359     }
360   }
361 
362   // Keep track of the tilings that were used so that tilings that are
363   // unused can be considered for removal.
364   last_append_quads_tilings_.clear();
365 
366   // Ignore missing tiles outside of viewport for tile priority. This is
367   // normally the same as draw viewport but can be independently overridden by
368   // embedders like Android WebView with SetExternalTilePriorityConstraints.
369   gfx::Rect scaled_viewport_for_tile_priority = gfx::ScaleToEnclosingRect(
370       viewport_rect_for_tile_priority_in_content_space_, max_contents_scale);
371 
372   size_t missing_tile_count = 0u;
373   size_t on_demand_missing_tile_count = 0u;
374   only_used_low_res_last_append_quads_ = true;
375   gfx::Rect scaled_recorded_viewport = gfx::ScaleToEnclosingRect(
376       raster_source_->RecordedViewport(), max_contents_scale);
377   for (PictureLayerTilingSet::CoverageIterator iter(
378            tilings_.get(), max_contents_scale,
379            shared_quad_state->visible_quad_layer_rect, ideal_contents_scale_);
380        iter; ++iter) {
381     gfx::Rect geometry_rect = iter.geometry_rect();
382     gfx::Rect visible_geometry_rect =
383         scaled_occlusion.GetUnoccludedContentRect(geometry_rect);
384 
385     gfx::Rect offset_geometry_rect = geometry_rect;
386     offset_geometry_rect.Offset(quad_offset);
387     gfx::Rect offset_visible_geometry_rect = visible_geometry_rect;
388     offset_visible_geometry_rect.Offset(quad_offset);
389 
390     bool needs_blending = !contents_opaque();
391     if (visible_geometry_rect.IsEmpty())
392       continue;
393 
394     int64_t visible_geometry_area =
395         static_cast<int64_t>(visible_geometry_rect.width()) *
396         visible_geometry_rect.height();
397     append_quads_data->visible_layer_area += visible_geometry_area;
398 
399     bool has_draw_quad = false;
400     if (*iter && iter->draw_info().IsReadyToDraw()) {
401       const TileDrawInfo& draw_info = iter->draw_info();
402 
403       switch (draw_info.mode()) {
404         case TileDrawInfo::RESOURCE_MODE: {
405           gfx::RectF texture_rect = iter.texture_rect();
406 
407           // The raster_contents_scale_ is the best scale that the layer is
408           // trying to produce, even though it may not be ideal. Since that's
409           // the best the layer can promise in the future, consider those as
410           // complete. But if a tile is ideal scale, we don't want to consider
411           // it incomplete and trying to replace it with a tile at a worse
412           // scale.
413           if (iter->contents_scale_key() != raster_contents_scale_ &&
414               iter->contents_scale_key() != ideal_contents_scale_ &&
415               geometry_rect.Intersects(scaled_viewport_for_tile_priority)) {
416             append_quads_data->num_incomplete_tiles++;
417           }
418 
419           auto* quad =
420               render_pass->CreateAndAppendDrawQuad<viz::TileDrawQuad>();
421           quad->SetNew(
422               shared_quad_state, offset_geometry_rect,
423               offset_visible_geometry_rect, needs_blending,
424               draw_info.resource_id_for_export(), texture_rect,
425               draw_info.resource_size(), draw_info.is_premultiplied(),
426               nearest_neighbor_,
427               !layer_tree_impl()->settings().enable_edge_anti_aliasing);
428           ValidateQuadResources(quad);
429           has_draw_quad = true;
430           break;
431         }
432         case TileDrawInfo::SOLID_COLOR_MODE: {
433           float alpha =
434               (SkColorGetA(draw_info.solid_color()) * (1.0f / 255.0f)) *
435               shared_quad_state->opacity;
436           if (alpha >= std::numeric_limits<float>::epsilon()) {
437             auto* quad =
438                 render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
439             quad->SetNew(
440                 shared_quad_state, offset_geometry_rect,
441                 offset_visible_geometry_rect, draw_info.solid_color(),
442                 !layer_tree_impl()->settings().enable_edge_anti_aliasing);
443             ValidateQuadResources(quad);
444           }
445           has_draw_quad = true;
446           break;
447         }
448         case TileDrawInfo::OOM_MODE:
449           break;  // Checkerboard.
450       }
451     }
452 
453     if (!has_draw_quad) {
454       // Checkerboard.
455       SkColor color = SafeOpaqueBackgroundColor();
456       if (ShowDebugBorders(DebugBorderType::LAYER)) {
457         // Fill the whole tile with the missing tile color.
458         color = DebugColors::DefaultCheckerboardColor();
459       }
460       auto* quad =
461           render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
462       quad->SetNew(shared_quad_state, offset_geometry_rect,
463                    offset_visible_geometry_rect, color, false);
464       ValidateQuadResources(quad);
465 
466       if (geometry_rect.Intersects(scaled_viewport_for_tile_priority)) {
467         append_quads_data->num_missing_tiles++;
468         ++missing_tile_count;
469       }
470       append_quads_data->checkerboarded_visible_content_area +=
471           visible_geometry_area;
472       // Intersect checkerboard rect with interest rect to generate rect where
473       // we checkerboarded and has recording. The area where we don't have
474       // recording is not necessarily a Rect, and its area is calculated using
475       // subtraction.
476       gfx::Rect visible_rect_has_recording = visible_geometry_rect;
477       visible_rect_has_recording.Intersect(scaled_recorded_viewport);
478       int64_t checkerboarded_has_recording_area =
479           static_cast<int64_t>(visible_rect_has_recording.width()) *
480           visible_rect_has_recording.height();
481       append_quads_data->checkerboarded_needs_raster_content_area +=
482           checkerboarded_has_recording_area;
483       append_quads_data->checkerboarded_no_recording_content_area +=
484           visible_geometry_area - checkerboarded_has_recording_area;
485       continue;
486     }
487 
488     if (iter.resolution() != HIGH_RESOLUTION) {
489       append_quads_data->approximated_visible_content_area +=
490           visible_geometry_area;
491     }
492 
493     // If we have a draw quad, but it's not low resolution, then
494     // mark that we've used something other than low res to draw.
495     if (iter.resolution() != LOW_RESOLUTION)
496       only_used_low_res_last_append_quads_ = false;
497 
498     if (last_append_quads_tilings_.empty() ||
499         last_append_quads_tilings_.back() != iter.CurrentTiling()) {
500       last_append_quads_tilings_.push_back(iter.CurrentTiling());
501     }
502   }
503 
504   // Adjust shared_quad_state with the quad_offset, since we've adjusted each
505   // quad we've appended by it.
506   shared_quad_state->quad_to_target_transform.Translate(-quad_offset);
507   shared_quad_state->quad_layer_rect.Offset(quad_offset);
508   shared_quad_state->visible_quad_layer_rect.Offset(quad_offset);
509 
510   if (missing_tile_count) {
511     TRACE_EVENT_INSTANT2("cc",
512                          "PictureLayerImpl::AppendQuads checkerboard",
513                          TRACE_EVENT_SCOPE_THREAD,
514                          "missing_tile_count",
515                          missing_tile_count,
516                          "on_demand_missing_tile_count",
517                          on_demand_missing_tile_count);
518   }
519 
520   // Aggressively remove any tilings that are not seen to save memory. Note
521   // that this is at the expense of doing cause more frequent re-painting. A
522   // better scheme would be to maintain a tighter visible_layer_rect for the
523   // finer tilings.
524   CleanUpTilingsOnActiveLayer(last_append_quads_tilings_);
525 }
526 
UpdateTiles()527 bool PictureLayerImpl::UpdateTiles() {
528   if (!CanHaveTilings()) {
529     ideal_page_scale_ = 0.f;
530     ideal_device_scale_ = 0.f;
531     ideal_contents_scale_ = 0.f;
532     ideal_source_scale_ = 0.f;
533     SanityCheckTilingState();
534     return false;
535   }
536 
537   // Remove any non-ideal tilings that were not used last time we generated
538   // quads to save memory and processing time. Note that pending tree should
539   // only have one or two tilings (high and low res), so only clean up the
540   // active layer. This cleans it up here in case AppendQuads didn't run.
541   // If it did run, this would not remove any additional tilings.
542   if (layer_tree_impl()->IsActiveTree())
543     CleanUpTilingsOnActiveLayer(last_append_quads_tilings_);
544 
545   UpdateIdealScales();
546 
547   if (!raster_contents_scale_ || ShouldAdjustRasterScale()) {
548     RecalculateRasterScales();
549     AddTilingsForRasterScale();
550   }
551 
552   if (layer_tree_impl()->IsActiveTree())
553     AddLowResolutionTilingIfNeeded();
554 
555   DCHECK(raster_page_scale_);
556   DCHECK(raster_device_scale_);
557   DCHECK(raster_source_scale_);
558   DCHECK(raster_contents_scale_);
559   DCHECK(low_res_raster_contents_scale_);
560 
561   was_screen_space_transform_animating_ =
562       draw_properties().screen_space_transform_is_animating;
563 
564   double current_frame_time_in_seconds =
565       (layer_tree_impl()->CurrentBeginFrameArgs().frame_time -
566        base::TimeTicks()).InSecondsF();
567   UpdateViewportRectForTilePriorityInContentSpace();
568 
569   // The tiling set can require tiles for activation any of the following
570   // conditions are true:
571   // - This layer produced a high-res or non-ideal-res tile last frame.
572   // - We're in requires high res to draw mode.
573   // - We're not in smoothness takes priority mode.
574   // To put different, the tiling set can't require tiles for activation if
575   // we're in smoothness mode and only used low-res or checkerboard to draw last
576   // frame and we don't need high res to draw.
577   //
578   // The reason for this is that we should be able to activate sooner and get a
579   // more up to date recording, so we don't run out of recording on the active
580   // tree.
581   // A layer must be a drawing layer for it to require tiles for activation.
582   bool can_require_tiles_for_activation = false;
583   if (contributes_to_drawn_render_surface()) {
584     can_require_tiles_for_activation =
585         !only_used_low_res_last_append_quads_ || RequiresHighResToDraw() ||
586         !layer_tree_impl()->SmoothnessTakesPriority();
587   }
588 
589   static const base::NoDestructor<Occlusion> kEmptyOcclusion;
590   const Occlusion& occlusion_in_content_space =
591       layer_tree_impl()->settings().use_occlusion_for_tile_prioritization
592           ? draw_properties().occlusion_in_content_space
593           : *kEmptyOcclusion;
594 
595   // Pass |occlusion_in_content_space| for |occlusion_in_layer_space| since
596   // they are the same space in picture layer, as contents scale is always 1.
597   bool updated = tilings_->UpdateTilePriorities(
598       viewport_rect_for_tile_priority_in_content_space_, ideal_contents_scale_,
599       current_frame_time_in_seconds, occlusion_in_content_space,
600       can_require_tiles_for_activation);
601   return updated;
602 }
603 
UpdateViewportRectForTilePriorityInContentSpace()604 void PictureLayerImpl::UpdateViewportRectForTilePriorityInContentSpace() {
605   // If visible_layer_rect() is empty or viewport_rect_for_tile_priority is
606   // set to be different from the device viewport, try to inverse project the
607   // viewport into layer space and use that. Otherwise just use
608   // visible_layer_rect().
609   gfx::Rect visible_rect_in_content_space = visible_layer_rect();
610   gfx::Rect viewport_rect_for_tile_priority =
611       layer_tree_impl()->ViewportRectForTilePriority();
612   if (visible_rect_in_content_space.IsEmpty() ||
613       layer_tree_impl()->GetDeviceViewport() !=
614           viewport_rect_for_tile_priority) {
615     gfx::Transform view_to_layer(gfx::Transform::kSkipInitialization);
616     if (ScreenSpaceTransform().GetInverse(&view_to_layer)) {
617       // Transform from view space to content space.
618       visible_rect_in_content_space = MathUtil::ProjectEnclosingClippedRect(
619           view_to_layer, viewport_rect_for_tile_priority);
620 
621       // We have to allow for a viewport that is outside of the layer bounds in
622       // order to compute tile priorities correctly for offscreen content that
623       // is going to make it on screen. However, we also have to limit the
624       // viewport since it can be very large due to screen_space_transforms. As
625       // a heuristic, we clip to bounds padded by skewport_extrapolation_limit *
626       // maximum tiling scale, since this should allow sufficient room for
627       // skewport calculations.
628       gfx::Rect padded_bounds(bounds());
629       int padding_amount = layer_tree_impl()
630                                ->settings()
631                                .skewport_extrapolation_limit_in_screen_pixels *
632                            MaximumTilingContentsScale();
633       padded_bounds.Inset(-padding_amount, -padding_amount);
634       visible_rect_in_content_space =
635           SafeIntersectRects(visible_rect_in_content_space, padded_bounds);
636     }
637   }
638   viewport_rect_for_tile_priority_in_content_space_ =
639       visible_rect_in_content_space;
640 }
641 
GetPendingOrActiveTwinLayer() const642 PictureLayerImpl* PictureLayerImpl::GetPendingOrActiveTwinLayer() const {
643   if (!twin_layer_ || !twin_layer_->IsOnActiveOrPendingTree())
644     return nullptr;
645   return twin_layer_;
646 }
647 
UpdateRasterSource(scoped_refptr<RasterSource> raster_source,Region * new_invalidation,const PictureLayerTilingSet * pending_set,const PaintWorkletRecordMap * pending_paint_worklet_records)648 void PictureLayerImpl::UpdateRasterSource(
649     scoped_refptr<RasterSource> raster_source,
650     Region* new_invalidation,
651     const PictureLayerTilingSet* pending_set,
652     const PaintWorkletRecordMap* pending_paint_worklet_records) {
653   // The bounds and the pile size may differ if the pile wasn't updated (ie.
654   // PictureLayer::Update didn't happen). In that case the pile will be empty.
655   DCHECK(raster_source->GetSize().IsEmpty() ||
656          bounds() == raster_source->GetSize())
657       << " bounds " << bounds().ToString() << " pile "
658       << raster_source->GetSize().ToString();
659 
660   // We have an updated recording if the DisplayItemList in the new RasterSource
661   // is different.
662   const bool recording_updated =
663       !raster_source_ || raster_source_->GetDisplayItemList() !=
664                              raster_source->GetDisplayItemList();
665 
666   // Unregister for all images on the current raster source, if the recording
667   // was updated.
668   if (recording_updated) {
669     UnregisterAnimatedImages();
670 
671     // When the display list changes, the set of PaintWorklets may also change.
672     if (pending_paint_worklet_records) {
673       paint_worklet_records_ = *pending_paint_worklet_records;
674     } else {
675       if (raster_source->GetDisplayItemList()) {
676         SetPaintWorkletInputs(raster_source->GetDisplayItemList()
677                                   ->discardable_image_map()
678                                   .paint_worklet_inputs());
679       } else {
680         SetPaintWorkletInputs({});
681       }
682     }
683 
684     // If the MSAA sample count has changed, we need to re-raster the complete
685     // layer.
686     if (raster_source_) {
687       const auto& current_display_item_list =
688           raster_source_->GetDisplayItemList();
689       const auto& new_display_item_list = raster_source->GetDisplayItemList();
690       if (current_display_item_list && new_display_item_list) {
691         bool needs_full_invalidation =
692             layer_tree_impl()->GetMSAASampleCountForRaster(
693                 current_display_item_list) !=
694             layer_tree_impl()->GetMSAASampleCountForRaster(
695                 new_display_item_list);
696         needs_full_invalidation |=
697             current_display_item_list->discardable_image_map()
698                 .contains_only_srgb_images() !=
699             new_display_item_list->discardable_image_map()
700                 .contains_only_srgb_images();
701         if (needs_full_invalidation)
702           new_invalidation->Union(gfx::Rect(raster_source->GetSize()));
703       }
704     }
705   }
706 
707   // The |raster_source_| is initially null, so have to check for that for the
708   // first frame.
709   bool could_have_tilings = raster_source_.get() && CanHaveTilings();
710   raster_source_.swap(raster_source);
711 
712   // Register images from the new raster source, if the recording was updated.
713   // TODO(khushalsagar): UMA the number of animated images in layer?
714   if (recording_updated)
715     RegisterAnimatedImages();
716 
717   // The |new_invalidation| must be cleared before updating tilings since they
718   // access the invalidation through the PictureLayerTilingClient interface.
719   invalidation_.Clear();
720   invalidation_.Swap(new_invalidation);
721 
722   bool can_have_tilings = CanHaveTilings();
723   DCHECK(!pending_set ||
724          can_have_tilings == GetPendingOrActiveTwinLayer()->CanHaveTilings());
725 
726   // Need to call UpdateTiles again if CanHaveTilings changed.
727   if (could_have_tilings != can_have_tilings)
728     layer_tree_impl()->set_needs_update_draw_properties();
729 
730   if (!can_have_tilings) {
731     RemoveAllTilings();
732     return;
733   }
734 
735   // We could do this after doing UpdateTiles, which would avoid doing this for
736   // tilings that are going to disappear on the pending tree (if scale changed).
737   // But that would also be more complicated, so we just do it here for now.
738   //
739   // TODO(crbug.com/843787): If the LayerTreeFrameSink is lost, and we activate,
740   // this ends up running with the old LayerTreeFrameSink, or possibly with a
741   // null LayerTreeFrameSink, which can give incorrect results or maybe crash.
742   if (pending_set) {
743     tilings_->UpdateTilingsToCurrentRasterSourceForActivation(
744         raster_source_, pending_set, invalidation_, MinimumContentsScale(),
745         MaximumContentsScale());
746   } else {
747     tilings_->UpdateTilingsToCurrentRasterSourceForCommit(
748         raster_source_, invalidation_, MinimumContentsScale(),
749         MaximumContentsScale());
750     // We're in a commit, make sure to update the state of the checker image
751     // tracker with the new async attribute data.
752     layer_tree_impl()->UpdateImageDecodingHints(
753         raster_source_->TakeDecodingModeMap());
754   }
755 }
756 
UpdateCanUseLCDTextAfterCommit()757 bool PictureLayerImpl::UpdateCanUseLCDTextAfterCommit() {
758   DCHECK(layer_tree_impl()->IsSyncTree());
759 
760   // Once we disable lcd text, we don't re-enable it.
761   if (!can_use_lcd_text_)
762     return false;
763 
764   if (can_use_lcd_text_ == CanUseLCDText())
765     return false;
766 
767   can_use_lcd_text_ = CanUseLCDText();
768   // Synthetically invalidate everything.
769   gfx::Rect bounds_rect(bounds());
770   invalidation_ = Region(bounds_rect);
771   tilings_->Invalidate(invalidation_);
772   UnionUpdateRect(bounds_rect);
773   return true;
774 }
775 
NotifyTileStateChanged(const Tile * tile)776 void PictureLayerImpl::NotifyTileStateChanged(const Tile* tile) {
777   if (layer_tree_impl()->IsActiveTree())
778     damage_rect_.Union(tile->enclosing_layer_rect());
779   if (tile->draw_info().NeedsRaster()) {
780     PictureLayerTiling* tiling =
781         tilings_->FindTilingWithScaleKey(tile->contents_scale_key());
782     if (tiling)
783       tiling->set_all_tiles_done(false);
784   }
785 }
786 
GetDamageRect() const787 gfx::Rect PictureLayerImpl::GetDamageRect() const {
788   return damage_rect_;
789 }
790 
ResetChangeTracking()791 void PictureLayerImpl::ResetChangeTracking() {
792   LayerImpl::ResetChangeTracking();
793   damage_rect_.SetRect(0, 0, 0, 0);
794 }
795 
DidBeginTracing()796 void PictureLayerImpl::DidBeginTracing() {
797   raster_source_->DidBeginTracing();
798 }
799 
ReleaseResources()800 void PictureLayerImpl::ReleaseResources() {
801   tilings_->ReleaseAllResources();
802   ResetRasterScale();
803 }
804 
ReleaseTileResources()805 void PictureLayerImpl::ReleaseTileResources() {
806   // All resources are tile resources.
807   ReleaseResources();
808 }
809 
RecreateTileResources()810 void PictureLayerImpl::RecreateTileResources() {
811   // Recreate tilings with new settings, since some of those might change when
812   // we release resources.
813   tilings_ = CreatePictureLayerTilingSet();
814 }
815 
GetInvalidationRegionForDebugging()816 Region PictureLayerImpl::GetInvalidationRegionForDebugging() {
817   // |invalidation_| gives the invalidation contained in the source frame, but
818   // is not cleared after drawing from the layer. However, update_rect() is
819   // cleared once the invalidation is drawn, which is useful for debugging
820   // visualizations. This method intersects the two to give a more exact
821   // representation of what was invalidated that is cleared after drawing.
822   return IntersectRegions(invalidation_, update_rect());
823 }
824 
CreateTile(const Tile::CreateInfo & info)825 std::unique_ptr<Tile> PictureLayerImpl::CreateTile(
826     const Tile::CreateInfo& info) {
827   int flags = 0;
828 
829   // We don't handle solid color single texture masks for backdrop filters,
830   // so we shouldn't bother analyzing those.
831   // Otherwise, always analyze to maximize memory savings.
832   if (!is_backdrop_filter_mask_)
833     flags = Tile::USE_PICTURE_ANALYSIS;
834 
835   if (contents_opaque())
836     flags |= Tile::IS_OPAQUE;
837 
838   return layer_tree_impl()->tile_manager()->CreateTile(
839       info, id(), layer_tree_impl()->source_frame_number(), flags,
840       can_use_lcd_text_);
841 }
842 
GetPendingInvalidation()843 const Region* PictureLayerImpl::GetPendingInvalidation() {
844   if (layer_tree_impl()->IsPendingTree())
845     return &invalidation_;
846   if (layer_tree_impl()->IsRecycleTree())
847     return nullptr;
848   DCHECK(layer_tree_impl()->IsActiveTree());
849   if (PictureLayerImpl* twin_layer = GetPendingOrActiveTwinLayer())
850     return &twin_layer->invalidation_;
851   return nullptr;
852 }
853 
GetPendingOrActiveTwinTiling(const PictureLayerTiling * tiling) const854 const PictureLayerTiling* PictureLayerImpl::GetPendingOrActiveTwinTiling(
855     const PictureLayerTiling* tiling) const {
856   PictureLayerImpl* twin_layer = GetPendingOrActiveTwinLayer();
857   if (!twin_layer)
858     return nullptr;
859   const PictureLayerTiling* twin_tiling =
860       twin_layer->tilings_->FindTilingWithScaleKey(
861           tiling->contents_scale_key());
862   if (twin_tiling &&
863       twin_tiling->raster_transform() == tiling->raster_transform())
864     return twin_tiling;
865   return nullptr;
866 }
867 
RequiresHighResToDraw() const868 bool PictureLayerImpl::RequiresHighResToDraw() const {
869   return layer_tree_impl()->RequiresHighResToDraw();
870 }
871 
GetPaintWorkletRecords() const872 const PaintWorkletRecordMap& PictureLayerImpl::GetPaintWorkletRecords() const {
873   return paint_worklet_records_;
874 }
875 
GetEnclosingRectInTargetSpace() const876 gfx::Rect PictureLayerImpl::GetEnclosingRectInTargetSpace() const {
877   return GetScaledEnclosingRectInTargetSpace(MaximumTilingContentsScale());
878 }
879 
ShouldAnimate(PaintImage::Id paint_image_id) const880 bool PictureLayerImpl::ShouldAnimate(PaintImage::Id paint_image_id) const {
881   // If we are registered with the animation controller, which queries whether
882   // the image should be animated, then we must have recordings with this image.
883   DCHECK(raster_source_);
884   DCHECK(raster_source_->GetDisplayItemList());
885   DCHECK(
886       !raster_source_->GetDisplayItemList()->discardable_image_map().empty());
887 
888   // Only animate images for layers which HasValidTilePriorities. This check is
889   // important for 2 reasons:
890   // 1) It avoids doing additional work for layers we don't plan to rasterize
891   //    and/or draw. The updated state will be pulled by the animation system
892   //    if the draw properties change.
893   // 2) It eliminates considering layers on the recycle tree. Once the pending
894   //    tree is activated, the layers on the recycle tree remain registered as
895   //    animation drivers, but should not drive animations since they don't have
896   //    updated draw properties.
897   //
898   //  Additionally only animate images which are on-screen, animations are
899   //  paused once they are not visible.
900   if (!HasValidTilePriorities())
901     return false;
902 
903   const auto& rects = raster_source_->GetDisplayItemList()
904                           ->discardable_image_map()
905                           .GetRectsForImage(paint_image_id);
906   for (const auto& r : rects.container()) {
907     if (r.Intersects(visible_layer_rect()))
908       return true;
909   }
910   return false;
911 }
912 
CalculateTileSize(const gfx::Size & content_bounds)913 gfx::Size PictureLayerImpl::CalculateTileSize(const gfx::Size& content_bounds) {
914   content_bounds_ = content_bounds;
915   return tile_size_calculator_.CalculateTileSize();
916 }
917 
GetContentsResourceId(viz::ResourceId * resource_id,gfx::Size * resource_size,gfx::SizeF * resource_uv_size) const918 void PictureLayerImpl::GetContentsResourceId(
919     viz::ResourceId* resource_id,
920     gfx::Size* resource_size,
921     gfx::SizeF* resource_uv_size) const {
922   // We need contents resource for backdrop filter masks only.
923   if (!is_backdrop_filter_mask()) {
924     *resource_id = 0;
925     return;
926   }
927 
928   // The bounds and the pile size may differ if the pile wasn't updated (ie.
929   // PictureLayer::Update didn't happen). In that case the pile will be empty.
930   DCHECK(raster_source_->GetSize().IsEmpty() ||
931          bounds() == raster_source_->GetSize())
932       << " bounds " << bounds().ToString() << " pile "
933       << raster_source_->GetSize().ToString();
934   float dest_scale = MaximumTilingContentsScale();
935   gfx::Rect content_rect =
936       gfx::ScaleToEnclosingRect(gfx::Rect(bounds()), dest_scale);
937   PictureLayerTilingSet::CoverageIterator iter(
938       tilings_.get(), dest_scale, content_rect, ideal_contents_scale_);
939 
940   // Mask resource not ready yet.
941   if (!iter || !*iter) {
942     *resource_id = 0;
943     return;
944   }
945 
946   // Masks only supported if they fit on exactly one tile.
947   DCHECK(iter.geometry_rect() == content_rect)
948       << "iter rect " << iter.geometry_rect().ToString() << " content rect "
949       << content_rect.ToString();
950 
951   const TileDrawInfo& draw_info = iter->draw_info();
952   if (!draw_info.IsReadyToDraw() ||
953       draw_info.mode() != TileDrawInfo::RESOURCE_MODE) {
954     *resource_id = 0;
955     return;
956   }
957 
958   *resource_id = draw_info.resource_id_for_export();
959   *resource_size = draw_info.resource_size();
960   // |resource_uv_size| represents the range of UV coordinates that map to the
961   // content being drawn. Typically, we draw to the entire texture, so these
962   // coordinates are (1.0f, 1.0f). However, if we are rasterizing to an
963   // over-large texture, this size will be smaller, mapping to the subset of the
964   // texture being used.
965   gfx::SizeF requested_tile_size =
966       gfx::SizeF(iter->tiling()->tiling_data()->tiling_size());
967   DCHECK_LE(requested_tile_size.width(), draw_info.resource_size().width());
968   DCHECK_LE(requested_tile_size.height(), draw_info.resource_size().height());
969   *resource_uv_size = gfx::SizeF(
970       requested_tile_size.width() / draw_info.resource_size().width(),
971       requested_tile_size.height() / draw_info.resource_size().height());
972 }
973 
SetNearestNeighbor(bool nearest_neighbor)974 void PictureLayerImpl::SetNearestNeighbor(bool nearest_neighbor) {
975   if (nearest_neighbor_ == nearest_neighbor)
976     return;
977 
978   nearest_neighbor_ = nearest_neighbor;
979   NoteLayerPropertyChanged();
980 }
981 
SetUseTransformedRasterization(bool use)982 void PictureLayerImpl::SetUseTransformedRasterization(bool use) {
983   if (use_transformed_rasterization_ == use)
984     return;
985 
986   use_transformed_rasterization_ = use;
987   NoteLayerPropertyChanged();
988 }
989 
SetDirectlyCompositedImageSize(base::Optional<gfx::Size> size)990 void PictureLayerImpl::SetDirectlyCompositedImageSize(
991     base::Optional<gfx::Size> size) {
992   if (directly_composited_image_size_ == size)
993     return;
994 
995   directly_composited_image_size_ = size;
996   NoteLayerPropertyChanged();
997 }
998 
GetDirectlyCompositedImageRasterScale() const999 float PictureLayerImpl::GetDirectlyCompositedImageRasterScale() const {
1000   float x = static_cast<float>(directly_composited_image_size_->width()) /
1001             bounds().width();
1002   float y = static_cast<float>(directly_composited_image_size_->height()) /
1003             bounds().height();
1004   DCHECK_EQ(x, 1.f);
1005   DCHECK_EQ(y, 1.f);
1006   return GetPreferredRasterScale(gfx::Vector2dF(x, y));
1007 }
1008 
AddTiling(const gfx::AxisTransform2d & contents_transform)1009 PictureLayerTiling* PictureLayerImpl::AddTiling(
1010     const gfx::AxisTransform2d& contents_transform) {
1011   DCHECK(CanHaveTilings());
1012   DCHECK_GE(contents_transform.scale(), MinimumContentsScale());
1013   DCHECK_LE(contents_transform.scale(), MaximumContentsScale());
1014   DCHECK(raster_source_->HasRecordings());
1015   return tilings_->AddTiling(contents_transform, raster_source_);
1016 }
1017 
RemoveAllTilings()1018 void PictureLayerImpl::RemoveAllTilings() {
1019   tilings_->RemoveAllTilings();
1020   // If there are no tilings, then raster scales are no longer meaningful.
1021   ResetRasterScale();
1022 }
1023 
AddTilingsForRasterScale()1024 void PictureLayerImpl::AddTilingsForRasterScale() {
1025   // Reset all resolution enums on tilings, we'll be setting new values in this
1026   // function.
1027   tilings_->MarkAllTilingsNonIdeal();
1028 
1029   PictureLayerTiling* high_res =
1030       tilings_->FindTilingWithScaleKey(raster_contents_scale_);
1031   // Note: This function is always invoked when raster scale is recomputed,
1032   // but not necessarily changed. This means raster translation update is also
1033   // always done when there are significant changes that triggered raster scale
1034   // recomputation.
1035   gfx::Vector2dF raster_translation =
1036       CalculateRasterTranslation(raster_contents_scale_);
1037   if (high_res &&
1038       high_res->raster_transform().translation() != raster_translation) {
1039     tilings_->Remove(high_res);
1040     high_res = nullptr;
1041   }
1042   if (!high_res) {
1043     // We always need a high res tiling, so create one if it doesn't exist.
1044     high_res = AddTiling(
1045         gfx::AxisTransform2d(raster_contents_scale_, raster_translation));
1046   } else if (high_res->may_contain_low_resolution_tiles()) {
1047     // If the tiling we find here was LOW_RESOLUTION previously, it may not be
1048     // fully rastered, so destroy the old tiles.
1049     high_res->Reset();
1050     // Reset the flag now that we'll make it high res, it will have fully
1051     // rastered content.
1052     high_res->reset_may_contain_low_resolution_tiles();
1053   }
1054   high_res->set_resolution(HIGH_RESOLUTION);
1055 
1056   if (layer_tree_impl()->IsPendingTree()) {
1057     // On the pending tree, drop any tilings that are non-ideal since we don't
1058     // need them to activate anyway.
1059     tilings_->RemoveNonIdealTilings();
1060   }
1061 
1062   SanityCheckTilingState();
1063 }
1064 
ShouldAdjustRasterScale() const1065 bool PictureLayerImpl::ShouldAdjustRasterScale() const {
1066   if (directly_composited_image_size_) {
1067     float desired_raster_scale = GetDirectlyCompositedImageRasterScale();
1068     float max_scale = std::max(desired_raster_scale, MinimumContentsScale());
1069     if (raster_source_scale_ < std::min(ideal_source_scale_, max_scale))
1070       return true;
1071     if (raster_source_scale_ > 4 * ideal_source_scale_)
1072       return true;
1073     return false;
1074   }
1075 
1076   if (was_screen_space_transform_animating_ !=
1077       draw_properties().screen_space_transform_is_animating)
1078     return true;
1079 
1080   bool is_pinching = layer_tree_impl()->PinchGestureActive();
1081   if (is_pinching && raster_page_scale_) {
1082     // We change our raster scale when it is:
1083     // - Higher than ideal (need a lower-res tiling available)
1084     // - Too far from ideal (need a higher-res tiling available)
1085     float ratio = ideal_page_scale_ / raster_page_scale_;
1086     if (raster_page_scale_ > ideal_page_scale_ ||
1087         ratio > kMaxScaleRatioDuringPinch)
1088       return true;
1089   }
1090 
1091   if (!is_pinching) {
1092     // When not pinching, match the ideal page scale factor.
1093     if (raster_page_scale_ != ideal_page_scale_)
1094       return true;
1095   }
1096 
1097   // Always match the ideal device scale factor.
1098   if (raster_device_scale_ != ideal_device_scale_)
1099     return true;
1100 
1101   if (raster_contents_scale_ > MaximumContentsScale())
1102     return true;
1103   if (raster_contents_scale_ < MinimumContentsScale())
1104     return true;
1105 
1106   // Don't change the raster scale if any of the following are true:
1107   //  - We have an animating transform.
1108   //  - The raster scale is already ideal.
1109   if (draw_properties().screen_space_transform_is_animating ||
1110       raster_source_scale_ == ideal_source_scale_) {
1111     return false;
1112   }
1113 
1114   // Don't update will-change: transform layers if the raster contents scale is
1115   // at least the native scale (otherwise, we'd need to clamp it).
1116   if (has_will_change_transform_hint() &&
1117       raster_contents_scale_ >= raster_page_scale_ * raster_device_scale_) {
1118     return false;
1119   }
1120 
1121   // Match the raster scale in all other cases.
1122   return true;
1123 }
1124 
AddLowResolutionTilingIfNeeded()1125 void PictureLayerImpl::AddLowResolutionTilingIfNeeded() {
1126   DCHECK(layer_tree_impl()->IsActiveTree());
1127 
1128   if (!layer_tree_impl()->create_low_res_tiling())
1129     return;
1130 
1131   // We should have a high resolution tiling at raster_contents_scale, so if the
1132   // low res one is the same then we shouldn't try to override this tiling by
1133   // marking it as a low res.
1134   if (raster_contents_scale_ == low_res_raster_contents_scale_)
1135     return;
1136 
1137   PictureLayerTiling* low_res =
1138       tilings_->FindTilingWithScaleKey(low_res_raster_contents_scale_);
1139   DCHECK(!low_res || low_res->resolution() != HIGH_RESOLUTION);
1140 
1141   // Only create new low res tilings when the transform is static.  This
1142   // prevents wastefully creating a paired low res tiling for every new high
1143   // res tiling during a pinch or a CSS animation.
1144   bool is_pinching = layer_tree_impl()->PinchGestureActive();
1145   bool is_animating = draw_properties().screen_space_transform_is_animating;
1146   if (!is_pinching && !is_animating) {
1147     if (!low_res)
1148       low_res = AddTiling(gfx::AxisTransform2d(low_res_raster_contents_scale_,
1149                                                gfx::Vector2dF()));
1150     low_res->set_resolution(LOW_RESOLUTION);
1151   }
1152 }
1153 
RecalculateRasterScales()1154 void PictureLayerImpl::RecalculateRasterScales() {
1155   if (directly_composited_image_size_) {
1156     if (!raster_source_scale_)
1157       raster_source_scale_ = GetDirectlyCompositedImageRasterScale();
1158 
1159     float min_scale = MinimumContentsScale();
1160     float desired_raster_scale = GetDirectlyCompositedImageRasterScale();
1161     float max_scale = std::max(desired_raster_scale, MinimumContentsScale());
1162     float clamped_ideal_source_scale =
1163         base::ClampToRange(ideal_source_scale_, min_scale, max_scale);
1164 
1165     while (raster_source_scale_ < clamped_ideal_source_scale)
1166       raster_source_scale_ *= 2.f;
1167     while (raster_source_scale_ > 4 * clamped_ideal_source_scale)
1168       raster_source_scale_ /= 2.f;
1169 
1170     raster_source_scale_ =
1171         base::ClampToRange(raster_source_scale_, min_scale, max_scale);
1172 
1173     raster_page_scale_ = 1.f;
1174     raster_device_scale_ = 1.f;
1175     raster_contents_scale_ = raster_source_scale_;
1176     low_res_raster_contents_scale_ = raster_contents_scale_;
1177     return;
1178   }
1179 
1180   float old_raster_contents_scale = raster_contents_scale_;
1181   float old_raster_page_scale = raster_page_scale_;
1182 
1183   raster_device_scale_ = ideal_device_scale_;
1184   raster_page_scale_ = ideal_page_scale_;
1185   raster_source_scale_ = ideal_source_scale_;
1186   raster_contents_scale_ = ideal_contents_scale_;
1187 
1188   // During pinch we completely ignore the current ideal scale, and just use
1189   // a multiple of the previous scale.
1190   bool is_pinching = layer_tree_impl()->PinchGestureActive();
1191   if (is_pinching && old_raster_contents_scale) {
1192     // See ShouldAdjustRasterScale:
1193     // - When zooming out, preemptively create new tiling at lower resolution.
1194     // - When zooming in, approximate ideal using multiple of kMaxScaleRatio.
1195     bool zooming_out = old_raster_page_scale > ideal_page_scale_;
1196     float desired_contents_scale = old_raster_contents_scale;
1197     if (zooming_out) {
1198       while (desired_contents_scale > ideal_contents_scale_)
1199         desired_contents_scale /= kMaxScaleRatioDuringPinch;
1200     } else {
1201       while (desired_contents_scale < ideal_contents_scale_)
1202         desired_contents_scale *= kMaxScaleRatioDuringPinch;
1203     }
1204     raster_contents_scale_ = tilings_->GetSnappedContentsScaleKey(
1205         desired_contents_scale, kSnapToExistingTilingRatio);
1206     raster_page_scale_ =
1207         raster_contents_scale_ / raster_device_scale_ / raster_source_scale_;
1208   }
1209 
1210   // We rasterize at the maximum scale that will occur during the animation, if
1211   // the maximum scale is known. However we want to avoid excessive memory use.
1212   // If the scale is smaller than what we would choose otherwise, then it's
1213   // always better off for us memory-wise. But otherwise, we don't choose a
1214   // scale at which this layer's rastered content would become larger than the
1215   // viewport.
1216   if (draw_properties().screen_space_transform_is_animating) {
1217     bool can_raster_at_maximum_scale = false;
1218     bool should_raster_at_starting_scale = false;
1219     CombinedAnimationScale animation_scales =
1220         layer_tree_impl()->property_trees()->GetAnimationScales(
1221             transform_tree_index(), layer_tree_impl());
1222     float maximum_scale = animation_scales.maximum_animation_scale;
1223     float starting_scale = animation_scales.starting_animation_scale;
1224     if (maximum_scale != kNotScaled) {
1225       gfx::Size bounds_at_maximum_scale =
1226           gfx::ScaleToCeiledSize(raster_source_->GetSize(), maximum_scale);
1227       int64_t maximum_area =
1228           static_cast<int64_t>(bounds_at_maximum_scale.width()) *
1229           static_cast<int64_t>(bounds_at_maximum_scale.height());
1230       gfx::Size viewport = layer_tree_impl()->GetDeviceViewport().size();
1231 
1232       // Use the square of the maximum viewport dimension direction, to
1233       // compensate for viewports with different aspect ratios.
1234       int64_t max_viewport_dimension =
1235           std::max(static_cast<int64_t>(viewport.width()),
1236                    static_cast<int64_t>(viewport.height()));
1237       int64_t squared_viewport_area =
1238           max_viewport_dimension * max_viewport_dimension;
1239 
1240       if (maximum_area <= squared_viewport_area)
1241         can_raster_at_maximum_scale = true;
1242     }
1243     if (starting_scale != kNotScaled && starting_scale > maximum_scale) {
1244       gfx::Size bounds_at_starting_scale =
1245           gfx::ScaleToCeiledSize(raster_source_->GetSize(), starting_scale);
1246       int64_t start_area =
1247           static_cast<int64_t>(bounds_at_starting_scale.width()) *
1248           static_cast<int64_t>(bounds_at_starting_scale.height());
1249       gfx::Size viewport = layer_tree_impl()->GetDeviceViewport().size();
1250       int64_t viewport_area = static_cast<int64_t>(viewport.width()) *
1251                               static_cast<int64_t>(viewport.height());
1252       if (start_area <= viewport_area)
1253         should_raster_at_starting_scale = true;
1254     }
1255     // Use the computed scales for the raster scale directly, do not try to use
1256     // the ideal scale here. The current ideal scale may be way too large in the
1257     // case of an animation with scale, and will be constantly changing.
1258     if (should_raster_at_starting_scale)
1259       raster_contents_scale_ = starting_scale;
1260     else if (can_raster_at_maximum_scale)
1261       raster_contents_scale_ = maximum_scale;
1262     else
1263       raster_contents_scale_ = 1.f * ideal_page_scale_ * ideal_device_scale_;
1264   }
1265 
1266   // Clamp will-change: transform layers to be at least the native scale.
1267   if (has_will_change_transform_hint()) {
1268     float min_desired_scale = raster_device_scale_ * raster_page_scale_;
1269     if (raster_contents_scale_ < min_desired_scale) {
1270       raster_contents_scale_ = min_desired_scale;
1271       raster_page_scale_ = 1.f;
1272     }
1273   }
1274 
1275   raster_contents_scale_ =
1276       std::max(raster_contents_scale_, MinimumContentsScale());
1277   raster_contents_scale_ =
1278       std::min(raster_contents_scale_, MaximumContentsScale());
1279   DCHECK_GE(raster_contents_scale_, MinimumContentsScale());
1280   DCHECK_LE(raster_contents_scale_, MaximumContentsScale());
1281 
1282   // If this layer would create zero or one tiles at this content scale,
1283   // don't create a low res tiling.
1284   gfx::Size raster_bounds =
1285       gfx::ScaleToCeiledSize(raster_source_->GetSize(), raster_contents_scale_);
1286   gfx::Size tile_size = CalculateTileSize(raster_bounds);
1287   bool tile_covers_bounds = tile_size.width() >= raster_bounds.width() &&
1288                             tile_size.height() >= raster_bounds.height();
1289   if (tile_size.IsEmpty() || tile_covers_bounds) {
1290     low_res_raster_contents_scale_ = raster_contents_scale_;
1291     return;
1292   }
1293 
1294   float low_res_factor =
1295       layer_tree_impl()->settings().low_res_contents_scale_factor;
1296   low_res_raster_contents_scale_ =
1297       std::max(raster_contents_scale_ * low_res_factor, MinimumContentsScale());
1298   DCHECK_LE(low_res_raster_contents_scale_, raster_contents_scale_);
1299   DCHECK_GE(low_res_raster_contents_scale_, MinimumContentsScale());
1300   DCHECK_LE(low_res_raster_contents_scale_, MaximumContentsScale());
1301 }
1302 
CleanUpTilingsOnActiveLayer(const std::vector<PictureLayerTiling * > & used_tilings)1303 void PictureLayerImpl::CleanUpTilingsOnActiveLayer(
1304     const std::vector<PictureLayerTiling*>& used_tilings) {
1305   DCHECK(layer_tree_impl()->IsActiveTree());
1306   if (tilings_->num_tilings() == 0)
1307     return;
1308 
1309   float min_acceptable_high_res_scale = std::min(
1310       raster_contents_scale_, ideal_contents_scale_);
1311   float max_acceptable_high_res_scale = std::max(
1312       raster_contents_scale_, ideal_contents_scale_);
1313 
1314   PictureLayerImpl* twin = GetPendingOrActiveTwinLayer();
1315   if (twin && twin->CanHaveTilings()) {
1316     min_acceptable_high_res_scale =
1317         std::min({min_acceptable_high_res_scale, twin->raster_contents_scale_,
1318                   twin->ideal_contents_scale_});
1319     max_acceptable_high_res_scale =
1320         std::max({max_acceptable_high_res_scale, twin->raster_contents_scale_,
1321                   twin->ideal_contents_scale_});
1322   }
1323 
1324   PictureLayerTilingSet* twin_set = twin ? twin->tilings_.get() : nullptr;
1325   tilings_->CleanUpTilings(min_acceptable_high_res_scale,
1326                            max_acceptable_high_res_scale, used_tilings,
1327                            twin_set);
1328   DCHECK_GT(tilings_->num_tilings(), 0u);
1329   SanityCheckTilingState();
1330 }
1331 
CalculateRasterTranslation(float raster_scale)1332 gfx::Vector2dF PictureLayerImpl::CalculateRasterTranslation(
1333     float raster_scale) {
1334   if (!use_transformed_rasterization_)
1335     return gfx::Vector2dF();
1336 
1337   gfx::Transform draw_transform = DrawTransform();
1338   // TODO(enne): for performance reasons, we should only have a raster
1339   // translation when the screen space transform is not animating.  We try to
1340   // avoid this elsewhere but it still happens: http://crbug.com/778440
1341   // TODO(enne): Also, we shouldn't ever get here if the draw transform is not
1342   // just a scale + translation, but we do sometimes: http://crbug.com/740113
1343   if (draw_properties().screen_space_transform_is_animating ||
1344       !draw_transform.IsScaleOrTranslation()) {
1345     // For now, while these problems are not well understood, avoid changing
1346     // the raster scale in these cases.
1347     return gfx::Vector2dF();
1348   }
1349 
1350   // It is only useful to align the content space to the target space if their
1351   // relative pixel ratio is some small rational number. Currently we only
1352   // align if the relative pixel ratio is 1:1.
1353   // Good match if the maximum alignment error on a layer of size 10000px
1354   // does not exceed 0.001px.
1355   static constexpr float kErrorThreshold = 0.0000001f;
1356   if (std::abs(draw_transform.matrix().getFloat(0, 0) - raster_scale) >
1357           kErrorThreshold ||
1358       std::abs(draw_transform.matrix().getFloat(1, 1) - raster_scale) >
1359           kErrorThreshold)
1360     return gfx::Vector2dF();
1361 
1362   // Extract the fractional part of layer origin in the target space.
1363   float origin_x = draw_transform.matrix().getFloat(0, 3);
1364   float origin_y = draw_transform.matrix().getFloat(1, 3);
1365   return gfx::Vector2dF(origin_x - floorf(origin_x),
1366                         origin_y - floorf(origin_y));
1367 }
1368 
MinimumContentsScale() const1369 float PictureLayerImpl::MinimumContentsScale() const {
1370   float setting_min = layer_tree_impl()->settings().minimum_contents_scale;
1371 
1372   // If the contents scale is less than 1 / width (also for height),
1373   // then it will end up having less than one pixel of content in that
1374   // dimension.  Bump the minimum contents scale up in this case to prevent
1375   // this from happening.
1376   int min_dimension = std::min(raster_source_->GetSize().width(),
1377                                raster_source_->GetSize().height());
1378   if (!min_dimension)
1379     return setting_min;
1380 
1381   return std::max(1.f / min_dimension, setting_min);
1382 }
1383 
MaximumContentsScale() const1384 float PictureLayerImpl::MaximumContentsScale() const {
1385   if (bounds().IsEmpty())
1386     return 0;
1387   // When mask tiling is disabled or the mask is single textured, masks can not
1388   // have tilings that would become larger than the max_texture_size since they
1389   // use a single tile for the entire tiling. Other layers can have tilings such
1390   // that dimension * scale does not overflow.
1391   float max_dimension = static_cast<float>(
1392       is_backdrop_filter_mask_ ? layer_tree_impl()->max_texture_size()
1393                                : std::numeric_limits<int>::max());
1394   int higher_dimension = std::max(bounds().width(), bounds().height());
1395   float max_scale = max_dimension / higher_dimension;
1396 
1397   // We require that multiplying the layer size by the contents scale and
1398   // ceiling produces a value <= |max_dimension|. Because for large layer
1399   // sizes floating point ambiguity may crop up, making the result larger or
1400   // smaller than expected, we use a slightly smaller floating point value for
1401   // the scale, to help ensure that the resulting content bounds will never end
1402   // up larger than |max_dimension|.
1403   return nextafterf(max_scale, 0.f);
1404 }
1405 
ResetRasterScale()1406 void PictureLayerImpl::ResetRasterScale() {
1407   raster_page_scale_ = 0.f;
1408   raster_device_scale_ = 0.f;
1409   raster_source_scale_ = 0.f;
1410   raster_contents_scale_ = 0.f;
1411   low_res_raster_contents_scale_ = 0.f;
1412 }
1413 
CanHaveTilings() const1414 bool PictureLayerImpl::CanHaveTilings() const {
1415   if (raster_source_->IsSolidColor())
1416     return false;
1417   if (!DrawsContent())
1418     return false;
1419   if (!raster_source_->HasRecordings())
1420     return false;
1421   // If the |raster_source_| has a recording it should have non-empty bounds.
1422   DCHECK(!raster_source_->GetSize().IsEmpty());
1423   if (MaximumContentsScale() < MinimumContentsScale())
1424     return false;
1425   return true;
1426 }
1427 
SanityCheckTilingState() const1428 void PictureLayerImpl::SanityCheckTilingState() const {
1429 #if DCHECK_IS_ON()
1430   if (!CanHaveTilings()) {
1431     DCHECK_EQ(0u, tilings_->num_tilings());
1432     return;
1433   }
1434   if (tilings_->num_tilings() == 0)
1435     return;
1436 
1437   // We should only have one high res tiling.
1438   DCHECK_EQ(1, tilings_->NumHighResTilings());
1439 #endif
1440 }
1441 
MaximumTilingContentsScale() const1442 float PictureLayerImpl::MaximumTilingContentsScale() const {
1443   float max_contents_scale = tilings_->GetMaximumContentsScale();
1444   return std::max(max_contents_scale, MinimumContentsScale());
1445 }
1446 
1447 std::unique_ptr<PictureLayerTilingSet>
CreatePictureLayerTilingSet()1448 PictureLayerImpl::CreatePictureLayerTilingSet() {
1449   const LayerTreeSettings& settings = layer_tree_impl()->settings();
1450   return PictureLayerTilingSet::Create(
1451       IsActive() ? ACTIVE_TREE : PENDING_TREE, this,
1452       settings.tiling_interest_area_padding,
1453       layer_tree_impl()->use_gpu_rasterization()
1454           ? settings.gpu_rasterization_skewport_target_time_in_seconds
1455           : settings.skewport_target_time_in_seconds,
1456       settings.skewport_extrapolation_limit_in_screen_pixels,
1457       settings.max_preraster_distance_in_screen_pixels);
1458 }
1459 
UpdateIdealScales()1460 void PictureLayerImpl::UpdateIdealScales() {
1461   DCHECK(CanHaveTilings());
1462 
1463   float min_contents_scale = MinimumContentsScale();
1464   DCHECK_GT(min_contents_scale, 0.f);
1465 
1466   ideal_device_scale_ = layer_tree_impl()->device_scale_factor();
1467   if (layer_tree_impl()->PageScaleTransformNode()) {
1468     ideal_page_scale_ = IsAffectedByPageScale()
1469                             ? layer_tree_impl()->current_page_scale_factor()
1470                             : 1.f;
1471     ideal_contents_scale_ = GetIdealContentsScale();
1472   } else {
1473     // This layer may be in a layer tree embedded in a hierarchy that has its
1474     // own page scale factor. We represent that here as
1475     // 'external_page_scale_factor', a value that affects raster scale in the
1476     // same way that page_scale_factor does, but doesn't affect any geometry
1477     // calculations.
1478     float external_page_scale_factor =
1479         layer_tree_impl() ? layer_tree_impl()->external_page_scale_factor()
1480                           : 1.f;
1481     DCHECK(!layer_tree_impl() || external_page_scale_factor == 1.f ||
1482            layer_tree_impl()->current_page_scale_factor() == 1.f);
1483     ideal_page_scale_ = external_page_scale_factor;
1484     ideal_contents_scale_ =
1485         GetIdealContentsScale() * external_page_scale_factor;
1486   }
1487   ideal_contents_scale_ = base::ClampToRange(
1488       ideal_contents_scale_, min_contents_scale, kMaxIdealContentsScale);
1489   ideal_source_scale_ =
1490       ideal_contents_scale_ / ideal_page_scale_ / ideal_device_scale_;
1491 }
1492 
GetDebugBorderProperties(SkColor * color,float * width) const1493 void PictureLayerImpl::GetDebugBorderProperties(
1494     SkColor* color,
1495     float* width) const {
1496   float device_scale_factor =
1497       layer_tree_impl() ? layer_tree_impl()->device_scale_factor() : 1;
1498 
1499   if (directly_composited_image_size_) {
1500     *color = DebugColors::ImageLayerBorderColor();
1501     *width = DebugColors::ImageLayerBorderWidth(device_scale_factor);
1502   } else {
1503     *color = DebugColors::TiledContentLayerBorderColor();
1504     *width = DebugColors::TiledContentLayerBorderWidth(device_scale_factor);
1505   }
1506 }
1507 
GetAllPrioritizedTilesForTracing(std::vector<PrioritizedTile> * prioritized_tiles) const1508 void PictureLayerImpl::GetAllPrioritizedTilesForTracing(
1509     std::vector<PrioritizedTile>* prioritized_tiles) const {
1510   if (!tilings_)
1511     return;
1512   tilings_->GetAllPrioritizedTilesForTracing(prioritized_tiles);
1513 }
1514 
AsValueInto(base::trace_event::TracedValue * state) const1515 void PictureLayerImpl::AsValueInto(
1516     base::trace_event::TracedValue* state) const {
1517   LayerImpl::AsValueInto(state);
1518   state->SetDouble("ideal_contents_scale", ideal_contents_scale_);
1519   state->SetDouble("geometry_contents_scale", MaximumTilingContentsScale());
1520   state->BeginArray("tilings");
1521   tilings_->AsValueInto(state);
1522   state->EndArray();
1523 
1524   MathUtil::AddToTracedValue("tile_priority_rect",
1525                              viewport_rect_for_tile_priority_in_content_space_,
1526                              state);
1527   MathUtil::AddToTracedValue("visible_rect", visible_layer_rect(), state);
1528 
1529   state->BeginArray("pictures");
1530   raster_source_->AsValueInto(state);
1531   state->EndArray();
1532 
1533   state->BeginArray("invalidation");
1534   invalidation_.AsValueInto(state);
1535   state->EndArray();
1536 
1537   state->BeginArray("coverage_tiles");
1538   for (PictureLayerTilingSet::CoverageIterator iter(
1539            tilings_.get(), MaximumTilingContentsScale(),
1540            gfx::Rect(raster_source_->GetSize()), ideal_contents_scale_);
1541        iter; ++iter) {
1542     state->BeginDictionary();
1543 
1544     MathUtil::AddToTracedValue("geometry_rect", iter.geometry_rect(), state);
1545 
1546     if (*iter)
1547       viz::TracedValue::SetIDRef(*iter, state, "tile");
1548 
1549     state->EndDictionary();
1550   }
1551   state->EndArray();
1552 
1553   state->BeginDictionary("can_have_tilings_state");
1554   state->SetBoolean("can_have_tilings", CanHaveTilings());
1555   state->SetBoolean("raster_source_solid_color",
1556                     raster_source_->IsSolidColor());
1557   state->SetBoolean("draws_content", DrawsContent());
1558   state->SetBoolean("raster_source_has_recordings",
1559                     raster_source_->HasRecordings());
1560   state->SetDouble("max_contents_scale", MaximumTilingContentsScale());
1561   state->SetDouble("min_contents_scale", MinimumContentsScale());
1562   state->EndDictionary();
1563 
1564   state->BeginDictionary("raster_scales");
1565   state->SetDouble("page_scale", raster_page_scale_);
1566   state->SetDouble("device_scale", raster_device_scale_);
1567   state->SetDouble("source_scale", raster_source_scale_);
1568   state->SetDouble("contents_scale", raster_contents_scale_);
1569   state->SetDouble("low_res_contents_scale", low_res_raster_contents_scale_);
1570   state->EndDictionary();
1571 
1572   state->BeginDictionary("ideal_scales");
1573   state->SetDouble("page_scale", ideal_page_scale_);
1574   state->SetDouble("device_scale", ideal_device_scale_);
1575   state->SetDouble("source_scale", ideal_source_scale_);
1576   state->SetDouble("contents_scale", ideal_contents_scale_);
1577   state->EndDictionary();
1578 }
1579 
GPUMemoryUsageInBytes() const1580 size_t PictureLayerImpl::GPUMemoryUsageInBytes() const {
1581   return tilings_->GPUMemoryUsageInBytes();
1582 }
1583 
RunMicroBenchmark(MicroBenchmarkImpl * benchmark)1584 void PictureLayerImpl::RunMicroBenchmark(MicroBenchmarkImpl* benchmark) {
1585   benchmark->RunOnLayer(this);
1586 }
1587 
IsOnActiveOrPendingTree() const1588 bool PictureLayerImpl::IsOnActiveOrPendingTree() const {
1589   return !layer_tree_impl()->IsRecycleTree();
1590 }
1591 
HasValidTilePriorities() const1592 bool PictureLayerImpl::HasValidTilePriorities() const {
1593   return IsOnActiveOrPendingTree() &&
1594          (contributes_to_drawn_render_surface() || raster_even_if_not_drawn());
1595 }
1596 
1597 PictureLayerImpl::ImageInvalidationResult
InvalidateRegionForImages(const PaintImageIdFlatSet & images_to_invalidate)1598 PictureLayerImpl::InvalidateRegionForImages(
1599     const PaintImageIdFlatSet& images_to_invalidate) {
1600   if (!raster_source_ || !raster_source_->GetDisplayItemList() ||
1601       raster_source_->GetDisplayItemList()->discardable_image_map().empty()) {
1602     return ImageInvalidationResult::kNoImages;
1603   }
1604 
1605   InvalidationRegion image_invalidation;
1606   for (auto image_id : images_to_invalidate) {
1607     const auto& rects = raster_source_->GetDisplayItemList()
1608                             ->discardable_image_map()
1609                             .GetRectsForImage(image_id);
1610     for (const auto& r : rects.container())
1611       image_invalidation.Union(r);
1612   }
1613   Region invalidation;
1614   image_invalidation.Swap(&invalidation);
1615 
1616   if (invalidation.IsEmpty())
1617     return ImageInvalidationResult::kNoInvalidation;
1618 
1619   // Note: We can use a rect here since this is only used to track damage for a
1620   // frame and not raster invalidation.
1621   UnionUpdateRect(invalidation.bounds());
1622 
1623   invalidation_.Union(invalidation);
1624   tilings_->Invalidate(invalidation);
1625   // TODO(crbug.com/303943): SetNeedsPushProperties() would be needed here if
1626   // PictureLayerImpl didn't always push properties every activation.
1627   return ImageInvalidationResult::kInvalidated;
1628 }
1629 
SetPaintWorkletRecord(scoped_refptr<const PaintWorkletInput> input,sk_sp<PaintRecord> record)1630 void PictureLayerImpl::SetPaintWorkletRecord(
1631     scoped_refptr<const PaintWorkletInput> input,
1632     sk_sp<PaintRecord> record) {
1633   DCHECK(paint_worklet_records_.find(input) != paint_worklet_records_.end());
1634   paint_worklet_records_[input].second = std::move(record);
1635 }
1636 
RegisterAnimatedImages()1637 void PictureLayerImpl::RegisterAnimatedImages() {
1638   if (!raster_source_ || !raster_source_->GetDisplayItemList())
1639     return;
1640 
1641   auto* controller = layer_tree_impl()->image_animation_controller();
1642   const auto& metadata = raster_source_->GetDisplayItemList()
1643                              ->discardable_image_map()
1644                              .animated_images_metadata();
1645   for (const auto& data : metadata) {
1646     // Only update the metadata from updated recordings received from a commit.
1647     if (layer_tree_impl()->IsSyncTree())
1648       controller->UpdateAnimatedImage(data);
1649     controller->RegisterAnimationDriver(data.paint_image_id, this);
1650   }
1651 }
1652 
UnregisterAnimatedImages()1653 void PictureLayerImpl::UnregisterAnimatedImages() {
1654   if (!raster_source_ || !raster_source_->GetDisplayItemList())
1655     return;
1656 
1657   auto* controller = layer_tree_impl()->image_animation_controller();
1658   const auto& metadata = raster_source_->GetDisplayItemList()
1659                              ->discardable_image_map()
1660                              .animated_images_metadata();
1661   for (const auto& data : metadata)
1662     controller->UnregisterAnimationDriver(data.paint_image_id, this);
1663 }
1664 
SetPaintWorkletInputs(const std::vector<DiscardableImageMap::PaintWorkletInputWithImageId> & inputs)1665 void PictureLayerImpl::SetPaintWorkletInputs(
1666     const std::vector<DiscardableImageMap::PaintWorkletInputWithImageId>&
1667         inputs) {
1668   // PaintWorklets are not supported when committing directly to the active
1669   // tree, so in that case the |inputs| should always be empty.
1670   DCHECK(layer_tree_impl()->IsPendingTree() || inputs.empty());
1671 
1672   bool had_paint_worklets = !paint_worklet_records_.empty();
1673   PaintWorkletRecordMap new_records;
1674   for (const auto& input_with_id : inputs) {
1675     const auto& input = input_with_id.first;
1676     const auto& paint_image_id = input_with_id.second;
1677     auto it = new_records.find(input);
1678     // We should never have multiple PaintImages sharing the same paint worklet.
1679     DCHECK(it == new_records.end() || it->second.first == paint_image_id);
1680     // Attempt to re-use an existing PaintRecord if possible.
1681     new_records[input] = std::make_pair(
1682         paint_image_id, std::move(paint_worklet_records_[input].second));
1683   }
1684   paint_worklet_records_.swap(new_records);
1685 
1686   // The pending tree tracks which PictureLayerImpls have PaintWorkletInputs as
1687   // an optimization to avoid walking all picture layers.
1688   bool has_paint_worklets = !paint_worklet_records_.empty();
1689   if ((has_paint_worklets != had_paint_worklets) &&
1690       layer_tree_impl()->IsPendingTree()) {
1691     // TODO(xidachen): We don't need additional tracking on LayerTreeImpl. The
1692     // tracking in AnimatedPaintWorkletTracker should be enough.
1693     layer_tree_impl()->NotifyLayerHasPaintWorkletsChanged(this,
1694                                                           has_paint_worklets);
1695   }
1696   if (layer_tree_impl()->IsPendingTree()) {
1697     layer_tree_impl()
1698         ->paint_worklet_tracker()
1699         .UpdatePaintWorkletInputProperties(inputs, this);
1700   }
1701 }
1702 
InvalidatePaintWorklets(const PaintWorkletInput::PropertyKey & key)1703 void PictureLayerImpl::InvalidatePaintWorklets(
1704     const PaintWorkletInput::PropertyKey& key) {
1705   for (auto& entry : paint_worklet_records_) {
1706     const std::vector<PaintWorkletInput::PropertyKey>& prop_ids =
1707         entry.first->GetPropertyKeys();
1708     // If the PaintWorklet depends on the property whose value was changed by
1709     // the animation system, then invalidate its associated PaintRecord so that
1710     // we can repaint the PaintWorklet during impl side invalidation.
1711     if (base::Contains(prop_ids, key))
1712       entry.second.second = nullptr;
1713   }
1714 }
1715 
GetContentColorUsage() const1716 gfx::ContentColorUsage PictureLayerImpl::GetContentColorUsage() const {
1717   auto display_item_list = raster_source_->GetDisplayItemList();
1718   bool contains_only_srgb_images = true;
1719   if (display_item_list) {
1720     contains_only_srgb_images =
1721         display_item_list->discardable_image_map().contains_only_srgb_images();
1722   }
1723 
1724   if (contains_only_srgb_images)
1725     return gfx::ContentColorUsage::kSRGB;
1726 
1727   // TODO(cblume) This assumes only wide color gamut and not HDR
1728   return gfx::ContentColorUsage::kWideColorGamut;
1729 }
1730 
1731 }  // namespace cc
1732