layer_impl.cc 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989
  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. #include "cc/layers/layer_impl.h"
  5. #include <stddef.h>
  6. #include <stdint.h>
  7. #include <algorithm>
  8. #include <utility>
  9. #include "base/json/json_reader.h"
  10. #include "base/json/json_writer.h"
  11. #include "base/notreached.h"
  12. #include "base/numerics/safe_conversions.h"
  13. #include "base/trace_event/trace_event.h"
  14. #include "base/trace_event/traced_value.h"
  15. #include "cc/base/math_util.h"
  16. #include "cc/base/simple_enclosed_region.h"
  17. #include "cc/benchmarks/micro_benchmark_impl.h"
  18. #include "cc/debug/debug_colors.h"
  19. #include "cc/debug/layer_tree_debug_state.h"
  20. #include "cc/input/scroll_state.h"
  21. #include "cc/layers/layer.h"
  22. #include "cc/trees/clip_node.h"
  23. #include "cc/trees/draw_property_utils.h"
  24. #include "cc/trees/effect_node.h"
  25. #include "cc/trees/layer_tree_impl.h"
  26. #include "cc/trees/layer_tree_settings.h"
  27. #include "cc/trees/mutator_host.h"
  28. #include "cc/trees/proxy.h"
  29. #include "cc/trees/scroll_node.h"
  30. #include "cc/trees/transform_node.h"
  31. #include "components/viz/client/client_resource_provider.h"
  32. #include "components/viz/common/frame_sinks/copy_output_request.h"
  33. #include "components/viz/common/quads/compositor_render_pass.h"
  34. #include "components/viz/common/quads/debug_border_draw_quad.h"
  35. #include "components/viz/common/traced_value.h"
  36. #include "ui/gfx/geometry/point_conversions.h"
  37. #include "ui/gfx/geometry/quad_f.h"
  38. #include "ui/gfx/geometry/rect_conversions.h"
  39. #include "ui/gfx/geometry/size_conversions.h"
  40. #include "ui/gfx/geometry/transform_util.h"
  41. #include "ui/gfx/geometry/vector2d_conversions.h"
  42. namespace {
  43. template <typename T>
  44. std::unique_ptr<T> ClonePtr(const std::unique_ptr<T>& value) {
  45. return value ? std::make_unique<T>(*value) : nullptr;
  46. }
  47. } // namespace
  48. namespace cc {
  49. LayerImpl::LayerImpl(LayerTreeImpl* tree_impl,
  50. int id,
  51. bool will_always_push_properties)
  52. : layer_id_(id),
  53. layer_tree_impl_(tree_impl),
  54. will_always_push_properties_(will_always_push_properties),
  55. scrollable_(false),
  56. layer_property_changed_not_from_property_trees_(false),
  57. layer_property_changed_from_property_trees_(false),
  58. may_contain_video_(false),
  59. contents_opaque_(false),
  60. contents_opaque_for_text_(false),
  61. should_check_backface_visibility_(false),
  62. draws_content_(false),
  63. contributes_to_drawn_render_surface_(false),
  64. hit_testable_(false),
  65. is_inner_viewport_scroll_layer_(false),
  66. background_color_(SkColors::kTransparent),
  67. safe_opaque_background_color_(SkColors::kTransparent),
  68. transform_tree_index_(kInvalidPropertyNodeId),
  69. effect_tree_index_(kInvalidPropertyNodeId),
  70. clip_tree_index_(kInvalidPropertyNodeId),
  71. scroll_tree_index_(kInvalidPropertyNodeId),
  72. current_draw_mode_(DRAW_MODE_NONE),
  73. needs_push_properties_(false),
  74. needs_show_scrollbars_(false),
  75. raster_even_if_not_drawn_(false),
  76. has_transform_node_(false) {
  77. DCHECK_GT(layer_id_, 0);
  78. DCHECK(layer_tree_impl_);
  79. layer_tree_impl_->RegisterLayer(this);
  80. SetNeedsPushProperties();
  81. }
  82. LayerImpl::~LayerImpl() {
  83. layer_tree_impl_->UnregisterLayer(this);
  84. TRACE_EVENT_OBJECT_DELETED_WITH_ID(
  85. TRACE_DISABLED_BY_DEFAULT("cc.debug"), "cc::LayerImpl", this);
  86. }
  87. ElementListType LayerImpl::GetElementTypeForAnimation() const {
  88. return IsActive() ? ElementListType::ACTIVE : ElementListType::PENDING;
  89. }
  90. void LayerImpl::UpdateDebugInfo(LayerDebugInfo* debug_info) {
  91. // nullptr means we have stopped collecting debug info.
  92. if (!debug_info) {
  93. debug_info_.reset();
  94. return;
  95. }
  96. auto new_invalidations = std::move(debug_info->invalidations);
  97. if (!debug_info_) {
  98. debug_info_ = std::make_unique<LayerDebugInfo>(*debug_info);
  99. debug_info_->invalidations = std::move(new_invalidations);
  100. return;
  101. }
  102. // Accumulate invalidations until we draw the layer.
  103. auto existing_invalidations = std::move(debug_info_->invalidations);
  104. *debug_info_ = *debug_info;
  105. debug_info_->invalidations.insert(debug_info_->invalidations.begin(),
  106. existing_invalidations.begin(),
  107. existing_invalidations.end());
  108. }
  109. void LayerImpl::SetTransformTreeIndex(int index) {
  110. transform_tree_index_ = index;
  111. }
  112. void LayerImpl::SetClipTreeIndex(int index) {
  113. clip_tree_index_ = index;
  114. }
  115. void LayerImpl::SetEffectTreeIndex(int index) {
  116. effect_tree_index_ = index;
  117. }
  118. int LayerImpl::render_target_effect_tree_index() const {
  119. EffectNode* effect_node = GetEffectTree().Node(effect_tree_index_);
  120. return GetEffectTree().GetRenderSurface(effect_tree_index_)
  121. ? effect_node->id
  122. : effect_node->target_id;
  123. }
  124. void LayerImpl::SetScrollTreeIndex(int index) {
  125. scroll_tree_index_ = index;
  126. }
  127. void LayerImpl::PopulateSharedQuadState(viz::SharedQuadState* state,
  128. bool contents_opaque) const {
  129. EffectNode* effect_node = GetEffectTree().Node(effect_tree_index_);
  130. absl::optional<gfx::Rect> clip_rect;
  131. if (draw_properties_.is_clipped) {
  132. clip_rect = draw_properties_.clip_rect;
  133. }
  134. state->SetAll(draw_properties_.target_space_transform, gfx::Rect(bounds()),
  135. draw_properties_.visible_layer_rect,
  136. draw_properties_.mask_filter_info, clip_rect, contents_opaque,
  137. draw_properties_.opacity,
  138. effect_node->HasRenderSurface() ? SkBlendMode::kSrcOver
  139. : effect_node->blend_mode,
  140. GetSortingContextId());
  141. state->is_fast_rounded_corner = draw_properties_.is_fast_rounded_corner;
  142. }
  143. void LayerImpl::PopulateScaledSharedQuadState(viz::SharedQuadState* state,
  144. float layer_to_content_scale,
  145. bool contents_opaque) const {
  146. gfx::Size scaled_bounds =
  147. gfx::ScaleToCeiledSize(bounds(), layer_to_content_scale);
  148. gfx::Rect scaled_visible_layer_rect =
  149. gfx::ScaleToEnclosingRect(visible_layer_rect(), layer_to_content_scale);
  150. scaled_visible_layer_rect.Intersect(gfx::Rect(scaled_bounds));
  151. PopulateScaledSharedQuadStateWithContentRects(
  152. state, layer_to_content_scale, gfx::Rect(scaled_bounds),
  153. scaled_visible_layer_rect, contents_opaque);
  154. }
  155. void LayerImpl::PopulateScaledSharedQuadStateWithContentRects(
  156. viz::SharedQuadState* state,
  157. float layer_to_content_scale,
  158. const gfx::Rect& content_rect,
  159. const gfx::Rect& visible_content_rect,
  160. bool contents_opaque) const {
  161. gfx::Transform scaled_draw_transform =
  162. GetScaledDrawTransform(layer_to_content_scale);
  163. EffectNode* effect_node = GetEffectTree().Node(effect_tree_index_);
  164. absl::optional<gfx::Rect> clip_rect;
  165. if (draw_properties().is_clipped) {
  166. clip_rect = draw_properties().clip_rect;
  167. }
  168. state->SetAll(scaled_draw_transform, content_rect, visible_content_rect,
  169. draw_properties().mask_filter_info, clip_rect, contents_opaque,
  170. draw_properties().opacity,
  171. effect_node->HasRenderSurface() ? SkBlendMode::kSrcOver
  172. : effect_node->blend_mode,
  173. GetSortingContextId());
  174. state->is_fast_rounded_corner = draw_properties().is_fast_rounded_corner;
  175. }
  176. bool LayerImpl::WillDraw(DrawMode draw_mode,
  177. viz::ClientResourceProvider* resource_provider) {
  178. if (visible_layer_rect().IsEmpty() ||
  179. draw_properties().occlusion_in_content_space.IsOccluded(
  180. visible_layer_rect())) {
  181. return false;
  182. }
  183. // Resourceless mode does not support non-default blend mode. If we draw,
  184. // the result will be just like kSrcOver which is not too bad for blend modes
  185. // other than kDstIn. For kDstIn mode, we should ignore the source because
  186. // otherwise we would draw a bad black mask over the destination.
  187. if (draw_mode == DRAW_MODE_RESOURCELESS_SOFTWARE) {
  188. const auto* effect_node = GetEffectTree().Node(effect_tree_index());
  189. if (effect_node && effect_node->blend_mode == SkBlendMode::kDstIn)
  190. return false;
  191. }
  192. current_draw_mode_ = draw_mode;
  193. return true;
  194. }
  195. void LayerImpl::DidDraw(viz::ClientResourceProvider* resource_provider) {
  196. current_draw_mode_ = DRAW_MODE_NONE;
  197. }
  198. bool LayerImpl::ShowDebugBorders(DebugBorderType type) const {
  199. return layer_tree_impl()->debug_state().show_debug_borders.test(type);
  200. }
  201. void LayerImpl::GetDebugBorderProperties(SkColor4f* color, float* width) const {
  202. float device_scale_factor =
  203. layer_tree_impl() ? layer_tree_impl()->device_scale_factor() : 1;
  204. if (draws_content_) {
  205. *color = DebugColors::ContentLayerBorderColor();
  206. *width = DebugColors::ContentLayerBorderWidth(device_scale_factor);
  207. return;
  208. }
  209. *color = DebugColors::ContainerLayerBorderColor();
  210. *width = DebugColors::ContainerLayerBorderWidth(device_scale_factor);
  211. }
  212. void LayerImpl::AppendDebugBorderQuad(
  213. viz::CompositorRenderPass* render_pass,
  214. const gfx::Rect& quad_rect,
  215. const viz::SharedQuadState* shared_quad_state,
  216. AppendQuadsData* append_quads_data) const {
  217. SkColor4f color;
  218. float width;
  219. GetDebugBorderProperties(&color, &width);
  220. AppendDebugBorderQuad(render_pass, quad_rect, shared_quad_state,
  221. append_quads_data, color, width);
  222. }
  223. void LayerImpl::AppendDebugBorderQuad(
  224. viz::CompositorRenderPass* render_pass,
  225. const gfx::Rect& quad_rect,
  226. const viz::SharedQuadState* shared_quad_state,
  227. AppendQuadsData* append_quads_data,
  228. SkColor4f color,
  229. float width) const {
  230. if (!ShowDebugBorders(DebugBorderType::LAYER))
  231. return;
  232. // This is the debug border quad layer size. The mojo serialization will fail
  233. // if the area overflows, so just drop this debug border quad in that case to
  234. // avoid crashes.
  235. if (!quad_rect.size().GetCheckedArea().IsValid())
  236. return;
  237. gfx::Rect visible_quad_rect(quad_rect);
  238. auto* debug_border_quad =
  239. render_pass->CreateAndAppendDrawQuad<viz::DebugBorderDrawQuad>();
  240. debug_border_quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect,
  241. color, width);
  242. if (contents_opaque()) {
  243. // When opaque, draw a second inner border that is thicker than the outer
  244. // border, but more transparent.
  245. static const float kFillOpacity = 0.3f;
  246. SkColor4f fill_color = color;
  247. fill_color.fA *= kFillOpacity;
  248. float fill_width = width * 3;
  249. gfx::Rect fill_rect = quad_rect;
  250. fill_rect.Inset(fill_width / 2.f);
  251. if (fill_rect.IsEmpty())
  252. return;
  253. gfx::Rect visible_fill_rect =
  254. gfx::IntersectRects(visible_quad_rect, fill_rect);
  255. auto* fill_quad =
  256. render_pass->CreateAndAppendDrawQuad<viz::DebugBorderDrawQuad>();
  257. fill_quad->SetNew(shared_quad_state, fill_rect, visible_fill_rect,
  258. fill_color, fill_width);
  259. }
  260. }
  261. void LayerImpl::GetContentsResourceId(viz::ResourceId* resource_id,
  262. gfx::Size* resource_size,
  263. gfx::SizeF* resource_uv_size) const {
  264. NOTREACHED();
  265. *resource_id = viz::kInvalidResourceId;
  266. }
  267. gfx::Vector2dF LayerImpl::ScrollBy(const gfx::Vector2dF& scroll) {
  268. ScrollTree& scroll_tree = GetScrollTree();
  269. ScrollNode* scroll_node = scroll_tree.Node(scroll_tree_index());
  270. DCHECK(scroll_node);
  271. return scroll_tree.ScrollBy(*scroll_node, scroll, layer_tree_impl());
  272. }
  273. void LayerImpl::UpdateScrollable() {
  274. if (!element_id()) {
  275. scrollable_ = false;
  276. return;
  277. }
  278. const auto* scroll_node = GetScrollTree().FindNodeFromElementId(element_id());
  279. bool was_scrollable = scrollable_;
  280. scrollable_ = scroll_node && scroll_node->scrollable;
  281. if (was_scrollable == scrollable_) {
  282. if (!scrollable_)
  283. return;
  284. if (scroll_container_bounds_ == scroll_node->container_bounds &&
  285. scroll_contents_bounds_ == scroll_node->bounds)
  286. return;
  287. }
  288. scroll_container_bounds_ =
  289. scrollable_ ? scroll_node->container_bounds : gfx::Size();
  290. scroll_contents_bounds_ = scrollable_ ? scroll_node->bounds : gfx::Size();
  291. // Scrollbar positions depend on the bounds.
  292. layer_tree_impl()->SetScrollbarGeometriesNeedUpdate();
  293. if (layer_tree_impl()->settings().scrollbar_animator ==
  294. LayerTreeSettings::AURA_OVERLAY) {
  295. set_needs_show_scrollbars(scrollable_);
  296. }
  297. NoteLayerPropertyChanged();
  298. }
  299. void LayerImpl::SetTouchActionRegion(TouchActionRegion region) {
  300. // Avoid recalculating the cached |all_touch_action_regions_| value.
  301. if (touch_action_region_ == region)
  302. return;
  303. touch_action_region_ = std::move(region);
  304. all_touch_action_regions_ = nullptr;
  305. }
  306. const Region& LayerImpl::GetAllTouchActionRegions() const {
  307. if (!all_touch_action_regions_) {
  308. all_touch_action_regions_ =
  309. std::make_unique<Region>(touch_action_region_.GetAllRegions());
  310. } else {
  311. // Ensure the cached value of |all_touch_action_regions_| is up to date.
  312. DCHECK_EQ(touch_action_region_.GetAllRegions(), *all_touch_action_regions_);
  313. }
  314. return *all_touch_action_regions_;
  315. }
  316. void LayerImpl::SetCaptureBounds(viz::RegionCaptureBounds bounds) {
  317. if (rare_properties_ || !bounds.IsEmpty())
  318. EnsureRareProperties().capture_bounds = std::move(bounds);
  319. }
  320. std::unique_ptr<LayerImpl> LayerImpl::CreateLayerImpl(
  321. LayerTreeImpl* tree_impl) const {
  322. return LayerImpl::Create(tree_impl, layer_id_);
  323. }
  324. bool LayerImpl::IsSnappedToPixelGridInTarget() {
  325. return false;
  326. }
  327. void LayerImpl::PushPropertiesTo(LayerImpl* layer) {
  328. DCHECK(layer->IsActive());
  329. // The element id should be set first because other setters may
  330. // depend on it. Referencing element id on a layer is
  331. // deprecated. http://crbug.com/709137
  332. layer->SetElementId(element_id_);
  333. layer->has_transform_node_ = has_transform_node_;
  334. layer->offset_to_transform_parent_ = offset_to_transform_parent_;
  335. layer->contents_opaque_ = contents_opaque_;
  336. layer->contents_opaque_for_text_ = contents_opaque_for_text_;
  337. layer->may_contain_video_ = may_contain_video_;
  338. layer->should_check_backface_visibility_ = should_check_backface_visibility_;
  339. layer->draws_content_ = draws_content_;
  340. layer->hit_testable_ = hit_testable_;
  341. layer->touch_action_region_ = touch_action_region_;
  342. layer->all_touch_action_regions_ = ClonePtr(all_touch_action_regions_);
  343. layer->background_color_ = background_color_;
  344. layer->safe_opaque_background_color_ = safe_opaque_background_color_;
  345. layer->transform_tree_index_ = transform_tree_index_;
  346. layer->effect_tree_index_ = effect_tree_index_;
  347. layer->clip_tree_index_ = clip_tree_index_;
  348. layer->scroll_tree_index_ = scroll_tree_index_;
  349. if (needs_show_scrollbars_)
  350. layer->needs_show_scrollbars_ = needs_show_scrollbars_;
  351. if (layer_property_changed_not_from_property_trees_ ||
  352. layer_property_changed_from_property_trees_)
  353. layer->layer_tree_impl()->set_needs_update_draw_properties();
  354. if (layer_property_changed_not_from_property_trees_)
  355. layer->layer_property_changed_not_from_property_trees_ = true;
  356. if (layer_property_changed_from_property_trees_)
  357. layer->layer_property_changed_from_property_trees_ = true;
  358. layer->SetBounds(bounds_);
  359. layer->UpdateScrollable();
  360. layer->UnionUpdateRect(update_rect_);
  361. layer->UpdateDebugInfo(debug_info_.get());
  362. if (rare_properties_) {
  363. layer->rare_properties_ =
  364. std::make_unique<RareProperties>(*rare_properties_);
  365. } else {
  366. layer->rare_properties_.reset();
  367. }
  368. // Reset any state that should be cleared for the next update.
  369. needs_show_scrollbars_ = false;
  370. ResetChangeTracking();
  371. }
  372. bool LayerImpl::IsAffectedByPageScale() const {
  373. TransformTree& transform_tree = GetTransformTree();
  374. return transform_tree.Node(transform_tree_index())
  375. ->in_subtree_of_page_scale_layer;
  376. }
  377. bool LayerImpl::LayerPropertyChanged() const {
  378. return layer_property_changed_not_from_property_trees_ ||
  379. LayerPropertyChangedFromPropertyTrees();
  380. }
  381. bool LayerImpl::LayerPropertyChangedFromPropertyTrees() const {
  382. if (layer_property_changed_from_property_trees_ ||
  383. GetPropertyTrees()->full_tree_damaged())
  384. return true;
  385. if (transform_tree_index() == kInvalidPropertyNodeId)
  386. return false;
  387. TransformNode* transform_node =
  388. GetTransformTree().Node(transform_tree_index());
  389. if (transform_node && transform_node->transform_changed)
  390. return true;
  391. if (effect_tree_index() == kInvalidPropertyNodeId)
  392. return false;
  393. EffectNode* effect_node = GetEffectTree().Node(effect_tree_index());
  394. if (effect_node && effect_node->effect_changed)
  395. return true;
  396. return false;
  397. }
  398. bool LayerImpl::LayerPropertyChangedNotFromPropertyTrees() const {
  399. return layer_property_changed_not_from_property_trees_;
  400. }
  401. void LayerImpl::NoteLayerPropertyChanged() {
  402. layer_property_changed_not_from_property_trees_ = true;
  403. layer_tree_impl()->set_needs_update_draw_properties();
  404. }
  405. void LayerImpl::NoteLayerPropertyChangedFromPropertyTrees() {
  406. layer_property_changed_from_property_trees_ = true;
  407. layer_tree_impl()->set_needs_update_draw_properties();
  408. }
  409. void LayerImpl::ValidateQuadResourcesInternal(viz::DrawQuad* quad) const {
  410. #if DCHECK_IS_ON()
  411. const viz::ClientResourceProvider* resource_provider =
  412. layer_tree_impl_->resource_provider();
  413. for (viz::ResourceId resource_id : quad->resources)
  414. resource_provider->ValidateResource(resource_id);
  415. #endif
  416. }
  417. gfx::Transform LayerImpl::GetScaledDrawTransform(
  418. float layer_to_content_scale) const {
  419. gfx::Transform scaled_draw_transform =
  420. draw_properties_.target_space_transform;
  421. scaled_draw_transform.Scale(SK_Scalar1 / layer_to_content_scale,
  422. SK_Scalar1 / layer_to_content_scale);
  423. return scaled_draw_transform;
  424. }
  425. const char* LayerImpl::LayerTypeAsString() const {
  426. return "cc::LayerImpl";
  427. }
  428. void LayerImpl::ResetChangeTracking() {
  429. layer_property_changed_not_from_property_trees_ = false;
  430. layer_property_changed_from_property_trees_ = false;
  431. needs_push_properties_ = false;
  432. update_rect_.SetRect(0, 0, 0, 0);
  433. if (debug_info_)
  434. debug_info_->invalidations.clear();
  435. }
  436. bool LayerImpl::IsActive() const {
  437. return layer_tree_impl_->IsActiveTree();
  438. }
  439. gfx::Size LayerImpl::bounds() const {
  440. if (!is_inner_viewport_scroll_layer_)
  441. return bounds_;
  442. auto viewport_bounds_delta = gfx::ToCeiledVector2d(
  443. GetPropertyTrees()->inner_viewport_scroll_bounds_delta());
  444. return gfx::Size(bounds_.width() + viewport_bounds_delta.x(),
  445. bounds_.height() + viewport_bounds_delta.y());
  446. }
  447. void LayerImpl::SetBounds(const gfx::Size& bounds) {
  448. if (bounds_ == bounds)
  449. return;
  450. bounds_ = bounds;
  451. // Scrollbar positions depend on the scrolling layer bounds.
  452. if (scrollable_)
  453. layer_tree_impl()->SetScrollbarGeometriesNeedUpdate();
  454. NoteLayerPropertyChanged();
  455. }
  456. bool LayerImpl::IsScrollbarLayer() const {
  457. return false;
  458. }
  459. bool LayerImpl::IsScrollerOrScrollbar() const {
  460. return IsScrollbarLayer() ||
  461. GetScrollTree().FindNodeFromElementId(element_id());
  462. }
  463. void LayerImpl::SetDrawsContent(bool draws_content) {
  464. if (draws_content_ == draws_content)
  465. return;
  466. draws_content_ = draws_content;
  467. NoteLayerPropertyChanged();
  468. }
  469. void LayerImpl::SetHitTestable(bool should_hit_test) {
  470. if (hit_testable_ == should_hit_test)
  471. return;
  472. hit_testable_ = should_hit_test;
  473. NoteLayerPropertyChanged();
  474. }
  475. bool LayerImpl::HitTestable() const {
  476. EffectTree& effect_tree = GetEffectTree();
  477. bool should_hit_test = hit_testable_;
  478. // TODO(sunxd): remove or refactor SetHideLayerAndSubtree, or move this logic
  479. // to subclasses of Layer. See https://crbug.com/595843 and
  480. // https://crbug.com/931865.
  481. // The bit |subtree_hidden| can only be true for ui::Layers. Other layers are
  482. // not supposed to set this bit.
  483. if (effect_tree.Node(effect_tree_index())) {
  484. should_hit_test &= !effect_tree.Node(effect_tree_index())->subtree_hidden;
  485. }
  486. return should_hit_test;
  487. }
  488. void LayerImpl::SetBackgroundColor(SkColor4f background_color) {
  489. if (background_color_ == background_color)
  490. return;
  491. background_color_ = background_color;
  492. NoteLayerPropertyChanged();
  493. }
  494. void LayerImpl::SetSafeOpaqueBackgroundColor(SkColor4f background_color) {
  495. safe_opaque_background_color_ = background_color;
  496. }
  497. void LayerImpl::SetContentsOpaque(bool opaque) {
  498. contents_opaque_ = opaque;
  499. contents_opaque_for_text_ = opaque;
  500. }
  501. void LayerImpl::SetContentsOpaqueForText(bool opaque) {
  502. DCHECK(!contents_opaque_ || opaque);
  503. contents_opaque_for_text_ = opaque;
  504. }
  505. float LayerImpl::Opacity() const {
  506. if (const EffectNode* node = GetEffectTree().Node(effect_tree_index()))
  507. return node->opacity;
  508. else
  509. return 1.f;
  510. }
  511. void LayerImpl::SetElementId(ElementId element_id) {
  512. if (element_id == element_id_)
  513. return;
  514. TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "LayerImpl::SetElementId",
  515. "element", element_id.ToString());
  516. element_id_ = element_id;
  517. }
  518. void LayerImpl::UnionUpdateRect(const gfx::Rect& update_rect) {
  519. update_rect_.Union(update_rect);
  520. }
  521. gfx::Rect LayerImpl::GetDamageRect() const {
  522. return gfx::Rect();
  523. }
  524. void LayerImpl::SetCurrentScrollOffset(const gfx::PointF& scroll_offset) {
  525. DCHECK(IsActive());
  526. if (GetScrollTree().SetScrollOffset(element_id(), scroll_offset))
  527. layer_tree_impl()->DidUpdateScrollOffset(element_id());
  528. }
  529. SimpleEnclosedRegion LayerImpl::VisibleOpaqueRegion() const {
  530. if (contents_opaque())
  531. return SimpleEnclosedRegion(visible_layer_rect());
  532. return SimpleEnclosedRegion();
  533. }
  534. void LayerImpl::DidBeginTracing() {}
  535. void LayerImpl::ReleaseResources() {}
  536. void LayerImpl::OnPurgeMemory() {
  537. ReleaseResources();
  538. }
  539. void LayerImpl::ReleaseTileResources() {}
  540. void LayerImpl::RecreateTileResources() {}
  541. void LayerImpl::SetNeedsPushProperties() {
  542. // There's no need to push layer properties on the active tree, or when
  543. // |will_always_push_properties_| is true.
  544. if (will_always_push_properties_ || layer_tree_impl()->IsActiveTree())
  545. return;
  546. if (!needs_push_properties_) {
  547. needs_push_properties_ = true;
  548. layer_tree_impl()->AddLayerShouldPushProperties(this);
  549. }
  550. }
  551. void LayerImpl::GetAllPrioritizedTilesForTracing(
  552. std::vector<PrioritizedTile>* prioritized_tiles) const {
  553. }
  554. void LayerImpl::AsValueInto(base::trace_event::TracedValue* state) const {
  555. // The output is consumed at least by
  556. // 1. DevTools for showing layer tree information for frame snapshots in
  557. // performance timeline (third_party/devtools_frontend/src/front_end/
  558. // timeline_model/TracingLayerTree.js),
  559. // 2. trace_viewer
  560. // (third_party/catapult/tracing/tracing/extras/chrome/cc/layer_impl.html)
  561. // Note that trace_viewer uses "namingStyle" style instead of
  562. // "naming_style". The difference is intentional and the names are
  563. // converted automatically, but we need to keep this in mind when we
  564. // search trace_viewer code for the usage of the names here.
  565. // When making changes here, we need to make sure we won't break these
  566. // consumers.
  567. viz::TracedValue::MakeDictIntoImplicitSnapshotWithCategory(
  568. TRACE_DISABLED_BY_DEFAULT("cc.debug"), state, "cc::LayerImpl",
  569. LayerTypeAsString(), this);
  570. state->SetInteger("layer_id", id());
  571. MathUtil::AddToTracedValue("bounds", bounds_, state);
  572. state->SetDouble("opacity", Opacity());
  573. // For backward-compatibility of DevTools front-end.
  574. MathUtil::AddToTracedValue("position", gfx::PointF(), state);
  575. state->SetInteger("transform_tree_index", transform_tree_index());
  576. state->SetInteger("clip_tree_index", clip_tree_index());
  577. state->SetInteger("effect_tree_index", effect_tree_index());
  578. state->SetInteger("scroll_tree_index", scroll_tree_index());
  579. state->SetInteger("sorting_context_id", GetSortingContextId());
  580. state->SetInteger("draws_content", draws_content());
  581. state->SetInteger("gpu_memory_usage",
  582. base::saturated_cast<int>(GPUMemoryUsageInBytes()));
  583. if (element_id_)
  584. element_id_.AddToTracedValue(state);
  585. if (!ScreenSpaceTransform().IsIdentity())
  586. MathUtil::AddToTracedValue("screen_space_transform", ScreenSpaceTransform(),
  587. state);
  588. bool clipped;
  589. gfx::QuadF layer_quad =
  590. MathUtil::MapQuad(ScreenSpaceTransform(),
  591. gfx::QuadF(gfx::RectF(gfx::Rect(bounds()))), &clipped);
  592. MathUtil::AddToTracedValue("layer_quad", layer_quad, state);
  593. if (!GetAllTouchActionRegions().IsEmpty()) {
  594. state->BeginArray("all_touch_action_regions");
  595. GetAllTouchActionRegions().AsValueInto(state);
  596. state->EndArray();
  597. }
  598. state->BeginArray("wheel_event_handler_region");
  599. wheel_event_handler_region().AsValueInto(state);
  600. state->EndArray();
  601. state->BeginArray("non_fast_scrollable_region");
  602. non_fast_scrollable_region().AsValueInto(state);
  603. state->EndArray();
  604. state->SetBoolean("hit_testable", HitTestable());
  605. state->SetBoolean("contents_opaque", contents_opaque());
  606. if (debug_info_) {
  607. state->SetString("layer_name", debug_info_->name);
  608. if (debug_info_->owner_node_id)
  609. state->SetInteger("owner_node", debug_info_->owner_node_id);
  610. if (debug_info_->compositing_reasons.size()) {
  611. state->BeginArray("compositing_reasons");
  612. for (const char* reason : debug_info_->compositing_reasons)
  613. state->AppendString(reason);
  614. state->EndArray();
  615. }
  616. if (debug_info_->compositing_reason_ids.size()) {
  617. state->BeginArray("compositing_reason_ids");
  618. for (const char* reason_id : debug_info_->compositing_reason_ids)
  619. state->AppendString(reason_id);
  620. state->EndArray();
  621. }
  622. if (debug_info_->invalidations.size()) {
  623. state->BeginArray("annotated_invalidation_rects");
  624. for (auto& invalidation : debug_info_->invalidations) {
  625. state->BeginDictionary();
  626. MathUtil::AddToTracedValue("geometry_rect", invalidation.rect, state);
  627. state->SetString("reason", invalidation.reason);
  628. state->SetString("client", invalidation.client);
  629. state->EndDictionary();
  630. }
  631. state->EndArray();
  632. }
  633. }
  634. }
  635. std::string LayerImpl::ToString() const {
  636. base::trace_event::TracedValueJSON value;
  637. AsValueInto(&value);
  638. return value.ToFormattedJSON();
  639. }
  640. size_t LayerImpl::GPUMemoryUsageInBytes() const { return 0; }
  641. void LayerImpl::RunMicroBenchmark(MicroBenchmarkImpl* benchmark) {
  642. benchmark->RunOnLayer(this);
  643. }
  644. gfx::Transform LayerImpl::DrawTransform() const {
  645. // Only drawn layers have up-to-date draw properties.
  646. if (!contributes_to_drawn_render_surface()) {
  647. return draw_property_utils::DrawTransform(this, GetTransformTree(),
  648. GetEffectTree());
  649. }
  650. return draw_properties().target_space_transform;
  651. }
  652. gfx::Transform LayerImpl::ScreenSpaceTransform() const {
  653. // Only drawn layers have up-to-date draw properties.
  654. if (!contributes_to_drawn_render_surface()) {
  655. return draw_property_utils::ScreenSpaceTransform(this, GetTransformTree());
  656. }
  657. return draw_properties().screen_space_transform;
  658. }
  659. int LayerImpl::GetSortingContextId() const {
  660. return GetTransformTree().Node(transform_tree_index())->sorting_context_id;
  661. }
  662. Region LayerImpl::GetInvalidationRegionForDebugging() {
  663. return Region(update_rect_);
  664. }
  665. gfx::Rect LayerImpl::GetEnclosingVisibleRectInTargetSpace() const {
  666. return GetScaledEnclosingVisibleRectInTargetSpace(1.0f);
  667. }
  668. gfx::Rect LayerImpl::GetScaledEnclosingVisibleRectInTargetSpace(
  669. float scale) const {
  670. // TODO(oshima): Define an utility function to scale layer and conslidate with
  671. // the logic in ComputeDrawPropertiesOfVisibleLayers() in
  672. // draw_property_util.cc.
  673. DCHECK_GT(scale, 0.0);
  674. bool only_draws_visible_content = GetPropertyTrees()
  675. ->effect_tree()
  676. .Node(effect_tree_index())
  677. ->only_draws_visible_content;
  678. gfx::Rect drawable_bounds = visible_layer_rect();
  679. if (!only_draws_visible_content) {
  680. drawable_bounds = gfx::Rect(bounds());
  681. }
  682. gfx::Transform scaled_draw_transform = GetScaledDrawTransform(scale);
  683. gfx::Rect scaled_bounds = ScaleToEnclosingRect(drawable_bounds, scale);
  684. return MathUtil::MapEnclosingClippedRect(scaled_draw_transform,
  685. scaled_bounds);
  686. }
  687. RenderSurfaceImpl* LayerImpl::render_target() {
  688. return GetEffectTree().GetRenderSurface(render_target_effect_tree_index());
  689. }
  690. const RenderSurfaceImpl* LayerImpl::render_target() const {
  691. return GetEffectTree().GetRenderSurface(render_target_effect_tree_index());
  692. }
  693. gfx::Vector2dF LayerImpl::GetIdealContentsScale() const {
  694. const auto& transform = ScreenSpaceTransform();
  695. absl::optional<gfx::Vector2dF> transform_scales =
  696. gfx::TryComputeTransform2dScaleComponents(transform);
  697. if (transform_scales) {
  698. // TODO(crbug.com/1196414): Remove this scale cap.
  699. float scale_cap = GetPreferredRasterScale(*transform_scales);
  700. transform_scales->SetToMin(gfx::Vector2dF(scale_cap, scale_cap));
  701. return *transform_scales;
  702. }
  703. // TryComputeTransform2dScaleComponents couldn't compute a scale because of
  704. // perspective components in the transform.
  705. float page_scale = IsAffectedByPageScale()
  706. ? layer_tree_impl()->current_page_scale_factor()
  707. : 1.f;
  708. float device_scale = layer_tree_impl()->device_scale_factor();
  709. float default_scale = page_scale * device_scale;
  710. // TODO(crbug.com/1196414): This function should return a 2D scale.
  711. float scale = gfx::ComputeApproximateMaxScale(transform);
  712. const int kMaxTilesToCoverLayerDimension = 5;
  713. // Cap the scale in a way that it should be covered by at most
  714. // |kMaxTilesToCoverLayerDimension|^2 default tile sizes. If this is left
  715. // uncapped, then we can fairly easily use too much memory (or too many
  716. // tiles). See crbug.com/752382 for an example of such a page. Note that
  717. // because this is an approximation anyway, it's fine to use a smaller scale
  718. // that desired. On top of this, the layer has a perspective transform so
  719. // technically it could all be within the viewport, so it's important for us
  720. // to have a reasonable scale here. The scale we use would also be at least
  721. // |default_scale|, as checked below.
  722. float scale_cap = std::min(
  723. (layer_tree_impl()->settings().default_tile_size.width() - 2) *
  724. kMaxTilesToCoverLayerDimension / static_cast<float>(bounds().width()),
  725. (layer_tree_impl()->settings().default_tile_size.height() - 2) *
  726. kMaxTilesToCoverLayerDimension /
  727. static_cast<float>(bounds().height()));
  728. scale = std::min(scale, scale_cap);
  729. // Since we're approximating the scale anyway, round it to the nearest
  730. // integer to prevent jitter when animating the transform.
  731. scale = std::round(scale);
  732. // Don't let the scale fall below the default scale.
  733. scale = std::max(scale, default_scale);
  734. return gfx::Vector2dF(scale, scale);
  735. }
  736. float LayerImpl::GetIdealContentsScaleKey() const {
  737. return GetPreferredRasterScale(GetIdealContentsScale());
  738. }
  739. float LayerImpl::GetPreferredRasterScale(
  740. gfx::Vector2dF raster_space_scale_factor) {
  741. constexpr float kMaxScaleRatio = 5.f;
  742. float lower_scale =
  743. std::min(raster_space_scale_factor.x(), raster_space_scale_factor.y());
  744. float higher_scale =
  745. std::max(raster_space_scale_factor.x(), raster_space_scale_factor.y());
  746. return std::min(kMaxScaleRatio * lower_scale, higher_scale);
  747. }
  748. PropertyTrees* LayerImpl::GetPropertyTrees() const {
  749. return layer_tree_impl_->property_trees();
  750. }
  751. ClipTree& LayerImpl::GetClipTree() const {
  752. return GetPropertyTrees()->clip_tree_mutable();
  753. }
  754. EffectTree& LayerImpl::GetEffectTree() const {
  755. return GetPropertyTrees()->effect_tree_mutable();
  756. }
  757. ScrollTree& LayerImpl::GetScrollTree() const {
  758. return GetPropertyTrees()->scroll_tree_mutable();
  759. }
  760. TransformTree& LayerImpl::GetTransformTree() const {
  761. return GetPropertyTrees()->transform_tree_mutable();
  762. }
  763. void LayerImpl::EnsureValidPropertyTreeIndices() const {
  764. DCHECK(GetTransformTree().Node(transform_tree_index()));
  765. DCHECK(GetEffectTree().Node(effect_tree_index()));
  766. DCHECK(GetClipTree().Node(clip_tree_index()));
  767. DCHECK(GetScrollTree().Node(scroll_tree_index()));
  768. }
  769. bool LayerImpl::is_surface_layer() const {
  770. return false;
  771. }
  772. static float TranslationFromActiveTreeLayerScreenSpaceTransform(
  773. LayerImpl* pending_tree_layer) {
  774. LayerTreeImpl* layer_tree_impl = pending_tree_layer->layer_tree_impl();
  775. if (layer_tree_impl) {
  776. LayerImpl* active_tree_layer =
  777. layer_tree_impl->FindActiveTreeLayerById(pending_tree_layer->id());
  778. if (active_tree_layer) {
  779. gfx::Transform active_tree_screen_space_transform =
  780. active_tree_layer->draw_properties().screen_space_transform;
  781. if (active_tree_screen_space_transform.IsIdentity())
  782. return 0.f;
  783. if (active_tree_screen_space_transform.ApproximatelyEqual(
  784. pending_tree_layer->draw_properties().screen_space_transform))
  785. return 0.f;
  786. return (active_tree_layer->draw_properties()
  787. .screen_space_transform.To2dTranslation() -
  788. pending_tree_layer->draw_properties()
  789. .screen_space_transform.To2dTranslation())
  790. .Length();
  791. }
  792. }
  793. return 0.f;
  794. }
  795. // A layer jitters if its screen space transform is same on two successive
  796. // commits, but has changed in between the commits. CalculateLayerJitter
  797. // computes the jitter for the layer.
  798. int LayerImpl::CalculateJitter() {
  799. float jitter = 0.f;
  800. performance_properties().translation_from_last_frame = 0.f;
  801. performance_properties().last_commit_screen_space_transform =
  802. draw_properties().screen_space_transform;
  803. if (!visible_layer_rect().IsEmpty()) {
  804. if (draw_properties().screen_space_transform.ApproximatelyEqual(
  805. performance_properties().last_commit_screen_space_transform)) {
  806. float translation_from_last_commit =
  807. TranslationFromActiveTreeLayerScreenSpaceTransform(this);
  808. if (translation_from_last_commit > 0.f) {
  809. performance_properties().num_fixed_point_hits++;
  810. performance_properties().translation_from_last_frame =
  811. translation_from_last_commit;
  812. if (performance_properties().num_fixed_point_hits >
  813. LayerTreeImpl::kFixedPointHitsThreshold) {
  814. // Jitter = Translation from fixed point * sqrt(Area of the layer).
  815. // The square root of the area is used instead of the area to match
  816. // the dimensions of both terms on the rhs.
  817. jitter += translation_from_last_commit *
  818. sqrt(visible_layer_rect().size().GetArea());
  819. }
  820. } else {
  821. performance_properties().num_fixed_point_hits = 0;
  822. }
  823. }
  824. }
  825. return jitter;
  826. }
  827. std::string LayerImpl::DebugName() const {
  828. return debug_info_ ? debug_info_->name : "";
  829. }
  830. gfx::ContentColorUsage LayerImpl::GetContentColorUsage() const {
  831. return gfx::ContentColorUsage::kSRGB;
  832. }
  833. } // namespace cc