123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989 |
- // Copyright 2012 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "cc/layers/layer_impl.h"
- #include <stddef.h>
- #include <stdint.h>
- #include <algorithm>
- #include <utility>
- #include "base/json/json_reader.h"
- #include "base/json/json_writer.h"
- #include "base/notreached.h"
- #include "base/numerics/safe_conversions.h"
- #include "base/trace_event/trace_event.h"
- #include "base/trace_event/traced_value.h"
- #include "cc/base/math_util.h"
- #include "cc/base/simple_enclosed_region.h"
- #include "cc/benchmarks/micro_benchmark_impl.h"
- #include "cc/debug/debug_colors.h"
- #include "cc/debug/layer_tree_debug_state.h"
- #include "cc/input/scroll_state.h"
- #include "cc/layers/layer.h"
- #include "cc/trees/clip_node.h"
- #include "cc/trees/draw_property_utils.h"
- #include "cc/trees/effect_node.h"
- #include "cc/trees/layer_tree_impl.h"
- #include "cc/trees/layer_tree_settings.h"
- #include "cc/trees/mutator_host.h"
- #include "cc/trees/proxy.h"
- #include "cc/trees/scroll_node.h"
- #include "cc/trees/transform_node.h"
- #include "components/viz/client/client_resource_provider.h"
- #include "components/viz/common/frame_sinks/copy_output_request.h"
- #include "components/viz/common/quads/compositor_render_pass.h"
- #include "components/viz/common/quads/debug_border_draw_quad.h"
- #include "components/viz/common/traced_value.h"
- #include "ui/gfx/geometry/point_conversions.h"
- #include "ui/gfx/geometry/quad_f.h"
- #include "ui/gfx/geometry/rect_conversions.h"
- #include "ui/gfx/geometry/size_conversions.h"
- #include "ui/gfx/geometry/transform_util.h"
- #include "ui/gfx/geometry/vector2d_conversions.h"
- namespace {
- template <typename T>
- std::unique_ptr<T> ClonePtr(const std::unique_ptr<T>& value) {
- return value ? std::make_unique<T>(*value) : nullptr;
- }
- } // namespace
- namespace cc {
- LayerImpl::LayerImpl(LayerTreeImpl* tree_impl,
- int id,
- bool will_always_push_properties)
- : layer_id_(id),
- layer_tree_impl_(tree_impl),
- will_always_push_properties_(will_always_push_properties),
- scrollable_(false),
- layer_property_changed_not_from_property_trees_(false),
- layer_property_changed_from_property_trees_(false),
- may_contain_video_(false),
- contents_opaque_(false),
- contents_opaque_for_text_(false),
- should_check_backface_visibility_(false),
- draws_content_(false),
- contributes_to_drawn_render_surface_(false),
- hit_testable_(false),
- is_inner_viewport_scroll_layer_(false),
- background_color_(SkColors::kTransparent),
- safe_opaque_background_color_(SkColors::kTransparent),
- transform_tree_index_(kInvalidPropertyNodeId),
- effect_tree_index_(kInvalidPropertyNodeId),
- clip_tree_index_(kInvalidPropertyNodeId),
- scroll_tree_index_(kInvalidPropertyNodeId),
- current_draw_mode_(DRAW_MODE_NONE),
- needs_push_properties_(false),
- needs_show_scrollbars_(false),
- raster_even_if_not_drawn_(false),
- has_transform_node_(false) {
- DCHECK_GT(layer_id_, 0);
- DCHECK(layer_tree_impl_);
- layer_tree_impl_->RegisterLayer(this);
- SetNeedsPushProperties();
- }
- LayerImpl::~LayerImpl() {
- layer_tree_impl_->UnregisterLayer(this);
- TRACE_EVENT_OBJECT_DELETED_WITH_ID(
- TRACE_DISABLED_BY_DEFAULT("cc.debug"), "cc::LayerImpl", this);
- }
- ElementListType LayerImpl::GetElementTypeForAnimation() const {
- return IsActive() ? ElementListType::ACTIVE : ElementListType::PENDING;
- }
- void LayerImpl::UpdateDebugInfo(LayerDebugInfo* debug_info) {
- // nullptr means we have stopped collecting debug info.
- if (!debug_info) {
- debug_info_.reset();
- return;
- }
- auto new_invalidations = std::move(debug_info->invalidations);
- if (!debug_info_) {
- debug_info_ = std::make_unique<LayerDebugInfo>(*debug_info);
- debug_info_->invalidations = std::move(new_invalidations);
- return;
- }
- // Accumulate invalidations until we draw the layer.
- auto existing_invalidations = std::move(debug_info_->invalidations);
- *debug_info_ = *debug_info;
- debug_info_->invalidations.insert(debug_info_->invalidations.begin(),
- existing_invalidations.begin(),
- existing_invalidations.end());
- }
- void LayerImpl::SetTransformTreeIndex(int index) {
- transform_tree_index_ = index;
- }
- void LayerImpl::SetClipTreeIndex(int index) {
- clip_tree_index_ = index;
- }
- void LayerImpl::SetEffectTreeIndex(int index) {
- effect_tree_index_ = index;
- }
- int LayerImpl::render_target_effect_tree_index() const {
- EffectNode* effect_node = GetEffectTree().Node(effect_tree_index_);
- return GetEffectTree().GetRenderSurface(effect_tree_index_)
- ? effect_node->id
- : effect_node->target_id;
- }
- void LayerImpl::SetScrollTreeIndex(int index) {
- scroll_tree_index_ = index;
- }
- void LayerImpl::PopulateSharedQuadState(viz::SharedQuadState* state,
- bool contents_opaque) const {
- EffectNode* effect_node = GetEffectTree().Node(effect_tree_index_);
- absl::optional<gfx::Rect> clip_rect;
- if (draw_properties_.is_clipped) {
- clip_rect = draw_properties_.clip_rect;
- }
- state->SetAll(draw_properties_.target_space_transform, gfx::Rect(bounds()),
- draw_properties_.visible_layer_rect,
- draw_properties_.mask_filter_info, clip_rect, contents_opaque,
- draw_properties_.opacity,
- effect_node->HasRenderSurface() ? SkBlendMode::kSrcOver
- : effect_node->blend_mode,
- GetSortingContextId());
- state->is_fast_rounded_corner = draw_properties_.is_fast_rounded_corner;
- }
- void LayerImpl::PopulateScaledSharedQuadState(viz::SharedQuadState* state,
- float layer_to_content_scale,
- bool contents_opaque) const {
- gfx::Size scaled_bounds =
- gfx::ScaleToCeiledSize(bounds(), layer_to_content_scale);
- gfx::Rect scaled_visible_layer_rect =
- gfx::ScaleToEnclosingRect(visible_layer_rect(), layer_to_content_scale);
- scaled_visible_layer_rect.Intersect(gfx::Rect(scaled_bounds));
- PopulateScaledSharedQuadStateWithContentRects(
- state, layer_to_content_scale, gfx::Rect(scaled_bounds),
- scaled_visible_layer_rect, contents_opaque);
- }
- void LayerImpl::PopulateScaledSharedQuadStateWithContentRects(
- viz::SharedQuadState* state,
- float layer_to_content_scale,
- const gfx::Rect& content_rect,
- const gfx::Rect& visible_content_rect,
- bool contents_opaque) const {
- gfx::Transform scaled_draw_transform =
- GetScaledDrawTransform(layer_to_content_scale);
- EffectNode* effect_node = GetEffectTree().Node(effect_tree_index_);
- absl::optional<gfx::Rect> clip_rect;
- if (draw_properties().is_clipped) {
- clip_rect = draw_properties().clip_rect;
- }
- state->SetAll(scaled_draw_transform, content_rect, visible_content_rect,
- draw_properties().mask_filter_info, clip_rect, contents_opaque,
- draw_properties().opacity,
- effect_node->HasRenderSurface() ? SkBlendMode::kSrcOver
- : effect_node->blend_mode,
- GetSortingContextId());
- state->is_fast_rounded_corner = draw_properties().is_fast_rounded_corner;
- }
- bool LayerImpl::WillDraw(DrawMode draw_mode,
- viz::ClientResourceProvider* resource_provider) {
- if (visible_layer_rect().IsEmpty() ||
- draw_properties().occlusion_in_content_space.IsOccluded(
- visible_layer_rect())) {
- return false;
- }
- // Resourceless mode does not support non-default blend mode. If we draw,
- // the result will be just like kSrcOver which is not too bad for blend modes
- // other than kDstIn. For kDstIn mode, we should ignore the source because
- // otherwise we would draw a bad black mask over the destination.
- if (draw_mode == DRAW_MODE_RESOURCELESS_SOFTWARE) {
- const auto* effect_node = GetEffectTree().Node(effect_tree_index());
- if (effect_node && effect_node->blend_mode == SkBlendMode::kDstIn)
- return false;
- }
- current_draw_mode_ = draw_mode;
- return true;
- }
- void LayerImpl::DidDraw(viz::ClientResourceProvider* resource_provider) {
- current_draw_mode_ = DRAW_MODE_NONE;
- }
- bool LayerImpl::ShowDebugBorders(DebugBorderType type) const {
- return layer_tree_impl()->debug_state().show_debug_borders.test(type);
- }
- void LayerImpl::GetDebugBorderProperties(SkColor4f* color, float* width) const {
- float device_scale_factor =
- layer_tree_impl() ? layer_tree_impl()->device_scale_factor() : 1;
- if (draws_content_) {
- *color = DebugColors::ContentLayerBorderColor();
- *width = DebugColors::ContentLayerBorderWidth(device_scale_factor);
- return;
- }
- *color = DebugColors::ContainerLayerBorderColor();
- *width = DebugColors::ContainerLayerBorderWidth(device_scale_factor);
- }
- void LayerImpl::AppendDebugBorderQuad(
- viz::CompositorRenderPass* render_pass,
- const gfx::Rect& quad_rect,
- const viz::SharedQuadState* shared_quad_state,
- AppendQuadsData* append_quads_data) const {
- SkColor4f color;
- float width;
- GetDebugBorderProperties(&color, &width);
- AppendDebugBorderQuad(render_pass, quad_rect, shared_quad_state,
- append_quads_data, color, width);
- }
- void LayerImpl::AppendDebugBorderQuad(
- viz::CompositorRenderPass* render_pass,
- const gfx::Rect& quad_rect,
- const viz::SharedQuadState* shared_quad_state,
- AppendQuadsData* append_quads_data,
- SkColor4f color,
- float width) const {
- if (!ShowDebugBorders(DebugBorderType::LAYER))
- return;
- // This is the debug border quad layer size. The mojo serialization will fail
- // if the area overflows, so just drop this debug border quad in that case to
- // avoid crashes.
- if (!quad_rect.size().GetCheckedArea().IsValid())
- return;
- gfx::Rect visible_quad_rect(quad_rect);
- auto* debug_border_quad =
- render_pass->CreateAndAppendDrawQuad<viz::DebugBorderDrawQuad>();
- debug_border_quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect,
- color, width);
- if (contents_opaque()) {
- // When opaque, draw a second inner border that is thicker than the outer
- // border, but more transparent.
- static const float kFillOpacity = 0.3f;
- SkColor4f fill_color = color;
- fill_color.fA *= kFillOpacity;
- float fill_width = width * 3;
- gfx::Rect fill_rect = quad_rect;
- fill_rect.Inset(fill_width / 2.f);
- if (fill_rect.IsEmpty())
- return;
- gfx::Rect visible_fill_rect =
- gfx::IntersectRects(visible_quad_rect, fill_rect);
- auto* fill_quad =
- render_pass->CreateAndAppendDrawQuad<viz::DebugBorderDrawQuad>();
- fill_quad->SetNew(shared_quad_state, fill_rect, visible_fill_rect,
- fill_color, fill_width);
- }
- }
- void LayerImpl::GetContentsResourceId(viz::ResourceId* resource_id,
- gfx::Size* resource_size,
- gfx::SizeF* resource_uv_size) const {
- NOTREACHED();
- *resource_id = viz::kInvalidResourceId;
- }
- gfx::Vector2dF LayerImpl::ScrollBy(const gfx::Vector2dF& scroll) {
- ScrollTree& scroll_tree = GetScrollTree();
- ScrollNode* scroll_node = scroll_tree.Node(scroll_tree_index());
- DCHECK(scroll_node);
- return scroll_tree.ScrollBy(*scroll_node, scroll, layer_tree_impl());
- }
- void LayerImpl::UpdateScrollable() {
- if (!element_id()) {
- scrollable_ = false;
- return;
- }
- const auto* scroll_node = GetScrollTree().FindNodeFromElementId(element_id());
- bool was_scrollable = scrollable_;
- scrollable_ = scroll_node && scroll_node->scrollable;
- if (was_scrollable == scrollable_) {
- if (!scrollable_)
- return;
- if (scroll_container_bounds_ == scroll_node->container_bounds &&
- scroll_contents_bounds_ == scroll_node->bounds)
- return;
- }
- scroll_container_bounds_ =
- scrollable_ ? scroll_node->container_bounds : gfx::Size();
- scroll_contents_bounds_ = scrollable_ ? scroll_node->bounds : gfx::Size();
- // Scrollbar positions depend on the bounds.
- layer_tree_impl()->SetScrollbarGeometriesNeedUpdate();
- if (layer_tree_impl()->settings().scrollbar_animator ==
- LayerTreeSettings::AURA_OVERLAY) {
- set_needs_show_scrollbars(scrollable_);
- }
- NoteLayerPropertyChanged();
- }
- void LayerImpl::SetTouchActionRegion(TouchActionRegion region) {
- // Avoid recalculating the cached |all_touch_action_regions_| value.
- if (touch_action_region_ == region)
- return;
- touch_action_region_ = std::move(region);
- all_touch_action_regions_ = nullptr;
- }
- const Region& LayerImpl::GetAllTouchActionRegions() const {
- if (!all_touch_action_regions_) {
- all_touch_action_regions_ =
- std::make_unique<Region>(touch_action_region_.GetAllRegions());
- } else {
- // Ensure the cached value of |all_touch_action_regions_| is up to date.
- DCHECK_EQ(touch_action_region_.GetAllRegions(), *all_touch_action_regions_);
- }
- return *all_touch_action_regions_;
- }
- void LayerImpl::SetCaptureBounds(viz::RegionCaptureBounds bounds) {
- if (rare_properties_ || !bounds.IsEmpty())
- EnsureRareProperties().capture_bounds = std::move(bounds);
- }
- std::unique_ptr<LayerImpl> LayerImpl::CreateLayerImpl(
- LayerTreeImpl* tree_impl) const {
- return LayerImpl::Create(tree_impl, layer_id_);
- }
- bool LayerImpl::IsSnappedToPixelGridInTarget() {
- return false;
- }
- void LayerImpl::PushPropertiesTo(LayerImpl* layer) {
- DCHECK(layer->IsActive());
- // The element id should be set first because other setters may
- // depend on it. Referencing element id on a layer is
- // deprecated. http://crbug.com/709137
- layer->SetElementId(element_id_);
- layer->has_transform_node_ = has_transform_node_;
- layer->offset_to_transform_parent_ = offset_to_transform_parent_;
- layer->contents_opaque_ = contents_opaque_;
- layer->contents_opaque_for_text_ = contents_opaque_for_text_;
- layer->may_contain_video_ = may_contain_video_;
- layer->should_check_backface_visibility_ = should_check_backface_visibility_;
- layer->draws_content_ = draws_content_;
- layer->hit_testable_ = hit_testable_;
- layer->touch_action_region_ = touch_action_region_;
- layer->all_touch_action_regions_ = ClonePtr(all_touch_action_regions_);
- layer->background_color_ = background_color_;
- layer->safe_opaque_background_color_ = safe_opaque_background_color_;
- layer->transform_tree_index_ = transform_tree_index_;
- layer->effect_tree_index_ = effect_tree_index_;
- layer->clip_tree_index_ = clip_tree_index_;
- layer->scroll_tree_index_ = scroll_tree_index_;
- if (needs_show_scrollbars_)
- layer->needs_show_scrollbars_ = needs_show_scrollbars_;
- if (layer_property_changed_not_from_property_trees_ ||
- layer_property_changed_from_property_trees_)
- layer->layer_tree_impl()->set_needs_update_draw_properties();
- if (layer_property_changed_not_from_property_trees_)
- layer->layer_property_changed_not_from_property_trees_ = true;
- if (layer_property_changed_from_property_trees_)
- layer->layer_property_changed_from_property_trees_ = true;
- layer->SetBounds(bounds_);
- layer->UpdateScrollable();
- layer->UnionUpdateRect(update_rect_);
- layer->UpdateDebugInfo(debug_info_.get());
- if (rare_properties_) {
- layer->rare_properties_ =
- std::make_unique<RareProperties>(*rare_properties_);
- } else {
- layer->rare_properties_.reset();
- }
- // Reset any state that should be cleared for the next update.
- needs_show_scrollbars_ = false;
- ResetChangeTracking();
- }
- bool LayerImpl::IsAffectedByPageScale() const {
- TransformTree& transform_tree = GetTransformTree();
- return transform_tree.Node(transform_tree_index())
- ->in_subtree_of_page_scale_layer;
- }
- bool LayerImpl::LayerPropertyChanged() const {
- return layer_property_changed_not_from_property_trees_ ||
- LayerPropertyChangedFromPropertyTrees();
- }
- bool LayerImpl::LayerPropertyChangedFromPropertyTrees() const {
- if (layer_property_changed_from_property_trees_ ||
- GetPropertyTrees()->full_tree_damaged())
- return true;
- if (transform_tree_index() == kInvalidPropertyNodeId)
- return false;
- TransformNode* transform_node =
- GetTransformTree().Node(transform_tree_index());
- if (transform_node && transform_node->transform_changed)
- return true;
- if (effect_tree_index() == kInvalidPropertyNodeId)
- return false;
- EffectNode* effect_node = GetEffectTree().Node(effect_tree_index());
- if (effect_node && effect_node->effect_changed)
- return true;
- return false;
- }
- bool LayerImpl::LayerPropertyChangedNotFromPropertyTrees() const {
- return layer_property_changed_not_from_property_trees_;
- }
- void LayerImpl::NoteLayerPropertyChanged() {
- layer_property_changed_not_from_property_trees_ = true;
- layer_tree_impl()->set_needs_update_draw_properties();
- }
- void LayerImpl::NoteLayerPropertyChangedFromPropertyTrees() {
- layer_property_changed_from_property_trees_ = true;
- layer_tree_impl()->set_needs_update_draw_properties();
- }
- void LayerImpl::ValidateQuadResourcesInternal(viz::DrawQuad* quad) const {
- #if DCHECK_IS_ON()
- const viz::ClientResourceProvider* resource_provider =
- layer_tree_impl_->resource_provider();
- for (viz::ResourceId resource_id : quad->resources)
- resource_provider->ValidateResource(resource_id);
- #endif
- }
- gfx::Transform LayerImpl::GetScaledDrawTransform(
- float layer_to_content_scale) const {
- gfx::Transform scaled_draw_transform =
- draw_properties_.target_space_transform;
- scaled_draw_transform.Scale(SK_Scalar1 / layer_to_content_scale,
- SK_Scalar1 / layer_to_content_scale);
- return scaled_draw_transform;
- }
- const char* LayerImpl::LayerTypeAsString() const {
- return "cc::LayerImpl";
- }
- void LayerImpl::ResetChangeTracking() {
- layer_property_changed_not_from_property_trees_ = false;
- layer_property_changed_from_property_trees_ = false;
- needs_push_properties_ = false;
- update_rect_.SetRect(0, 0, 0, 0);
- if (debug_info_)
- debug_info_->invalidations.clear();
- }
- bool LayerImpl::IsActive() const {
- return layer_tree_impl_->IsActiveTree();
- }
- gfx::Size LayerImpl::bounds() const {
- if (!is_inner_viewport_scroll_layer_)
- return bounds_;
- auto viewport_bounds_delta = gfx::ToCeiledVector2d(
- GetPropertyTrees()->inner_viewport_scroll_bounds_delta());
- return gfx::Size(bounds_.width() + viewport_bounds_delta.x(),
- bounds_.height() + viewport_bounds_delta.y());
- }
- void LayerImpl::SetBounds(const gfx::Size& bounds) {
- if (bounds_ == bounds)
- return;
- bounds_ = bounds;
- // Scrollbar positions depend on the scrolling layer bounds.
- if (scrollable_)
- layer_tree_impl()->SetScrollbarGeometriesNeedUpdate();
- NoteLayerPropertyChanged();
- }
- bool LayerImpl::IsScrollbarLayer() const {
- return false;
- }
- bool LayerImpl::IsScrollerOrScrollbar() const {
- return IsScrollbarLayer() ||
- GetScrollTree().FindNodeFromElementId(element_id());
- }
- void LayerImpl::SetDrawsContent(bool draws_content) {
- if (draws_content_ == draws_content)
- return;
- draws_content_ = draws_content;
- NoteLayerPropertyChanged();
- }
- void LayerImpl::SetHitTestable(bool should_hit_test) {
- if (hit_testable_ == should_hit_test)
- return;
- hit_testable_ = should_hit_test;
- NoteLayerPropertyChanged();
- }
- bool LayerImpl::HitTestable() const {
- EffectTree& effect_tree = GetEffectTree();
- bool should_hit_test = hit_testable_;
- // TODO(sunxd): remove or refactor SetHideLayerAndSubtree, or move this logic
- // to subclasses of Layer. See https://crbug.com/595843 and
- // https://crbug.com/931865.
- // The bit |subtree_hidden| can only be true for ui::Layers. Other layers are
- // not supposed to set this bit.
- if (effect_tree.Node(effect_tree_index())) {
- should_hit_test &= !effect_tree.Node(effect_tree_index())->subtree_hidden;
- }
- return should_hit_test;
- }
- void LayerImpl::SetBackgroundColor(SkColor4f background_color) {
- if (background_color_ == background_color)
- return;
- background_color_ = background_color;
- NoteLayerPropertyChanged();
- }
- void LayerImpl::SetSafeOpaqueBackgroundColor(SkColor4f background_color) {
- safe_opaque_background_color_ = background_color;
- }
- void LayerImpl::SetContentsOpaque(bool opaque) {
- contents_opaque_ = opaque;
- contents_opaque_for_text_ = opaque;
- }
- void LayerImpl::SetContentsOpaqueForText(bool opaque) {
- DCHECK(!contents_opaque_ || opaque);
- contents_opaque_for_text_ = opaque;
- }
- float LayerImpl::Opacity() const {
- if (const EffectNode* node = GetEffectTree().Node(effect_tree_index()))
- return node->opacity;
- else
- return 1.f;
- }
- void LayerImpl::SetElementId(ElementId element_id) {
- if (element_id == element_id_)
- return;
- TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "LayerImpl::SetElementId",
- "element", element_id.ToString());
- element_id_ = element_id;
- }
- void LayerImpl::UnionUpdateRect(const gfx::Rect& update_rect) {
- update_rect_.Union(update_rect);
- }
- gfx::Rect LayerImpl::GetDamageRect() const {
- return gfx::Rect();
- }
- void LayerImpl::SetCurrentScrollOffset(const gfx::PointF& scroll_offset) {
- DCHECK(IsActive());
- if (GetScrollTree().SetScrollOffset(element_id(), scroll_offset))
- layer_tree_impl()->DidUpdateScrollOffset(element_id());
- }
- SimpleEnclosedRegion LayerImpl::VisibleOpaqueRegion() const {
- if (contents_opaque())
- return SimpleEnclosedRegion(visible_layer_rect());
- return SimpleEnclosedRegion();
- }
- void LayerImpl::DidBeginTracing() {}
- void LayerImpl::ReleaseResources() {}
- void LayerImpl::OnPurgeMemory() {
- ReleaseResources();
- }
- void LayerImpl::ReleaseTileResources() {}
- void LayerImpl::RecreateTileResources() {}
- void LayerImpl::SetNeedsPushProperties() {
- // There's no need to push layer properties on the active tree, or when
- // |will_always_push_properties_| is true.
- if (will_always_push_properties_ || layer_tree_impl()->IsActiveTree())
- return;
- if (!needs_push_properties_) {
- needs_push_properties_ = true;
- layer_tree_impl()->AddLayerShouldPushProperties(this);
- }
- }
- void LayerImpl::GetAllPrioritizedTilesForTracing(
- std::vector<PrioritizedTile>* prioritized_tiles) const {
- }
- void LayerImpl::AsValueInto(base::trace_event::TracedValue* state) const {
- // The output is consumed at least by
- // 1. DevTools for showing layer tree information for frame snapshots in
- // performance timeline (third_party/devtools_frontend/src/front_end/
- // timeline_model/TracingLayerTree.js),
- // 2. trace_viewer
- // (third_party/catapult/tracing/tracing/extras/chrome/cc/layer_impl.html)
- // Note that trace_viewer uses "namingStyle" style instead of
- // "naming_style". The difference is intentional and the names are
- // converted automatically, but we need to keep this in mind when we
- // search trace_viewer code for the usage of the names here.
- // When making changes here, we need to make sure we won't break these
- // consumers.
- viz::TracedValue::MakeDictIntoImplicitSnapshotWithCategory(
- TRACE_DISABLED_BY_DEFAULT("cc.debug"), state, "cc::LayerImpl",
- LayerTypeAsString(), this);
- state->SetInteger("layer_id", id());
- MathUtil::AddToTracedValue("bounds", bounds_, state);
- state->SetDouble("opacity", Opacity());
- // For backward-compatibility of DevTools front-end.
- MathUtil::AddToTracedValue("position", gfx::PointF(), state);
- state->SetInteger("transform_tree_index", transform_tree_index());
- state->SetInteger("clip_tree_index", clip_tree_index());
- state->SetInteger("effect_tree_index", effect_tree_index());
- state->SetInteger("scroll_tree_index", scroll_tree_index());
- state->SetInteger("sorting_context_id", GetSortingContextId());
- state->SetInteger("draws_content", draws_content());
- state->SetInteger("gpu_memory_usage",
- base::saturated_cast<int>(GPUMemoryUsageInBytes()));
- if (element_id_)
- element_id_.AddToTracedValue(state);
- if (!ScreenSpaceTransform().IsIdentity())
- MathUtil::AddToTracedValue("screen_space_transform", ScreenSpaceTransform(),
- state);
- bool clipped;
- gfx::QuadF layer_quad =
- MathUtil::MapQuad(ScreenSpaceTransform(),
- gfx::QuadF(gfx::RectF(gfx::Rect(bounds()))), &clipped);
- MathUtil::AddToTracedValue("layer_quad", layer_quad, state);
- if (!GetAllTouchActionRegions().IsEmpty()) {
- state->BeginArray("all_touch_action_regions");
- GetAllTouchActionRegions().AsValueInto(state);
- state->EndArray();
- }
- state->BeginArray("wheel_event_handler_region");
- wheel_event_handler_region().AsValueInto(state);
- state->EndArray();
- state->BeginArray("non_fast_scrollable_region");
- non_fast_scrollable_region().AsValueInto(state);
- state->EndArray();
- state->SetBoolean("hit_testable", HitTestable());
- state->SetBoolean("contents_opaque", contents_opaque());
- if (debug_info_) {
- state->SetString("layer_name", debug_info_->name);
- if (debug_info_->owner_node_id)
- state->SetInteger("owner_node", debug_info_->owner_node_id);
- if (debug_info_->compositing_reasons.size()) {
- state->BeginArray("compositing_reasons");
- for (const char* reason : debug_info_->compositing_reasons)
- state->AppendString(reason);
- state->EndArray();
- }
- if (debug_info_->compositing_reason_ids.size()) {
- state->BeginArray("compositing_reason_ids");
- for (const char* reason_id : debug_info_->compositing_reason_ids)
- state->AppendString(reason_id);
- state->EndArray();
- }
- if (debug_info_->invalidations.size()) {
- state->BeginArray("annotated_invalidation_rects");
- for (auto& invalidation : debug_info_->invalidations) {
- state->BeginDictionary();
- MathUtil::AddToTracedValue("geometry_rect", invalidation.rect, state);
- state->SetString("reason", invalidation.reason);
- state->SetString("client", invalidation.client);
- state->EndDictionary();
- }
- state->EndArray();
- }
- }
- }
- std::string LayerImpl::ToString() const {
- base::trace_event::TracedValueJSON value;
- AsValueInto(&value);
- return value.ToFormattedJSON();
- }
- size_t LayerImpl::GPUMemoryUsageInBytes() const { return 0; }
- void LayerImpl::RunMicroBenchmark(MicroBenchmarkImpl* benchmark) {
- benchmark->RunOnLayer(this);
- }
- gfx::Transform LayerImpl::DrawTransform() const {
- // Only drawn layers have up-to-date draw properties.
- if (!contributes_to_drawn_render_surface()) {
- return draw_property_utils::DrawTransform(this, GetTransformTree(),
- GetEffectTree());
- }
- return draw_properties().target_space_transform;
- }
- gfx::Transform LayerImpl::ScreenSpaceTransform() const {
- // Only drawn layers have up-to-date draw properties.
- if (!contributes_to_drawn_render_surface()) {
- return draw_property_utils::ScreenSpaceTransform(this, GetTransformTree());
- }
- return draw_properties().screen_space_transform;
- }
- int LayerImpl::GetSortingContextId() const {
- return GetTransformTree().Node(transform_tree_index())->sorting_context_id;
- }
- Region LayerImpl::GetInvalidationRegionForDebugging() {
- return Region(update_rect_);
- }
- gfx::Rect LayerImpl::GetEnclosingVisibleRectInTargetSpace() const {
- return GetScaledEnclosingVisibleRectInTargetSpace(1.0f);
- }
- gfx::Rect LayerImpl::GetScaledEnclosingVisibleRectInTargetSpace(
- float scale) const {
- // TODO(oshima): Define an utility function to scale layer and conslidate with
- // the logic in ComputeDrawPropertiesOfVisibleLayers() in
- // draw_property_util.cc.
- DCHECK_GT(scale, 0.0);
- bool only_draws_visible_content = GetPropertyTrees()
- ->effect_tree()
- .Node(effect_tree_index())
- ->only_draws_visible_content;
- gfx::Rect drawable_bounds = visible_layer_rect();
- if (!only_draws_visible_content) {
- drawable_bounds = gfx::Rect(bounds());
- }
- gfx::Transform scaled_draw_transform = GetScaledDrawTransform(scale);
- gfx::Rect scaled_bounds = ScaleToEnclosingRect(drawable_bounds, scale);
- return MathUtil::MapEnclosingClippedRect(scaled_draw_transform,
- scaled_bounds);
- }
- RenderSurfaceImpl* LayerImpl::render_target() {
- return GetEffectTree().GetRenderSurface(render_target_effect_tree_index());
- }
- const RenderSurfaceImpl* LayerImpl::render_target() const {
- return GetEffectTree().GetRenderSurface(render_target_effect_tree_index());
- }
- gfx::Vector2dF LayerImpl::GetIdealContentsScale() const {
- const auto& transform = ScreenSpaceTransform();
- absl::optional<gfx::Vector2dF> transform_scales =
- gfx::TryComputeTransform2dScaleComponents(transform);
- if (transform_scales) {
- // TODO(crbug.com/1196414): Remove this scale cap.
- float scale_cap = GetPreferredRasterScale(*transform_scales);
- transform_scales->SetToMin(gfx::Vector2dF(scale_cap, scale_cap));
- return *transform_scales;
- }
- // TryComputeTransform2dScaleComponents couldn't compute a scale because of
- // perspective components in the transform.
- float page_scale = IsAffectedByPageScale()
- ? layer_tree_impl()->current_page_scale_factor()
- : 1.f;
- float device_scale = layer_tree_impl()->device_scale_factor();
- float default_scale = page_scale * device_scale;
- // TODO(crbug.com/1196414): This function should return a 2D scale.
- float scale = gfx::ComputeApproximateMaxScale(transform);
- const int kMaxTilesToCoverLayerDimension = 5;
- // Cap the scale in a way that it should be covered by at most
- // |kMaxTilesToCoverLayerDimension|^2 default tile sizes. If this is left
- // uncapped, then we can fairly easily use too much memory (or too many
- // tiles). See crbug.com/752382 for an example of such a page. Note that
- // because this is an approximation anyway, it's fine to use a smaller scale
- // that desired. On top of this, the layer has a perspective transform so
- // technically it could all be within the viewport, so it's important for us
- // to have a reasonable scale here. The scale we use would also be at least
- // |default_scale|, as checked below.
- float scale_cap = std::min(
- (layer_tree_impl()->settings().default_tile_size.width() - 2) *
- kMaxTilesToCoverLayerDimension / static_cast<float>(bounds().width()),
- (layer_tree_impl()->settings().default_tile_size.height() - 2) *
- kMaxTilesToCoverLayerDimension /
- static_cast<float>(bounds().height()));
- scale = std::min(scale, scale_cap);
- // Since we're approximating the scale anyway, round it to the nearest
- // integer to prevent jitter when animating the transform.
- scale = std::round(scale);
- // Don't let the scale fall below the default scale.
- scale = std::max(scale, default_scale);
- return gfx::Vector2dF(scale, scale);
- }
- float LayerImpl::GetIdealContentsScaleKey() const {
- return GetPreferredRasterScale(GetIdealContentsScale());
- }
- float LayerImpl::GetPreferredRasterScale(
- gfx::Vector2dF raster_space_scale_factor) {
- constexpr float kMaxScaleRatio = 5.f;
- float lower_scale =
- std::min(raster_space_scale_factor.x(), raster_space_scale_factor.y());
- float higher_scale =
- std::max(raster_space_scale_factor.x(), raster_space_scale_factor.y());
- return std::min(kMaxScaleRatio * lower_scale, higher_scale);
- }
- PropertyTrees* LayerImpl::GetPropertyTrees() const {
- return layer_tree_impl_->property_trees();
- }
- ClipTree& LayerImpl::GetClipTree() const {
- return GetPropertyTrees()->clip_tree_mutable();
- }
- EffectTree& LayerImpl::GetEffectTree() const {
- return GetPropertyTrees()->effect_tree_mutable();
- }
- ScrollTree& LayerImpl::GetScrollTree() const {
- return GetPropertyTrees()->scroll_tree_mutable();
- }
- TransformTree& LayerImpl::GetTransformTree() const {
- return GetPropertyTrees()->transform_tree_mutable();
- }
- void LayerImpl::EnsureValidPropertyTreeIndices() const {
- DCHECK(GetTransformTree().Node(transform_tree_index()));
- DCHECK(GetEffectTree().Node(effect_tree_index()));
- DCHECK(GetClipTree().Node(clip_tree_index()));
- DCHECK(GetScrollTree().Node(scroll_tree_index()));
- }
- bool LayerImpl::is_surface_layer() const {
- return false;
- }
- static float TranslationFromActiveTreeLayerScreenSpaceTransform(
- LayerImpl* pending_tree_layer) {
- LayerTreeImpl* layer_tree_impl = pending_tree_layer->layer_tree_impl();
- if (layer_tree_impl) {
- LayerImpl* active_tree_layer =
- layer_tree_impl->FindActiveTreeLayerById(pending_tree_layer->id());
- if (active_tree_layer) {
- gfx::Transform active_tree_screen_space_transform =
- active_tree_layer->draw_properties().screen_space_transform;
- if (active_tree_screen_space_transform.IsIdentity())
- return 0.f;
- if (active_tree_screen_space_transform.ApproximatelyEqual(
- pending_tree_layer->draw_properties().screen_space_transform))
- return 0.f;
- return (active_tree_layer->draw_properties()
- .screen_space_transform.To2dTranslation() -
- pending_tree_layer->draw_properties()
- .screen_space_transform.To2dTranslation())
- .Length();
- }
- }
- return 0.f;
- }
- // A layer jitters if its screen space transform is same on two successive
- // commits, but has changed in between the commits. CalculateLayerJitter
- // computes the jitter for the layer.
- int LayerImpl::CalculateJitter() {
- float jitter = 0.f;
- performance_properties().translation_from_last_frame = 0.f;
- performance_properties().last_commit_screen_space_transform =
- draw_properties().screen_space_transform;
- if (!visible_layer_rect().IsEmpty()) {
- if (draw_properties().screen_space_transform.ApproximatelyEqual(
- performance_properties().last_commit_screen_space_transform)) {
- float translation_from_last_commit =
- TranslationFromActiveTreeLayerScreenSpaceTransform(this);
- if (translation_from_last_commit > 0.f) {
- performance_properties().num_fixed_point_hits++;
- performance_properties().translation_from_last_frame =
- translation_from_last_commit;
- if (performance_properties().num_fixed_point_hits >
- LayerTreeImpl::kFixedPointHitsThreshold) {
- // Jitter = Translation from fixed point * sqrt(Area of the layer).
- // The square root of the area is used instead of the area to match
- // the dimensions of both terms on the rhs.
- jitter += translation_from_last_commit *
- sqrt(visible_layer_rect().size().GetArea());
- }
- } else {
- performance_properties().num_fixed_point_hits = 0;
- }
- }
- }
- return jitter;
- }
- std::string LayerImpl::DebugName() const {
- return debug_info_ ? debug_info_->name : "";
- }
- gfx::ContentColorUsage LayerImpl::GetContentColorUsage() const {
- return gfx::ContentColorUsage::kSRGB;
- }
- } // namespace cc
|