summaryrefslogtreecommitdiffstats
path: root/chromium/cc/trees
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-08-30 10:22:43 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-08-30 12:36:28 +0000
commit271a6c3487a14599023a9106329505597638d793 (patch)
treee040d58ffc86c1480b79ca8528020ca9ec919bf8 /chromium/cc/trees
parent7b2ffa587235a47d4094787d72f38102089f402a (diff)
BASELINE: Update Chromium to 77.0.3865.59
Change-Id: I1e89a5f3b009a9519a6705102ad65c92fe736f21 Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/cc/trees')
-rw-r--r--chromium/cc/trees/damage_tracker.cc4
-rw-r--r--chromium/cc/trees/damage_tracker_unittest.cc81
-rw-r--r--chromium/cc/trees/draw_property_utils.cc24
-rw-r--r--chromium/cc/trees/draw_property_utils.h3
-rw-r--r--chromium/cc/trees/effect_node.cc6
-rw-r--r--chromium/cc/trees/effect_node.h7
-rw-r--r--chromium/cc/trees/element_id.cc51
-rw-r--r--chromium/cc/trees/element_id.h89
-rw-r--r--chromium/cc/trees/frame_sequence_tracker.cc390
-rw-r--r--chromium/cc/trees/frame_sequence_tracker.h238
-rw-r--r--chromium/cc/trees/frame_sequence_tracker_unittest.cc109
-rw-r--r--chromium/cc/trees/image_animation_controller.cc2
-rw-r--r--chromium/cc/trees/image_animation_controller.h2
-rw-r--r--chromium/cc/trees/layer_tree_frame_sink.cc3
-rw-r--r--chromium/cc/trees/layer_tree_frame_sink.h5
-rw-r--r--chromium/cc/trees/layer_tree_frame_sink_client.h3
-rw-r--r--chromium/cc/trees/layer_tree_frame_sink_unittest.cc3
-rw-r--r--chromium/cc/trees/layer_tree_host.cc32
-rw-r--r--chromium/cc/trees/layer_tree_host.h15
-rw-r--r--chromium/cc/trees/layer_tree_host_client.h14
-rw-r--r--chromium/cc/trees/layer_tree_host_common.cc14
-rw-r--r--chromium/cc/trees/layer_tree_host_common.h8
-rw-r--r--chromium/cc/trees/layer_tree_host_common_perftest.cc1
-rw-r--r--chromium/cc/trees/layer_tree_host_common_unittest.cc371
-rw-r--r--chromium/cc/trees/layer_tree_host_impl.cc454
-rw-r--r--chromium/cc/trees/layer_tree_host_impl.h105
-rw-r--r--chromium/cc/trees/layer_tree_host_impl_unittest.cc354
-rw-r--r--chromium/cc/trees/layer_tree_host_perftest.cc6
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_blending.cc68
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_filters.cc233
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_masks.cc194
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_mirror.cc83
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_readback.cc91
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc29
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc11
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc44
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest.cc418
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_animation.cc17
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_capture_content.cc107
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc2
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_context.cc6
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc10
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_masks.cc195
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_picture.cc8
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_scroll.cc228
-rw-r--r--chromium/cc/trees/layer_tree_impl.cc65
-rw-r--r--chromium/cc/trees/layer_tree_impl.h21
-rw-r--r--chromium/cc/trees/layer_tree_impl_unittest.cc68
-rw-r--r--chromium/cc/trees/layer_tree_settings.cc8
-rw-r--r--chromium/cc/trees/layer_tree_settings.h4
-rw-r--r--chromium/cc/trees/mutator_host.h9
-rw-r--r--chromium/cc/trees/mutator_host_client.h2
-rw-r--r--chromium/cc/trees/occlusion_tracker_unittest.cc1
-rw-r--r--chromium/cc/trees/property_tree.cc30
-rw-r--r--chromium/cc/trees/property_tree.h3
-rw-r--r--chromium/cc/trees/property_tree_builder.cc77
-rw-r--r--chromium/cc/trees/proxy.h4
-rw-r--r--chromium/cc/trees/proxy_impl.cc36
-rw-r--r--chromium/cc/trees/proxy_impl.h3
-rw-r--r--chromium/cc/trees/proxy_main.cc61
-rw-r--r--chromium/cc/trees/proxy_main.h5
-rw-r--r--chromium/cc/trees/scroll_node.cc2
-rw-r--r--chromium/cc/trees/scroll_node.h2
-rw-r--r--chromium/cc/trees/single_thread_proxy.cc46
-rw-r--r--chromium/cc/trees/single_thread_proxy.h8
-rw-r--r--chromium/cc/trees/transform_node.h5
-rw-r--r--chromium/cc/trees/tree_synchronizer.cc6
-rw-r--r--chromium/cc/trees/tree_synchronizer_unittest.cc28
-rw-r--r--chromium/cc/trees/viewport_layers.h3
69 files changed, 3189 insertions, 1446 deletions
diff --git a/chromium/cc/trees/damage_tracker.cc b/chromium/cc/trees/damage_tracker.cc
index f3ddee21062..743b681dc6a 100644
--- a/chromium/cc/trees/damage_tracker.cc
+++ b/chromium/cc/trees/damage_tracker.cc
@@ -386,7 +386,7 @@ void DamageTracker::AccumulateDamageFromLayer(LayerImpl* layer) {
// If the layer properties haven't changed, then the the target surface is
// only affected by the layer's damaged area, which could be empty.
gfx::Rect damage_rect =
- gfx::UnionRects(layer->update_rect(), layer->damage_rect());
+ gfx::UnionRects(layer->update_rect(), layer->GetDamageRect());
damage_rect.Intersect(gfx::Rect(layer->bounds()));
if (!damage_rect.IsEmpty()) {
@@ -416,7 +416,7 @@ void DamageTracker::AccumulateDamageFromLayer(LayerImpl* layer) {
if (layer_is_new || !layer->update_rect().IsEmpty() ||
layer->LayerPropertyChangedNotFromPropertyTrees() ||
- !layer->damage_rect().IsEmpty() || property_change_on_non_target_node) {
+ !layer->GetDamageRect().IsEmpty() || property_change_on_non_target_node) {
has_damage_from_contributing_content_ |= !damage_for_this_update_.IsEmpty();
}
}
diff --git a/chromium/cc/trees/damage_tracker_unittest.cc b/chromium/cc/trees/damage_tracker_unittest.cc
index fcd75ca4f75..b9046c6644b 100644
--- a/chromium/cc/trees/damage_tracker_unittest.cc
+++ b/chromium/cc/trees/damage_tracker_unittest.cc
@@ -26,6 +26,36 @@
namespace cc {
namespace {
+class TestLayerImpl : public LayerImpl {
+ public:
+ TestLayerImpl(LayerTreeImpl* tree_impl, int id);
+
+ void AddDamageRect(const gfx::Rect& damage_rect);
+
+ // LayerImpl overrides.
+ gfx::Rect GetDamageRect() const override;
+ void ResetChangeTracking() override;
+
+ private:
+ gfx::Rect damage_rect_;
+};
+
+TestLayerImpl::TestLayerImpl(LayerTreeImpl* tree_impl, int id)
+ : LayerImpl(tree_impl, id) {}
+
+void TestLayerImpl::AddDamageRect(const gfx::Rect& damage_rect) {
+ damage_rect_.Union(damage_rect);
+}
+
+gfx::Rect TestLayerImpl::GetDamageRect() const {
+ return damage_rect_;
+}
+
+void TestLayerImpl::ResetChangeTracking() {
+ LayerImpl::ResetChangeTracking();
+ damage_rect_.SetRect(0, 0, 0, 0);
+}
+
void ExecuteCalculateDrawProperties(LayerImpl* root,
float device_scale_factor,
RenderSurfaceList* render_surface_list) {
@@ -71,16 +101,15 @@ class DamageTrackerTest : public testing::Test {
LayerImpl* CreateTestTreeWithOneSurface(int number_of_children) {
host_impl_.active_tree()->DetachLayers();
- std::unique_ptr<LayerImpl> root =
- LayerImpl::Create(host_impl_.active_tree(), 1);
+ auto root = std::make_unique<TestLayerImpl>(host_impl_.active_tree(), 1);
root->SetBounds(gfx::Size(500, 500));
root->SetDrawsContent(true);
root->test_properties()->force_render_surface = true;
for (int i = 0; i < number_of_children; ++i) {
- std::unique_ptr<LayerImpl> child =
- LayerImpl::Create(host_impl_.active_tree(), 2 + i);
+ auto child =
+ std::make_unique<TestLayerImpl>(host_impl_.active_tree(), 2 + i);
child->test_properties()->position = gfx::PointF(100.f, 100.f);
child->SetBounds(gfx::Size(30, 30));
child->SetDrawsContent(true);
@@ -98,16 +127,13 @@ class DamageTrackerTest : public testing::Test {
// two children of its own.
host_impl_.active_tree()->DetachLayers();
- std::unique_ptr<LayerImpl> root =
- LayerImpl::Create(host_impl_.active_tree(), 1);
- std::unique_ptr<LayerImpl> child1 =
- LayerImpl::Create(host_impl_.active_tree(), 2);
- std::unique_ptr<LayerImpl> child2 =
- LayerImpl::Create(host_impl_.active_tree(), 3);
- std::unique_ptr<LayerImpl> grand_child1 =
- LayerImpl::Create(host_impl_.active_tree(), 4);
- std::unique_ptr<LayerImpl> grand_child2 =
- LayerImpl::Create(host_impl_.active_tree(), 5);
+ auto root = std::make_unique<TestLayerImpl>(host_impl_.active_tree(), 1);
+ auto child1 = std::make_unique<TestLayerImpl>(host_impl_.active_tree(), 2);
+ auto child2 = std::make_unique<TestLayerImpl>(host_impl_.active_tree(), 3);
+ auto grand_child1 =
+ std::make_unique<TestLayerImpl>(host_impl_.active_tree(), 4);
+ auto grand_child2 =
+ std::make_unique<TestLayerImpl>(host_impl_.active_tree(), 5);
root->SetBounds(gfx::Size(500, 500));
root->SetDrawsContent(true);
@@ -276,7 +302,8 @@ TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) {
TEST_F(DamageTrackerTest, VerifyDamageForLayerDamageRects) {
LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface();
- LayerImpl* child = root->test_properties()->children[0];
+ auto* child =
+ static_cast<TestLayerImpl*>(root->test_properties()->children[0]);
// CASE 1: Adding the layer damage rect should cause the corresponding damage
// to the surface.
@@ -336,7 +363,8 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerDamageRects) {
TEST_F(DamageTrackerTest, VerifyDamageForLayerUpdateAndDamageRects) {
LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface();
- LayerImpl* child = root->test_properties()->children[0];
+ auto* child =
+ static_cast<TestLayerImpl*>(root->test_properties()->children[0]);
// CASE 1: Adding the layer damage rect and update rect should cause the
// corresponding damage to the surface.
@@ -547,9 +575,12 @@ TEST_F(DamageTrackerTest, TransformPropertyChangeNoSurface) {
TEST_F(DamageTrackerTest,
VerifyDamageForUpdateAndDamageRectsFromContributingContents) {
LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces();
- LayerImpl* child1 = root->test_properties()->children[0];
- LayerImpl* child2 = root->test_properties()->children[1];
- LayerImpl* grandchild1 = child1->test_properties()->children[0];
+ auto* child1 =
+ static_cast<TestLayerImpl*>(root->test_properties()->children[0]);
+ auto* child2 =
+ static_cast<TestLayerImpl*>(root->test_properties()->children[1]);
+ auto* grandchild1 =
+ static_cast<TestLayerImpl*>(child1->test_properties()->children[0]);
// CASE 1: Adding the layer1's damage rect and update rect should cause the
// corresponding damage to the surface.
@@ -1912,8 +1943,10 @@ TEST_F(DamageTrackerTest, DamageRectTooBigWithFilter) {
TEST_F(DamageTrackerTest, DamageRectTooBigInRenderSurface) {
LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces();
LayerImpl* child1 = root->test_properties()->children[0];
- LayerImpl* grandchild1 = child1->test_properties()->children[0];
- LayerImpl* grandchild2 = child1->test_properties()->children[1];
+ auto* grandchild1 =
+ static_cast<TestLayerImpl*>(child1->test_properties()->children[0]);
+ auto* grandchild2 =
+ static_cast<TestLayerImpl*>(child1->test_properties()->children[1]);
// Really far left.
grandchild1->test_properties()->position =
@@ -2002,8 +2035,10 @@ TEST_F(DamageTrackerTest, DamageRectTooBigInRenderSurface) {
TEST_F(DamageTrackerTest, DamageRectTooBigInRenderSurfaceWithFilter) {
LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces();
LayerImpl* child1 = root->test_properties()->children[0];
- LayerImpl* grandchild1 = child1->test_properties()->children[0];
- LayerImpl* grandchild2 = child1->test_properties()->children[1];
+ auto* grandchild1 =
+ static_cast<TestLayerImpl*>(child1->test_properties()->children[0]);
+ auto* grandchild2 =
+ static_cast<TestLayerImpl*>(child1->test_properties()->children[1]);
// Set up a moving pixels filter on the child.
FilterOperations filters;
diff --git a/chromium/cc/trees/draw_property_utils.cc b/chromium/cc/trees/draw_property_utils.cc
index 9c1bec65c92..cf566cb9b6e 100644
--- a/chromium/cc/trees/draw_property_utils.cc
+++ b/chromium/cc/trees/draw_property_utils.cc
@@ -838,8 +838,17 @@ void FindLayersThatNeedUpdates(LayerTreeImpl* layer_tree_impl,
}
void ComputeTransforms(TransformTree* transform_tree) {
- if (!transform_tree->needs_update())
+ if (!transform_tree->needs_update()) {
+#if DCHECK_IS_ON()
+ // If the transform tree does not need an update, no TransformNode should
+ // need a local transform update.
+ for (int i = TransformTree::kContentsRootNodeId;
+ i < static_cast<int>(transform_tree->size()); ++i) {
+ DCHECK(!transform_tree->Node(i)->needs_local_transform_update);
+ }
+#endif
return;
+ }
for (int i = TransformTree::kContentsRootNodeId;
i < static_cast<int>(transform_tree->size()); ++i)
transform_tree->UpdateTransforms(i);
@@ -872,22 +881,11 @@ void UpdatePropertyTrees(LayerTreeHost* layer_tree_host,
}
void UpdatePropertyTreesAndRenderSurfaces(LayerImpl* root_layer,
- PropertyTrees* property_trees,
- bool can_adjust_raster_scales) {
- bool render_surfaces_need_update = false;
- if (property_trees->can_adjust_raster_scales != can_adjust_raster_scales) {
- property_trees->can_adjust_raster_scales = can_adjust_raster_scales;
- property_trees->transform_tree.set_needs_update(true);
- render_surfaces_need_update = true;
- }
+ PropertyTrees* property_trees) {
if (property_trees->transform_tree.needs_update()) {
property_trees->clip_tree.set_needs_update(true);
property_trees->effect_tree.set_needs_update(true);
}
- if (render_surfaces_need_update) {
- property_trees->effect_tree.UpdateRenderSurfaces(
- root_layer->layer_tree_impl());
- }
UpdateRenderTarget(&property_trees->effect_tree);
ComputeTransforms(&property_trees->transform_tree);
diff --git a/chromium/cc/trees/draw_property_utils.h b/chromium/cc/trees/draw_property_utils.h
index c37eaa0c066..6ca984986bd 100644
--- a/chromium/cc/trees/draw_property_utils.h
+++ b/chromium/cc/trees/draw_property_utils.h
@@ -44,8 +44,7 @@ void CC_EXPORT UpdatePropertyTrees(LayerTreeHost* layer_tree_host,
void CC_EXPORT
UpdatePropertyTreesAndRenderSurfaces(LayerImpl* root_layer,
- PropertyTrees* property_trees,
- bool can_adjust_raster_scales);
+ PropertyTrees* property_trees);
void CC_EXPORT FindLayersThatNeedUpdates(LayerTreeHost* layer_tree_host,
const PropertyTrees* property_trees,
diff --git a/chromium/cc/trees/effect_node.cc b/chromium/cc/trees/effect_node.cc
index 8c7a016eee4..847432950b3 100644
--- a/chromium/cc/trees/effect_node.cc
+++ b/chromium/cc/trees/effect_node.cc
@@ -57,6 +57,7 @@ bool EffectNode::operator==(const EffectNode& other) const {
filters == other.filters &&
backdrop_filters == other.backdrop_filters &&
backdrop_filter_bounds == other.backdrop_filter_bounds &&
+ backdrop_mask_element_id == other.backdrop_mask_element_id &&
filters_origin == other.filters_origin &&
rounded_corner_bounds == other.rounded_corner_bounds &&
is_fast_rounded_corner == other.is_fast_rounded_corner &&
@@ -142,10 +143,15 @@ const char* RenderSurfaceReasonToString(RenderSurfaceReason reason) {
}
void EffectNode::AsValueInto(base::trace_event::TracedValue* value) const {
+ value->SetInteger("backdrop_mask_element_id",
+ backdrop_mask_element_id.GetInternalValue());
value->SetInteger("id", id);
value->SetInteger("parent_id", parent_id);
value->SetInteger("stable_id", stable_id);
value->SetDouble("opacity", opacity);
+ if (!backdrop_filters.IsEmpty()) {
+ value->SetString("backdrop_filters", backdrop_filters.ToString());
+ }
value->SetDouble("backdrop_filter_quality", backdrop_filter_quality);
value->SetBoolean("is_fast_rounded_corner", is_fast_rounded_corner);
if (!rounded_corner_bounds.IsEmpty()) {
diff --git a/chromium/cc/trees/effect_node.h b/chromium/cc/trees/effect_node.h
index 340305e9355..eaddb83fb4e 100644
--- a/chromium/cc/trees/effect_node.h
+++ b/chromium/cc/trees/effect_node.h
@@ -6,6 +6,7 @@
#define CC_TREES_EFFECT_NODE_H_
#include "cc/cc_export.h"
+#include "cc/paint/element_id.h"
#include "cc/paint/filter_operations.h"
#include "third_party/skia/include/core/SkBlendMode.h"
#include "ui/gfx/geometry/point_f.h"
@@ -40,6 +41,7 @@ enum class RenderSurfaceReason : uint8_t {
kTrilinearFiltering,
kCache,
kCopyRequest,
+ kMirrored,
// This must be the last value because it's used in tracing code to know the
// number of reasons.
kTest,
@@ -73,6 +75,11 @@ struct CC_EXPORT EffectNode {
float backdrop_filter_quality;
gfx::PointF filters_origin;
+ // The element id corresponding to the mask to apply to the filtered backdrop
+ // image. Note that this is separate from mask_layer_id, which is a layer id,
+ // and is used for masking the "normal" (non-backdrop-filter) content.
+ ElementId backdrop_mask_element_id;
+
// Bounds of rounded corner rrect in the space of the transform node
// associated with this effect node.
gfx::RRectF rounded_corner_bounds;
diff --git a/chromium/cc/trees/element_id.cc b/chromium/cc/trees/element_id.cc
deleted file mode 100644
index 6690378fc16..00000000000
--- a/chromium/cc/trees/element_id.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2016 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/trees/element_id.h"
-
-#include <inttypes.h>
-#include <limits>
-#include <ostream>
-
-#include "base/strings/stringprintf.h"
-#include "base/trace_event/traced_value.h"
-#include "base/values.h"
-
-namespace cc {
-
-const ElementIdType ElementId::kInvalidElementId = 0;
-
-ElementId LayerIdToElementIdForTesting(int layer_id) {
- return ElementId(std::numeric_limits<int>::max() - layer_id);
-}
-
-void ElementId::AddToTracedValue(base::trace_event::TracedValue* res) const {
- res->BeginDictionary("element_id");
- res->SetInteger("id_", id_);
- res->EndDictionary();
-}
-
-ElementIdType ElementId::GetInternalValue() const {
- return id_;
-}
-
-std::string ElementId::ToString() const {
- return base::StringPrintf("(%" PRIu64 ")", id_);
-}
-
-std::unique_ptr<base::Value> ElementId::AsValue() const {
- std::unique_ptr<base::DictionaryValue> res(new base::DictionaryValue());
- res->SetInteger("id_", id_);
- return std::move(res);
-}
-
-size_t ElementIdHash::operator()(ElementId key) const {
- return std::hash<int>()(key.id_);
-}
-
-std::ostream& operator<<(std::ostream& out, const ElementId& id) {
- return out << id.ToString();
-}
-
-} // namespace cc
diff --git a/chromium/cc/trees/element_id.h b/chromium/cc/trees/element_id.h
deleted file mode 100644
index e8275c521cc..00000000000
--- a/chromium/cc/trees/element_id.h
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2016 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.
-
-#ifndef CC_TREES_ELEMENT_ID_H_
-#define CC_TREES_ELEMENT_ID_H_
-
-#include <stddef.h>
-
-#include <cstdint>
-#include <functional>
-#include <iosfwd>
-#include <memory>
-
-#include "base/hash/hash.h"
-#include "cc/cc_export.h"
-
-namespace base {
-class Value;
-namespace trace_event {
-class TracedValue;
-} // namespace trace_event
-} // namespace base
-
-namespace cc {
-
-using ElementIdType = uint64_t;
-
-// Element ids are chosen by cc's clients and can be used as a stable identifier
-// across updates.
-//
-// Historically, the layer tree stored all compositing data but this has been
-// refactored over time into auxilliary structures such as property trees.
-//
-// In composited scrolling, Layers directly reference scroll tree nodes
-// (Layer::scroll_tree_index) but scroll tree nodes are being refactored to
-// reference stable element ids instead of layers. Scroll property nodes have
-// unique element ids that blink creates from scrollable areas (though this is
-// opaque to the compositor). This refactoring of scroll nodes keeping a
-// scrolling element id instead of a scrolling layer id allows for more general
-// compositing where, for example, multiple layers scroll with one scroll node.
-//
-// The animation system (see ElementAnimations) is another auxilliary structure
-// to the layer tree and uses element ids as a stable identifier for animation
-// targets. A Layer's element id can change over the Layer's lifetime because
-// non-default ElementIds are only set during an animation's lifetime.
-struct CC_EXPORT ElementId {
- explicit ElementId(ElementIdType id) : id_(id) {
- DCHECK_NE(id, kInvalidElementId);
- }
-
- ElementId() : id_(kInvalidElementId) {}
-
- bool operator==(const ElementId& o) const { return id_ == o.id_; }
- bool operator!=(const ElementId& o) const { return !(*this == o); }
- bool operator<(const ElementId& o) const { return id_ < o.id_; }
-
- // Returns true if the ElementId has been initialized with a valid id.
- explicit operator bool() const { return !!id_; }
-
- void AddToTracedValue(base::trace_event::TracedValue* res) const;
- std::unique_ptr<base::Value> AsValue() const;
-
- ElementIdType GetInternalValue() const;
-
- std::string ToString() const;
-
- private:
- friend struct ElementIdHash;
- static const ElementIdType kInvalidElementId;
-
- // The compositor treats this as an opaque handle and should not know how to
- // interpret these bits. Non-blink cc clients typically operate in terms of
- // layers and may set this value to match the client's layer id.
- ElementIdType id_;
-};
-
-ElementId CC_EXPORT LayerIdToElementIdForTesting(int layer_id);
-
-struct CC_EXPORT ElementIdHash {
- size_t operator()(ElementId key) const;
-};
-
-// Stream operator so ElementId can be used in assertion statements.
-CC_EXPORT std::ostream& operator<<(std::ostream& out, const ElementId& id);
-
-} // namespace cc
-
-#endif // CC_TREES_ELEMENT_ID_H_
diff --git a/chromium/cc/trees/frame_sequence_tracker.cc b/chromium/cc/trees/frame_sequence_tracker.cc
new file mode 100644
index 00000000000..a4020409e7a
--- /dev/null
+++ b/chromium/cc/trees/frame_sequence_tracker.cc
@@ -0,0 +1,390 @@
+// Copyright 2019 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/trees/frame_sequence_tracker.h"
+
+#include "base/metrics/histogram.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/strings/strcat.h"
+#include "base/trace_event/trace_event.h"
+#include "base/trace_event/traced_value.h"
+#include "components/viz/common/frame_sinks/begin_frame_args.h"
+#include "components/viz/common/quads/compositor_frame_metadata.h"
+#include "ui/gfx/presentation_feedback.h"
+
+namespace cc {
+
+namespace {
+
+enum class ThreadType {
+ kMain,
+ kCompositor,
+};
+
+constexpr const char* const kBuiltinSequences[] = {
+ [FrameSequenceTrackerType::kCompositorAnimation] = "CompositorAnimation",
+ [FrameSequenceTrackerType::kMainThreadAnimation] = "MainThreadAnimation",
+ [FrameSequenceTrackerType::kPinchZoom] = "PinchZoom",
+ [FrameSequenceTrackerType::kRAF] = "RAF",
+ [FrameSequenceTrackerType::kTouchScroll] = "TouchScroll",
+ [FrameSequenceTrackerType::kWheelScroll] = "WheelScroll",
+};
+
+constexpr int kBuiltinSequenceNum = base::size(kBuiltinSequences);
+constexpr int kMaximumHistogramIndex = 2 * kBuiltinSequenceNum;
+
+int GetIndexForMetric(ThreadType thread_type, FrameSequenceTrackerType type) {
+ return thread_type == ThreadType::kMain
+ ? static_cast<int>(type)
+ : static_cast<int>(type + kBuiltinSequenceNum);
+}
+
+} // namespace
+
+////////////////////////////////////////////////////////////////////////////////
+// FrameSequenceTrackerCollection
+
+FrameSequenceTrackerCollection::FrameSequenceTrackerCollection() {}
+FrameSequenceTrackerCollection::~FrameSequenceTrackerCollection() {
+ removal_trackers_.clear();
+ DCHECK(frame_trackers_.empty());
+}
+
+std::unique_ptr<FrameSequenceTracker>
+FrameSequenceTrackerCollection::CreateTracker(FrameSequenceTrackerType type) {
+ // The collection always outlives the trackers. So using Unretained() here is
+ // safe.
+ auto tracker = base::WrapUnique(new FrameSequenceTracker(
+ type, base::BindOnce(&FrameSequenceTrackerCollection::RemoveFrameTracker,
+ base::Unretained(this))));
+ AddFrameTracker(tracker.get());
+ return tracker;
+}
+
+void FrameSequenceTrackerCollection::ScheduleRemoval(
+ std::unique_ptr<FrameSequenceTracker> tracker) {
+ if (!tracker)
+ return;
+ tracker->ScheduleTerminate();
+ removal_trackers_.push_back(std::move(tracker));
+}
+
+void FrameSequenceTrackerCollection::ClearAll() {
+ removal_trackers_.clear();
+ DCHECK(frame_trackers_.empty());
+}
+
+void FrameSequenceTrackerCollection::NotifyBeginImplFrame(
+ const viz::BeginFrameArgs& args) {
+ for (auto* tracker : frame_trackers_) {
+ tracker->ReportBeginImplFrame(args);
+ }
+}
+
+void FrameSequenceTrackerCollection::NotifyBeginMainFrame(
+ const viz::BeginFrameArgs& args) {
+ for (auto* tracker : frame_trackers_) {
+ tracker->ReportBeginMainFrame(args);
+ }
+}
+
+void FrameSequenceTrackerCollection::NotifyImplFrameCausedNoDamage(
+ const viz::BeginFrameAck& ack) {
+ for (auto* tracker : frame_trackers_) {
+ tracker->ReportImplFrameCausedNoDamage(ack);
+ }
+}
+
+void FrameSequenceTrackerCollection::NotifyMainFrameCausedNoDamage(
+ const viz::BeginFrameArgs& args) {
+ for (auto* tracker : frame_trackers_) {
+ tracker->ReportMainFrameCausedNoDamage(args);
+ }
+}
+
+void FrameSequenceTrackerCollection::NotifyPauseFrameProduction() {
+ for (auto* tracker : frame_trackers_)
+ tracker->PauseFrameProduction();
+}
+
+void FrameSequenceTrackerCollection::NotifySubmitFrame(
+ uint32_t frame_token,
+ const viz::BeginFrameAck& ack,
+ const viz::BeginFrameArgs& origin_args) {
+ for (auto* tracker : frame_trackers_) {
+ tracker->ReportSubmitFrame(frame_token, ack, origin_args);
+ }
+}
+
+void FrameSequenceTrackerCollection::NotifyFramePresented(
+ uint32_t frame_token,
+ const gfx::PresentationFeedback& feedback) {
+ for (auto* tracker : frame_trackers_)
+ tracker->ReportFramePresented(frame_token, feedback);
+
+ // Destroy the trackers that are ready to be terminated.
+ base::EraseIf(
+ removal_trackers_,
+ [](const std::unique_ptr<FrameSequenceTracker>& tracker) {
+ return tracker->termination_status() ==
+ FrameSequenceTracker::TerminationStatus::kReadyForTermination;
+ });
+}
+
+void FrameSequenceTrackerCollection::AddFrameTracker(
+ FrameSequenceTracker* tracker) {
+ frame_trackers_.push_back(tracker);
+}
+
+void FrameSequenceTrackerCollection::RemoveFrameTracker(
+ FrameSequenceTracker* tracker) {
+ base::Erase(frame_trackers_, tracker);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// FrameSequenceTracker
+
+FrameSequenceTracker::FrameSequenceTracker(
+ FrameSequenceTrackerType type,
+ base::OnceCallback<void(FrameSequenceTracker*)> destroy_callback)
+ : type_(type), destroy_callback_(std::move(destroy_callback)) {
+ DCHECK_LT(type_, FrameSequenceTrackerType::kMaxType);
+ TRACE_EVENT_ASYNC_BEGIN1("cc,benchmark", "FrameSequenceTracker", this, "name",
+ TRACE_STR_COPY(kBuiltinSequences[type_]));
+}
+
+FrameSequenceTracker::~FrameSequenceTracker() {
+ DCHECK_LE(impl_throughput_.frames_produced, impl_throughput_.frames_expected);
+ DCHECK_LE(main_throughput_.frames_produced, main_throughput_.frames_expected);
+ DCHECK_LE(main_throughput_.frames_produced, impl_throughput_.frames_produced);
+ TRACE_EVENT_ASYNC_END1(
+ "cc,benchmark", "FrameSequenceTracker", this, "args",
+ ThroughputData::ToTracedValue(impl_throughput_, main_throughput_));
+ ThroughputData::ReportHistogram(
+ type_, "CompositorThread",
+ GetIndexForMetric(ThreadType::kCompositor, type_), impl_throughput_);
+ ThroughputData::ReportHistogram(type_, "MainThread",
+ GetIndexForMetric(ThreadType::kMain, type_),
+ main_throughput_);
+ std::move(destroy_callback_).Run(this);
+}
+
+void FrameSequenceTracker::ReportBeginImplFrame(
+ const viz::BeginFrameArgs& args) {
+ if (termination_status_ != TerminationStatus::kActive)
+ return;
+
+ if (ShouldIgnoreBeginFrameSource(args.source_id))
+ return;
+
+ UpdateTrackedFrameData(&begin_impl_frame_data_, args.source_id,
+ args.sequence_number);
+ impl_throughput_.frames_expected +=
+ begin_impl_frame_data_.previous_sequence_delta;
+}
+
+void FrameSequenceTracker::ReportBeginMainFrame(
+ const viz::BeginFrameArgs& args) {
+ if (termination_status_ != TerminationStatus::kActive)
+ return;
+
+ if (ShouldIgnoreBeginFrameSource(args.source_id))
+ return;
+
+ UpdateTrackedFrameData(&begin_main_frame_data_, args.source_id,
+ args.sequence_number);
+ if (first_received_main_sequence_ == 0)
+ first_received_main_sequence_ = args.sequence_number;
+ main_throughput_.frames_expected +=
+ begin_main_frame_data_.previous_sequence_delta;
+}
+
+void FrameSequenceTracker::ReportSubmitFrame(
+ uint32_t frame_token,
+ const viz::BeginFrameAck& ack,
+ const viz::BeginFrameArgs& origin_args) {
+ if (termination_status_ != TerminationStatus::kActive)
+ return;
+
+ if (ShouldIgnoreBeginFrameSource(ack.source_id))
+ return;
+
+ if (begin_impl_frame_data_.previous_sequence == 0 ||
+ ack.sequence_number < begin_impl_frame_data_.previous_sequence) {
+ return;
+ }
+
+ if (first_submitted_frame_ == 0)
+ first_submitted_frame_ = frame_token;
+ last_submitted_frame_ = frame_token;
+
+ if (!ShouldIgnoreBeginFrameSource(origin_args.source_id) &&
+ first_received_main_sequence_ &&
+ origin_args.sequence_number >= first_received_main_sequence_) {
+ if (last_submitted_main_sequence_ == 0 ||
+ origin_args.sequence_number > last_submitted_main_sequence_) {
+ last_submitted_main_sequence_ = origin_args.sequence_number;
+ main_frames_.push_back(frame_token);
+ DCHECK_GE(main_throughput_.frames_expected, main_frames_.size());
+ }
+ }
+}
+
+void FrameSequenceTracker::ReportFramePresented(
+ uint32_t frame_token,
+ const gfx::PresentationFeedback& feedback) {
+ const bool frame_token_acks_last_frame =
+ frame_token == last_submitted_frame_ ||
+ viz::FrameTokenGT(frame_token, last_submitted_frame_);
+
+ // Update termination status if this is scheduled for termination, and it is
+ // not waiting for any frames, or it has received the presentation-feedback
+ // for the latest frame it is tracking.
+ if (termination_status_ == TerminationStatus::kScheduledForTermination &&
+ (last_submitted_frame_ == 0 || frame_token_acks_last_frame)) {
+ termination_status_ = TerminationStatus::kReadyForTermination;
+ }
+
+ if (first_submitted_frame_ == 0 ||
+ viz::FrameTokenGT(first_submitted_frame_, frame_token)) {
+ // We are getting presentation feedback for frames that were submitted
+ // before this sequence started. So ignore these.
+ return;
+ }
+
+ const bool was_presented = !feedback.timestamp.is_null();
+ if (was_presented && last_submitted_frame_) {
+ DCHECK_LT(impl_throughput_.frames_produced,
+ impl_throughput_.frames_expected);
+ ++impl_throughput_.frames_produced;
+
+ if (frame_token_acks_last_frame)
+ last_submitted_frame_ = 0;
+ }
+
+ while (!main_frames_.empty() &&
+ !viz::FrameTokenGT(main_frames_.front(), frame_token)) {
+ if (was_presented && main_frames_.front() == frame_token) {
+ DCHECK_LT(main_throughput_.frames_produced,
+ main_throughput_.frames_expected);
+ ++main_throughput_.frames_produced;
+ }
+ main_frames_.pop_front();
+ }
+}
+
+void FrameSequenceTracker::ReportImplFrameCausedNoDamage(
+ const viz::BeginFrameAck& ack) {
+ if (termination_status_ != TerminationStatus::kActive)
+ return;
+
+ if (ShouldIgnoreBeginFrameSource(ack.source_id))
+ return;
+
+ // It is possible that this is called before a begin-impl-frame has been
+ // dispatched for this frame-sequence. In such cases, ignore this call.
+ if (begin_impl_frame_data_.previous_sequence == 0 ||
+ ack.sequence_number < begin_impl_frame_data_.previous_sequence) {
+ return;
+ }
+ DCHECK_GT(impl_throughput_.frames_expected, 0u);
+ DCHECK_GT(impl_throughput_.frames_expected, impl_throughput_.frames_produced);
+ --impl_throughput_.frames_expected;
+
+ if (begin_impl_frame_data_.previous_sequence == ack.sequence_number)
+ begin_impl_frame_data_.previous_sequence = 0;
+}
+
+void FrameSequenceTracker::ReportMainFrameCausedNoDamage(
+ const viz::BeginFrameArgs& args) {
+ if (termination_status_ != TerminationStatus::kActive)
+ return;
+
+ if (ShouldIgnoreBeginFrameSource(args.source_id))
+ return;
+
+ // It is possible that this is called before a begin-main-frame has been
+ // dispatched for this frame-sequence. In such cases, ignore this call.
+ if (begin_main_frame_data_.previous_sequence == 0 ||
+ args.sequence_number < begin_main_frame_data_.previous_sequence) {
+ return;
+ }
+
+ DCHECK_GT(main_throughput_.frames_expected, 0u);
+ DCHECK_GT(main_throughput_.frames_expected, main_throughput_.frames_produced);
+ --main_throughput_.frames_expected;
+ DCHECK_GE(main_throughput_.frames_expected, main_frames_.size());
+
+ if (begin_main_frame_data_.previous_sequence == args.sequence_number)
+ begin_main_frame_data_.previous_sequence = 0;
+}
+
+void FrameSequenceTracker::PauseFrameProduction() {
+ // Reset the states, so that the tracker ignores the vsyncs until the next
+ // received begin-frame.
+ begin_impl_frame_data_ = {0, 0, 0};
+ begin_main_frame_data_ = {0, 0, 0};
+}
+
+void FrameSequenceTracker::UpdateTrackedFrameData(TrackedFrameData* frame_data,
+ uint64_t source_id,
+ uint64_t sequence_number) {
+ if (frame_data->previous_sequence &&
+ frame_data->previous_source == source_id) {
+ uint8_t current_latency = sequence_number - frame_data->previous_sequence;
+ frame_data->previous_sequence_delta = current_latency;
+ } else {
+ frame_data->previous_sequence_delta = 1;
+ }
+ frame_data->previous_source = source_id;
+ frame_data->previous_sequence = sequence_number;
+}
+
+bool FrameSequenceTracker::ShouldIgnoreBeginFrameSource(
+ uint64_t source_id) const {
+ if (begin_impl_frame_data_.previous_source == 0)
+ return false;
+ return source_id != begin_impl_frame_data_.previous_source;
+}
+
+std::unique_ptr<base::trace_event::TracedValue>
+FrameSequenceTracker::ThroughputData::ToTracedValue(
+ const ThroughputData& impl,
+ const ThroughputData& main) {
+ auto dict = std::make_unique<base::trace_event::TracedValue>();
+ dict->SetInteger("impl-frames-produced", impl.frames_produced);
+ dict->SetInteger("impl-frames-expected", impl.frames_expected);
+ dict->SetInteger("main-frames-produced", main.frames_produced);
+ dict->SetInteger("main-frames-expected", main.frames_expected);
+ return dict;
+}
+
+void FrameSequenceTracker::ThroughputData::ReportHistogram(
+ FrameSequenceTrackerType sequence_type,
+ const char* thread_name,
+ int metric_index,
+ const ThroughputData& data) {
+ DCHECK_LT(sequence_type, FrameSequenceTrackerType::kMaxType);
+
+ UMA_HISTOGRAM_COUNTS_1000("Graphics.Smoothness.FrameSequenceLength",
+ data.frames_expected);
+
+ // Avoid reporting any throughput metric for sequences that had a small amount
+ // of frames.
+ constexpr int kMinFramesForThroughputMetric = 4;
+ if (data.frames_expected < kMinFramesForThroughputMetric)
+ return;
+
+ const std::string name =
+ base::StrCat({"Graphics.Smoothness.Throughput.", thread_name, ".",
+ kBuiltinSequences[sequence_type]});
+ const int percent =
+ static_cast<int>(100 * data.frames_produced / data.frames_expected);
+ STATIC_HISTOGRAM_POINTER_GROUP(
+ name, metric_index, kMaximumHistogramIndex, Add(percent),
+ base::LinearHistogram::FactoryGet(
+ name, 1, 100, 101, base::HistogramBase::kUmaTargetedHistogramFlag));
+}
+
+} // namespace cc
diff --git a/chromium/cc/trees/frame_sequence_tracker.h b/chromium/cc/trees/frame_sequence_tracker.h
new file mode 100644
index 00000000000..57b370eb316
--- /dev/null
+++ b/chromium/cc/trees/frame_sequence_tracker.h
@@ -0,0 +1,238 @@
+// Copyright 2019 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.
+
+#ifndef CC_TREES_FRAME_SEQUENCE_TRACKER_H_
+#define CC_TREES_FRAME_SEQUENCE_TRACKER_H_
+
+#include <stdint.h>
+#include <memory>
+#include <set>
+#include <utility>
+#include <vector>
+
+#include "base/callback_helpers.h"
+#include "base/containers/circular_deque.h"
+#include "base/macros.h"
+#include "base/trace_event/traced_value.h"
+#include "cc/cc_export.h"
+
+namespace gfx {
+struct PresentationFeedback;
+}
+
+namespace viz {
+struct BeginFrameAck;
+struct BeginFrameArgs;
+} // namespace viz
+
+namespace cc {
+class FrameSequenceTracker;
+
+enum FrameSequenceTrackerType {
+ kCompositorAnimation,
+ kMainThreadAnimation,
+ kPinchZoom,
+ kRAF,
+ kTouchScroll,
+ kWheelScroll,
+ kMaxType
+};
+
+// Used for notifying attached FrameSequenceTracker's of begin-frames and
+// submitted frames.
+class CC_EXPORT FrameSequenceTrackerCollection {
+ public:
+ FrameSequenceTrackerCollection();
+ ~FrameSequenceTrackerCollection();
+
+ FrameSequenceTrackerCollection(const FrameSequenceTrackerCollection&) =
+ delete;
+ FrameSequenceTrackerCollection& operator=(
+ const FrameSequenceTrackerCollection&) = delete;
+
+ // Creates a tracker for the specified sequence-type.
+ std::unique_ptr<FrameSequenceTracker> CreateTracker(
+ FrameSequenceTrackerType type);
+
+ // Schedules |tracker| for destruction. This is preferred instead of outright
+ // desrtruction of the tracker, since this ensures that the actual tracker
+ // instance is destroyed *after* the presentation-feedbacks have been received
+ // for all submitted frames.
+ void ScheduleRemoval(std::unique_ptr<FrameSequenceTracker> tracker);
+
+ // Removes all trackers. This also immediately destroys all trackers that had
+ // been scheduled for destruction, even if there are pending
+ // presentation-feedbacks. This is typically used if the client no longer
+ // expects to receive presentation-feedbacks for the previously submitted
+ // frames (e.g. when the gpu process dies).
+ void ClearAll();
+
+ // Notifies all trackers of various events.
+ void NotifyBeginImplFrame(const viz::BeginFrameArgs& args);
+ void NotifyBeginMainFrame(const viz::BeginFrameArgs& args);
+ void NotifyImplFrameCausedNoDamage(const viz::BeginFrameAck& ack);
+ void NotifyMainFrameCausedNoDamage(const viz::BeginFrameArgs& args);
+ void NotifyPauseFrameProduction();
+ void NotifySubmitFrame(uint32_t frame_token,
+ const viz::BeginFrameAck& ack,
+ const viz::BeginFrameArgs& origin_args);
+
+ // Note that this notifies the trackers of the presentation-feedbacks, and
+ // destroys any tracker that had been scheduled for destruction (using
+ // |ScheduleRemoval()|) if it has no more pending frames.
+ void NotifyFramePresented(uint32_t frame_token,
+ const gfx::PresentationFeedback& feedback);
+
+ private:
+ void AddFrameTracker(FrameSequenceTracker* tracker);
+ void RemoveFrameTracker(FrameSequenceTracker* tracker);
+
+ std::vector<FrameSequenceTracker*> frame_trackers_;
+ std::vector<std::unique_ptr<FrameSequenceTracker>> removal_trackers_;
+};
+
+// Tracks a sequence of frames to determine the throughput. It tracks this by
+// tracking the vsync sequence-numbers (from |BeginFrameArgs::sequence_number|),
+// and the presentation-timestamps (from |gfx::PresentationFeedback|). It also
+// tracks which frames were expected to include update from the main-thread, and
+// which presented frames did include updates from the main-thread.
+// This object should be created through
+// FrameSequenceTrackerCollection::CreateTracker() API.
+class CC_EXPORT FrameSequenceTracker {
+ public:
+ enum class TerminationStatus {
+ kActive,
+ kScheduledForTermination,
+ kReadyForTermination,
+ };
+
+ ~FrameSequenceTracker();
+
+ FrameSequenceTracker(const FrameSequenceTracker&) = delete;
+ FrameSequenceTracker& operator=(const FrameSequenceTracker&) = delete;
+
+ // Notifies the tracker when the compositor thread starts to process a
+ // BeginFrameArgs.
+ void ReportBeginImplFrame(const viz::BeginFrameArgs& args);
+
+ // Notifies the tracker when a BeginFrameArgs is dispatched to the main
+ // thread.
+ void ReportBeginMainFrame(const viz::BeginFrameArgs& args);
+
+ // Notifies the tracker when the compositor submits a CompositorFrame.
+ // |origin_args| represents the BeginFrameArgs that triggered the update from
+ // the main-thread.
+ void ReportSubmitFrame(uint32_t frame_token,
+ const viz::BeginFrameAck& ack,
+ const viz::BeginFrameArgs& origin_args);
+
+ // Notifies the tracker of the presentation-feedback of a previously submitted
+ // CompositorFrame with |frame_token|.
+ void ReportFramePresented(uint32_t frame_token,
+ const gfx::PresentationFeedback& feedback);
+
+ // Notifies the tracker that a CompositorFrame is not going to be submitted
+ // for a particular BeginFrameArgs because it did not cause any damage (visual
+ // change). Note that if a begin-main-frame was dispatched, then a separate
+ // call to |ReportMainFrameCausedNoDamage()| is made to notify that the
+ // main-thread did not cause any damage/updates.
+ void ReportImplFrameCausedNoDamage(const viz::BeginFrameAck& ack);
+
+ // Notifies the tracker that a |BeginFrameArgs| either was not dispatched to
+ // the main-thread (because it did not ask for it), or that a |BeginFrameArgs|
+ // that was dispatched to the main-thread did not cause any updates/damage.
+ void ReportMainFrameCausedNoDamage(const viz::BeginFrameArgs& args);
+
+ // Notifies that frame production has currently paused. This is typically used
+ // for interactive frame-sequences, e.g. during touch-scroll.
+ void PauseFrameProduction();
+
+ TerminationStatus termination_status() const { return termination_status_; }
+
+ private:
+ friend class FrameSequenceTrackerCollection;
+
+ FrameSequenceTracker(
+ FrameSequenceTrackerType type,
+ base::OnceCallback<void(FrameSequenceTracker*)> destroy_callback);
+
+ void ScheduleTerminate() {
+ termination_status_ = TerminationStatus::kScheduledForTermination;
+ }
+
+ struct TrackedFrameData {
+ // Represents the |BeginFrameArgs::source_id| and
+ // |BeginFrameArgs::sequence_number| fields of the last processed
+ // BeginFrameArgs.
+ uint64_t previous_source = 0;
+ uint64_t previous_sequence = 0;
+
+ // The difference in |BeginFrameArgs::sequence_number| fields of the last
+ // two processed BeginFrameArgs.
+ uint8_t previous_sequence_delta = 0;
+ };
+
+ struct ThroughputData {
+ static std::unique_ptr<base::trace_event::TracedValue> ToTracedValue(
+ const ThroughputData& impl,
+ const ThroughputData& main);
+ static void ReportHistogram(FrameSequenceTrackerType sequence_type,
+ const char* thread_name,
+ int metric_index,
+ const ThroughputData& data);
+ // Tracks the number of frames that were expected to be shown during this
+ // frame-sequence.
+ uint32_t frames_expected = 0;
+
+ // Tracks the number of frames that were actually presented to the user
+ // during this frame-sequence.
+ uint32_t frames_produced = 0;
+ };
+
+ void UpdateTrackedFrameData(TrackedFrameData* frame_data,
+ uint64_t source_id,
+ uint64_t sequence_number);
+
+ bool ShouldIgnoreBeginFrameSource(uint64_t source_id) const;
+
+ const FrameSequenceTrackerType type_;
+ base::OnceCallback<void(FrameSequenceTracker*)> destroy_callback_;
+
+ TerminationStatus termination_status_ = TerminationStatus::kActive;
+
+ TrackedFrameData begin_impl_frame_data_;
+ TrackedFrameData begin_main_frame_data_;
+
+ ThroughputData impl_throughput_;
+ ThroughputData main_throughput_;
+
+ // Tracks the list of frame-tokens for compositor-frames that included new
+ // updates from the main-thread, whose presentation-feedback have not been
+ // received yet. When the presentation-feedback for a frame is received, the
+ // corresponding frame-token is removed from this collection.
+ base::circular_deque<uint32_t> main_frames_;
+
+ // Keeps track of the sequence-number of the first received begin-main-frame.
+ // This is used to ignore submitted frames that include updates from earlier
+ // begin-main-frames.
+ uint64_t first_received_main_sequence_ = 0;
+
+ // Keeps track of the first submitted compositor-frame. This is used to ignore
+ // reports from frames that were submitted before this tracker had been
+ // created.
+ uint32_t first_submitted_frame_ = 0;
+
+ // Keeps track of the latest submitted compositor-frame, so that it can
+ // determine when it has received presentation-feedback for submitted frames.
+ // This is used to decide when to terminate this FrameSequenceTracker object.
+ uint32_t last_submitted_frame_ = 0;
+
+ // Keeps track of the last sequence-number that produced a frame from the
+ // main-thread.
+ uint64_t last_submitted_main_sequence_ = 0;
+};
+
+} // namespace cc
+
+#endif // CC_TREES_FRAME_SEQUENCE_TRACKER_H_
diff --git a/chromium/cc/trees/frame_sequence_tracker_unittest.cc b/chromium/cc/trees/frame_sequence_tracker_unittest.cc
new file mode 100644
index 00000000000..1de4c9c38a9
--- /dev/null
+++ b/chromium/cc/trees/frame_sequence_tracker_unittest.cc
@@ -0,0 +1,109 @@
+// Copyright 2019 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/trees/frame_sequence_tracker.h"
+
+#include "base/macros.h"
+#include "components/viz/common/frame_sinks/begin_frame_args.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+namespace {
+
+class FrameSequenceTrackerTest;
+
+class FrameSequenceTrackerTest : public testing::Test {
+ public:
+ const uint32_t kImplDamage = 0x1;
+ const uint32_t kMainDamage = 0x2;
+
+ FrameSequenceTrackerTest()
+ : tracker_(
+ collection_.CreateTracker(FrameSequenceTrackerType::kTouchScroll)) {
+ }
+ ~FrameSequenceTrackerTest() override = default;
+
+ std::unique_ptr<FrameSequenceTracker> CreateNewTracker() {
+ return collection_.CreateTracker(FrameSequenceTrackerType::kTouchScroll);
+ }
+
+ viz::BeginFrameArgs CreateBeginFrameArgs(uint64_t source_id,
+ uint64_t sequence_number) {
+ auto now = base::TimeTicks::Now();
+ auto interval = base::TimeDelta::FromMilliseconds(16);
+ auto deadline = now + interval;
+ return viz::BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, source_id,
+ sequence_number, now, deadline, interval,
+ viz::BeginFrameArgs::NORMAL);
+ }
+
+ void StartImplAndMainFrames(const viz::BeginFrameArgs& args) {
+ collection_.NotifyBeginImplFrame(args);
+ collection_.NotifyBeginMainFrame(args);
+ }
+
+ uint32_t DispatchCompleteFrame(const viz::BeginFrameArgs& args,
+ uint32_t damage_type) {
+ StartImplAndMainFrames(args);
+
+ if (damage_type & kImplDamage) {
+ if (!(damage_type & kMainDamage)) {
+ collection_.NotifyMainFrameCausedNoDamage(args);
+ }
+ uint32_t frame_token = NextFrameToken();
+ collection_.NotifySubmitFrame(frame_token, viz::BeginFrameAck(args, true),
+ args);
+ return frame_token;
+ } else {
+ collection_.NotifyImplFrameCausedNoDamage(
+ viz::BeginFrameAck(args, false));
+ collection_.NotifyMainFrameCausedNoDamage(args);
+ }
+ return 0;
+ }
+
+ uint32_t NextFrameToken() {
+ static uint32_t frame_token = 0;
+ return ++frame_token;
+ }
+
+ protected:
+ FrameSequenceTrackerCollection collection_;
+
+ std::unique_ptr<FrameSequenceTracker> tracker_;
+};
+
+// Tests that the tracker works correctly when the source-id for the
+// begin-frames change.
+TEST_F(FrameSequenceTrackerTest, SourceIdChangeDuringSequence) {
+ const uint64_t source_1 = 1;
+ uint64_t sequence_1 = 0;
+
+ // Dispatch some frames, both causing damage to impl/main, and both impl and
+ // main providing damage to the frame.
+ auto args_1 = CreateBeginFrameArgs(source_1, ++sequence_1);
+ DispatchCompleteFrame(args_1, kImplDamage | kMainDamage);
+ args_1 = CreateBeginFrameArgs(source_1, ++sequence_1);
+ DispatchCompleteFrame(args_1, kImplDamage | kMainDamage);
+
+ // Start a new tracker.
+ auto tracker = CreateNewTracker();
+
+ // Change the source-id, and start an impl frame. This time, the main-frame
+ // does not provide any damage.
+ const uint64_t source_2 = 2;
+ uint64_t sequence_2 = 0;
+ auto args_2 = CreateBeginFrameArgs(source_2, ++sequence_2);
+ collection_.NotifyBeginImplFrame(args_2);
+ collection_.NotifyBeginMainFrame(args_2);
+ collection_.NotifyMainFrameCausedNoDamage(args_2);
+ // Since the main-frame did not have any new damage from the latest
+ // BeginFrameArgs, the submit-frame will carry the previous BeginFrameArgs
+ // (from source_1);
+ collection_.NotifySubmitFrame(NextFrameToken(),
+ viz::BeginFrameAck(args_2, true), args_1);
+}
+
+} // namespace
+} // namespace cc
diff --git a/chromium/cc/trees/image_animation_controller.cc b/chromium/cc/trees/image_animation_controller.cc
index eb92e3b4f5f..a7e1ebf6de6 100644
--- a/chromium/cc/trees/image_animation_controller.cc
+++ b/chromium/cc/trees/image_animation_controller.cc
@@ -454,7 +454,7 @@ size_t ImageAnimationController::AnimationState::NextFrameIndex() const {
ImageAnimationController::InvalidationScheduler::InvalidationScheduler(
base::SingleThreadTaskRunner* task_runner,
Client* client)
- : task_runner_(task_runner), client_(client), weak_factory_(this) {
+ : task_runner_(task_runner), client_(client) {
DCHECK(task_runner_->BelongsToCurrentThread());
}
diff --git a/chromium/cc/trees/image_animation_controller.h b/chromium/cc/trees/image_animation_controller.h
index a95ec12448e..1f118704810 100644
--- a/chromium/cc/trees/image_animation_controller.h
+++ b/chromium/cc/trees/image_animation_controller.h
@@ -267,7 +267,7 @@ class CC_EXPORT ImageAnimationController {
// The time at which the next animation is expected to run.
base::TimeTicks next_animation_time_;
- base::WeakPtrFactory<InvalidationScheduler> weak_factory_;
+ base::WeakPtrFactory<InvalidationScheduler> weak_factory_{this};
};
// The AnimationState for images is persisted until they are cleared on
diff --git a/chromium/cc/trees/layer_tree_frame_sink.cc b/chromium/cc/trees/layer_tree_frame_sink.cc
index 71ed2774860..34ac5b7dfa5 100644
--- a/chromium/cc/trees/layer_tree_frame_sink.cc
+++ b/chromium/cc/trees/layer_tree_frame_sink.cc
@@ -48,8 +48,7 @@ LayerTreeFrameSink::LayerTreeFrameSink(
: context_provider_(std::move(context_provider)),
worker_context_provider_(std::move(worker_context_provider)),
compositor_task_runner_(std::move(compositor_task_runner)),
- gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
- weak_ptr_factory_(this) {
+ gpu_memory_buffer_manager_(gpu_memory_buffer_manager) {
DETACH_FROM_THREAD(thread_checker_);
}
diff --git a/chromium/cc/trees/layer_tree_frame_sink.h b/chromium/cc/trees/layer_tree_frame_sink.h
index 76634a79771..68b9734737a 100644
--- a/chromium/cc/trees/layer_tree_frame_sink.h
+++ b/chromium/cc/trees/layer_tree_frame_sink.h
@@ -8,6 +8,7 @@
#include <deque>
#include <memory>
+#include "base/memory/read_only_shared_memory_region.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
@@ -127,7 +128,7 @@ class CC_EXPORT LayerTreeFrameSink : public viz::SharedBitmapReporter,
virtual void DidNotProduceFrame(const viz::BeginFrameAck& ack) = 0;
// viz::SharedBitmapReporter implementation.
- void DidAllocateSharedBitmap(mojo::ScopedSharedBufferHandle buffer,
+ void DidAllocateSharedBitmap(base::ReadOnlySharedMemoryRegion region,
const viz::SharedBitmapId& id) override = 0;
void DidDeleteSharedBitmap(const viz::SharedBitmapId& id) override = 0;
@@ -154,7 +155,7 @@ class CC_EXPORT LayerTreeFrameSink : public viz::SharedBitmapReporter,
private:
THREAD_CHECKER(thread_checker_);
- base::WeakPtrFactory<LayerTreeFrameSink> weak_ptr_factory_;
+ base::WeakPtrFactory<LayerTreeFrameSink> weak_ptr_factory_{this};
};
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_frame_sink_client.h b/chromium/cc/trees/layer_tree_frame_sink_client.h
index fc298c8fef5..50848593309 100644
--- a/chromium/cc/trees/layer_tree_frame_sink_client.h
+++ b/chromium/cc/trees/layer_tree_frame_sink_client.h
@@ -68,9 +68,6 @@ class CC_EXPORT LayerTreeFrameSinkClient {
// viz::ContextProviders) must be recreated.
virtual void DidLoseLayerTreeFrameSink() = 0;
- // Notification that the client does not need a new BeginFrame.
- virtual void DidNotNeedBeginFrame() = 0;
-
// For SynchronousCompositor (WebView) to ask the layer compositor to submit
// a new CompositorFrame synchronously.
virtual void OnDraw(const gfx::Transform& transform,
diff --git a/chromium/cc/trees/layer_tree_frame_sink_unittest.cc b/chromium/cc/trees/layer_tree_frame_sink_unittest.cc
index 58334b8322f..5eabeb0a5dc 100644
--- a/chromium/cc/trees/layer_tree_frame_sink_unittest.cc
+++ b/chromium/cc/trees/layer_tree_frame_sink_unittest.cc
@@ -4,6 +4,7 @@
#include "cc/trees/layer_tree_frame_sink.h"
+#include "base/memory/read_only_shared_memory_region.h"
#include "base/single_thread_task_runner.h"
#include "base/test/test_simple_task_runner.h"
#include "cc/test/fake_layer_tree_frame_sink_client.h"
@@ -34,7 +35,7 @@ class StubLayerTreeFrameSink : public LayerTreeFrameSink {
client_->DidReceiveCompositorFrameAck();
}
void DidNotProduceFrame(const viz::BeginFrameAck& ack) override {}
- void DidAllocateSharedBitmap(mojo::ScopedSharedBufferHandle buffer,
+ void DidAllocateSharedBitmap(base::ReadOnlySharedMemoryRegion region,
const viz::SharedBitmapId& id) override {}
void DidDeleteSharedBitmap(const viz::SharedBitmapId& id) override {}
};
diff --git a/chromium/cc/trees/layer_tree_host.cc b/chromium/cc/trees/layer_tree_host.cc
index 4e9a9393289..5270f43d422 100644
--- a/chromium/cc/trees/layer_tree_host.cc
+++ b/chromium/cc/trees/layer_tree_host.cc
@@ -131,10 +131,8 @@ LayerTreeHost::LayerTreeHost(InitParams params, CompositorMode mode)
debug_state_(settings_.initial_debug_state),
id_(s_layer_tree_host_sequence_number.GetNext() + 1),
task_graph_runner_(params.task_graph_runner),
- content_source_id_(0),
event_listener_properties_(),
- mutator_host_(params.mutator_host),
- defer_main_frame_update_weak_ptr_factory_(this) {
+ mutator_host_(params.mutator_host) {
DCHECK(task_graph_runner_);
DCHECK(!settings_.enable_checker_imaging || image_worker_task_runner_);
@@ -392,7 +390,11 @@ void LayerTreeHost::FinishCommitOnImplThread(
// Dump property trees and layers if run with:
// --vmodule=layer_tree_host=3
if (VLOG_IS_ON(3)) {
- VLOG(3) << "After finishing commit on impl, the sync tree:"
+ const char* client_name = GetClientNameForMetrics();
+ if (!client_name)
+ client_name = "<unknown client>";
+ VLOG(3) << "After finishing (" << client_name
+ << ") commit on impl, the sync tree:"
<< "\nproperty_trees:\n"
<< sync_tree->property_trees()->ToString() << "\n"
<< "cc::LayerImpls:\n"
@@ -769,7 +771,7 @@ std::string LayerTreeHost::LayersAsString() const {
return layers;
}
-bool LayerTreeHost::CaptureContent(std::vector<NodeHolder>* content) {
+bool LayerTreeHost::CaptureContent(std::vector<NodeId>* content) {
if (viewport_visible_rect_.IsEmpty())
return false;
@@ -914,15 +916,9 @@ void LayerTreeHost::ApplyViewportChanges(const ScrollAndScaleSet& info) {
SetNeedsUpdateLayers();
}
-void LayerTreeHost::RecordWheelAndTouchScrollingCount(
- const ScrollAndScaleSet& info) {
- bool has_scrolled_by_wheel = info.has_scrolled_by_wheel;
- bool has_scrolled_by_touch = info.has_scrolled_by_touch;
-
- if (has_scrolled_by_wheel || has_scrolled_by_touch) {
- client_->RecordWheelAndTouchScrollingCount(has_scrolled_by_wheel,
- has_scrolled_by_touch);
- }
+void LayerTreeHost::RecordManipulationTypeCounts(
+ const ScrollAndScaleSet& scroll_info) {
+ client_->RecordManipulationTypeCounts(scroll_info.manipulation_info);
}
void LayerTreeHost::SendOverscrollAndScrollEndEventsFromImplSide(
@@ -972,7 +968,7 @@ void LayerTreeHost::ApplyScrollAndScale(ScrollAndScaleSet* info) {
// on the main thread.
ApplyViewportChanges(*info);
- RecordWheelAndTouchScrollingCount(*info);
+ RecordManipulationTypeCounts(*info);
}
void LayerTreeHost::RecordStartOfFrameMetrics() {
@@ -1343,10 +1339,6 @@ void LayerTreeHost::SetExternalPageScaleFactor(
SetNeedsCommit();
}
-void LayerTreeHost::SetContentSourceId(uint32_t id) {
- content_source_id_ = id;
-}
-
void LayerTreeHost::ClearCachesOnNextCommit() {
clear_caches_on_next_commit_ = true;
}
@@ -1606,8 +1598,6 @@ void LayerTreeHost::PushLayerTreePropertiesTo(LayerTreeImpl* tree_impl) {
tree_impl->SetRasterColorSpace(raster_color_space_id_, raster_color_space_);
tree_impl->SetExternalPageScaleFactor(external_page_scale_factor_);
- tree_impl->set_content_source_id(content_source_id_);
-
tree_impl->set_painted_device_scale_factor(painted_device_scale_factor_);
tree_impl->SetDeviceScaleFactor(device_scale_factor_);
tree_impl->SetDeviceViewportSize(device_viewport_size_);
diff --git a/chromium/cc/trees/layer_tree_host.h b/chromium/cc/trees/layer_tree_host.h
index b7cf9d9af7d..54000cfece0 100644
--- a/chromium/cc/trees/layer_tree_host.h
+++ b/chromium/cc/trees/layer_tree_host.h
@@ -33,7 +33,7 @@
#include "cc/input/scrollbar.h"
#include "cc/layers/layer_collections.h"
#include "cc/layers/layer_list_iterator.h"
-#include "cc/paint/node_holder.h"
+#include "cc/paint/node_id.h"
#include "cc/trees/compositor_mode.h"
#include "cc/trees/layer_tree_frame_sink.h"
#include "cc/trees/layer_tree_host_client.h"
@@ -432,9 +432,6 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
return painted_device_scale_factor_;
}
- void SetContentSourceId(uint32_t);
- uint32_t content_source_id() const { return content_source_id_; }
-
// Clears image caches and resets the scheduling history for the content
// produced by this host so far.
void ClearCachesOnNextCommit();
@@ -678,8 +675,8 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
std::string LayersAsString() const;
// Captures the on-screen text content, if success, fills the associated
- // NodeHolder in |content| and return true, otherwise return false.
- bool CaptureContent(std::vector<NodeHolder>* content);
+ // NodeId in |content| and return true, otherwise return false.
+ bool CaptureContent(std::vector<NodeId>* content);
protected:
LayerTreeHost(InitParams params, CompositorMode mode);
@@ -722,7 +719,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
enum { kNumFramesToConsiderBeforeRemovingSlowPathFlag = 60 };
void ApplyViewportChanges(const ScrollAndScaleSet& info);
- void RecordWheelAndTouchScrollingCount(const ScrollAndScaleSet& info);
+ void RecordManipulationTypeCounts(const ScrollAndScaleSet& scroll_info);
void SendOverscrollAndScrollEndEventsFromImplSide(
const ScrollAndScaleSet& info);
void ApplyPageScaleDeltaFromImplSide(float page_scale_delta);
@@ -807,7 +804,6 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
gfx::ColorSpace raster_color_space_;
bool clear_caches_on_next_commit_ = false;
- uint32_t content_source_id_;
viz::LocalSurfaceIdAllocation local_surface_id_allocation_from_parent_;
// Used to detect surface invariant violations.
bool has_pushed_local_surface_id_from_parent_ = false;
@@ -882,7 +878,8 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
// Used to vend weak pointers to LayerTreeHost to ScopedDeferMainFrameUpdate
// objects.
- base::WeakPtrFactory<LayerTreeHost> defer_main_frame_update_weak_ptr_factory_;
+ base::WeakPtrFactory<LayerTreeHost> defer_main_frame_update_weak_ptr_factory_{
+ this};
};
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_client.h b/chromium/cc/trees/layer_tree_host_client.h
index 5ddc975a950..f48af6c6d1e 100644
--- a/chromium/cc/trees/layer_tree_host_client.h
+++ b/chromium/cc/trees/layer_tree_host_client.h
@@ -53,6 +53,14 @@ struct ApplyViewportChangesArgs {
bool scroll_gesture_did_end;
};
+using ManipulationInfo = uint32_t;
+constexpr ManipulationInfo kManipulationInfoNone = 0;
+constexpr ManipulationInfo kManipulationInfoHasScrolledByWheel = 1 << 0;
+constexpr ManipulationInfo kManipulationInfoHasScrolledByTouch = 1 << 1;
+constexpr ManipulationInfo kManipulationInfoHasScrolledByPrecisionTouchPad =
+ 1 << 2;
+constexpr ManipulationInfo kManipulationInfoHasPinchZoomed = 1 << 3;
+
// A LayerTreeHost is bound to a LayerTreeHostClient. The main rendering
// loop (in ProxyMain or SingleThreadProxy) calls methods on the
// LayerTreeHost, which then handles them and also calls into the equivalent
@@ -104,9 +112,9 @@ class LayerTreeHostClient {
// related to pinch-zoom, browser controls (aka URL bar), overscroll, etc.
virtual void ApplyViewportChanges(const ApplyViewportChangesArgs& args) = 0;
- virtual void RecordWheelAndTouchScrollingCount(
- bool has_scrolled_by_wheel,
- bool has_scrolled_by_touch) = 0;
+ // Record use counts of different methods of scrolling (e.g. wheel, touch,
+ // precision touchpad, etc.).
+ virtual void RecordManipulationTypeCounts(ManipulationInfo info) = 0;
// Notifies the client when an overscroll has happened.
virtual void SendOverscrollEventFromImplSide(
diff --git a/chromium/cc/trees/layer_tree_host_common.cc b/chromium/cc/trees/layer_tree_host_common.cc
index 6eb7ec07102..7ea7995ee11 100644
--- a/chromium/cc/trees/layer_tree_host_common.cc
+++ b/chromium/cc/trees/layer_tree_host_common.cc
@@ -81,7 +81,6 @@ LayerTreeHostCommon::CalcDrawPropsImplInputs::CalcDrawPropsImplInputs(
const gfx::Vector2dF& elastic_overscroll,
const ElementId elastic_overscroll_element_id,
int max_texture_size,
- bool can_adjust_raster_scales,
RenderSurfaceList* render_surface_list,
PropertyTrees* property_trees,
TransformNode* page_scale_transform_node)
@@ -96,7 +95,6 @@ LayerTreeHostCommon::CalcDrawPropsImplInputs::CalcDrawPropsImplInputs(
elastic_overscroll(elastic_overscroll),
elastic_overscroll_element_id(elastic_overscroll_element_id),
max_texture_size(max_texture_size),
- can_adjust_raster_scales(can_adjust_raster_scales),
render_surface_list(render_surface_list),
property_trees(property_trees),
page_scale_transform_node(page_scale_transform_node) {}
@@ -118,7 +116,6 @@ LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting::
gfx::Vector2dF(),
ElementId(),
std::numeric_limits<int>::max() / 2,
- false,
render_surface_list,
GetPropertyTrees(root_layer),
nullptr) {
@@ -181,9 +178,8 @@ ScrollAndScaleSet::ScrollAndScaleSet()
top_controls_delta(0.f),
browser_controls_constraint(BrowserControlsState::kBoth),
browser_controls_constraint_changed(false),
- has_scrolled_by_wheel(false),
- has_scrolled_by_touch(false),
- scroll_gesture_did_end(false) {}
+ scroll_gesture_did_end(false),
+ manipulation_info(kManipulationInfoNone) {}
ScrollAndScaleSet::~ScrollAndScaleSet() = default;
@@ -541,8 +537,7 @@ void CalculateDrawPropertiesInternal(
gfx::Rect(inputs->device_viewport_size), inputs->device_transform,
inputs->property_trees);
draw_property_utils::UpdatePropertyTreesAndRenderSurfaces(
- inputs->root_layer, inputs->property_trees,
- inputs->can_adjust_raster_scales);
+ inputs->root_layer, inputs->property_trees);
// Property trees are normally constructed on the main thread and
// passed to compositor thread. Source to parent updates on them are not
@@ -609,8 +604,7 @@ void CalculateDrawPropertiesInternal(
inputs->device_scale_factor, page_scale_factor_for_root,
inputs->device_transform);
draw_property_utils::UpdatePropertyTreesAndRenderSurfaces(
- inputs->root_layer, inputs->property_trees,
- inputs->can_adjust_raster_scales);
+ inputs->root_layer, inputs->property_trees);
break;
}
}
diff --git a/chromium/cc/trees/layer_tree_host_common.h b/chromium/cc/trees/layer_tree_host_common.h
index c27157a9939..07c0bc586c2 100644
--- a/chromium/cc/trees/layer_tree_host_common.h
+++ b/chromium/cc/trees/layer_tree_host_common.h
@@ -74,7 +74,6 @@ class CC_EXPORT LayerTreeHostCommon {
const gfx::Vector2dF& elastic_overscroll,
const ElementId elastic_overscroll_element_id,
int max_texture_size,
- bool can_adjust_raster_scales,
RenderSurfaceList* render_surface_list,
PropertyTrees* property_trees,
TransformNode* page_scale_transform_node);
@@ -90,7 +89,6 @@ class CC_EXPORT LayerTreeHostCommon {
gfx::Vector2dF elastic_overscroll;
const ElementId elastic_overscroll_element_id;
int max_texture_size;
- bool can_adjust_raster_scales;
RenderSurfaceList* render_surface_list;
PropertyTrees* property_trees;
TransformNode* page_scale_transform_node;
@@ -189,12 +187,14 @@ struct CC_EXPORT ScrollAndScaleSet {
std::vector<std::unique_ptr<SwapPromise>> swap_promises;
BrowserControlsState browser_controls_constraint;
bool browser_controls_constraint_changed;
- bool has_scrolled_by_wheel;
- bool has_scrolled_by_touch;
// Set to true when a scroll gesture being handled on the compositor has
// ended.
bool scroll_gesture_did_end;
+
+ // Tracks different methods of scrolling (e.g. wheel, touch, precision
+ // touchpad, etc.).
+ ManipulationInfo manipulation_info;
};
template <typename Function>
diff --git a/chromium/cc/trees/layer_tree_host_common_perftest.cc b/chromium/cc/trees/layer_tree_host_common_perftest.cc
index 2c1c4ab1d82..4cb8bc9e760 100644
--- a/chromium/cc/trees/layer_tree_host_common_perftest.cc
+++ b/chromium/cc/trees/layer_tree_host_common_perftest.cc
@@ -107,7 +107,6 @@ class CalcDrawPropsTest : public LayerTreeHostCommonPerfTest {
active_tree->OuterViewportScrollLayer(),
active_tree->elastic_overscroll()->Current(active_tree->IsActiveTree()),
active_tree->OverscrollElasticityElementId(), max_texture_size,
- host_impl->settings().layer_transforms_should_scale_layer_contents,
&update_list, active_tree->property_trees(),
active_tree->property_trees()->transform_tree.Node(
active_tree->InnerViewportContainerLayer()
diff --git a/chromium/cc/trees/layer_tree_host_common_unittest.cc b/chromium/cc/trees/layer_tree_host_common_unittest.cc
index 93750755adb..12652e57e9f 100644
--- a/chromium/cc/trees/layer_tree_host_common_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_common_unittest.cc
@@ -168,7 +168,6 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest {
inputs.page_scale_layer = page_scale_layer;
inputs.inner_viewport_scroll_layer = inner_viewport_scroll_layer;
inputs.outer_viewport_scroll_layer = outer_viewport_scroll_layer;
- inputs.can_adjust_raster_scales = true;
if (page_scale_layer) {
PropertyTrees* property_trees =
root_layer->layer_tree_impl()->property_trees();
@@ -236,7 +235,6 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest {
void ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(
LayerImpl* root_layer) {
DCHECK(root_layer->layer_tree_impl());
- bool can_adjust_raster_scales = true;
const LayerImpl* page_scale_layer = nullptr;
LayerImpl* inner_viewport_scroll_layer =
@@ -262,8 +260,8 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest {
outer_viewport_scroll_layer, overscroll_elasticity_element_id,
elastic_overscroll, page_scale_factor, device_scale_factor,
gfx::Rect(device_viewport_size), gfx::Transform(), property_trees);
- draw_property_utils::UpdatePropertyTreesAndRenderSurfaces(
- root_layer, property_trees, can_adjust_raster_scales);
+ draw_property_utils::UpdatePropertyTreesAndRenderSurfaces(root_layer,
+ property_trees);
draw_property_utils::FindLayersThatNeedUpdates(
root_layer->layer_tree_impl(), property_trees,
update_layer_impl_list_.get());
@@ -280,7 +278,6 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest {
DCHECK(!root_layer->bounds().IsEmpty());
LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
root_layer, device_viewport_size, render_surface_list_impl_.get());
- inputs.can_adjust_raster_scales = false;
LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
}
@@ -311,7 +308,7 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest {
bool VerifyLayerInList(scoped_refptr<Layer> layer,
const LayerList* layer_list) {
- return base::ContainsValue(*layer_list, layer);
+ return base::Contains(*layer_list, layer);
}
private:
@@ -323,18 +320,11 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest {
class LayerTreeHostCommonTest : public LayerTreeHostCommonTestBase,
public testing::Test {};
-class LayerTreeSettingsScaleContent : public VerifyTreeCalcsLayerTreeSettings {
- public:
- LayerTreeSettingsScaleContent() {
- layer_transforms_should_scale_layer_contents = true;
- }
-};
-
class LayerTreeHostCommonScalingTest : public LayerTreeHostCommonTestBase,
public testing::Test {
public:
LayerTreeHostCommonScalingTest()
- : LayerTreeHostCommonTestBase(LayerTreeSettingsScaleContent()) {}
+ : LayerTreeHostCommonTestBase(VerifyTreeCalcsLayerTreeSettings()) {}
};
class LayerTreeHostCommonDrawRectsTest : public LayerTreeHostCommonTest {
@@ -1401,7 +1391,6 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceListForTransparentChild) {
RenderSurfaceList render_surface_list;
LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
root, root->bounds(), &render_surface_list);
- inputs.can_adjust_raster_scales = true;
LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
// Since the layer is transparent, render_surface1->GetRenderSurface() should
@@ -1437,7 +1426,6 @@ TEST_F(LayerTreeHostCommonTest,
RenderSurfaceList render_surface_list;
LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
root, root->bounds(), &render_surface_list);
- inputs.can_adjust_raster_scales = true;
LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
EXPECT_EQ(2U, render_surface_list.size());
}
@@ -1461,7 +1449,6 @@ TEST_F(LayerTreeHostCommonTest,
RenderSurfaceList render_surface_list;
LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
root, root->bounds(), &render_surface_list);
- inputs.can_adjust_raster_scales = true;
LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
}
@@ -1496,7 +1483,6 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceListForFilter) {
RenderSurfaceList render_surface_list;
LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
root, root->bounds(), &render_surface_list);
- inputs.can_adjust_raster_scales = true;
LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
ASSERT_TRUE(GetRenderSurface(parent));
@@ -4436,7 +4422,6 @@ TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) {
RenderSurfaceList render_surface_list;
LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
root_layer, root_layer->bounds(), &render_surface_list);
- inputs.can_adjust_raster_scales = true;
LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
// We should have one render surface and two layers. The child
@@ -4451,7 +4436,6 @@ TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) {
RenderSurfaceList render_surface_list2;
LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs2(
root_layer, root_layer->bounds(), &render_surface_list2);
- inputs2.can_adjust_raster_scales = true;
LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs2);
LayerImpl* child_ptr = root_layer->layer_tree_impl()->LayerById(2);
@@ -4468,7 +4452,6 @@ TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) {
RenderSurfaceList render_surface_list3;
LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs3(
root_layer, root_layer->bounds(), &render_surface_list3);
- inputs3.can_adjust_raster_scales = true;
LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs3);
child_ptr = root_layer->layer_tree_impl()->LayerById(2);
@@ -4754,7 +4737,6 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHidden_SingleLayerImpl) {
RenderSurfaceList render_surface_list;
LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
root_layer, root_layer->bounds(), &render_surface_list);
- inputs.can_adjust_raster_scales = true;
LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
// We should have one render surface and two layers. The grand child has
@@ -4798,7 +4780,6 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHidden_TwoLayersImpl) {
RenderSurfaceList render_surface_list;
LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
root_layer, root_layer->bounds(), &render_surface_list);
- inputs.can_adjust_raster_scales = true;
LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
// We should have one render surface and one layer. The child has
@@ -4894,7 +4875,6 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) {
RenderSurfaceList render_surface_list;
LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
root_layer, root_layer->bounds(), &render_surface_list);
- inputs.can_adjust_raster_scales = true;
LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
auto& effect_tree =
@@ -5002,7 +4982,6 @@ TEST_F(LayerTreeHostCommonTest, ClippedOutCopyRequest) {
root_layer->layer_tree_impl()->SetRootLayerForTesting(std::move(root));
LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
root_layer, root_layer->bounds(), &render_surface_list);
- inputs.can_adjust_raster_scales = true;
LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
// We should have two render surface, as the others are clipped out.
@@ -6442,7 +6421,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionSubpixelScroll) {
sticky_position.is_sticky = true;
sticky_position.is_anchored_bottom = true;
sticky_position.bottom_offset = 10.0f;
- sticky_position.constraint_box_rect = gfx::RectF(0, 0, 100, 100);
+ sticky_position.constraint_box_rect = gfx::Rect(0, 0, 100, 100);
sticky_position.scroll_container_relative_sticky_box_rect =
gfx::Rect(0, 200, 10, 10);
sticky_position.scroll_container_relative_containing_block_rect =
@@ -6489,7 +6468,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionBottom) {
sticky_position.is_sticky = true;
sticky_position.is_anchored_bottom = true;
sticky_position.bottom_offset = 10.0f;
- sticky_position.constraint_box_rect = gfx::RectF(0, 0, 100, 100);
+ sticky_position.constraint_box_rect = gfx::Rect(0, 0, 100, 100);
sticky_position.scroll_container_relative_sticky_box_rect =
gfx::Rect(0, 150, 10, 10);
sticky_position.scroll_container_relative_containing_block_rect =
@@ -6571,7 +6550,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionBottomOuterViewportDelta) {
sticky_position.is_sticky = true;
sticky_position.is_anchored_bottom = true;
sticky_position.bottom_offset = 10.0f;
- sticky_position.constraint_box_rect = gfx::RectF(0, 0, 100, 100);
+ sticky_position.constraint_box_rect = gfx::Rect(0, 0, 100, 100);
sticky_position.scroll_container_relative_sticky_box_rect =
gfx::Rect(0, 70, 10, 10);
sticky_position.scroll_container_relative_containing_block_rect =
@@ -6650,7 +6629,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionLeftRight) {
sticky_position.is_anchored_right = true;
sticky_position.left_offset = 10.f;
sticky_position.right_offset = 10.f;
- sticky_position.constraint_box_rect = gfx::RectF(0, 0, 100, 100);
+ sticky_position.constraint_box_rect = gfx::Rect(0, 0, 100, 100);
sticky_position.scroll_container_relative_sticky_box_rect =
gfx::Rect(145, 0, 10, 10);
sticky_position.scroll_container_relative_containing_block_rect =
@@ -7303,7 +7282,6 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) {
FakeImplTaskRunnerProvider task_runner_provider;
TestTaskGraphRunner task_graph_runner;
LayerTreeSettings settings = host()->GetSettings();
- settings.layer_transforms_should_scale_layer_contents = true;
FakeLayerTreeHostImpl host_impl(settings, &task_runner_provider,
&task_graph_runner);
std::unique_ptr<AnimationScaleFactorTrackingLayerImpl> grand_parent =
@@ -7790,7 +7768,6 @@ TEST_F(LayerTreeHostCommonTest, DrawPropertyScales) {
FakeImplTaskRunnerProvider task_runner_provider;
TestTaskGraphRunner task_graph_runner;
LayerTreeSettings settings = host()->GetSettings();
- settings.layer_transforms_should_scale_layer_contents = true;
FakeLayerTreeHostImpl host_impl(settings, &task_runner_provider,
&task_graph_runner);
@@ -7864,7 +7841,6 @@ TEST_F(LayerTreeHostCommonTest, DrawPropertyScales) {
root_layer, device_viewport_size, &render_surface_list);
inputs.page_scale_factor = page_scale_factor;
- inputs.can_adjust_raster_scales = true;
inputs.page_scale_layer = root_layer;
inputs.page_scale_transform_node = inputs.property_trees->transform_tree.Node(
inputs.page_scale_layer->transform_tree_index());
@@ -7886,7 +7862,6 @@ TEST_F(LayerTreeHostCommonTest, DrawPropertyScales) {
device_scale_factor = 4.0f;
inputs.device_scale_factor = device_scale_factor;
- inputs.can_adjust_raster_scales = true;
root_layer->layer_tree_impl()->property_trees()->needs_rebuild = true;
LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
@@ -7906,7 +7881,6 @@ TEST_F(LayerTreeHostCommonTest, AnimationScales) {
FakeImplTaskRunnerProvider task_runner_provider;
TestTaskGraphRunner task_graph_runner;
LayerTreeSettings settings = host()->GetSettings();
- settings.layer_transforms_should_scale_layer_contents = true;
FakeLayerTreeHostImpl host_impl(settings, &task_runner_provider,
&task_graph_runner);
@@ -7974,56 +7948,6 @@ TEST_F(LayerTreeHostCommonTest, AnimationScales) {
EXPECT_FLOAT_EQ(100.f, GetStartingAnimationScale(child2_layer));
}
-TEST_F(LayerTreeHostCommonTest,
- AnimationScaleWhenLayerTransformShouldNotScaleLayerBounds) {
- // Returns empty scale if layer_transforms_should_scale_layer_contents is
- // false.
- FakeImplTaskRunnerProvider task_runner_provider;
- TestTaskGraphRunner task_graph_runner;
- LayerTreeSettings settings = host()->GetSettings();
- settings.layer_transforms_should_scale_layer_contents = false;
- FakeLayerTreeHostImpl host_impl(settings, &task_runner_provider,
- &task_graph_runner);
-
- std::unique_ptr<LayerImpl> root =
- LayerImpl::Create(host_impl.active_tree(), 1);
- LayerImpl* root_layer = root.get();
- std::unique_ptr<LayerImpl> child =
- LayerImpl::Create(host_impl.active_tree(), 2);
- LayerImpl* child_layer = child.get();
-
- root->test_properties()->AddChild(std::move(child));
- host_impl.active_tree()->SetRootLayerForTesting(std::move(root));
-
- host_impl.active_tree()->SetElementIdsForTesting();
-
- gfx::Transform scale_transform_child;
- scale_transform_child.Scale(4, 5);
-
- root_layer->SetBounds(gfx::Size(1, 1));
- child_layer->test_properties()->transform = scale_transform_child;
- child_layer->SetBounds(gfx::Size(1, 1));
-
- TransformOperations scale;
- scale.AppendScale(5.f, 8.f, 3.f);
-
- scoped_refptr<AnimationTimeline> timeline =
- AnimationTimeline::Create(AnimationIdProvider::NextTimelineId());
- host_impl.animation_host()->AddAnimationTimeline(timeline);
-
- AddAnimatedTransformToElementWithAnimation(
- child_layer->element_id(), timeline, 1.0, TransformOperations(), scale);
-
- root_layer->layer_tree_impl()->property_trees()->needs_rebuild = true;
- ExecuteCalculateDrawProperties(root_layer);
-
- EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(root_layer));
- EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(child_layer));
-
- EXPECT_FLOAT_EQ(kNotScaled, GetStartingAnimationScale(root_layer));
- EXPECT_FLOAT_EQ(kNotScaled, GetStartingAnimationScale(child_layer));
-}
-
TEST_F(LayerTreeHostCommonTest, VisibleContentRectInChildRenderSurface) {
LayerImpl* root = root_layer_for_testing();
LayerImpl* clip = AddChild<LayerImpl>(root);
@@ -9789,7 +9713,7 @@ TEST_F(LayerTreeHostCommonTest, LargeTransformTest) {
// The root layer should be in the RenderSurfaceList.
const auto* rsl = render_surface_list_impl();
- EXPECT_TRUE(base::ContainsValue(*rsl, GetRenderSurface(root)));
+ EXPECT_TRUE(base::Contains(*rsl, GetRenderSurface(root)));
}
TEST_F(LayerTreeHostCommonTest, PropertyTreesRebuildWithOpacityChanges) {
@@ -10143,40 +10067,7 @@ TEST_F(LayerTreeHostCommonTest, ScrollTreeBuilderTest) {
EXPECT_EQ(scroll_root1.id, grand_child12->scroll_tree_index());
}
-TEST_F(LayerTreeHostCommonTest, CanAdjustRasterScaleTest) {
- LayerImpl* root = root_layer_for_testing();
- LayerImpl* render_surface = AddChild<LayerImpl>(root);
- LayerImpl* child = AddChild<LayerImpl>(render_surface);
-
- root->SetBounds(gfx::Size(50, 50));
-
- render_surface->SetBounds(gfx::Size(10, 10));
- render_surface->test_properties()->force_render_surface = true;
- gfx::Transform transform;
- transform.Scale(5.f, 5.f);
- render_surface->test_properties()->transform = transform;
-
- child->SetDrawsContent(true);
- child->SetMasksToBounds(true);
- child->SetBounds(gfx::Size(10, 10));
-
- ExecuteCalculateDrawPropertiesWithoutAdjustingRasterScales(root);
-
- // Check surface draw properties.
- EXPECT_EQ(gfx::Rect(10, 10),
- GetRenderSurface(render_surface)->content_rect());
- EXPECT_EQ(transform, GetRenderSurface(render_surface)->draw_transform());
- EXPECT_EQ(gfx::RectF(50.0f, 50.0f),
- GetRenderSurface(render_surface)->DrawableContentRect());
-
- // Check child layer draw properties.
- EXPECT_EQ(gfx::Rect(10, 10), child->visible_layer_rect());
- EXPECT_EQ(gfx::Transform(), child->DrawTransform());
- EXPECT_EQ(gfx::Rect(10, 10), child->clip_rect());
- EXPECT_EQ(gfx::Rect(10, 10), child->drawable_content_rect());
-}
-
-TEST_F(LayerTreeHostCommonTest, SurfaceContentsScaleChangeWithCopyRequestTest) {
+TEST_F(LayerTreeHostCommonTest, CopyRequestScalingTest) {
LayerImpl* root = root_layer_for_testing();
LayerImpl* scale_layer = AddChild<LayerImpl>(root);
LayerImpl* copy_layer = AddChild<LayerImpl>(scale_layer);
@@ -10203,7 +10094,7 @@ TEST_F(LayerTreeHostCommonTest, SurfaceContentsScaleChangeWithCopyRequestTest) {
test_layer->SetMasksToBounds(true);
test_layer->SetBounds(gfx::Size(20, 20));
- ExecuteCalculateDrawPropertiesWithoutAdjustingRasterScales(root);
+ ExecuteCalculateDrawProperties(root);
// Check surface with copy request draw properties.
EXPECT_EQ(gfx::Rect(50, 50), GetRenderSurface(copy_layer)->content_rect());
@@ -10219,19 +10110,7 @@ TEST_F(LayerTreeHostCommonTest, SurfaceContentsScaleChangeWithCopyRequestTest) {
// Clear the copy request and call UpdateSurfaceContentsScale.
host_impl()->active_tree()->property_trees()->effect_tree.ClearCopyRequests();
- ExecuteCalculateDrawPropertiesWithoutAdjustingRasterScales(root);
-
- // Check surface draw properties without copy request.
- EXPECT_EQ(gfx::Rect(10, 10), GetRenderSurface(copy_layer)->content_rect());
- EXPECT_EQ(transform, GetRenderSurface(copy_layer)->draw_transform());
- EXPECT_EQ(gfx::RectF(50.0f, 50.0f),
- GetRenderSurface(copy_layer)->DrawableContentRect());
-
- // Check test layer draw properties without copy request.
- EXPECT_EQ(gfx::Rect(10, 10), test_layer->visible_layer_rect());
- EXPECT_EQ(gfx::Transform(), test_layer->DrawTransform());
- EXPECT_EQ(gfx::Rect(10, 10), test_layer->clip_rect());
- EXPECT_EQ(gfx::Rect(10, 10), test_layer->drawable_content_rect());
+ ExecuteCalculateDrawProperties(root);
}
TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCacheRenderSurface) {
@@ -10316,7 +10195,6 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCacheRenderSurface) {
RenderSurfaceList render_surface_list;
LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
root_layer, root_layer->bounds(), &render_surface_list);
- inputs.can_adjust_raster_scales = true;
LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
// We should have four render surfaces, one for the root, one for the grand
@@ -10541,7 +10419,6 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceListForTrilinearFiltering) {
RenderSurfaceList render_surface_list;
LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
root, root->bounds(), &render_surface_list);
- inputs.can_adjust_raster_scales = true;
LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
ASSERT_TRUE(GetRenderSurface(parent));
@@ -11677,5 +11554,229 @@ TEST_F(LayerTreeHostCommonTest,
kRoundedCorner4Radius * kDeviceScale);
}
+TEST_F(LayerTreeHostCommonTest, CustomLayerClipBounds) {
+ // The custom clip API should have the same effect as if an intermediate
+ // clip layer has been added to the layer tree. To check this the test creates
+ // 2 subtree for a root layer. One of the subtree uses the clip API to clip
+ // its subtree while the other uses an intermediate layer. The resulting clip
+ // in draw properties are expected to be the same.
+ // -Root
+ // - Parent [Clip set to |kClipBounds| using API]
+ // - Child
+ // - Clip Layer [Masks to bounds = true] [Layer bounds set to |kClipBounds|]
+ // - Expected Parent
+ // - Expected Child
+ constexpr float kDeviceScale = 1.f;
+
+ const gfx::Rect kRootLayerBounds(0, 0, 100, 100);
+ const gfx::Rect kParentLayerBounds(0, 0, 50, 100);
+ const gfx::Rect kChildLayerBounds(20, 20, 30, 60);
+
+ constexpr gfx::Rect kClipBounds(10, 10, 50, 50);
+
+ // The position of |Expected Parent| on screen should be same as |Parent|.
+ const gfx::Rect kExpectedParentLayerBounds(
+ gfx::Point(0, 0) - kClipBounds.OffsetFromOrigin(), gfx::Size(50, 100));
+
+ scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> parent = Layer::Create();
+ scoped_refptr<Layer> child = Layer::Create();
+
+ scoped_refptr<Layer> clip_layer = Layer::Create();
+ scoped_refptr<Layer> expected_parent = Layer::Create();
+ scoped_refptr<Layer> expected_child = Layer::Create();
+
+ root->AddChild(parent);
+ parent->AddChild(child);
+
+ root->AddChild(clip_layer);
+ clip_layer->AddChild(expected_parent);
+ expected_parent->AddChild(expected_child);
+
+ host()->SetRootLayer(root);
+
+ root->SetIsDrawable(true);
+ parent->SetIsDrawable(true);
+ child->SetIsDrawable(true);
+ expected_parent->SetIsDrawable(true);
+ expected_child->SetIsDrawable(true);
+
+ // Set layer positions.
+ root->SetPosition(gfx::PointF(kRootLayerBounds.origin()));
+ parent->SetPosition(gfx::PointF(kParentLayerBounds.origin()));
+ child->SetPosition(gfx::PointF(kChildLayerBounds.origin()));
+
+ clip_layer->SetPosition(gfx::PointF(kClipBounds.origin()));
+ expected_parent->SetPosition(
+ gfx::PointF(kExpectedParentLayerBounds.origin()));
+ expected_child->SetPosition(gfx::PointF(kChildLayerBounds.origin()));
+
+ root->SetBounds(kRootLayerBounds.size());
+ parent->SetBounds(kParentLayerBounds.size());
+ child->SetBounds(kChildLayerBounds.size());
+
+ clip_layer->SetBounds(kClipBounds.size());
+ expected_parent->SetBounds(kExpectedParentLayerBounds.size());
+ expected_child->SetBounds(kChildLayerBounds.size());
+
+ parent->SetClipRect(kClipBounds);
+ clip_layer->SetMasksToBounds(true);
+
+ ExecuteCalculateDrawProperties(root.get(), kDeviceScale);
+
+ const ClipTree& clip_tree =
+ root->layer_tree_host()->property_trees()->clip_tree;
+
+ const ClipNode* parent_clip_node = clip_tree.Node(parent->clip_tree_index());
+ EXPECT_EQ(parent_clip_node->clip, gfx::RectF(kClipBounds));
+ EXPECT_TRUE(!parent->clip_rect().IsEmpty());
+
+ const ClipNode* child_clip_node = clip_tree.Node(child->clip_tree_index());
+ EXPECT_EQ(child_clip_node->clip, gfx::RectF(kClipBounds));
+
+ host()->host_impl()->CreatePendingTree();
+ host()->CommitAndCreatePendingTree();
+ // TODO(https://crbug.com/939968) This call should be handled by
+ // FakeLayerTreeHost instead of manually pushing the properties from the
+ // layer tree host to the pending tree.
+ root->layer_tree_host()->PushLayerTreePropertiesTo(host()->pending_tree());
+ host()->host_impl()->ActivateSyncTree();
+ LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree();
+
+ // Get the layer impl for each Layer.
+ LayerImpl* root_impl = layer_tree_impl->LayerById(root->id());
+ LayerImpl* parent_impl = layer_tree_impl->LayerById(parent->id());
+ LayerImpl* child_impl = layer_tree_impl->LayerById(child->id());
+ LayerImpl* expected_parent_impl =
+ layer_tree_impl->LayerById(expected_parent->id());
+ LayerImpl* expected_child_impl =
+ layer_tree_impl->LayerById(expected_child->id());
+
+ ExecuteCalculateDrawProperties(root_impl, kDeviceScale);
+
+ EXPECT_TRUE(parent_impl->is_clipped());
+ EXPECT_TRUE(child_impl->is_clipped());
+ ASSERT_TRUE(expected_parent_impl->is_clipped());
+ ASSERT_TRUE(expected_child_impl->is_clipped());
+
+ EXPECT_EQ(parent_impl->clip_rect(), expected_parent_impl->clip_rect());
+ EXPECT_EQ(child_impl->clip_rect(), expected_child_impl->clip_rect());
+}
+
+TEST_F(LayerTreeHostCommonTest, CustomLayerClipBoundsWithMaskToBounds) {
+ // The custom clip API should have the same effect as if an intermediate
+ // clip layer has been added to the layer tree. To check this the test creates
+ // 2 subtree for a root layer. One of the subtree uses the clip API to clip
+ // its subtree while the other uses an intermediate layer. The resulting clip
+ // in draw properties are expected to be the same. In this test, the subtree
+ // roots also have their masks to bounds property set.
+ // -Root
+ // - Parent [Clip set to |kClipBounds| using API]
+ // - Child
+ // - Clip Layer [Masks to bounds = true] [Layer bounds set to |kClipBounds|]
+ // - Expected Parent [Masks to bounds = true]
+ // - Expected Child
+ constexpr float kDeviceScale = 1.f;
+
+ const gfx::Rect kRootLayerBounds(0, 0, 100, 100);
+ const gfx::Rect kParentLayerBounds(0, 0, 50, 100);
+ const gfx::Rect kChildLayerBounds(20, 20, 30, 60);
+
+ constexpr gfx::Rect kClipBounds(10, 10, 50, 50);
+
+ // The position of |Expected Parent| on screen should be same as |Parent|.
+ const gfx::Rect kExpectedParentLayerBounds(
+ gfx::Point(0, 0) - kClipBounds.OffsetFromOrigin(), gfx::Size(50, 100));
+
+ scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> parent = Layer::Create();
+ scoped_refptr<Layer> child = Layer::Create();
+
+ scoped_refptr<Layer> clip_layer = Layer::Create();
+ scoped_refptr<Layer> expected_parent = Layer::Create();
+ scoped_refptr<Layer> expected_child = Layer::Create();
+
+ root->AddChild(parent);
+ parent->AddChild(child);
+
+ root->AddChild(clip_layer);
+ clip_layer->AddChild(expected_parent);
+ expected_parent->AddChild(expected_child);
+
+ host()->SetRootLayer(root);
+
+ root->SetIsDrawable(true);
+ parent->SetIsDrawable(true);
+ child->SetIsDrawable(true);
+ expected_parent->SetIsDrawable(true);
+ expected_child->SetIsDrawable(true);
+
+ // Set layer positions.
+ root->SetPosition(gfx::PointF(kRootLayerBounds.origin()));
+ parent->SetPosition(gfx::PointF(kParentLayerBounds.origin()));
+ child->SetPosition(gfx::PointF(kChildLayerBounds.origin()));
+
+ clip_layer->SetPosition(gfx::PointF(kClipBounds.origin()));
+ expected_parent->SetPosition(
+ gfx::PointF(kExpectedParentLayerBounds.origin()));
+ expected_child->SetPosition(gfx::PointF(kChildLayerBounds.origin()));
+
+ root->SetBounds(kRootLayerBounds.size());
+ parent->SetBounds(kParentLayerBounds.size());
+ child->SetBounds(kChildLayerBounds.size());
+
+ clip_layer->SetBounds(kClipBounds.size());
+ expected_parent->SetBounds(kExpectedParentLayerBounds.size());
+ expected_child->SetBounds(kChildLayerBounds.size());
+
+ parent->SetClipRect(kClipBounds);
+ parent->SetMasksToBounds(true);
+
+ clip_layer->SetMasksToBounds(true);
+ expected_parent->SetMasksToBounds(true);
+
+ ExecuteCalculateDrawProperties(root.get(), kDeviceScale);
+
+ const ClipTree& clip_tree =
+ root->layer_tree_host()->property_trees()->clip_tree;
+
+ const ClipNode* parent_clip_node = clip_tree.Node(parent->clip_tree_index());
+ const gfx::RectF expected_clip_bounds = gfx::IntersectRects(
+ gfx::RectF(kClipBounds), gfx::RectF(kParentLayerBounds));
+ EXPECT_EQ(parent_clip_node->clip, expected_clip_bounds);
+ EXPECT_TRUE(!parent->clip_rect().IsEmpty());
+
+ const ClipNode* child_clip_node = clip_tree.Node(child->clip_tree_index());
+ EXPECT_EQ(child_clip_node->clip, expected_clip_bounds);
+
+ host()->host_impl()->CreatePendingTree();
+ host()->CommitAndCreatePendingTree();
+ // TODO(https://crbug.com/939968) This call should be handled by
+ // FakeLayerTreeHost instead of manually pushing the properties from the
+ // layer tree host to the pending tree.
+ root->layer_tree_host()->PushLayerTreePropertiesTo(host()->pending_tree());
+ host()->host_impl()->ActivateSyncTree();
+ LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree();
+
+ // Get the layer impl for each Layer.
+ LayerImpl* root_impl = layer_tree_impl->LayerById(root->id());
+ LayerImpl* parent_impl = layer_tree_impl->LayerById(parent->id());
+ LayerImpl* child_impl = layer_tree_impl->LayerById(child->id());
+ LayerImpl* expected_parent_impl =
+ layer_tree_impl->LayerById(expected_parent->id());
+ LayerImpl* expected_child_impl =
+ layer_tree_impl->LayerById(expected_child->id());
+
+ ExecuteCalculateDrawProperties(root_impl, kDeviceScale);
+
+ EXPECT_TRUE(parent_impl->is_clipped());
+ EXPECT_TRUE(child_impl->is_clipped());
+ ASSERT_TRUE(expected_parent_impl->is_clipped());
+ ASSERT_TRUE(expected_child_impl->is_clipped());
+
+ EXPECT_EQ(parent_impl->clip_rect(), expected_parent_impl->clip_rect());
+ EXPECT_EQ(child_impl->clip_rect(), expected_child_impl->clip_rect());
+}
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_impl.cc b/chromium/cc/trees/layer_tree_host_impl.cc
index e2921219d25..0585a41551c 100644
--- a/chromium/cc/trees/layer_tree_host_impl.cc
+++ b/chromium/cc/trees/layer_tree_host_impl.cc
@@ -38,6 +38,7 @@
#include "cc/input/page_scale_animation.h"
#include "cc/input/scroll_elasticity_helper.h"
#include "cc/input/scroll_state.h"
+#include "cc/input/scrollbar.h"
#include "cc/input/scrollbar_animation_controller.h"
#include "cc/input/scroller_size_metrics.h"
#include "cc/input/snap_selection_strategy.h"
@@ -323,7 +324,8 @@ LayerTreeHostImpl::LayerTreeHostImpl(
task_runner_provider_(task_runner_provider),
current_begin_frame_tracker_(BEGINFRAMETRACKER_FROM_HERE),
compositor_frame_reporting_controller_(
- std::make_unique<CompositorFrameReportingController>()),
+ std::make_unique<CompositorFrameReportingController>(
+ settings.single_thread_proxy_scheduler)),
settings_(settings),
is_synchronous_single_threaded_(!task_runner_provider->HasImplThread() &&
!settings_.single_thread_proxy_scheduler),
@@ -358,8 +360,7 @@ LayerTreeHostImpl::LayerTreeHostImpl(
is_animating_for_snap_(false),
paint_image_generator_client_id_(PaintImage::GetNextGeneratorClientId()),
scrollbar_controller_(std::make_unique<ScrollbarController>(this)),
- scroll_gesture_did_end_(false),
- weak_factory_(this) {
+ scroll_gesture_did_end_(false) {
DCHECK(mutator_host_);
mutator_host_->SetMutatorHostClient(this);
@@ -427,9 +428,21 @@ LayerTreeHostImpl::~LayerTreeHostImpl() {
mutator_host_->SetMutatorHostClient(nullptr);
}
+void LayerTreeHostImpl::DidSendBeginMainFrame(const viz::BeginFrameArgs& args) {
+ if (impl_thread_phase_ == ImplThreadPhase::INSIDE_IMPL_FRAME)
+ begin_main_frame_sent_during_impl_ = true;
+ frame_trackers_.NotifyBeginMainFrame(args);
+}
+
void LayerTreeHostImpl::BeginMainFrameAborted(
CommitEarlyOutReason reason,
- std::vector<std::unique_ptr<SwapPromise>> swap_promises) {
+ std::vector<std::unique_ptr<SwapPromise>> swap_promises,
+ const viz::BeginFrameArgs& args) {
+ if (reason == CommitEarlyOutReason::ABORTED_NOT_VISIBLE ||
+ reason == CommitEarlyOutReason::FINISHED_NO_UPDATES) {
+ frame_trackers_.NotifyMainFrameCausedNoDamage(args);
+ }
+
// If the begin frame data was handled, then scroll and scale set was applied
// by the main thread, so the active tree needs to be updated as if these sent
// values were applied and committed.
@@ -457,7 +470,7 @@ void LayerTreeHostImpl::CommitComplete() {
// In high latency mode commit cannot finish within the same frame. We need to
// flush input here to make sure they got picked up by |PrepareTiles()|.
if (input_handler_client_ && impl_thread_phase_ == ImplThreadPhase::IDLE)
- input_handler_client_->DeliverInputForBeginFrame();
+ input_handler_client_->DeliverInputForHighLatencyMode();
if (CommitToActiveTree()) {
active_tree_->HandleScrollbarShowRequestsFromMain();
@@ -483,6 +496,18 @@ void LayerTreeHostImpl::CommitComplete() {
UpdateSyncTreeAfterCommitOrImplSideInvalidation();
micro_benchmark_controller_.DidCompleteCommit();
+
+ if (mutator_host_->CurrentFrameHadRAF() &&
+ !request_animation_frame_tracker_) {
+ request_animation_frame_tracker_ =
+ frame_trackers_.CreateTracker(FrameSequenceTrackerType::kRAF);
+ }
+
+ if (mutator_host_->MainThreadAnimationsCount() > 0 &&
+ !main_thread_animation_frame_tracker_) {
+ main_thread_animation_frame_tracker_ = frame_trackers_.CreateTracker(
+ FrameSequenceTrackerType::kMainThreadAnimation);
+ }
}
void LayerTreeHostImpl::UpdateSyncTreeAfterCommitOrImplSideInvalidation() {
@@ -529,6 +554,97 @@ void LayerTreeHostImpl::UpdateSyncTreeAfterCommitOrImplSideInvalidation() {
if (CommitToActiveTree())
ActivateStateForImages();
+ if (!paint_worklet_painter_) {
+ // Blink should not send us any PaintWorklet inputs until we have a painter
+ // registered.
+ DCHECK(sync_tree()->picture_layers_with_paint_worklets().empty());
+ pending_tree_fully_painted_ = true;
+ NotifyPendingTreeFullyPainted();
+ return;
+ }
+
+ PaintWorkletJobMap dirty_paint_worklets = GatherDirtyPaintWorklets();
+ if (!dirty_paint_worklets.size()) {
+ pending_tree_fully_painted_ = true;
+ NotifyPendingTreeFullyPainted();
+ return;
+ }
+
+ client_->NotifyPaintWorkletStateChange(
+ Scheduler::PaintWorkletState::PROCESSING);
+ auto done_callback = base::BindOnce(
+ &LayerTreeHostImpl::OnPaintWorkletResultsReady, base::Unretained(this));
+ paint_worklet_painter_->DispatchWorklets(std::move(dirty_paint_worklets),
+ std::move(done_callback));
+}
+
+PaintWorkletJobMap LayerTreeHostImpl::GatherDirtyPaintWorklets() const {
+ PaintWorkletJobMap dirty_paint_worklets;
+ for (PictureLayerImpl* layer :
+ sync_tree()->picture_layers_with_paint_worklets()) {
+ for (const auto& entry : layer->GetPaintWorkletRecordMap()) {
+ // If we already have a record we can reuse it and so the
+ // PaintWorkletInput isn't dirty.
+ if (entry.second)
+ continue;
+
+ int id = entry.first->WorkletId();
+ auto result = dirty_paint_worklets.insert(
+ std::make_pair(id, scoped_refptr<PaintWorkletJobVector>{}));
+ scoped_refptr<PaintWorkletJobVector>& job_vector = result.first->second;
+ if (!job_vector)
+ job_vector = base::WrapRefCounted(new PaintWorkletJobVector);
+ job_vector->data.emplace_back(layer->id(), entry.first);
+ }
+ }
+ return dirty_paint_worklets;
+}
+
+void LayerTreeHostImpl::OnPaintWorkletResultsReady(PaintWorkletJobMap results) {
+ // Nothing else should have painted the PaintWorklets while we were waiting,
+ // and the results should have painted every PaintWorklet, so these should be
+ // the same.
+ DCHECK_EQ(results.size(), GatherDirtyPaintWorklets().size());
+
+ for (const auto& entry : results) {
+ for (const PaintWorkletJob& job : entry.second->data) {
+ LayerImpl* layer_impl =
+ pending_tree_->FindPendingTreeLayerById(job.layer_id());
+ // Painting the pending tree occurs asynchronously but stalls the pending
+ // tree pipeline, so nothing should have changed while we were doing that.
+ DCHECK(layer_impl);
+ static_cast<PictureLayerImpl*>(layer_impl)
+ ->SetPaintWorkletRecord(job.input(), job.output());
+ }
+ }
+
+ // While the pending tree is being painted by PaintWorklets, we restrict the
+ // tiles the TileManager is able to see. This may cause the TileManager to
+ // believe that it has finished rastering all the necessary tiles. When we
+ // finish painting the tree and release all the tiles, we need to mark the
+ // tile priorities as dirty so that the TileManager logic properly re-runs.
+ tile_priorities_dirty_ = true;
+
+ // Set the painted state before calling the scheduler, to ensure any callback
+ // running as a result sees the correct painted state.
+ pending_tree_fully_painted_ = true;
+ client_->NotifyPaintWorkletStateChange(Scheduler::PaintWorkletState::IDLE);
+
+ // The pending tree may have been force activated from the signal to the
+ // scheduler above, in which case there is no longer a tree to paint.
+ if (pending_tree_)
+ NotifyPendingTreeFullyPainted();
+}
+
+void LayerTreeHostImpl::NotifyPendingTreeFullyPainted() {
+ // The pending tree must be fully painted at this point.
+ DCHECK(pending_tree_fully_painted_);
+
+ // Nobody should claim the pending tree is fully painted if there is an
+ // ongoing dispatch.
+ DCHECK(!paint_worklet_painter_ ||
+ !paint_worklet_painter_->HasOngoingDispatch());
+
// Start working on newly created tiles immediately if needed.
// TODO(vmpstr): Investigate always having PrepareTiles issue
// NotifyReadyToActivate, instead of handling it here.
@@ -714,8 +830,7 @@ bool LayerTreeHostImpl::IsCurrentlyScrollingViewport() const {
}
bool LayerTreeHostImpl::IsCurrentlyScrollingLayerAt(
- const gfx::Point& viewport_point,
- InputHandler::ScrollInputType type) const {
+ const gfx::Point& viewport_point) const {
auto* scrolling_node = CurrentlyScrollingNode();
if (!scrolling_node)
return false;
@@ -729,7 +844,7 @@ bool LayerTreeHostImpl::IsCurrentlyScrollingLayerAt(
bool scroll_on_main_thread = false;
uint32_t main_thread_scrolling_reasons;
auto* test_scroll_node = FindScrollNodeForDeviceViewportPoint(
- device_viewport_point, type, layer_impl, &scroll_on_main_thread,
+ device_viewport_point, layer_impl, &scroll_on_main_thread,
&main_thread_scrolling_reasons);
if (scroll_on_main_thread)
@@ -1183,6 +1298,7 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) {
}
frame->use_default_lower_bound_deadline |=
append_quads_data.use_default_lower_bound_deadline;
+ frame->mirror_rect.Union(append_quads_data.mirror_rect);
}
// If CommitToActiveTree() is true, then we wait to draw until
@@ -1338,10 +1454,19 @@ DrawResult LayerTreeHostImpl::PrepareToDraw(FrameData* frame) {
if (client_name) {
size_t total_memory_in_bytes = 0;
size_t total_gpu_memory_for_tilings_in_bytes = 0;
+ int layers_with_text_count = 0;
+ int layers_with_text_no_lcd_text_count = 0;
for (const PictureLayerImpl* layer : active_tree()->picture_layers()) {
total_memory_in_bytes += layer->GetRasterSource()->GetMemoryUsage();
total_gpu_memory_for_tilings_in_bytes += layer->GPUMemoryUsageInBytes();
+ if (layer->GetRasterSource()->HasText()) {
+ layers_with_text_count++;
+ if (!layer->can_use_lcd_text()) {
+ layers_with_text_no_lcd_text_count++;
+ }
+ }
}
+
if (total_memory_in_bytes != 0) {
UMA_HISTOGRAM_COUNTS_1M(
base::StringPrintf("Compositing.%s.PictureMemoryUsageKb",
@@ -1359,6 +1484,34 @@ DrawResult LayerTreeHostImpl::PrepareToDraw(FrameData* frame) {
base::saturated_cast<int>(active_tree_->picture_layers().size()), 1,
400, 20);
+ if (layers_with_text_count > 0) {
+ int percent =
+ 100.0 * layers_with_text_no_lcd_text_count / layers_with_text_count;
+
+ if (layers_with_text_count < 10) {
+ UMA_HISTOGRAM_PERCENTAGE(
+ base::StringPrintf(
+ "Compositing.%s.PercentPictureLayersWithTextButLCDTextDisabled."
+ "LessThan10",
+ client_name),
+ percent);
+ } else if (layers_with_text_count <= 30) {
+ UMA_HISTOGRAM_PERCENTAGE(
+ base::StringPrintf(
+ "Compositing.%s.PercentPictureLayersWithTextButLCDTextDisabled."
+ "10To30",
+ client_name),
+ percent);
+ } else {
+ UMA_HISTOGRAM_PERCENTAGE(
+ base::StringPrintf(
+ "Compositing.%s."
+ "PercentPictureLayersWithTextButLCDTextDisabled.MoreThan30",
+ client_name),
+ percent);
+ }
+ }
+
// TODO(yigu): Maybe we should use the same check above. Need to figure out
// why exactly we skip 0.
if (!active_tree()->picture_layers().empty()) {
@@ -1588,11 +1741,12 @@ std::unique_ptr<RasterTilePriorityQueue> LayerTreeHostImpl::BuildRasterQueue(
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
"LayerTreeHostImpl::BuildRasterQueue");
- return RasterTilePriorityQueue::Create(active_tree_->picture_layers(),
- pending_tree_
- ? pending_tree_->picture_layers()
- : std::vector<PictureLayerImpl*>(),
- tree_priority, type);
+ return RasterTilePriorityQueue::Create(
+ active_tree_->picture_layers(),
+ pending_tree_ && pending_tree_fully_painted_
+ ? pending_tree_->picture_layers()
+ : std::vector<PictureLayerImpl*>(),
+ tree_priority, type);
}
std::unique_ptr<EvictionTilePriorityQueue>
@@ -1666,6 +1820,13 @@ size_t LayerTreeHostImpl::GetFrameIndexForImage(const PaintImage& paint_image,
}
void LayerTreeHostImpl::NotifyReadyToActivate() {
+ // The TileManager may call this method while the pending tree is still being
+ // painted, as it isn't aware of the ongoing paint. We shouldn't tell the
+ // scheduler we are ready to activate in that case, as if we do it will
+ // immediately activate once we call NotifyPaintWorkletStateChange, rather
+ // than wait for the TileManager to actually raster the content!
+ if (!pending_tree_fully_painted_)
+ return;
pending_tree_raster_duration_timer_.reset();
client_->NotifyReadyToActivate();
}
@@ -1800,6 +1961,7 @@ void LayerTreeHostImpl::DidReceiveCompositorFrameAck() {
void LayerTreeHostImpl::DidPresentCompositorFrame(
uint32_t frame_token,
const gfx::PresentationFeedback& feedback) {
+ frame_trackers_.NotifyFramePresented(frame_token, feedback);
PresentationTimeCallbackBuffer::PendingCallbacks activated =
presentation_time_callbacks_.PopPendingCallbacks(frame_token);
@@ -1817,6 +1979,7 @@ void LayerTreeHostImpl::DidPresentCompositorFrame(
void LayerTreeHostImpl::DidNotNeedBeginFrame() {
skipped_frame_tracker_.WillNotProduceFrame();
+ frame_trackers_.NotifyPauseFrameProduction();
}
void LayerTreeHostImpl::ReclaimResources(
@@ -1909,7 +2072,6 @@ viz::CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() {
metadata.page_scale_factor = active_tree_->current_page_scale_factor();
metadata.scrollable_viewport_size = active_tree_->ScrollableViewportSize();
metadata.root_background_color = active_tree_->background_color();
- metadata.content_source_id = active_tree_->content_source_id();
if (active_tree_->has_presentation_callbacks()) {
presentation_time_callbacks_.RegisterMainThreadPresentationCallbacks(
@@ -2061,6 +2223,7 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) {
if (frame->has_no_damage) {
DCHECK(!resourceless_software_draw_);
+ frame_trackers_.NotifyImplFrameCausedNoDamage(frame->begin_frame_ack);
TRACE_EVENT_INSTANT0("cc", "EarlyOut_NoDamage", TRACE_EVENT_SCOPE_THREAD);
active_tree()->BreakSwapPromises(SwapPromise::SWAP_FAILS);
return false;
@@ -2070,10 +2233,26 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) {
active_tree_->source_frame_number());
auto compositor_frame = GenerateCompositorFrame(frame);
+ frame->frame_token = compositor_frame.metadata.frame_token;
layer_tree_frame_sink_->SubmitCompositorFrame(
std::move(compositor_frame),
/*hit_test_data_changed=*/false, debug_state_.show_hit_test_borders);
+ frame_trackers_.NotifySubmitFrame(compositor_frame.metadata.frame_token,
+ frame->begin_frame_ack,
+ frame->origin_begin_main_frame_args);
+ if (request_animation_frame_tracker_ &&
+ !mutator_host_->NextFrameHasPendingRAF()) {
+ frame_trackers_.ScheduleRemoval(
+ std::move(request_animation_frame_tracker_));
+ }
+
+ if (main_thread_animation_frame_tracker_ &&
+ mutator_host_->MainThreadAnimationsCount() == 0) {
+ frame_trackers_.ScheduleRemoval(
+ std::move(main_thread_animation_frame_tracker_));
+ }
+
// Clears the list of swap promises after calling DidSwap on each of them to
// signal that the swap is over.
active_tree()->ClearSwapPromises();
@@ -2097,7 +2276,6 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) {
viz::CompositorFrame LayerTreeHostImpl::GenerateCompositorFrame(
FrameData* frame) {
- TRACE_EVENT0("cc,benchmark", "LayerTreeHostImpl::GenerateCompositorFrame");
TRACE_EVENT_WITH_FLOW1("viz,benchmark", "Graphics.Pipeline",
TRACE_ID_GLOBAL(CurrentBeginFrameArgs().trace_id),
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
@@ -2177,15 +2355,15 @@ viz::CompositorFrame LayerTreeHostImpl::GenerateCompositorFrame(
ui::LatencyInfo& new_latency_info = metadata.latency_info.back();
if (CommitToActiveTree()) {
new_latency_info.AddLatencyNumberWithTimestamp(
- ui::LATENCY_BEGIN_FRAME_UI_COMPOSITOR_COMPONENT, frame_time, 1);
+ ui::LATENCY_BEGIN_FRAME_UI_COMPOSITOR_COMPONENT, frame_time);
} else {
new_latency_info.AddLatencyNumberWithTimestamp(
- ui::LATENCY_BEGIN_FRAME_RENDERER_COMPOSITOR_COMPONENT, frame_time, 1);
+ ui::LATENCY_BEGIN_FRAME_RENDERER_COMPOSITOR_COMPONENT, frame_time);
base::TimeTicks draw_time = base::TimeTicks::Now();
for (auto& latency : metadata.latency_info) {
latency.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT, draw_time, 1);
+ ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT, draw_time);
}
}
ui::LatencyInfo::TraceIntermediateFlowEvents(metadata.latency_info,
@@ -2204,6 +2382,8 @@ viz::CompositorFrame LayerTreeHostImpl::GenerateCompositorFrame(
frame->begin_frame_ack.sequence_number);
metadata.begin_frame_ack = frame->begin_frame_ack;
+ metadata.mirror_rect = frame->mirror_rect;
+
viz::CompositorFrame compositor_frame;
compositor_frame.metadata = std::move(metadata);
resource_provider_.PrepareSendToParent(
@@ -2226,15 +2406,6 @@ viz::CompositorFrame LayerTreeHostImpl::GenerateCompositorFrame(
}
last_draw_local_surface_id_allocation_ =
child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation();
- if (const char* client_name = GetClientNameForMetrics()) {
- size_t total_quad_count = 0;
- for (const auto& pass : compositor_frame.render_pass_list)
- total_quad_count += pass->quad_list.size();
- UMA_HISTOGRAM_COUNTS_1000(
- base::StringPrintf("Compositing.%s.CompositorFrame.Quads", client_name),
- total_quad_count);
- }
-
return compositor_frame;
}
@@ -2305,13 +2476,16 @@ void LayerTreeHostImpl::GetGpuRasterizationCapabilities(
if (!*gpu_rasterization_enabled && !settings_.gpu_rasterization_forced)
return;
+ bool use_msaa = !caps.msaa_is_slow && !caps.avoid_stencil_buffers;
+
if (use_oop_rasterization_) {
*gpu_rasterization_supported = true;
*supports_disable_msaa = caps.multisample_compatibility;
// For OOP raster, the gpu service side will disable msaa if the
// requested samples are not enough. GPU raster does this same
// logic below client side.
- *max_msaa_samples = RequestedMSAASampleCount();
+ if (use_msaa)
+ *max_msaa_samples = RequestedMSAASampleCount();
return;
}
@@ -2326,7 +2500,7 @@ void LayerTreeHostImpl::GetGpuRasterizationCapabilities(
return;
*supports_disable_msaa = caps.multisample_compatibility;
- if (!caps.msaa_is_slow && !caps.avoid_stencil_buffers) {
+ if (use_msaa) {
// Skia may blacklist MSAA independently of Chrome. Query Skia for its max
// supported sample count. Assume gpu compositing + gpu raster for this, as
// that is what we are hoping to use.
@@ -2432,6 +2606,10 @@ void LayerTreeHostImpl::UpdateTreeResourcesForGpuRasterizationIfNeeded() {
bool LayerTreeHostImpl::WillBeginImplFrame(const viz::BeginFrameArgs& args) {
impl_thread_phase_ = ImplThreadPhase::INSIDE_IMPL_FRAME;
current_begin_frame_tracker_.Start(args);
+ frame_trackers_.NotifyBeginImplFrame(args);
+
+ begin_main_frame_expected_during_impl_ = client_->IsBeginMainFrameExpected();
+ begin_main_frame_sent_during_impl_ = false;
if (is_likely_to_require_a_draw_) {
// Optimistically schedule a draw. This will let us expect the tile manager
@@ -2440,8 +2618,10 @@ bool LayerTreeHostImpl::WillBeginImplFrame(const viz::BeginFrameArgs& args) {
SetNeedsRedraw();
}
- if (input_handler_client_)
- input_handler_client_->DeliverInputForBeginFrame();
+ if (input_handler_client_) {
+ scrollbar_controller_->WillBeginImplFrame();
+ input_handler_client_->DeliverInputForBeginFrame(args);
+ }
Animate();
@@ -2475,6 +2655,18 @@ bool LayerTreeHostImpl::WillBeginImplFrame(const viz::BeginFrameArgs& args) {
}
void LayerTreeHostImpl::DidFinishImplFrame() {
+ if (!begin_main_frame_sent_during_impl_ &&
+ !begin_main_frame_expected_during_impl_) {
+ // A begin-main-frame was never dispatched for this BeginFrameArgs, and one
+ // was not expected to be dispatched either. So notify the trackers of the
+ // begin-main-frame, and not to expect any updates from it. This is
+ // necessary to make sure the trackers can correctly know which frames were
+ // not expected to produce any updates.
+ frame_trackers_.NotifyBeginMainFrame(
+ current_begin_frame_tracker_.Current());
+ frame_trackers_.NotifyMainFrameCausedNoDamage(
+ current_begin_frame_tracker_.Current());
+ }
skipped_frame_tracker_.FinishFrame();
impl_thread_phase_ = ImplThreadPhase::IDLE;
current_begin_frame_tracker_.Finish();
@@ -2812,6 +3004,7 @@ void LayerTreeHostImpl::CreatePendingTree() {
active_tree()->top_controls_shown_ratio(),
active_tree()->elastic_overscroll());
}
+ pending_tree_fully_painted_ = false;
client_->OnCanDrawStateChanged(CanDraw());
TRACE_EVENT_ASYNC_BEGIN0("cc", "PendingTree:waiting", pending_tree_.get());
@@ -2967,7 +3160,11 @@ void LayerTreeHostImpl::ActivateSyncTree() {
// Dump property trees and layers if run with:
// --vmodule=layer_tree_host_impl=3
if (VLOG_IS_ON(3)) {
- VLOG(3) << "After activating sync tree, the active tree:"
+ const char* client_name = GetClientNameForMetrics();
+ if (!client_name)
+ client_name = "<unknown client>";
+ VLOG(3) << "After activating (" << client_name
+ << ") sync tree, the active tree:"
<< "\nproperty_trees:\n"
<< active_tree_->property_trees()->ToString() << "\n"
<< "cc::LayerImpls:\n"
@@ -3204,7 +3401,7 @@ void LayerTreeHostImpl::SetLayerTreeMutator(
void LayerTreeHostImpl::SetPaintWorkletLayerPainter(
std::unique_ptr<PaintWorkletLayerPainter> painter) {
- tile_manager_.SetPaintWorkletLayerPainter(std::move(painter));
+ paint_worklet_painter_ = std::move(painter);
}
LayerImpl* LayerTreeHostImpl::ViewportMainScrollLayer() {
@@ -3320,6 +3517,14 @@ void LayerTreeHostImpl::ReleaseLayerTreeFrameSink() {
bool all_resources_are_lost = layer_tree_frame_sink_->context_provider();
+ // Destroy the submit-frame trackers before destroying the frame sink.
+ pinch_frame_tracker_ = nullptr;
+ scroll_frame_tracker_ = nullptr;
+ compositor_animation_frame_tracker_ = nullptr;
+ request_animation_frame_tracker_ = nullptr;
+ main_thread_animation_frame_tracker_ = nullptr;
+ frame_trackers_.ClearAll();
+
// Detach from the old LayerTreeFrameSink and reset |layer_tree_frame_sink_|
// pointer as this surface is going to be destroyed independent of if binding
// the new LayerTreeFrameSink succeeds or not.
@@ -3329,15 +3534,24 @@ void LayerTreeHostImpl::ReleaseLayerTreeFrameSink() {
// If gpu compositing, then any resources created with the gpu context in the
// LayerTreeFrameSink were exported to the display compositor may be modified
// by it, and thus we would be unable to determine what state they are in, in
- // order to reuse them, so they must be lost. In software compositing, the
- // resources are not modified by the display compositor (there is no stateful
- // metadata for shared memory), so we do not need to consider them lost.
+ // order to reuse them, so they must be lost. Note that this includes
+ // resources created using the gpu context associated with
+ // |layer_tree_frame_sink_| internally by the compositor and any resources
+ // received from an external source (for instance, TextureLayers). This is
+ // because the API contract for releasing these external resources requires
+ // that the compositor return them with a valid sync token and no
+ // modifications to their GL state. Since that can not be guaranteed, these
+ // must also be marked lost.
+ //
+ // In software compositing, the resources are not modified by the display
+ // compositor (there is no stateful metadata for shared memory), so we do not
+ // need to consider them lost.
//
// In both cases, the resources that are exported to the display compositor
// will have no means of being returned to this client without the
- // LayerTreeFrameSink, so they should no longer be considered as exported.
- // Do this *after* any interactions with the |layer_tree_frame_sink_| in case
- // it tries to return resources during destruction.
+ // LayerTreeFrameSink, so they should no longer be considered as exported. Do
+ // this *after* any interactions with the |layer_tree_frame_sink_| in case it
+ // tries to return resources during destruction.
//
// The assumption being made here is that the display compositor WILL NOT use
// any resources previously exported when the CompositorFrameSink is closed.
@@ -3472,7 +3686,6 @@ void LayerTreeHostImpl::BindToClient(InputHandlerClient* client) {
InputHandler::ScrollStatus LayerTreeHostImpl::TryScroll(
const gfx::PointF& screen_space_point,
- InputHandler::ScrollInputType type,
const ScrollTree& scroll_tree,
ScrollNode* scroll_node) const {
InputHandler::ScrollStatus scroll_status;
@@ -3516,29 +3729,6 @@ InputHandler::ScrollStatus LayerTreeHostImpl::TryScroll(
return scroll_status;
}
- if (layer && !layer->non_fast_scrollable_region().IsEmpty()) {
- bool clipped = false;
- gfx::Transform inverse_screen_space_transform(
- gfx::Transform::kSkipInitialization);
- if (!screen_space_transform.GetInverse(&inverse_screen_space_transform)) {
- // TODO(shawnsingh): We shouldn't be applying a projection if screen space
- // transform is uninvertible here. Perhaps we should be returning
- // SCROLL_ON_MAIN_THREAD in this case?
- }
-
- gfx::PointF hit_test_point_in_layer_space = MathUtil::ProjectPoint(
- inverse_screen_space_transform, screen_space_point, &clipped);
- if (!clipped && layer->non_fast_scrollable_region().Contains(
- gfx::ToRoundedPoint(hit_test_point_in_layer_space))) {
- TRACE_EVENT0("cc",
- "LayerImpl::tryScroll: Failed NonFastScrollableRegion");
- scroll_status.thread = InputHandler::SCROLL_ON_MAIN_THREAD;
- scroll_status.main_thread_scrolling_reasons =
- MainThreadScrollingReason::kNonFastScrollableRegion;
- return scroll_status;
- }
- }
-
if (!scroll_node->scrollable) {
TRACE_EVENT0("cc", "LayerImpl::tryScroll: Ignored not scrollable");
scroll_status.thread = InputHandler::SCROLL_IGNORED;
@@ -3578,9 +3768,21 @@ static bool IsMainThreadScrolling(const InputHandler::ScrollStatus& status,
return false;
}
+base::flat_set<int> LayerTreeHostImpl::NonFastScrollableNodes(
+ const gfx::PointF& device_viewport_point) const {
+ base::flat_set<int> non_fast_scrollable_nodes;
+
+ const auto& non_fast_layers =
+ active_tree_->FindLayersHitByPointInNonFastScrollableRegion(
+ device_viewport_point);
+ for (const auto* layer : non_fast_layers)
+ non_fast_scrollable_nodes.insert(layer->scroll_tree_index());
+
+ return non_fast_scrollable_nodes;
+}
+
ScrollNode* LayerTreeHostImpl::FindScrollNodeForDeviceViewportPoint(
const gfx::PointF& device_viewport_point,
- InputHandler::ScrollInputType type,
LayerImpl* layer_impl,
bool* scroll_on_main_thread,
uint32_t* main_thread_scrolling_reasons) const {
@@ -3589,6 +3791,9 @@ ScrollNode* LayerTreeHostImpl::FindScrollNodeForDeviceViewportPoint(
*main_thread_scrolling_reasons =
MainThreadScrollingReason::kNotScrollingOnMain;
+ const auto& non_fast_scrollable_nodes =
+ NonFastScrollableNodes(device_viewport_point);
+
// Walk up the hierarchy and look for a scrollable layer.
ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree;
ScrollNode* impl_scroll_node = nullptr;
@@ -3611,13 +3816,20 @@ ScrollNode* LayerTreeHostImpl::FindScrollNodeForDeviceViewportPoint(
// The content layer can also block attempts to scroll outside the main
// thread.
ScrollStatus status =
- TryScroll(device_viewport_point, type, scroll_tree, scroll_node);
+ TryScroll(device_viewport_point, scroll_tree, scroll_node);
if (IsMainThreadScrolling(status, scroll_node)) {
*scroll_on_main_thread = true;
*main_thread_scrolling_reasons = status.main_thread_scrolling_reasons;
return scroll_node;
}
+ if (non_fast_scrollable_nodes.contains(scroll_node->id)) {
+ *scroll_on_main_thread = true;
+ *main_thread_scrolling_reasons =
+ MainThreadScrollingReason::kNonFastScrollableRegion;
+ return scroll_node;
+ }
+
if (status.thread == InputHandler::SCROLL_ON_IMPL_THREAD &&
!impl_scroll_node) {
impl_scroll_node = scroll_node;
@@ -3638,10 +3850,14 @@ ScrollNode* LayerTreeHostImpl::FindScrollNodeForDeviceViewportPoint(
if (impl_scroll_node) {
// Ensure that final layer scrolls on impl thread (crbug.com/625100)
ScrollStatus status =
- TryScroll(device_viewport_point, type, scroll_tree, impl_scroll_node);
+ TryScroll(device_viewport_point, scroll_tree, impl_scroll_node);
if (IsMainThreadScrolling(status, impl_scroll_node)) {
*scroll_on_main_thread = true;
*main_thread_scrolling_reasons = status.main_thread_scrolling_reasons;
+ } else if (non_fast_scrollable_nodes.contains(impl_scroll_node->id)) {
+ *scroll_on_main_thread = true;
+ *main_thread_scrolling_reasons =
+ MainThreadScrollingReason::kNonFastScrollableRegion;
}
}
@@ -3710,10 +3926,13 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl(
scroll_status.bubble = true;
}
+ scroll_frame_tracker_ = frame_trackers_.CreateTracker(
+ wheel_scrolling_ ? FrameSequenceTrackerType::kWheelScroll
+ : FrameSequenceTrackerType::kTouchScroll);
client_->RenewTreePriority();
RecordCompositorSlowScrollMetric(type, CC_THREAD);
- UpdateScrollSourceInfo(type);
+ UpdateScrollSourceInfo(type, scroll_state);
return scroll_status;
}
@@ -3796,7 +4015,7 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin(
}
scrolling_node = FindScrollNodeForDeviceViewportPoint(
- device_viewport_point, type, layer_impl, &scroll_on_main_thread,
+ device_viewport_point, layer_impl, &scroll_on_main_thread,
&scroll_status.main_thread_scrolling_reasons);
}
@@ -3943,14 +4162,31 @@ gfx::Vector2dF LayerTreeHostImpl::ComputeScrollDelta(
return gfx::Vector2dF(scrolled.x(), scrolled.y());
}
+bool LayerTreeHostImpl::AutoScrollAnimationCreate(ScrollNode* scroll_node,
+ const gfx::Vector2dF& delta,
+ float autoscroll_velocity) {
+ return ScrollAnimationCreateInternal(scroll_node, delta, base::TimeDelta(),
+ autoscroll_velocity);
+}
+
bool LayerTreeHostImpl::ScrollAnimationCreate(ScrollNode* scroll_node,
const gfx::Vector2dF& delta,
base::TimeDelta delayed_by) {
+ return ScrollAnimationCreateInternal(scroll_node, delta, delayed_by,
+ base::nullopt);
+}
+
+bool LayerTreeHostImpl::ScrollAnimationCreateInternal(
+ ScrollNode* scroll_node,
+ const gfx::Vector2dF& delta,
+ base::TimeDelta delayed_by,
+ base::Optional<float> autoscroll_velocity) {
ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree;
const float kEpsilon = 0.1f;
bool scroll_animated =
- (std::abs(delta.x()) > kEpsilon || std::abs(delta.y()) > kEpsilon);
+ (std::abs(delta.x()) > kEpsilon || std::abs(delta.y()) > kEpsilon) ||
+ autoscroll_velocity;
if (!scroll_animated) {
scroll_tree.ScrollBy(scroll_node, delta, active_tree());
TRACE_EVENT_INSTANT0("cc", "no scroll animation due to small delta",
@@ -3970,9 +4206,15 @@ bool LayerTreeHostImpl::ScrollAnimationCreate(ScrollNode* scroll_node,
// input latency tracking architecture from working.
base::TimeDelta animation_start_offset = CurrentBeginFrameArgs().interval;
- mutator_host_->ImplOnlyScrollAnimationCreate(
- scroll_node->element_id, target_offset, current_offset, delayed_by,
- animation_start_offset);
+ if (autoscroll_velocity) {
+ mutator_host_->ImplOnlyAutoScrollAnimationCreate(
+ scroll_node->element_id, gfx::ScrollOffset(delta), current_offset,
+ autoscroll_velocity.value(), animation_start_offset);
+ } else {
+ mutator_host_->ImplOnlyScrollAnimationCreate(
+ scroll_node->element_id, target_offset, current_offset, delayed_by,
+ animation_start_offset);
+ }
SetNeedsOneBeginImplFrame();
@@ -4762,6 +5004,7 @@ void LayerTreeHostImpl::ScrollEndImpl(ScrollState* scroll_state) {
DistributeScrollDelta(scroll_state);
browser_controls_offset_manager_->ScrollEnd();
ClearCurrentlyScrollingNode();
+ frame_trackers_.ScheduleRemoval(std::move(scroll_frame_tracker_));
}
void LayerTreeHostImpl::ScrollEnd(ScrollState* scroll_state, bool should_snap) {
@@ -4843,8 +5086,8 @@ InputHandlerPointerResult LayerTreeHostImpl::MouseMoveAt(
bool scroll_on_main_thread = false;
uint32_t main_thread_scrolling_reasons;
auto* scroll_node = FindScrollNodeForDeviceViewportPoint(
- device_viewport_point, InputHandler::TOUCHSCREEN, layer_impl,
- &scroll_on_main_thread, &main_thread_scrolling_reasons);
+ device_viewport_point, layer_impl, &scroll_on_main_thread,
+ &main_thread_scrolling_reasons);
if (scroll_node)
scroll_element_id = scroll_node->element_id;
@@ -4895,6 +5138,8 @@ void LayerTreeHostImpl::PinchGestureBegin() {
OuterViewportScrollNode() ? false : true);
active_tree_->SetCurrentlyScrollingNode(OuterViewportScrollNode());
browser_controls_offset_manager_->PinchBegin();
+ pinch_frame_tracker_ =
+ frame_trackers_.CreateTracker(FrameSequenceTrackerType::kPinchZoom);
}
void LayerTreeHostImpl::PinchGestureUpdate(float magnify_delta,
@@ -4902,6 +5147,7 @@ void LayerTreeHostImpl::PinchGestureUpdate(float magnify_delta,
TRACE_EVENT0("cc", "LayerTreeHostImpl::PinchGestureUpdate");
if (!InnerViewportScrollNode())
return;
+ has_pinch_zoomed_ = true;
viewport()->PinchUpdate(magnify_delta, anchor);
client_->SetNeedsCommitOnImplThread();
SetNeedsRedraw();
@@ -4926,6 +5172,7 @@ void LayerTreeHostImpl::PinchGestureEnd(const gfx::Point& anchor,
// scales that we want when we're not inside a pinch.
active_tree_->set_needs_update_draw_properties();
SetNeedsRedraw();
+ frame_trackers_.ScheduleRemoval(std::move(pinch_frame_tracker_));
}
void LayerTreeHostImpl::CollectScrollDeltas(
@@ -4971,10 +5218,23 @@ std::unique_ptr<ScrollAndScaleSet> LayerTreeHostImpl::ProcessScrollDeltas() {
scroll_info->swap_promises.swap(swap_promises_for_main_thread_scroll_update_);
// Record and reset scroll source flags.
- scroll_info->has_scrolled_by_wheel = has_scrolled_by_wheel_;
- scroll_info->has_scrolled_by_touch = has_scrolled_by_touch_;
+ if (has_scrolled_by_wheel_) {
+ scroll_info->manipulation_info |= kManipulationInfoHasScrolledByWheel;
+ }
+ if (has_scrolled_by_touch_) {
+ scroll_info->manipulation_info |= kManipulationInfoHasScrolledByTouch;
+ }
+ if (has_scrolled_by_precisiontouchpad_) {
+ scroll_info->manipulation_info |=
+ kManipulationInfoHasScrolledByPrecisionTouchPad;
+ }
+ if (has_pinch_zoomed_) {
+ scroll_info->manipulation_info |= kManipulationInfoHasPinchZoomed;
+ }
+
+ has_scrolled_by_wheel_ = has_scrolled_by_touch_ =
+ has_scrolled_by_precisiontouchpad_ = has_pinch_zoomed_ = false;
scroll_info->scroll_gesture_did_end = scroll_gesture_did_end_;
- has_scrolled_by_wheel_ = has_scrolled_by_touch_ = false;
// Record and reset overscroll delta.
scroll_info->overscroll_delta = overscroll_delta_for_main_thread_;
@@ -5091,8 +5351,17 @@ bool LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time,
// TODO(crbug.com/551138): We currently have a single signal from the
// animation_host, so on the last frame of an animation we will
// still request an extra SetNeedsAnimate here.
- if (animated)
+ if (animated) {
SetNeedsOneBeginImplFrame();
+ if (!compositor_animation_frame_tracker_) {
+ compositor_animation_frame_tracker_ = frame_trackers_.CreateTracker(
+ FrameSequenceTrackerType::kCompositorAnimation);
+ }
+ } else {
+ frame_trackers_.ScheduleRemoval(
+ std::move(compositor_animation_frame_tracker_));
+ }
+
// TODO(crbug.com/551138): We could return true only if the animaitons are on
// the active tree. There's no need to cause a draw to take place from
// animations starting/ticking on the pending tree.
@@ -5371,7 +5640,7 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
GLenum texture_target = GL_TEXTURE_2D;
// For software compositing, shared memory will be allocated and the
// UIResource will be copied into it.
- base::MappedReadOnlyRegion mapped_region;
+ base::MappedReadOnlyRegion shm;
viz::SharedBitmapId shared_bitmap_id;
bool overlay_candidate = false;
@@ -5389,8 +5658,7 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
BufferFormat(format), caps);
}
} else {
- mapped_region =
- viz::bitmap_allocation::AllocateSharedBitmap(upload_size, format);
+ shm = viz::bitmap_allocation::AllocateSharedBitmap(upload_size, format);
shared_bitmap_id = viz::SharedBitmap::GenerateId();
}
@@ -5415,7 +5683,7 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
SkImageInfo::MakeN32Premul(gfx::SizeToSkISize(upload_size));
sk_sp<SkSurface> surface = SkSurface::MakeRasterDirect(
- dst_info, mapped_region.mapping.memory(), dst_info.minRowBytes());
+ dst_info, shm.mapping.memory(), dst_info.minRowBytes());
surface->getCanvas()->writePixels(
src_info, const_cast<uint8_t*>(bitmap.GetPixels()),
src_info.minRowBytes(), 0, 0);
@@ -5451,7 +5719,7 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
SkImageInfo dst_info =
SkImageInfo::MakeN32Premul(gfx::SizeToSkISize(upload_size));
scaled_surface = SkSurface::MakeRasterDirect(
- dst_info, mapped_region.mapping.memory(), dst_info.minRowBytes());
+ dst_info, shm.mapping.memory(), dst_info.minRowBytes());
}
SkCanvas* scaled_canvas = scaled_surface->getCanvas();
scaled_canvas->scale(canvas_scale_x, canvas_scale_y);
@@ -5494,9 +5762,8 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
overlay_candidate);
transferable.format = format;
} else {
- layer_tree_frame_sink_->DidAllocateSharedBitmap(
- viz::bitmap_allocation::ToMojoHandle(std::move(mapped_region.region)),
- shared_bitmap_id);
+ layer_tree_frame_sink_->DidAllocateSharedBitmap(std::move(shm.region),
+ shared_bitmap_id);
transferable = viz::TransferableResource::MakeSoftware(shared_bitmap_id,
upload_size, format);
}
@@ -5514,7 +5781,7 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
data.opaque = bitmap.GetOpaque();
data.format = format;
data.shared_bitmap_id = shared_bitmap_id;
- data.shared_mapping = std::move(mapped_region.mapping);
+ data.shared_mapping = std::move(shm.mapping);
data.mailbox = mailbox;
data.resource_id_for_export = id;
ui_resource_map_[uid] = std::move(data);
@@ -5916,11 +6183,18 @@ void LayerTreeHostImpl::SetContextVisibility(bool is_visible) {
}
void LayerTreeHostImpl::UpdateScrollSourceInfo(
- InputHandler::ScrollInputType type) {
- if (type == InputHandler::WHEEL)
+ InputHandler::ScrollInputType type,
+ ScrollState* scroll_state) {
+ if (type == InputHandler::WHEEL &&
+ scroll_state->delta_granularity() ==
+ static_cast<double>(
+ ui::input_types::ScrollGranularity::kScrollByPrecisePixel)) {
+ has_scrolled_by_precisiontouchpad_ = true;
+ } else if (type == InputHandler::WHEEL) {
has_scrolled_by_wheel_ = true;
- else if (type == InputHandler::TOUCHSCREEN)
+ } else if (type == InputHandler::TOUCHSCREEN) {
has_scrolled_by_touch_ = true;
+ }
}
void LayerTreeHostImpl::ShowScrollbarsForImplScroll(ElementId element_id) {
diff --git a/chromium/cc/trees/layer_tree_host_impl.h b/chromium/cc/trees/layer_tree_host_impl.h
index bb89bc998a4..ca403dbfd97 100644
--- a/chromium/cc/trees/layer_tree_host_impl.h
+++ b/chromium/cc/trees/layer_tree_host_impl.h
@@ -27,14 +27,17 @@
#include "cc/input/scrollbar_animation_controller.h"
#include "cc/input/scrollbar_controller.h"
#include "cc/layers/layer_collections.h"
+#include "cc/paint/paint_worklet_job.h"
#include "cc/resources/ui_resource_client.h"
#include "cc/scheduler/begin_frame_tracker.h"
#include "cc/scheduler/commit_earlyout_reason.h"
#include "cc/scheduler/draw_result.h"
+#include "cc/scheduler/scheduler.h"
#include "cc/scheduler/video_frame_controller.h"
#include "cc/tiles/decoded_image_tracker.h"
#include "cc/tiles/image_decode_cache.h"
#include "cc/tiles/tile_manager.h"
+#include "cc/trees/frame_sequence_tracker.h"
#include "cc/trees/layer_tree_frame_sink_client.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/layer_tree_mutator.h"
@@ -156,10 +159,16 @@ class LayerTreeHostImplClient {
std::vector<LayerTreeHost::PresentationTimeCallback> callbacks,
const gfx::PresentationFeedback& feedback) = 0;
+ // Returns whether the main-thread is expected to receive a BeginMainFrame.
+ virtual bool IsBeginMainFrameExpected() = 0;
+
virtual void NotifyAnimationWorkletStateChange(
AnimationWorkletMutationState state,
ElementListType tree_type) = 0;
+ virtual void NotifyPaintWorkletStateChange(
+ Scheduler::PaintWorkletState state) = 0;
+
protected:
virtual ~LayerTreeHostImplClient() {}
};
@@ -187,6 +196,9 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
FrameData& operator=(const FrameData&) = delete;
void AsValueInto(base::trace_event::TracedValue* value) const;
+ uint32_t frame_token = 0;
+ // frame_token is populated by the LayerTreeHostImpl when submitted.
+
std::vector<viz::SurfaceId> activation_dependencies;
base::Optional<uint32_t> deadline_in_frames;
bool use_default_lower_bound_deadline = false;
@@ -196,6 +208,13 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
bool has_no_damage = false;
bool may_contain_video = false;
viz::BeginFrameAck begin_frame_ack;
+ // The original BeginFrameArgs that triggered the latest update from the
+ // main thread.
+ viz::BeginFrameArgs origin_begin_main_frame_args;
+
+ // Union of visible rects of MirrorLayers in the frame, used to force damage
+ // on the surface.
+ gfx::Rect mirror_rect;
};
// A struct of data for a single UIResource, including the backing
@@ -275,8 +294,7 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
void SetNeedsAnimateInput() override;
bool IsCurrentlyScrollingViewport() const override;
bool IsCurrentlyScrollingLayerAt(
- const gfx::Point& viewport_point,
- InputHandler::ScrollInputType type) const override;
+ const gfx::Point& viewport_point) const override;
EventListenerProperties GetEventListenerProperties(
EventListenerClass event_class) const override;
InputHandler::TouchStartOrMoveEventListenerType
@@ -320,10 +338,11 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
}
virtual void WillSendBeginMainFrame() {}
- virtual void DidSendBeginMainFrame() {}
+ virtual void DidSendBeginMainFrame(const viz::BeginFrameArgs& args);
virtual void BeginMainFrameAborted(
CommitEarlyOutReason reason,
- std::vector<std::unique_ptr<SwapPromise>> swap_promises);
+ std::vector<std::unique_ptr<SwapPromise>> swap_promises,
+ const viz::BeginFrameArgs& args);
virtual void ReadyToCommit() {} // For tests.
virtual void BeginCommit();
virtual void CommitComplete();
@@ -432,6 +451,8 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
DrawMode GetDrawMode() const;
+ void DidNotNeedBeginFrame();
+
// TileManagerClient implementation.
void NotifyReadyToActivate() override;
void NotifyReadyToDraw() override;
@@ -471,7 +492,6 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
void DidPresentCompositorFrame(
uint32_t frame_token,
const gfx::PresentationFeedback& feedback) override;
- void DidNotNeedBeginFrame() override;
void ReclaimResources(
const std::vector<viz::ReturnedResource>& resources) override;
void SetMemoryPolicy(const ManagedMemoryPolicy& policy) override;
@@ -506,6 +526,7 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
int* max_msaa_samples,
bool* supports_disable_msaa);
bool use_gpu_rasterization() const { return use_gpu_rasterization_; }
+ bool use_oop_rasterization() const { return use_oop_rasterization_; }
bool use_msaa() const { return use_msaa_; }
GpuRasterizationStatus gpu_rasterization_status() const {
@@ -710,19 +731,30 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
}
InputHandler::ScrollStatus TryScroll(const gfx::PointF& screen_space_point,
- InputHandler::ScrollInputType type,
const ScrollTree& scroll_tree,
ScrollNode* scroll_node) const;
+ // Return all ScrollNode indices that have an associated layer with a non-fast
+ // region that intersects the point.
+ base::flat_set<int> NonFastScrollableNodes(
+ const gfx::PointF& device_viewport_point) const;
+
// Returns true if a scroll offset animation is created and false if we scroll
// by the desired amount without an animation.
bool ScrollAnimationCreate(ScrollNode* scroll_node,
const gfx::Vector2dF& scroll_amount,
base::TimeDelta delayed_by);
+ bool AutoScrollAnimationCreate(ScrollNode* scroll_node,
+ const gfx::Vector2dF& scroll_amount,
+ float autoscroll_velocity);
void SetLayerTreeMutator(std::unique_ptr<LayerTreeMutator> mutator);
+
void SetPaintWorkletLayerPainter(
std::unique_ptr<PaintWorkletLayerPainter> painter);
+ PaintWorkletLayerPainter* GetPaintWorkletLayerPainterForTesting() const {
+ return paint_worklet_painter_.get();
+ }
// The viewport has two scroll nodes, corresponding to the visual and layout
// viewports. However, when we compute the scroll chain we include only one
@@ -759,6 +791,10 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
return compositor_frame_reporting_controller_.get();
}
+ void set_pending_tree_fully_painted_for_testing(bool painted) {
+ pending_tree_fully_painted_ = painted;
+ }
+
protected:
LayerTreeHostImpl(
const LayerTreeSettings& settings,
@@ -810,6 +846,10 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
const gfx::PointF& viewport_point,
const gfx::Vector2dF& viewport_delta,
ScrollTree* scroll_tree);
+ bool ScrollAnimationCreateInternal(ScrollNode* scroll_node,
+ const gfx::Vector2dF& delta,
+ base::TimeDelta delayed_by,
+ base::Optional<float> autoscroll_velocity);
void CleanUpTileManagerResources();
void CreateTileManagerResources();
@@ -824,6 +864,18 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
// impl thread.
void UpdateSyncTreeAfterCommitOrImplSideInvalidation();
+ // Returns a job map for all 'dirty' PaintWorklets, e.g. PaintWorkletInputs
+ // that do not map to a PaintRecord.
+ PaintWorkletJobMap GatherDirtyPaintWorklets() const;
+
+ // Called when all PaintWorklet results are ready (i.e. have been painted) for
+ // the current pending tree.
+ void OnPaintWorkletResultsReady(PaintWorkletJobMap results);
+
+ // Called when the pending tree has been fully painted, i.e. all required data
+ // is available to raster the tree.
+ void NotifyPendingTreeFullyPainted();
+
// Returns true if status changed.
bool UpdateGpuRasterizationStatus();
void UpdateTreeResourcesForGpuRasterizationIfNeeded();
@@ -862,7 +914,6 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
ScrollNode* FindScrollNodeForDeviceViewportPoint(
const gfx::PointF& device_viewport_point,
- InputHandler::ScrollInputType type,
LayerImpl* layer_hit_by_point,
bool* scroll_on_main_thread,
uint32_t* main_thread_scrolling_reason) const;
@@ -910,7 +961,8 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
// thread side to keep track of the frequency of scrolling with different
// sources per page load. TODO(crbug.com/691886): Use GRC API to plumb the
// scroll source info for Use Counters.
- void UpdateScrollSourceInfo(InputHandler::ScrollInputType type);
+ void UpdateScrollSourceInfo(InputHandler::ScrollInputType type,
+ ScrollState* scroll_state);
bool IsScrolledBy(LayerImpl* child, ScrollNode* ancestor);
void ShowScrollbarsForImplScroll(ElementId element_id);
@@ -931,6 +983,13 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
void AllocateLocalSurfaceId();
const LayerTreeSettings settings_;
+
+ // This is set to true only if:
+ // . The compositor is running single-threaded (i.e. there is no separate
+ // compositor/impl thread).
+ // . There is no scheduler (which means layer-update, composite, etc. steps
+ // happen explicitly via. synchronous calls to appropriate functions).
+ // This is usually turned on only in some tests (e.g. web-tests).
const bool is_synchronous_single_threaded_;
const int default_color_space_id_ = gfx::ColorSpace::GetNextId();
@@ -1138,13 +1197,21 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
// success) state.
std::vector<std::pair<int, bool>> completed_image_decode_requests_;
- // These are used to transfer usage of touch and wheel scrolls to the main
- // thread.
+ // These are used to transfer usage of different types of scrolling to the
+ // main thread.
bool has_scrolled_by_wheel_ = false;
bool has_scrolled_by_touch_ = false;
+ bool has_scrolled_by_precisiontouchpad_ = false;
+ bool has_pinch_zoomed_ = false;
ImplThreadPhase impl_thread_phase_ = ImplThreadPhase::IDLE;
+ // Tracks whether a BeginMainFrame is expected to be dispatched during an
+ // 'impl frame' (i.e. between WillBeginImplFrame() and DidFinishImplFrame()),
+ // and whether it was actually dispatched during the impl frame.
+ bool begin_main_frame_expected_during_impl_ = false;
+ bool begin_main_frame_sent_during_impl_ = false;
+
ImageAnimationController image_animation_controller_;
std::unique_ptr<UkmManager> ukm_manager_;
@@ -1172,6 +1239,13 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
// Manages composited scrollbar hit testing.
std::unique_ptr<ScrollbarController> scrollbar_controller_;
+ FrameSequenceTrackerCollection frame_trackers_;
+ std::unique_ptr<FrameSequenceTracker> pinch_frame_tracker_;
+ std::unique_ptr<FrameSequenceTracker> scroll_frame_tracker_;
+ std::unique_ptr<FrameSequenceTracker> compositor_animation_frame_tracker_;
+ std::unique_ptr<FrameSequenceTracker> request_animation_frame_tracker_;
+ std::unique_ptr<FrameSequenceTracker> main_thread_animation_frame_tracker_;
+
// Set to true when a scroll gesture being handled on the compositor has
// ended. i.e. When a GSE has arrived and any ongoing scroll animation has
// ended.
@@ -1187,9 +1261,18 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
// once the animation is over.
base::Optional<ScrollState> deferred_scroll_end_state_;
+ // PaintWorklet painting is controlled from the LayerTreeHostImpl, dispatched
+ // to the worklet thread via |paint_worklet_painter_|.
+ std::unique_ptr<PaintWorkletLayerPainter> paint_worklet_painter_;
+
+ // While PaintWorklet painting is ongoing the PendingTree is not yet fully
+ // painted and cannot be rastered or activated. This boolean tracks whether or
+ // not we are in that state.
+ bool pending_tree_fully_painted_ = false;
+
// Must be the last member to ensure this is destroyed first in the
// destruction order and invalidates all weak pointers.
- base::WeakPtrFactory<LayerTreeHostImpl> weak_factory_;
+ base::WeakPtrFactory<LayerTreeHostImpl> weak_factory_{this};
};
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_impl_unittest.cc b/chromium/cc/trees/layer_tree_host_impl_unittest.cc
index 80d1f14a001..24ceca1c40c 100644
--- a/chromium/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_impl_unittest.cc
@@ -55,6 +55,8 @@
#include "cc/test/layer_test_common.h"
#include "cc/test/layer_tree_test.h"
#include "cc/test/skia_common.h"
+#include "cc/test/test_layer_tree_frame_sink.h"
+#include "cc/test/test_paint_worklet_layer_painter.h"
#include "cc/test/test_task_graph_runner.h"
#include "cc/trees/clip_node.h"
#include "cc/trees/draw_property_utils.h"
@@ -81,7 +83,6 @@
#include "components/viz/test/begin_frame_args_test.h"
#include "components/viz/test/fake_output_surface.h"
#include "components/viz/test/fake_skia_output_surface.h"
-#include "components/viz/test/test_layer_tree_frame_sink.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "media/base/media.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -135,6 +136,7 @@ class LayerTreeHostImplTest : public testing::Test,
did_request_redraw_(false),
did_request_next_frame_(false),
did_request_prepare_tiles_(false),
+ did_prepare_tiles_(false),
did_complete_page_scale_animation_(false),
reduce_memory_result_(true),
did_request_impl_side_invalidation_(false) {
@@ -159,6 +161,13 @@ class LayerTreeHostImplTest : public testing::Test,
host_impl_->active_tree()->GetDeviceViewport().size());
pending_tree->SetDeviceScaleFactor(
host_impl_->active_tree()->device_scale_factor());
+ // Normally a pending tree will not be fully painted until the commit has
+ // happened and any PaintWorklets have been resolved. However many of the
+ // unittests never actually commit the pending trees that they create, so to
+ // enable them to still treat the tree as painted we forcibly override the
+ // state here. Note that this marks a distinct departure from reality in the
+ // name of easier testing.
+ host_impl_->set_pending_tree_fully_painted_for_testing(true);
}
void TearDown() override {
@@ -189,6 +198,7 @@ class LayerTreeHostImplTest : public testing::Test,
void PostAnimationEventsToMainThreadOnImplThread(
std::unique_ptr<MutatorEvents> events) override {}
bool IsInsideDraw() override { return false; }
+ bool IsBeginMainFrameExpected() override { return true; }
void RenewTreePriority() override {}
void PostDelayedAnimationTaskOnImplThread(base::OnceClosure task,
base::TimeDelta delay) override {
@@ -203,7 +213,7 @@ class LayerTreeHostImplTest : public testing::Test,
base::TimeTicks::Now()));
}
void WillPrepareTiles() override {}
- void DidPrepareTiles() override {}
+ void DidPrepareTiles() override { did_prepare_tiles_ = true; }
void DidCompletePageScaleAnimationOnImplThread() override {
did_complete_page_scale_animation_ = true;
}
@@ -229,6 +239,8 @@ class LayerTreeHostImplTest : public testing::Test,
const gfx::PresentationFeedback& feedback) override {}
void NotifyAnimationWorkletStateChange(AnimationWorkletMutationState state,
ElementListType tree_type) override {}
+ void NotifyPaintWorkletStateChange(
+ Scheduler::PaintWorkletState state) override {}
void set_reduce_memory_result(bool reduce_memory_result) {
reduce_memory_result_ = reduce_memory_result;
@@ -796,6 +808,7 @@ class LayerTreeHostImplTest : public testing::Test,
bool did_request_redraw_;
bool did_request_next_frame_;
bool did_request_prepare_tiles_;
+ bool did_prepare_tiles_;
bool did_complete_page_scale_animation_;
bool reduce_memory_result_;
bool did_request_impl_side_invalidation_;
@@ -852,7 +865,8 @@ class TestInputHandlerClient : public InputHandlerClient {
min_page_scale_factor_ = min_page_scale_factor;
max_page_scale_factor_ = max_page_scale_factor;
}
- void DeliverInputForBeginFrame() override {}
+ void DeliverInputForBeginFrame(const viz::BeginFrameArgs& args) override {}
+ void DeliverInputForHighLatencyMode() override {}
gfx::ScrollOffset last_set_scroll_offset() { return last_set_scroll_offset_; }
@@ -1095,14 +1109,11 @@ TEST_F(LayerTreeHostImplTest, ScrollRootCallsCommitAndRedraw) {
EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
status.main_thread_scrolling_reasons);
- EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(),
- InputHandler::WHEEL));
+ EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point()));
host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
- EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(0, 10),
- InputHandler::WHEEL));
+ EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(0, 10)));
host_impl_->ScrollEnd(EndState().get());
- EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(),
- InputHandler::WHEEL));
+ EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point()));
EXPECT_TRUE(did_request_redraw_);
EXPECT_TRUE(did_request_commit_);
}
@@ -1374,16 +1385,14 @@ TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionBasic) {
EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion,
status.main_thread_scrolling_reasons);
- EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25),
- InputHandler::WHEEL));
+ EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25)));
status = host_impl_->ScrollBegin(BeginState(gfx::Point(25, 25)).get(),
InputHandler::TOUCHSCREEN);
EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion,
status.main_thread_scrolling_reasons);
- EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(
- gfx::Point(25, 25), InputHandler::TOUCHSCREEN));
+ EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25)));
// All scroll types outside this region should succeed.
status = host_impl_->ScrollBegin(BeginState(gfx::Point(75, 75)).get(),
@@ -1392,26 +1401,21 @@ TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionBasic) {
EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
status.main_thread_scrolling_reasons);
- EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(
- gfx::Point(75, 75), InputHandler::TOUCHSCREEN));
+ EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75)));
host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
- EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(
- gfx::Point(25, 25), InputHandler::TOUCHSCREEN));
+ EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25)));
host_impl_->ScrollEnd(EndState().get());
- EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(
- gfx::Point(75, 75), InputHandler::TOUCHSCREEN));
+ EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75)));
status = host_impl_->ScrollBegin(BeginState(gfx::Point(75, 75)).get(),
InputHandler::TOUCHSCREEN);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
status.main_thread_scrolling_reasons);
- EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(
- gfx::Point(75, 75), InputHandler::TOUCHSCREEN));
+ EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75)));
host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
host_impl_->ScrollEnd(EndState().get());
- EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(
- gfx::Point(75, 75), InputHandler::TOUCHSCREEN));
+ EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75)));
}
TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionWithOffset) {
@@ -1434,8 +1438,7 @@ TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionWithOffset) {
EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
status.main_thread_scrolling_reasons);
- EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(40, 10),
- InputHandler::WHEEL));
+ EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(40, 10)));
host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 1)).get());
host_impl_->ScrollEnd(EndState().get());
@@ -10410,7 +10413,88 @@ TEST_F(LayerTreeHostImplTest,
EXPECT_FALSE(host_impl_->EvictedUIResourcesExist());
}
-class FrameSinkClient : public viz::TestLayerTreeFrameSinkClient {
+TEST_F(LayerTreeHostImplTest, ObeyMSAACaps) {
+ LayerTreeSettings msaaSettings = DefaultSettings();
+ msaaSettings.gpu_rasterization_msaa_sample_count = 4;
+
+ // gpu raster, msaa on
+ {
+ bool msaa_is_slow = false;
+ EXPECT_TRUE(CreateHostImpl(
+ msaaSettings,
+ FakeLayerTreeFrameSink::Create3dForGpuRasterization(
+ msaaSettings.gpu_rasterization_msaa_sample_count, msaa_is_slow)));
+
+ host_impl_->SetHasGpuRasterizationTrigger(true);
+ host_impl_->SetContentHasSlowPaths(true);
+ host_impl_->CommitComplete();
+
+ EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT,
+ host_impl_->gpu_rasterization_status());
+ EXPECT_TRUE(host_impl_->use_gpu_rasterization());
+ EXPECT_FALSE(host_impl_->use_oop_rasterization());
+ EXPECT_TRUE(host_impl_->use_msaa());
+ }
+
+ // gpu raster, msaa off
+ {
+ bool msaa_is_slow = true;
+ EXPECT_TRUE(CreateHostImpl(
+ msaaSettings,
+ FakeLayerTreeFrameSink::Create3dForGpuRasterization(
+ msaaSettings.gpu_rasterization_msaa_sample_count, msaa_is_slow)));
+
+ host_impl_->SetHasGpuRasterizationTrigger(true);
+ host_impl_->SetContentHasSlowPaths(true);
+ host_impl_->CommitComplete();
+
+ EXPECT_EQ(GpuRasterizationStatus::ON,
+ host_impl_->gpu_rasterization_status());
+ EXPECT_TRUE(host_impl_->use_gpu_rasterization());
+ EXPECT_FALSE(host_impl_->use_oop_rasterization());
+ EXPECT_FALSE(host_impl_->use_msaa());
+ }
+
+ // oop raster, msaa on
+ {
+ bool msaa_is_slow = false;
+ EXPECT_TRUE(CreateHostImpl(
+ msaaSettings,
+ FakeLayerTreeFrameSink::Create3dForOopRasterization(
+ msaaSettings.gpu_rasterization_msaa_sample_count, msaa_is_slow)));
+
+ host_impl_->SetHasGpuRasterizationTrigger(true);
+ host_impl_->SetContentHasSlowPaths(true);
+ host_impl_->CommitComplete();
+
+ EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT,
+ host_impl_->gpu_rasterization_status());
+ EXPECT_TRUE(host_impl_->use_gpu_rasterization());
+ EXPECT_TRUE(host_impl_->use_oop_rasterization());
+ EXPECT_TRUE(host_impl_->use_msaa());
+ }
+
+ // oop raster, msaa off
+ {
+ bool msaa_is_slow = true;
+ EXPECT_TRUE(CreateHostImpl(
+ msaaSettings,
+ FakeLayerTreeFrameSink::Create3dForOopRasterization(
+ msaaSettings.gpu_rasterization_msaa_sample_count, msaa_is_slow)));
+
+ host_impl_->SetHasGpuRasterizationTrigger(true);
+ host_impl_->SetContentHasSlowPaths(true);
+ host_impl_->CommitComplete();
+
+ EXPECT_EQ(GpuRasterizationStatus::ON,
+ host_impl_->gpu_rasterization_status());
+ EXPECT_TRUE(host_impl_->use_gpu_rasterization());
+ EXPECT_TRUE(host_impl_->use_oop_rasterization());
+ EXPECT_FALSE(host_impl_->use_msaa());
+ }
+}
+
+class FrameSinkClient : public TestLayerTreeFrameSinkClient {
public:
explicit FrameSinkClient(
scoped_refptr<viz::ContextProvider> display_context_provider)
@@ -10464,7 +10548,7 @@ TEST_P(LayerTreeHostImplTestWithRenderer, ShutdownReleasesContext) {
constexpr double refresh_rate = 60.0;
viz::RendererSettings renderer_settings = viz::RendererSettings();
renderer_settings.use_skia_renderer = renderer_type() == RENDERER_SKIA;
- auto layer_tree_frame_sink = std::make_unique<viz::TestLayerTreeFrameSink>(
+ auto layer_tree_frame_sink = std::make_unique<TestLayerTreeFrameSink>(
context_provider, viz::TestContextProvider::CreateWorker(), nullptr,
renderer_settings, base::ThreadTaskRunnerHandle::Get().get(),
synchronous_composite, disable_display_vsync, refresh_rate);
@@ -11611,16 +11695,14 @@ TEST_F(LayerTreeHostImplVirtualViewportTest,
->ScrollBegin(BeginState(gfx::Point()).get(),
InputHandler::TOUCHSCREEN)
.thread);
- EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(
- gfx::Point(), InputHandler::TOUCHSCREEN));
+ EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point()));
// Scroll near the edge of the outer viewport.
gfx::Vector2d scroll_delta(inner_viewport.width() / 2.f,
inner_viewport.height() / 2.f);
host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
inner_expected += scroll_delta;
- EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(
- gfx::Point(), InputHandler::TOUCHSCREEN));
+ EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point()));
EXPECT_VECTOR_EQ(inner_expected, inner_scroll->CurrentScrollOffset());
EXPECT_VECTOR_EQ(outer_expected, outer_scroll->CurrentScrollOffset());
@@ -11630,13 +11712,11 @@ TEST_F(LayerTreeHostImplVirtualViewportTest,
// and outer viewport layers is perfect.
host_impl_->ScrollBy(
UpdateState(gfx::Point(), gfx::ScaleVector2d(scroll_delta, 2)).get());
- EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(
- gfx::Point(), InputHandler::TOUCHSCREEN));
+ EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point()));
outer_expected += scroll_delta;
inner_expected += scroll_delta;
host_impl_->ScrollEnd(EndState().get());
- EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(
- gfx::Point(), InputHandler::TOUCHSCREEN));
+ EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point()));
EXPECT_VECTOR_EQ(inner_expected, inner_scroll->CurrentScrollOffset());
EXPECT_VECTOR_EQ(outer_expected, outer_scroll->CurrentScrollOffset());
@@ -12452,16 +12532,13 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedAborted) {
host_impl_
->ScrollBegin(BeginState(gfx::Point(0, y)).get(), InputHandler::WHEEL)
.thread);
- EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(0, y),
- InputHandler::WHEEL));
+ EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(0, y)));
host_impl_->ScrollBy(
UpdateState(gfx::Point(0, y), gfx::Vector2d(0, 50)).get());
- EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(0, y + 50),
- InputHandler::WHEEL));
+ EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(0, y + 50)));
std::unique_ptr<ScrollState> scroll_state_end = EndState();
host_impl_->ScrollEnd(scroll_state_end.get());
- EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(),
- InputHandler::WHEEL));
+ EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point()));
// The instant scroll should have marked the smooth scroll animation as
// aborted.
@@ -12851,7 +12928,7 @@ TEST_F(LayerTreeHostImplTest, InvalidLayerNotAddedToRasterQueue) {
layer->SetDrawsContent(true);
layer->tilings()->AddTiling(gfx::AxisTransform2d(), raster_source_with_tiles);
layer->UpdateRasterSource(raster_source_with_tiles, &empty_invalidation,
- nullptr);
+ nullptr, nullptr);
layer->tilings()->tiling_at(0)->set_resolution(
TileResolution::HIGH_RESOLUTION);
layer->tilings()->tiling_at(0)->CreateAllTilesForTesting();
@@ -13447,9 +13524,7 @@ TEST_F(LayerTreeHostImplTest, UpdatePageScaleFactorOnActiveTree) {
CreateScrollAndContentsLayers(host_impl_->pending_tree(),
gfx::Size(100, 100));
host_impl_->pending_tree()->BuildPropertyTreesForTesting();
- LOG(ERROR) << "ACTIVATE SYNC TREE";
host_impl_->ActivateSyncTree();
- LOG(ERROR) << "DONE ACTIVATE SYNC TREE";
DrawFrame();
CreatePendingTree();
@@ -13475,9 +13550,7 @@ TEST_F(LayerTreeHostImplTest, UpdatePageScaleFactorOnActiveTree) {
page_scale_layer->transform_tree_index());
EXPECT_EQ(pending_tree_node->post_local_scale_factor, 2.f);
- LOG(ERROR) << "2 ACTIVATE SYNC TREE";
host_impl_->ActivateSyncTree();
- LOG(ERROR) << "DONE 2 ACTIVATE SYNC TREE";
host_impl_->active_tree()->UpdateDrawProperties();
active_tree_node =
host_impl_->active_tree()->property_trees()->transform_tree.Node(
@@ -14839,5 +14912,194 @@ TEST_F(LayerTreeHostImplTest, TouchScrollOnAndroidScrollbar) {
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
}
+TEST_F(CommitToPendingTreeLayerTreeHostImplTest,
+ CommitWithNoPaintWorkletLayerPainter) {
+ ASSERT_FALSE(host_impl_->GetPaintWorkletLayerPainterForTesting());
+ host_impl_->CreatePendingTree();
+
+ // When there is no PaintWorkletLayerPainter registered, commits should finish
+ // immediately and move onto preparing tiles.
+ ASSERT_FALSE(did_prepare_tiles_);
+ host_impl_->CommitComplete();
+ EXPECT_TRUE(did_prepare_tiles_);
+}
+
+TEST_F(CommitToPendingTreeLayerTreeHostImplTest, CommitWithNoPaintWorklets) {
+ host_impl_->SetPaintWorkletLayerPainter(
+ std::make_unique<TestPaintWorkletLayerPainter>());
+ host_impl_->CreatePendingTree();
+
+ // When there are no PaintWorklets in the committed display lists, commits
+ // should finish immediately and move onto preparing tiles.
+ ASSERT_FALSE(did_prepare_tiles_);
+ host_impl_->CommitComplete();
+ EXPECT_TRUE(did_prepare_tiles_);
+}
+
+TEST_F(CommitToPendingTreeLayerTreeHostImplTest, CommitWithDirtyPaintWorklets) {
+ auto painter_owned = std::make_unique<TestPaintWorkletLayerPainter>();
+ TestPaintWorkletLayerPainter* painter = painter_owned.get();
+ host_impl_->SetPaintWorkletLayerPainter(std::move(painter_owned));
+
+ // Setup the pending tree with a PictureLayerImpl that will contain
+ // PaintWorklets.
+ host_impl_->CreatePendingTree();
+ std::unique_ptr<PictureLayerImpl> root_owned = PictureLayerImpl::Create(
+ host_impl_->pending_tree(), 1, Layer::LayerMaskType::NOT_MASK);
+ PictureLayerImpl* root = root_owned.get();
+ host_impl_->pending_tree()->SetRootLayerForTesting(std::move(root_owned));
+
+ root->SetBounds(gfx::Size(100, 100));
+ root->test_properties()->force_render_surface = true;
+ root->SetNeedsPushProperties();
+
+ // Add a PaintWorkletInput to the PictureLayerImpl.
+ scoped_refptr<RasterSource> raster_source_with_pws(
+ FakeRasterSource::CreateFilledWithPaintWorklet(root->bounds()));
+ Region empty_invalidation;
+ root->UpdateRasterSource(raster_source_with_pws, &empty_invalidation, nullptr,
+ nullptr);
+
+ host_impl_->pending_tree()->SetElementIdsForTesting();
+ host_impl_->pending_tree()->BuildPropertyTreesForTesting();
+
+ // Since we have dirty PaintWorklets, committing will not cause tile
+ // preparation to happen. Instead, it will be delayed until the callback
+ // passed to the PaintWorkletLayerPainter is called.
+ did_prepare_tiles_ = false;
+ host_impl_->CommitComplete();
+ EXPECT_FALSE(did_prepare_tiles_);
+
+ // Set up a result to have been 'painted'.
+ ASSERT_EQ(root->GetPaintWorkletRecordMap().size(), 1u);
+ scoped_refptr<PaintWorkletInput> input =
+ root->GetPaintWorkletRecordMap().begin()->first;
+ int worklet_id = input->WorkletId();
+
+ PaintWorkletJob painted_job(worklet_id, input);
+ sk_sp<PaintRecord> record = sk_make_sp<PaintRecord>();
+ painted_job.SetOutput(record);
+
+ auto painted_job_vector = base::MakeRefCounted<PaintWorkletJobVector>();
+ painted_job_vector->data.push_back(std::move(painted_job));
+ PaintWorkletJobMap painted_job_map;
+ painted_job_map[worklet_id] = std::move(painted_job_vector);
+
+ // Finally, 'paint' the content. This should unlock tile preparation and
+ // update the PictureLayerImpl's map.
+ std::move(painter->TakeDoneCallback()).Run(std::move(painted_job_map));
+ EXPECT_EQ(root->GetPaintWorkletRecordMap().find(input)->second, record);
+ EXPECT_TRUE(did_prepare_tiles_);
+}
+
+TEST_F(CommitToPendingTreeLayerTreeHostImplTest,
+ CommitWithNoDirtyPaintWorklets) {
+ host_impl_->SetPaintWorkletLayerPainter(
+ std::make_unique<TestPaintWorkletLayerPainter>());
+
+ host_impl_->CreatePendingTree();
+ std::unique_ptr<PictureLayerImpl> root_owned = PictureLayerImpl::Create(
+ host_impl_->pending_tree(), 1, Layer::LayerMaskType::NOT_MASK);
+ PictureLayerImpl* root = root_owned.get();
+ host_impl_->pending_tree()->SetRootLayerForTesting(std::move(root_owned));
+
+ root->SetBounds(gfx::Size(100, 100));
+ root->test_properties()->force_render_surface = true;
+ root->SetNeedsPushProperties();
+
+ // Add some PaintWorklets.
+ scoped_refptr<RasterSource> raster_source_with_pws(
+ FakeRasterSource::CreateFilledWithPaintWorklet(root->bounds()));
+ Region empty_invalidation;
+ root->UpdateRasterSource(raster_source_with_pws, &empty_invalidation, nullptr,
+ nullptr);
+
+ host_impl_->pending_tree()->SetElementIdsForTesting();
+ host_impl_->pending_tree()->BuildPropertyTreesForTesting();
+
+ // Pretend that our worklets were already painted.
+ ASSERT_EQ(root->GetPaintWorkletRecordMap().size(), 1u);
+ root->SetPaintWorkletRecord(root->GetPaintWorkletRecordMap().begin()->first,
+ sk_make_sp<PaintRecord>());
+
+ // Since there are no dirty PaintWorklets, the commit should immediately
+ // prepare tiles.
+ ASSERT_FALSE(did_prepare_tiles_);
+ host_impl_->CommitComplete();
+ EXPECT_TRUE(did_prepare_tiles_);
+}
+
+class ForceActivateAfterPaintWorkletPaintLayerTreeHostImplTest
+ : public CommitToPendingTreeLayerTreeHostImplTest {
+ public:
+ void NotifyPaintWorkletStateChange(
+ Scheduler::PaintWorkletState state) override {
+ if (state == Scheduler::PaintWorkletState::IDLE) {
+ // Pretend a force activation happened.
+ host_impl_->ActivateSyncTree();
+ ASSERT_FALSE(host_impl_->pending_tree());
+ }
+ }
+};
+
+TEST_F(ForceActivateAfterPaintWorkletPaintLayerTreeHostImplTest,
+ ForceActivationAfterPaintWorkletsFinishPainting) {
+ auto painter_owned = std::make_unique<TestPaintWorkletLayerPainter>();
+ TestPaintWorkletLayerPainter* painter = painter_owned.get();
+ host_impl_->SetPaintWorkletLayerPainter(std::move(painter_owned));
+
+ // Setup the pending tree with a PictureLayerImpl that will contain
+ // PaintWorklets.
+ host_impl_->CreatePendingTree();
+ std::unique_ptr<PictureLayerImpl> root_owned = PictureLayerImpl::Create(
+ host_impl_->pending_tree(), 1, Layer::LayerMaskType::NOT_MASK);
+ PictureLayerImpl* root = root_owned.get();
+ host_impl_->pending_tree()->SetRootLayerForTesting(std::move(root_owned));
+
+ root->SetBounds(gfx::Size(100, 100));
+ root->test_properties()->force_render_surface = true;
+ root->SetNeedsPushProperties();
+
+ // Add a PaintWorkletInput to the PictureLayerImpl.
+ scoped_refptr<RasterSource> raster_source_with_pws(
+ FakeRasterSource::CreateFilledWithPaintWorklet(root->bounds()));
+ Region empty_invalidation;
+ root->UpdateRasterSource(raster_source_with_pws, &empty_invalidation, nullptr,
+ nullptr);
+
+ host_impl_->pending_tree()->SetElementIdsForTesting();
+ host_impl_->pending_tree()->BuildPropertyTreesForTesting();
+
+ // Since we have dirty PaintWorklets, committing will not cause tile
+ // preparation to happen. Instead, it will be delayed until the callback
+ // passed to the PaintWorkletLayerPainter is called.
+ did_prepare_tiles_ = false;
+ host_impl_->CommitComplete();
+ EXPECT_FALSE(did_prepare_tiles_);
+
+ // Set up a result to have been 'painted'.
+ ASSERT_EQ(root->GetPaintWorkletRecordMap().size(), 1u);
+ scoped_refptr<PaintWorkletInput> input =
+ root->GetPaintWorkletRecordMap().begin()->first;
+ int worklet_id = input->WorkletId();
+
+ PaintWorkletJob painted_job(worklet_id, input);
+ sk_sp<PaintRecord> record = sk_make_sp<PaintRecord>();
+ painted_job.SetOutput(record);
+
+ auto painted_job_vector = base::MakeRefCounted<PaintWorkletJobVector>();
+ painted_job_vector->data.push_back(std::move(painted_job));
+ PaintWorkletJobMap painted_job_map;
+ painted_job_map[worklet_id] = std::move(painted_job_vector);
+
+ // Finally, 'paint' the content. The test class causes a forced activation
+ // during NotifyPaintWorkletStateChange. The PictureLayerImpl should still be
+ // updated, but since the tree was force activated there should be no tile
+ // preparation.
+ std::move(painter->TakeDoneCallback()).Run(std::move(painted_job_map));
+ EXPECT_EQ(root->GetPaintWorkletRecordMap().find(input)->second, record);
+ EXPECT_FALSE(did_prepare_tiles_);
+}
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_perftest.cc b/chromium/cc/trees/layer_tree_host_perftest.cc
index 92fd3570952..c6036f13f59 100644
--- a/chromium/cc/trees/layer_tree_host_perftest.cc
+++ b/chromium/cc/trees/layer_tree_host_perftest.cc
@@ -21,10 +21,10 @@
#include "cc/test/fake_content_layer_client.h"
#include "cc/test/layer_tree_json_parser.h"
#include "cc/test/layer_tree_test.h"
+#include "cc/test/test_layer_tree_frame_sink.h"
#include "cc/trees/layer_tree_impl.h"
#include "components/viz/common/resources/single_release_callback.h"
#include "components/viz/test/paths.h"
-#include "components/viz/test/test_layer_tree_frame_sink.h"
#include "gpu/command_buffer/common/mailbox.h"
#include "gpu/command_buffer/common/sync_token.h"
#include "testing/perf/perf_test.h"
@@ -48,7 +48,7 @@ class LayerTreeHostPerfTest : public LayerTreeTest {
measure_commit_cost_(false) {
}
- std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
+ std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
const viz::RendererSettings& renderer_settings,
double refresh_rate,
scoped_refptr<viz::ContextProvider> compositor_context_provider,
@@ -58,7 +58,7 @@ class LayerTreeHostPerfTest : public LayerTreeTest {
bool synchronous_composite =
!HasImplThread() &&
!layer_tree_host()->GetSettings().single_thread_proxy_scheduler;
- return std::make_unique<viz::TestLayerTreeFrameSink>(
+ return std::make_unique<TestLayerTreeFrameSink>(
compositor_context_provider, std::move(worker_context_provider),
gpu_memory_buffer_manager(), renderer_settings, ImplThreadTaskRunner(),
synchronous_composite, disable_display_vsync, refresh_rate);
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc
index 3f0c28b4311..7d5ea2a2d08 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc
@@ -14,7 +14,7 @@
#include "cc/paint/skia_paint_canvas.h"
#include "cc/test/layer_tree_pixel_resource_test.h"
#include "cc/test/pixel_comparator.h"
-#include "components/viz/test/test_layer_tree_frame_sink.h"
+#include "cc/test/test_layer_tree_frame_sink.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkSurface.h"
@@ -71,7 +71,7 @@ class LayerTreeHostBlendingPixelTest
public:
LayerTreeHostBlendingPixelTest()
: force_antialiasing_(false), force_blending_with_shaders_(false) {
- pixel_comparator_.reset(new FuzzyPixelOffByOneComparator(true));
+ pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(true);
}
PixelResourceTestCase resource_type() const {
@@ -82,7 +82,7 @@ class LayerTreeHostBlendingPixelTest
}
protected:
- std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
+ std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
const viz::RendererSettings& renderer_settings,
double refresh_rate,
scoped_refptr<viz::ContextProvider> compositor_context_provider,
@@ -132,7 +132,7 @@ class LayerTreeHostBlendingPixelTest
gfx::Size bounds = layer->bounds();
scoped_refptr<PictureImageLayer> mask = PictureImageLayer::Create();
mask->SetIsDrawable(true);
- mask->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK);
+ mask->SetLayerMaskType(Layer::LayerMaskType::SINGLE_TEXTURE_MASK);
mask->SetBounds(bounds);
sk_sp<SkSurface> surface =
@@ -213,10 +213,10 @@ class LayerTreeHostBlendingPixelTest
InitializeFromTestCase(resource_type());
// Force shaders only applies to gl renderer.
- if (renderer_type_ != RENDERER_GL && flags & kForceShaders)
+ if (renderer_type() != RENDERER_GL && flags & kForceShaders)
return;
- SCOPED_TRACE(TestTypeToString(renderer_type_));
+ SCOPED_TRACE(TestTypeToString(renderer_type()));
SCOPED_TRACE(SkBlendMode_Name(current_blend_mode()));
scoped_refptr<SolidColorLayer> root = CreateSolidColorLayer(
@@ -229,28 +229,23 @@ class LayerTreeHostBlendingPixelTest
CreateBlendingColorLayers(kRootWidth, kRootHeight, background.get(), flags);
- this->force_antialiasing_ = (flags & kUseAntialiasing);
- this->force_blending_with_shaders_ = (flags & kForceShaders);
+ force_antialiasing_ = (flags & kUseAntialiasing);
+ force_blending_with_shaders_ = (flags & kForceShaders);
- if ((flags & kUseAntialiasing) && (renderer_type_ == RENDERER_GL)) {
+ if ((renderer_type() == RENDERER_GL && force_antialiasing_) ||
+ renderer_type() == RENDERER_SKIA_VK) {
// Blending results might differ with one pixel.
- // Don't allow large errors here, only off by ones.
- // However, large error still has to be specified to satisfy
- // the pixel comparator so set it equivalent to small errors.
+ float percentage_pixels_error = 35.f;
+ float percentage_pixels_small_error = 0.f;
+ float average_error_allowed_in_bad_pixels = 1.f;
int large_error_allowed = 1;
- int small_error_allowed = 1;
- float percentage_pixels_small_error = 35.0f;
- float percentage_pixels_error = 35.0f;
- // The average error is still close to 1.
- float average_error_allowed_in_bad_pixels = 1.4f;
-
- pixel_comparator_.reset(
- new FuzzyPixelComparator(false, // discard_alpha
- percentage_pixels_error,
- percentage_pixels_small_error,
- average_error_allowed_in_bad_pixels,
- large_error_allowed,
- small_error_allowed));
+ int small_error_allowed = 0;
+
+ pixel_comparator_ = std::make_unique<FuzzyPixelComparator>(
+ false, // discard_alpha
+ percentage_pixels_error, percentage_pixels_small_error,
+ average_error_allowed_in_bad_pixels, large_error_allowed,
+ small_error_allowed);
}
RunPixelResourceTest(root, CreateBlendingWithRenderPassExpected(
@@ -262,19 +257,18 @@ class LayerTreeHostBlendingPixelTest
SkColor misc_opaque_color_ = 0xffc86464;
};
-INSTANTIATE_TEST_SUITE_P(
- B,
- LayerTreeHostBlendingPixelTest,
- ::testing::Combine(::testing::Values(SOFTWARE, ZERO_COPY, SKIA_GL),
- ::testing::ValuesIn(kBlendModes)));
-
-using LayerTreeHostBlendingPixelTestNonSkia = LayerTreeHostBlendingPixelTest;
+std::vector<PixelResourceTestCase> const kTestCases = {
+ {LayerTreeTest::RENDERER_SOFTWARE, SOFTWARE},
+ {LayerTreeTest::RENDERER_GL, ZERO_COPY},
+ {LayerTreeTest::RENDERER_SKIA_GL, GPU},
+#if defined(ENABLE_CC_VULKAN_TESTS)
+ {LayerTreeTest::RENDERER_SKIA_VK, GPU},
+#endif
+};
-// TODO(crbug.com/948128): Enable these tests for Skia.
INSTANTIATE_TEST_SUITE_P(B,
- LayerTreeHostBlendingPixelTestNonSkia,
- ::testing::Combine(::testing::Values(SOFTWARE,
- ZERO_COPY),
+ LayerTreeHostBlendingPixelTest,
+ ::testing::Combine(::testing::ValuesIn(kTestCases),
::testing::ValuesIn(kBlendModes)));
TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithRoot) {
@@ -304,7 +298,7 @@ TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithRoot) {
RunPixelResourceTest(background, expected);
}
-TEST_P(LayerTreeHostBlendingPixelTestNonSkia, BlendingWithBackdropFilter) {
+TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithBackdropFilter) {
const int kRootWidth = 2;
const int kRootHeight = 2;
InitializeFromTestCase(resource_type());
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc
index 165f1d8879c..3ac848ed527 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc
@@ -4,6 +4,7 @@
#include <stddef.h>
+#include "base/strings/string_number_conversions.h"
#include "build/build_config.h"
#include "cc/layers/picture_layer.h"
#include "cc/layers/solid_color_layer.h"
@@ -21,14 +22,6 @@ class LayerTreeHostFiltersPixelTest
: public LayerTreePixelTest,
public ::testing::WithParamInterface<LayerTreeTest::RendererType> {
protected:
- void InitializeSettings(LayerTreeSettings* settings) override {
- LayerTreePixelTest::InitializeSettings(settings);
- // Required so that device scale is inherited by content scale. True for
- // most tests, but can be overwritten before RunPixelTest() is called.
- settings->layer_transforms_should_scale_layer_contents =
- layer_transforms_should_scale_layer_contents_;
- }
-
RendererType renderer_type() { return GetParam(); }
// Text string for graphics backend of the RendererType. Suitable for
@@ -38,7 +31,9 @@ class LayerTreeHostFiltersPixelTest
case RENDERER_GL:
return "gl";
case RENDERER_SKIA_GL:
- return "skia";
+ return "skia_gl";
+ case RENDERER_SKIA_VK:
+ return "skia_vk";
case RENDERER_SOFTWARE:
return "sw";
}
@@ -71,23 +66,20 @@ class LayerTreeHostFiltersPixelTest
return background;
}
+};
- bool layer_transforms_should_scale_layer_contents_ = true;
+LayerTreeTest::RendererType const kRendererTypes[] = {
+ LayerTreeTest::RENDERER_GL,
+ LayerTreeTest::RENDERER_SKIA_GL,
+ LayerTreeTest::RENDERER_SOFTWARE,
+#if defined(ENABLE_CC_VULKAN_TESTS)
+ LayerTreeTest::RENDERER_SKIA_VK,
+#endif
};
INSTANTIATE_TEST_SUITE_P(,
LayerTreeHostFiltersPixelTest,
- ::testing::Values(LayerTreeTest::RENDERER_GL,
- LayerTreeTest::RENDERER_SKIA_GL,
- LayerTreeTest::RENDERER_SOFTWARE));
-
-using LayerTreeHostFiltersPixelTestNonSkia = LayerTreeHostFiltersPixelTest;
-
-// TODO(crbug.com/948128): Enable these tests for Skia.
-INSTANTIATE_TEST_SUITE_P(,
- LayerTreeHostFiltersPixelTestNonSkia,
- ::testing::Values(LayerTreeTest::RENDERER_GL,
- LayerTreeTest::RENDERER_SOFTWARE));
+ ::testing::ValuesIn(kRendererTypes));
using LayerTreeHostFiltersPixelTestGL = LayerTreeHostFiltersPixelTest;
@@ -98,12 +90,19 @@ INSTANTIATE_TEST_SUITE_P(,
using LayerTreeHostFiltersPixelTestGPU = LayerTreeHostFiltersPixelTest;
+LayerTreeTest::RendererType const kRendererTypesGpu[] = {
+ LayerTreeTest::RENDERER_GL,
+ LayerTreeTest::RENDERER_SKIA_GL,
+#if defined(ENABLE_CC_VULKAN_TESTS)
+ LayerTreeTest::RENDERER_SKIA_VK,
+#endif
+};
+
INSTANTIATE_TEST_SUITE_P(,
LayerTreeHostFiltersPixelTestGPU,
- ::testing::Values(LayerTreeTest::RENDERER_GL,
- LayerTreeTest::RENDERER_SKIA_GL));
+ ::testing::ValuesIn(kRendererTypesGpu));
-TEST_P(LayerTreeHostFiltersPixelTestGPU, BackdropFilterBlurRect) {
+TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterBlurRect) {
scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
gfx::Rect(200, 200), SK_ColorWHITE);
@@ -139,11 +138,56 @@ TEST_P(LayerTreeHostFiltersPixelTestGPU, BackdropFilterBlurRect) {
small_error_allowed));
#endif
- RunPixelTest(renderer_type(), background,
- base::FilePath(FILE_PATH_LITERAL("backdrop_filter_blur.png")));
+ RunPixelTest(
+ renderer_type(), background,
+ (renderer_type() == RENDERER_SOFTWARE)
+ ? base::FilePath(FILE_PATH_LITERAL("backdrop_filter_blur_sw.png"))
+ : base::FilePath(FILE_PATH_LITERAL("backdrop_filter_blur.png")));
+}
+
+TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterBlurRadius) {
+ if (renderer_type() == RENDERER_SOFTWARE) {
+ // TODO(989238): Software renderer does not support/implement
+ // kClamp_TileMode.
+ return;
+ }
+ scoped_refptr<SolidColorLayer> background =
+ CreateSolidColorLayer(gfx::Rect(400, 400), SK_ColorRED);
+ scoped_refptr<SolidColorLayer> green =
+ CreateSolidColorLayer(gfx::Rect(200, 200, 200, 200), kCSSLime);
+ gfx::Rect blur_rect(100, 100, 200, 200);
+ scoped_refptr<SolidColorLayer> blur =
+ CreateSolidColorLayer(blur_rect, SkColorSetARGB(40, 10, 20, 200));
+ background->AddChild(green);
+ background->AddChild(blur);
+
+ FilterOperations filters;
+ filters.Append(FilterOperation::CreateBlurFilter(
+ 30.f, SkBlurImageFilter::kClamp_TileMode));
+ blur->SetBackdropFilters(filters);
+ gfx::RRectF backdrop_filter_bounds(gfx::RectF(gfx::SizeF(blur->bounds())), 0);
+ blur->SetBackdropFilterBounds(backdrop_filter_bounds);
+
+#if defined(OS_WIN) || defined(ARCH_CPU_ARM64)
+ // Windows and ARM64 have 436 pixels off by 1: crbug.com/259915
+ float percentage_pixels_large_error = 1.09f; // 436px / (200*200)
+ float percentage_pixels_small_error = 0.0f;
+ float average_error_allowed_in_bad_pixels = 1.f;
+ int large_error_allowed = 1;
+ int small_error_allowed = 0;
+ pixel_comparator_.reset(new FuzzyPixelComparator(
+ true, // discard_alpha
+ percentage_pixels_large_error, percentage_pixels_small_error,
+ average_error_allowed_in_bad_pixels, large_error_allowed,
+ small_error_allowed));
+#endif
+ RunPixelTest(
+ renderer_type(), background,
+ base::FilePath(FILE_PATH_LITERAL("backdrop_filter_blur_radius_.png"))
+ .InsertBeforeExtensionASCII(GetRendererSuffix()));
}
-TEST_P(LayerTreeHostFiltersPixelTestGPU, BackdropFilterBlurRounded) {
+TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterBlurRounded) {
scoped_refptr<SolidColorLayer> background =
CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
@@ -180,17 +224,17 @@ TEST_P(LayerTreeHostFiltersPixelTestGPU, BackdropFilterBlurRounded) {
pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(false);
#endif
- RunPixelTest(
- renderer_type(), background,
- base::FilePath(FILE_PATH_LITERAL("backdrop_filter_blur_rounded.png")));
+ RunPixelTest(renderer_type(), background,
+ (renderer_type() == RENDERER_SOFTWARE)
+ ? base::FilePath(FILE_PATH_LITERAL(
+ "backdrop_filter_blur_rounded_sw.png"))
+ : base::FilePath(FILE_PATH_LITERAL(
+ "backdrop_filter_blur_rounded.png")));
}
-TEST_P(LayerTreeHostFiltersPixelTestGPU, BackdropFilterBlurOutsets) {
- if (renderer_type() == RENDERER_SKIA_GL
-#if defined(ENABLE_CC_VULKAN_TESTS)
- || renderer_type() == RENDERER_SKIA_VK
-#endif
- ) {
+TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterBlurOutsets) {
+ if (renderer_type() == RENDERER_SKIA_GL ||
+ renderer_type() == RENDERER_SKIA_VK) {
// TODO(973696): Implement bounds clipping in skia_renderer.
return;
}
@@ -233,6 +277,9 @@ TEST_P(LayerTreeHostFiltersPixelTestGPU, BackdropFilterBlurOutsets) {
average_error_allowed_in_bad_pixels,
large_error_allowed,
small_error_allowed));
+#else
+ if (renderer_type() == RENDERER_SKIA_VK)
+ pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(true);
#endif
RunPixelTest(
@@ -380,9 +427,7 @@ class LayerTreeHostFiltersScaledPixelTest
INSTANTIATE_TEST_SUITE_P(,
LayerTreeHostFiltersScaledPixelTest,
- ::testing::Values(LayerTreeTest::RENDERER_GL,
- LayerTreeTest::RENDERER_SKIA_GL,
- LayerTreeTest::RENDERER_SOFTWARE));
+ ::testing::ValuesIn(kRendererTypes));
TEST_P(LayerTreeHostFiltersScaledPixelTest, StandardDpi) {
RunPixelTestType(100, 1.f);
@@ -393,8 +438,6 @@ TEST_P(LayerTreeHostFiltersScaledPixelTest, HiDpi) {
}
TEST_P(LayerTreeHostFiltersPixelTest, NullFilter) {
- layer_transforms_should_scale_layer_contents_ = false;
-
scoped_refptr<SolidColorLayer> foreground =
CreateSolidColorLayer(gfx::Rect(0, 0, 200, 200), SK_ColorGREEN);
@@ -407,8 +450,6 @@ TEST_P(LayerTreeHostFiltersPixelTest, NullFilter) {
}
TEST_P(LayerTreeHostFiltersPixelTest, CroppedFilter) {
- layer_transforms_should_scale_layer_contents_ = false;
-
scoped_refptr<SolidColorLayer> foreground =
CreateSolidColorLayer(gfx::Rect(0, 0, 200, 200), SK_ColorGREEN);
@@ -668,7 +709,7 @@ TEST_P(LayerTreeHostFiltersPixelTest, ImageRenderSurfaceScaled) {
.InsertBeforeExtensionASCII(GetRendererSuffix()));
}
-TEST_P(LayerTreeHostFiltersPixelTestNonSkia, ZoomFilter) {
+TEST_P(LayerTreeHostFiltersPixelTest, ZoomFilter) {
scoped_refptr<SolidColorLayer> root =
CreateSolidColorLayer(gfx::Rect(300, 300), SK_ColorWHITE);
@@ -945,8 +986,7 @@ TEST_P(LayerTreeHostFiltersPixelTest, EnlargedTextureWithCropOffsetFilter) {
base::FilePath(FILE_PATH_LITERAL("enlarged_texture_on_crop_offset.png")));
}
-// TODO(crbug.com/948128): Enable this test for SkiaRenderer.
-TEST_P(LayerTreeHostFiltersPixelTestNonSkia, BlurFilterWithClip) {
+TEST_P(LayerTreeHostFiltersPixelTest, BlurFilterWithClip) {
scoped_refptr<SolidColorLayer> child1 =
CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorBLUE);
scoped_refptr<SolidColorLayer> child2 =
@@ -1010,32 +1050,96 @@ TEST_P(LayerTreeHostFiltersPixelTestGPU, FilterWithGiantCropRectNoClip) {
base::FilePath(FILE_PATH_LITERAL("filter_with_giant_crop_rect.png")));
}
-class BackdropFilterWithDeviceScaleFactorTest
- : public LayerTreeHostFiltersPixelTest {
+class BackdropFilterOffsetTest : public LayerTreeHostFiltersPixelTest {
protected:
- void RunPixelTestType(float device_scale_factor,
- const base::FilePath& expected_result) {
- device_scale_factor_ = device_scale_factor;
-
+ void RunPixelTestType(int device_scale_factor) {
scoped_refptr<Layer> root =
CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
-
scoped_refptr<SolidColorLayer> background =
CreateSolidColorLayer(gfx::Rect(100, 120), SK_ColorBLACK);
root->AddChild(background);
-
scoped_refptr<SolidColorLayer> filtered = CreateSolidColorLayer(
gfx::Rect(0, 100, 200, 100), SkColorSetA(SK_ColorGREEN, 127));
FilterOperations filters;
+ // TODO(989329): This test actually also tests how the OffsetPaintFilter
+ // handles the edge condition. Because the OffsetPaintFilter is pulling
+ // content from outside the filter region (just the bottom 200x100 square),
+ // it must create content for all but the bottom 20px of the filter rect.
+ // The GPU implementation of OffsetPaintFilter effectively clamps to the
+ // edge pixels and copies them into the top 80px of the image. The CPU
+ // implementation, on the other hand, pulls in transparent pixels for those
+ // 80px. The behavior is basically unspecified, though for blur filters the
+ // explicitly specified behavior is edgemode:duplicate, as seen in [1]. And
+ // the default for svg filters, including feOffset, is also duplicate.
+ // [1] https://drafts.fxtf.org/filter-effects-2/#backdrop-filter-operation
+ // [2] https://www.w3.org/TR/SVG11/filters.html#feConvolveMatrixElementEdgeModeAttribute
filters.Append(FilterOperation::CreateReferenceFilter(
sk_make_sp<OffsetPaintFilter>(0, 80, nullptr)));
filtered->SetBackdropFilters(filters);
filtered->ClearBackdropFilterBounds();
root->AddChild(filtered);
-
// This should appear as a grid of 4 100x100 squares which are:
// BLACK WHITE
- // DARK GREEN LIGHT GREEN
+ // DARK GREEN* LIGHT GREEN
+ //
+ // *except for software (see crbug.com/989329) which will be a
+ // dark-light-dark horizontal sandwich.
+ device_scale_factor_ = device_scale_factor;
+
+ base::FilePath expected_result =
+ base::FilePath(FILE_PATH_LITERAL("offset_backdrop_filter_.png"));
+ expected_result = expected_result.InsertBeforeExtensionASCII(
+ base::NumberToString(device_scale_factor) + "x");
+ if (renderer_type() == RENDERER_SOFTWARE) {
+ expected_result = expected_result.InsertBeforeExtensionASCII("_sw");
+ }
+ RunPixelTest(renderer_type(), std::move(root), expected_result);
+ }
+
+ private:
+ // LayerTreePixelTest overrides
+ void SetupTree() override {
+ SetInitialDeviceScaleFactor(device_scale_factor_);
+ LayerTreeHostFiltersPixelTest::SetupTree();
+ }
+
+ float device_scale_factor_ = 1;
+};
+
+INSTANTIATE_TEST_SUITE_P(,
+ BackdropFilterOffsetTest,
+ ::testing::ValuesIn(kRendererTypes));
+
+TEST_P(BackdropFilterOffsetTest, StandardDpi) {
+ RunPixelTestType(1.f);
+}
+
+TEST_P(BackdropFilterOffsetTest, HiDpi) {
+ RunPixelTestType(2.f);
+}
+
+class BackdropFilterInvertTest : public LayerTreeHostFiltersPixelTest {
+ protected:
+ void RunPixelTestType(int device_scale_factor) {
+ scoped_refptr<Layer> root =
+ CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN);
+ scoped_refptr<SolidColorLayer> filtered =
+ CreateSolidColorLayer(gfx::Rect(50, 50, 100, 100), SK_ColorTRANSPARENT);
+ FilterOperations filters;
+ filters.Append(FilterOperation::CreateInvertFilter(1.0));
+ filtered->SetBackdropFilters(filters);
+ gfx::RRectF backdrop_filter_bounds(
+ gfx::RectF(gfx::SizeF(filtered->bounds())), 20);
+ filtered->SetBackdropFilterBounds(backdrop_filter_bounds);
+ root->AddChild(filtered);
+ device_scale_factor_ = device_scale_factor;
+ base::FilePath expected_result =
+ base::FilePath(FILE_PATH_LITERAL("invert_backdrop_filter_.png"));
+ expected_result = expected_result.InsertBeforeExtensionASCII(
+ base::NumberToString(device_scale_factor) + "x");
+ if (renderer_type() == RENDERER_SOFTWARE) {
+ expected_result = expected_result.InsertBeforeExtensionASCII("_sw");
+ }
RunPixelTest(renderer_type(), std::move(root), expected_result);
}
@@ -1049,21 +1153,16 @@ class BackdropFilterWithDeviceScaleFactorTest
float device_scale_factor_ = 1;
};
-// TODO(973699): This test is broken in software_renderer. Re-enable this test
-// when fixed.
INSTANTIATE_TEST_SUITE_P(,
- BackdropFilterWithDeviceScaleFactorTest,
- ::testing::Values(LayerTreeTest::RENDERER_GL,
- LayerTreeTest::RENDERER_SKIA_GL));
+ BackdropFilterInvertTest,
+ ::testing::ValuesIn(kRendererTypes));
-TEST_P(BackdropFilterWithDeviceScaleFactorTest, StandardDpi) {
- RunPixelTestType(
- 1.f, base::FilePath(FILE_PATH_LITERAL("offset_backdrop_filter_1x.png")));
+TEST_P(BackdropFilterInvertTest, StandardDpi) {
+ RunPixelTestType(1.f);
}
-TEST_P(BackdropFilterWithDeviceScaleFactorTest, HiDpi) {
- RunPixelTestType(
- 2.f, base::FilePath(FILE_PATH_LITERAL("offset_backdrop_filter_2x.png")));
+TEST_P(BackdropFilterInvertTest, HiDpi) {
+ RunPixelTestType(2.f);
}
} // namespace
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
index 9e125057e0d..1dcc664c201 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
@@ -18,7 +18,7 @@
#include "cc/test/layer_tree_pixel_resource_test.h"
#include "cc/test/pixel_comparator.h"
#include "cc/test/solid_color_content_layer_client.h"
-#include "components/viz/test/test_layer_tree_frame_sink.h"
+#include "cc/test/test_layer_tree_frame_sink.h"
#include "third_party/skia/include/core/SkImage.h"
#if !defined(OS_ANDROID)
@@ -26,9 +26,33 @@
namespace cc {
namespace {
+auto CombineWithLayerMaskTypes(
+ const std::vector<PixelResourceTestCase>& test_cases) {
+ return ::testing::Combine(
+ ::testing::ValuesIn(test_cases),
+ ::testing::Values(Layer::LayerMaskType::SINGLE_TEXTURE_MASK));
+}
+
+// TODO(penghuang): Fix vulkan with one copy or zero copy
+// https://crbug.com/979703
+std::vector<PixelResourceTestCase> const kTestCases = {
+ {LayerTreeTest::RENDERER_SOFTWARE, SOFTWARE},
+ {LayerTreeTest::RENDERER_GL, GPU},
+ {LayerTreeTest::RENDERER_GL, ONE_COPY},
+ {LayerTreeTest::RENDERER_GL, ZERO_COPY},
+ {LayerTreeTest::RENDERER_SKIA_GL, GPU},
+ {LayerTreeTest::RENDERER_SKIA_GL, ONE_COPY},
+ {LayerTreeTest::RENDERER_SKIA_GL, ZERO_COPY},
+#if defined(ENABLE_CC_VULKAN_TESTS)
+ {LayerTreeTest::RENDERER_SKIA_VK, GPU},
+#endif
+};
+
using LayerTreeHostMasksPixelTest = ParameterizedPixelResourceTest;
-INSTANTIATE_PIXEL_RESOURCE_TEST_SUITE_P(LayerTreeHostMasksPixelTest);
+INSTANTIATE_TEST_SUITE_P(PixelResourceTest,
+ LayerTreeHostMasksPixelTest,
+ CombineWithLayerMaskTypes(kTestCases));
class MaskContentLayerClient : public ContentLayerClient {
public:
@@ -89,17 +113,23 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskOfLayer) {
mask->SetLayerMaskType(mask_type_);
green->SetMaskLayer(mask.get());
+ pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(true);
+
RunPixelResourceTest(background,
base::FilePath(FILE_PATH_LITERAL("mask_of_layer.png")));
}
class LayerTreeHostLayerListPixelTest : public ParameterizedPixelResourceTest {
+ protected:
void InitializeSettings(LayerTreeSettings* settings) override {
settings->use_layer_lists = true;
+ settings->gpu_rasterization_forced = use_vulkan();
}
};
-INSTANTIATE_PIXEL_RESOURCE_TEST_SUITE_P(LayerTreeHostLayerListPixelTest);
+INSTANTIATE_TEST_SUITE_P(PixelResourceTest,
+ LayerTreeHostLayerListPixelTest,
+ CombineWithLayerMaskTypes(kTestCases));
TEST_P(LayerTreeHostLayerListPixelTest, MaskWithEffect) {
PropertyTrees property_trees;
@@ -153,6 +183,9 @@ TEST_P(LayerTreeHostLayerListPixelTest, MaskWithEffect) {
mask->SetTransformTreeIndex(1);
root_layer->AddChild(mask);
+ pixel_comparator_ =
+ std::make_unique<FuzzyPixelOffByOneComparator>(true /* discard_alpha */);
+
RunPixelResourceTestWithLayerList(
root_layer, base::FilePath(FILE_PATH_LITERAL("mask_with_effect.png")),
&property_trees);
@@ -418,18 +451,7 @@ TEST_P(LayerTreeHostLayerListPixelTest, MaskWithEffectNoContentToMask) {
&property_trees);
}
-using LayerTreeHostLayerListPixelTestNonSkia = LayerTreeHostLayerListPixelTest;
-
-// TODO(crbug.com/948128): Enable this test for Skia.
-INSTANTIATE_TEST_SUITE_P(
- PixelResourceTest,
- LayerTreeHostLayerListPixelTestNonSkia,
- ::testing::Combine(
- ::testing::Values(SOFTWARE, GPU, ONE_COPY, ZERO_COPY),
- ::testing::Values(Layer::LayerMaskType::SINGLE_TEXTURE_MASK,
- Layer::LayerMaskType::MULTI_TEXTURE_MASK)));
-
-TEST_P(LayerTreeHostLayerListPixelTestNonSkia, ScaledMaskWithEffect) {
+TEST_P(LayerTreeHostLayerListPixelTest, ScaledMaskWithEffect) {
PropertyTrees property_trees;
scoped_refptr<Layer> root_layer;
InitializeForLayerListMode(&root_layer, &property_trees);
@@ -450,10 +472,12 @@ TEST_P(LayerTreeHostLayerListPixelTestNonSkia, ScaledMaskWithEffect) {
// Scale the mask with a non-integral transform. This will trigger the
// AA path in the renderer.
- TransformNode transform;
- transform.local = gfx::Transform();
- transform.local.Scale(1.5, 1.5);
- property_trees.transform_tree.Insert(transform, 1);
+ TransformTree& transform_tree = property_trees.transform_tree;
+ auto& transform_node =
+ *transform_tree.Node(transform_tree.Insert(TransformNode(), 1));
+ transform_node.source_node_id = transform_node.parent_id;
+ transform_node.local = gfx::Transform();
+ transform_node.local.Scale(1.5, 1.5);
scoped_refptr<SolidColorLayer> background =
CreateSolidColorLayer(gfx::Rect(100, 100), SK_ColorWHITE);
@@ -488,20 +512,13 @@ TEST_P(LayerTreeHostLayerListPixelTestNonSkia, ScaledMaskWithEffect) {
mask->SetTransformTreeIndex(2);
root_layer->AddChild(mask);
- float percentage_pixels_large_error = 2.5f; // 2.5%, ~250px / (100*100)
- float percentage_pixels_small_error = 0.0f;
- float average_error_allowed_in_bad_pixels = 100.0f;
- int large_error_allowed = 256;
- int small_error_allowed = 0;
- pixel_comparator_ = std::make_unique<FuzzyPixelComparator>(
- true, // discard_alpha
- percentage_pixels_large_error, percentage_pixels_small_error,
- average_error_allowed_in_bad_pixels, large_error_allowed,
- small_error_allowed);
+ pixel_comparator_ =
+ std::make_unique<FuzzyPixelOffByOneComparator>(true /* discard_alpha */);
RunPixelResourceTestWithLayerList(
root_layer,
- base::FilePath(FILE_PATH_LITERAL("scaled_mask_with_effect.png")),
+ base::FilePath(FILE_PATH_LITERAL("scaled_mask_with_effect_.png"))
+ .InsertBeforeExtensionASCII(GetRendererSuffix()),
&property_trees);
}
@@ -557,6 +574,9 @@ TEST_P(LayerTreeHostLayerListPixelTest, MaskWithEffectDifferentSize) {
mask->SetTransformTreeIndex(1);
root_layer->AddChild(mask);
+ pixel_comparator_ =
+ std::make_unique<FuzzyPixelOffByOneComparator>(true /* discard_alpha */);
+
// The mask is half the size of thing it's masking. In layer-list mode,
// the mask is not automatically scaled to match the other layer.
RunPixelResourceTestWithLayerList(
@@ -631,6 +651,9 @@ TEST_P(LayerTreeHostLayerListPixelTest, ImageMaskWithEffect) {
SkMatrix::I(), false);
root_layer->AddChild(mask);
+ pixel_comparator_ =
+ std::make_unique<FuzzyPixelOffByOneComparator>(true /* discard_alpha */);
+
// The mask is half the size of thing it's masking. In layer-list mode,
// the mask is not automatically scaled to match the other layer.
RunPixelResourceTestWithLayerList(
@@ -670,6 +693,9 @@ TEST_P(LayerTreeHostMasksPixelTest, ImageMaskOfLayer) {
green->SetMaskLayer(mask.get());
background->AddChild(green);
+ pixel_comparator_ =
+ std::make_unique<FuzzyPixelOffByOneComparator>(true /* discard_alpha */);
+
RunPixelResourceTest(
background, base::FilePath(FILE_PATH_LITERAL("image_mask_of_layer.png")));
}
@@ -697,6 +723,9 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskOfClippedLayer) {
mask->SetLayerMaskType(mask_type_);
green->SetMaskLayer(mask.get());
+ pixel_comparator_ =
+ std::make_unique<FuzzyPixelOffByOneComparator>(true /* discard_alpha */);
+
RunPixelResourceTest(
background,
base::FilePath(FILE_PATH_LITERAL("mask_of_clipped_layer.png")));
@@ -719,6 +748,9 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskOfLayerNonExactTextureSize) {
mask->set_fixed_tile_size(gfx::Size(173, 135));
green->SetMaskLayer(mask.get());
+ pixel_comparator_ =
+ std::make_unique<FuzzyPixelOffByOneComparator>(true /* discard_alpha */);
+
RunPixelResourceTest(background,
base::FilePath(FILE_PATH_LITERAL(
"mask_with_non_exact_texture_size.png")));
@@ -817,20 +849,9 @@ class CircleContentLayerClient : public ContentLayerClient {
using LayerTreeHostMasksForBackdropFiltersPixelTest =
ParameterizedPixelResourceTest;
-INSTANTIATE_PIXEL_RESOURCE_TEST_SUITE_P(
- LayerTreeHostMasksForBackdropFiltersPixelTest);
-
-using LayerTreeHostMasksForBackdropFiltersPixelTestNonSkia =
- ParameterizedPixelResourceTest;
-
-// TODO(crbug.com/948128): Enable these tests for Skia.
-INSTANTIATE_TEST_SUITE_P(
- PixelResourceTest,
- LayerTreeHostMasksForBackdropFiltersPixelTestNonSkia,
- ::testing::Combine(
- ::testing::Values(SOFTWARE, GPU, ONE_COPY, ZERO_COPY),
- ::testing::Values(Layer::LayerMaskType::SINGLE_TEXTURE_MASK,
- Layer::LayerMaskType::MULTI_TEXTURE_MASK)));
+INSTANTIATE_TEST_SUITE_P(PixelResourceTest,
+ LayerTreeHostMasksForBackdropFiltersPixelTest,
+ CombineWithLayerMaskTypes(kTestCases));
TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest,
MaskOfLayerWithBackdropFilter) {
@@ -863,9 +884,24 @@ TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest,
CHECK_EQ(Layer::LayerMaskType::SINGLE_TEXTURE_MASK, mask->mask_type());
base::FilePath image_name =
- (test_case_ == GPU || test_case_ == SKIA_GL)
+ (raster_type() == GPU)
? base::FilePath(FILE_PATH_LITERAL("mask_of_backdrop_filter_gpu.png"))
: base::FilePath(FILE_PATH_LITERAL("mask_of_backdrop_filter.png"));
+
+ if (renderer_type() == RENDERER_SKIA_VK && raster_type() == GPU) {
+ // Vulkan with GPU raster has 4 pixels errors (the circle mask shape is
+ // slight different).
+ float percentage_pixels_large_error = 0.04f; // 4px / (100*100)
+ float percentage_pixels_small_error = 0.0f;
+ float average_error_allowed_in_bad_pixels = 182.f;
+ int large_error_allowed = 182;
+ int small_error_allowed = 0;
+ pixel_comparator_ = std::make_unique<FuzzyPixelComparator>(
+ true /* discard_alpha */, percentage_pixels_large_error,
+ percentage_pixels_small_error, average_error_allowed_in_bad_pixels,
+ large_error_allowed, small_error_allowed);
+ }
+
RunPixelResourceTest(background, image_name);
}
@@ -962,22 +998,16 @@ class LayerTreeHostMaskAsBlendingPixelTest
Layer::LayerMaskType::SINGLE_TEXTURE_MASK),
use_antialiasing_(GetParam().flags & kUseAntialiasing),
force_shaders_(GetParam().flags & kForceShaders) {
- float percentage_pixels_small_error = 0.f;
float percentage_pixels_error = 0.f;
+ float percentage_pixels_small_error = 0.f;
float average_error_allowed_in_bad_pixels = 0.f;
int large_error_allowed = 0;
int small_error_allowed = 0;
- if (use_antialiasing_) {
- percentage_pixels_small_error = 0.9f;
- percentage_pixels_error = 6.7f;
- average_error_allowed_in_bad_pixels = 3.5f;
- large_error_allowed = 15;
- small_error_allowed = 1;
- } else if (test_case_ != SOFTWARE) {
- percentage_pixels_small_error = 0.9f;
- percentage_pixels_error = 6.5f;
- average_error_allowed_in_bad_pixels = 3.5f;
- large_error_allowed = 15;
+ if (renderer_type() != RENDERER_SOFTWARE) {
+ percentage_pixels_error = 6.0f;
+ percentage_pixels_small_error = 2.f;
+ average_error_allowed_in_bad_pixels = 2.1f;
+ large_error_allowed = 11;
small_error_allowed = 1;
} else {
#if defined(ARCH_CPU_ARM64)
@@ -1061,7 +1091,7 @@ class LayerTreeHostMaskAsBlendingPixelTest
}
protected:
- std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
+ std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
const viz::RendererSettings& renderer_settings,
double refresh_rate,
scoped_refptr<viz::ContextProvider> compositor_context_provider,
@@ -1080,13 +1110,21 @@ class LayerTreeHostMaskAsBlendingPixelTest
bool force_shaders_;
};
-// TODO(crbug.com/948128): Enable these tests for Skia.
MaskTestConfig const kTestConfigs[] = {
- MaskTestConfig{SOFTWARE, 0},
- MaskTestConfig{ZERO_COPY, 0},
- MaskTestConfig{ZERO_COPY, kUseAntialiasing},
- MaskTestConfig{ZERO_COPY, kForceShaders},
- MaskTestConfig{ZERO_COPY, kUseAntialiasing | kForceShaders},
+ MaskTestConfig{{LayerTreeTest::RENDERER_SOFTWARE, SOFTWARE}, 0},
+ MaskTestConfig{{LayerTreeTest::RENDERER_GL, ZERO_COPY}, 0},
+ MaskTestConfig{{LayerTreeTest::RENDERER_GL, ZERO_COPY}, kUseAntialiasing},
+ MaskTestConfig{{LayerTreeTest::RENDERER_GL, ZERO_COPY}, kForceShaders},
+ MaskTestConfig{{LayerTreeTest::RENDERER_GL, ZERO_COPY},
+ kUseAntialiasing | kForceShaders},
+ MaskTestConfig{{LayerTreeTest::RENDERER_SKIA_GL, ZERO_COPY}, 0},
+ MaskTestConfig{{LayerTreeTest::RENDERER_SKIA_GL, ZERO_COPY},
+ kUseAntialiasing},
+#if defined(ENABLE_CC_VULKAN_TESTS)
+ MaskTestConfig{{LayerTreeTest::RENDERER_SKIA_VK, ZERO_COPY}, 0},
+ MaskTestConfig{{LayerTreeTest::RENDERER_SKIA_VK, ZERO_COPY},
+ kUseAntialiasing},
+#endif
};
INSTANTIATE_TEST_SUITE_P(All,
@@ -1229,7 +1267,7 @@ TEST_P(LayerTreeHostMaskAsBlendingPixelTest, RotatedClippedCircle) {
mask_isolation->AddChild(mask_layer);
base::FilePath image_name =
- (test_case_ == SOFTWARE)
+ (raster_type() == SOFTWARE)
? base::FilePath(
FILE_PATH_LITERAL("mask_as_blending_rotated_circle.png"))
: base::FilePath(
@@ -1276,7 +1314,7 @@ TEST_P(LayerTreeHostMaskAsBlendingPixelTest, RotatedClippedCircleUnderflow) {
mask_isolation->AddChild(mask_layer);
base::FilePath image_name =
- (test_case_ == SOFTWARE)
+ (raster_type() == SOFTWARE)
? base::FilePath(FILE_PATH_LITERAL(
"mask_as_blending_rotated_circle_underflow.png"))
: base::FilePath(FILE_PATH_LITERAL(
@@ -1284,7 +1322,7 @@ TEST_P(LayerTreeHostMaskAsBlendingPixelTest, RotatedClippedCircleUnderflow) {
RunPixelResourceTest(root, image_name);
}
-TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTestNonSkia,
+TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest,
MaskOfLayerWithBackdropFilterAndBlend) {
scoped_refptr<SolidColorLayer> background =
CreateSolidColorLayer(gfx::Rect(128, 128), SK_ColorWHITE);
@@ -1322,20 +1360,14 @@ TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTestNonSkia,
mask->SetLayerMaskType(mask_type_);
picture_horizontal->SetMaskLayer(mask.get());
- float percentage_pixels_large_error = 0.062f; // 0.062%, ~10px / (128*128)
- float percentage_pixels_small_error = 0.0f;
- float average_error_allowed_in_bad_pixels = 200.0f;
- int large_error_allowed = 256;
- int small_error_allowed = 0;
- pixel_comparator_ = std::make_unique<FuzzyPixelComparator>(
- true, // discard_alpha
- percentage_pixels_large_error, percentage_pixels_small_error,
- average_error_allowed_in_bad_pixels, large_error_allowed,
- small_error_allowed);
-
- RunPixelResourceTest(background,
- base::FilePath(FILE_PATH_LITERAL(
- "mask_of_backdrop_filter_and_blend.png")));
+ base::FilePath result_path(
+ FILE_PATH_LITERAL("mask_of_backdrop_filter_and_blend_.png"));
+ if (raster_type() != GPU) {
+ result_path = result_path.InsertBeforeExtensionASCII("sw");
+ } else {
+ result_path = result_path.InsertBeforeExtensionASCII(GetRendererSuffix());
+ }
+ RunPixelResourceTest(background, result_path);
}
} // namespace
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_mirror.cc b/chromium/cc/trees/layer_tree_host_pixeltest_mirror.cc
new file mode 100644
index 00000000000..ed011f43887
--- /dev/null
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_mirror.cc
@@ -0,0 +1,83 @@
+// Copyright 2019 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 "build/build_config.h"
+#include "cc/layers/mirror_layer.h"
+#include "cc/layers/solid_color_layer.h"
+#include "cc/test/layer_tree_pixel_test.h"
+#include "cc/test/pixel_comparator.h"
+#include "ui/gfx/geometry/size.h"
+#include "ui/gfx/transform_util.h"
+
+#if !defined(OS_ANDROID)
+
+namespace cc {
+namespace {
+
+class LayerTreeHostMirrorPixelTest
+ : public LayerTreePixelTest,
+ public ::testing::WithParamInterface<LayerTreeTest::RendererType> {
+ protected:
+ RendererType renderer_type() { return GetParam(); }
+};
+
+const LayerTreeTest::RendererType kRendererTypes[] = {
+ LayerTreeTest::RENDERER_GL,
+ LayerTreeTest::RENDERER_SKIA_GL,
+ LayerTreeTest::RENDERER_SOFTWARE,
+#if defined(ENABLE_CC_VULKAN_TESTS)
+ LayerTreeTest::RENDERER_SKIA_VK,
+#endif
+};
+
+INSTANTIATE_TEST_SUITE_P(,
+ LayerTreeHostMirrorPixelTest,
+ ::testing::ValuesIn(kRendererTypes));
+
+// Verifies that a mirror layer with a scale mirrors another layer correctly.
+TEST_P(LayerTreeHostMirrorPixelTest, MirrorLayer) {
+ const float scale = 2.f;
+ gfx::Rect background_bounds(120, 180);
+ gfx::Rect mirrored_bounds(10, 10, 50, 50);
+ gfx::Rect mirror_bounds(10, 70, 100, 100);
+
+ auto background = CreateSolidColorLayer(background_bounds, SK_ColorWHITE);
+
+ auto mirrored_layer = CreateSolidColorLayerWithBorder(
+ mirrored_bounds, SK_ColorGREEN, 5, SK_ColorBLUE);
+
+ auto mirror_layer = MirrorLayer::Create(mirrored_layer);
+ mirror_layer->SetIsDrawable(true);
+ mirror_layer->SetBounds(mirror_bounds.size());
+ mirror_layer->SetPosition(gfx::PointF(mirror_bounds.origin()));
+ mirror_layer->SetTransform(gfx::GetScaleTransform(gfx::Point(), scale));
+ background->AddChild(mirrored_layer);
+ background->AddChild(mirror_layer);
+
+ if (renderer_type() == RENDERER_SOFTWARE) {
+ const bool discard_alpha = true;
+ const float error_pixels_percentage_limit = 3.f;
+ const float small_error_pixels_percentage_limit = 0.f;
+ const float avg_abs_error_limit = 65.f;
+ const int max_abs_error_limit = 120;
+ const int small_error_threshold = 0;
+ pixel_comparator_ = std::make_unique<FuzzyPixelComparator>(
+ discard_alpha, error_pixels_percentage_limit,
+ small_error_pixels_percentage_limit, avg_abs_error_limit,
+ max_abs_error_limit, small_error_threshold);
+ }
+
+#if defined(ENABLE_CC_VULKAN_TESTS) && defined(OS_LINUX)
+ if (renderer_type() == RENDERER_SKIA_VK)
+ pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(true);
+#endif
+
+ RunPixelTest(renderer_type(), background,
+ base::FilePath(FILE_PATH_LITERAL("mirror_layer.png")));
+}
+
+} // namespace
+} // namespace cc
+
+#endif // !defined(OS_ANDROID)
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc b/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc
index 41660e1fb34..52317bb5fa2 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc
@@ -10,11 +10,11 @@
#include "cc/test/fake_picture_layer_impl.h"
#include "cc/test/layer_tree_pixel_test.h"
#include "cc/test/solid_color_content_layer_client.h"
+#include "cc/test/test_layer_tree_frame_sink.h"
#include "cc/trees/layer_tree_impl.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/copy_output_result.h"
#include "components/viz/test/paths.h"
-#include "components/viz/test/test_layer_tree_frame_sink.h"
#if !defined(OS_ANDROID)
@@ -29,9 +29,6 @@ enum ReadbackType {
};
struct ReadbackTestConfig {
- ReadbackTestConfig(LayerTreeTest::RendererType renderer_type_,
- ReadbackType readback_type_)
- : renderer_type(renderer_type_), readback_type(readback_type_) {}
LayerTreeTest::RendererType renderer_type;
ReadbackType readback_type;
};
@@ -191,7 +188,11 @@ TEST_P(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayerWithChild) {
base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
}
-TEST_P(LayerTreeHostReadbackPixelTest, ReadbackSubtreeSurroundsTargetLayer) {
+using LayerTreeHostReadbackPixelTestMaybeVulkan =
+ LayerTreeHostReadbackPixelTest;
+
+TEST_P(LayerTreeHostReadbackPixelTestMaybeVulkan,
+ ReadbackSubtreeSurroundsTargetLayer) {
scoped_refptr<SolidColorLayer> background =
CreateSolidColorLayer(gfx::Rect(0, 0, 200, 200), SK_ColorWHITE);
@@ -379,7 +380,7 @@ TEST_P(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayerOutsideViewport) {
base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")));
}
-TEST_P(LayerTreeHostReadbackPixelTest, ReadbackNonRootOrFirstLayer) {
+TEST_P(LayerTreeHostReadbackPixelTestMaybeVulkan, ReadbackNonRootOrFirstLayer) {
// This test has 3 render passes with the copy request on the render pass in
// the middle. This test caught an issue where copy requests on non-root
// non-first render passes were being treated differently from the first
@@ -415,15 +416,40 @@ TEST_P(LayerTreeHostReadbackPixelTest, MultipleReadbacksOnLayer) {
base::FilePath(FILE_PATH_LITERAL("green.png")));
}
-INSTANTIATE_TEST_SUITE_P(
- ,
- LayerTreeHostReadbackPixelTest,
- ::testing::Values(
- ReadbackTestConfig(LayerTreeTest::RENDERER_SOFTWARE, READBACK_BITMAP),
- ReadbackTestConfig(LayerTreeTest::RENDERER_GL, READBACK_TEXTURE),
- ReadbackTestConfig(LayerTreeTest::RENDERER_GL, READBACK_BITMAP),
- ReadbackTestConfig(LayerTreeTest::RENDERER_SKIA_GL, READBACK_BITMAP),
- ReadbackTestConfig(LayerTreeTest::RENDERER_SKIA_GL, READBACK_TEXTURE)));
+// TODO(crbug.com/963446): Enable these tests for Skia Vulkan using texture
+// readback.
+ReadbackTestConfig const kTestConfigs[] = {
+ ReadbackTestConfig{LayerTreeTest::RENDERER_SOFTWARE, READBACK_BITMAP},
+ ReadbackTestConfig{LayerTreeTest::RENDERER_GL, READBACK_TEXTURE},
+ ReadbackTestConfig{LayerTreeTest::RENDERER_GL, READBACK_BITMAP},
+ ReadbackTestConfig{LayerTreeTest::RENDERER_SKIA_GL, READBACK_TEXTURE},
+ ReadbackTestConfig{LayerTreeTest::RENDERER_SKIA_GL, READBACK_BITMAP},
+#if defined(ENABLE_CC_VULKAN_TESTS)
+ ReadbackTestConfig{LayerTreeTest::RENDERER_SKIA_VK, READBACK_BITMAP},
+#endif
+};
+
+INSTANTIATE_TEST_SUITE_P(,
+ LayerTreeHostReadbackPixelTest,
+ ::testing::ValuesIn(kTestConfigs));
+
+// TODO(crbug.com/974283): These tests are crashing with vulkan when TSan or
+// MSan are used.
+ReadbackTestConfig const kMaybeVulkanTestConfigs[] = {
+ ReadbackTestConfig{LayerTreeTest::RENDERER_SOFTWARE, READBACK_BITMAP},
+ ReadbackTestConfig{LayerTreeTest::RENDERER_GL, READBACK_TEXTURE},
+ ReadbackTestConfig{LayerTreeTest::RENDERER_GL, READBACK_BITMAP},
+ ReadbackTestConfig{LayerTreeTest::RENDERER_SKIA_GL, READBACK_TEXTURE},
+ ReadbackTestConfig{LayerTreeTest::RENDERER_SKIA_GL, READBACK_BITMAP},
+#if defined(ENABLE_CC_VULKAN_TESTS) && !defined(THREAD_SANITIZER) && \
+ !defined(MEMORY_SANITIZER)
+ ReadbackTestConfig{LayerTreeTest::RENDERER_SKIA_VK, READBACK_BITMAP},
+#endif
+};
+
+INSTANTIATE_TEST_SUITE_P(,
+ LayerTreeHostReadbackPixelTestMaybeVulkan,
+ ::testing::ValuesIn(kMaybeVulkanTestConfigs));
class LayerTreeHostReadbackDeviceScalePixelTest
: public LayerTreeHostReadbackPixelTest {
@@ -434,11 +460,6 @@ class LayerTreeHostReadbackDeviceScalePixelTest
green_client_(SK_ColorGREEN, gfx::Size(200, 200)),
blue_client_(SK_ColorBLUE, gfx::Size(200, 200)) {}
- void InitializeSettings(LayerTreeSettings* settings) override {
- // Cause the device scale factor to be inherited by contents scales.
- settings->layer_transforms_should_scale_layer_contents = true;
- }
-
void SetupTree() override {
SetInitialDeviceScaleFactor(device_scale_factor_);
LayerTreePixelTest::SetupTree();
@@ -510,15 +531,9 @@ TEST_P(LayerTreeHostReadbackDeviceScalePixelTest, ReadbackNonRootLayerSubrect) {
base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
}
-INSTANTIATE_TEST_SUITE_P(
- ,
- LayerTreeHostReadbackDeviceScalePixelTest,
- ::testing::Values(
- ReadbackTestConfig(LayerTreeTest::RENDERER_SOFTWARE, READBACK_BITMAP),
- ReadbackTestConfig(LayerTreeTest::RENDERER_GL, READBACK_TEXTURE),
- ReadbackTestConfig(LayerTreeTest::RENDERER_GL, READBACK_BITMAP),
- ReadbackTestConfig(LayerTreeTest::RENDERER_SKIA_GL, READBACK_BITMAP),
- ReadbackTestConfig(LayerTreeTest::RENDERER_SKIA_GL, READBACK_TEXTURE)));
+INSTANTIATE_TEST_SUITE_P(,
+ LayerTreeHostReadbackDeviceScalePixelTest,
+ ::testing::ValuesIn(kTestConfigs));
class LayerTreeHostReadbackColorSpacePixelTest
: public LayerTreeHostReadbackPixelTest {
@@ -528,17 +543,17 @@ class LayerTreeHostReadbackColorSpacePixelTest
output_color_space_ = gfx::ColorSpace::CreateDisplayP3D65();
}
- std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
+ std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
const viz::RendererSettings& renderer_settings,
double refresh_rate,
scoped_refptr<viz::ContextProvider> compositor_context_provider,
scoped_refptr<viz::RasterContextProvider> worker_context_provider)
override {
- std::unique_ptr<viz::TestLayerTreeFrameSink> frame_sink =
+ std::unique_ptr<TestLayerTreeFrameSink> frame_sink =
LayerTreePixelTest::CreateLayerTreeFrameSink(
renderer_settings, refresh_rate, compositor_context_provider,
worker_context_provider);
- frame_sink->SetDisplayColorSpace(output_color_space_, output_color_space_);
+ frame_sink->SetDisplayColorSpace(output_color_space_);
return frame_sink;
}
@@ -556,15 +571,9 @@ TEST_P(LayerTreeHostReadbackColorSpacePixelTest, Readback) {
base::FilePath(FILE_PATH_LITERAL("srgb_green_in_p3.png")));
}
-INSTANTIATE_TEST_SUITE_P(
- ,
- LayerTreeHostReadbackColorSpacePixelTest,
- ::testing::Values(
- ReadbackTestConfig(LayerTreeTest::RENDERER_SOFTWARE, READBACK_BITMAP),
- ReadbackTestConfig(LayerTreeTest::RENDERER_GL, READBACK_TEXTURE),
- ReadbackTestConfig(LayerTreeTest::RENDERER_GL, READBACK_BITMAP),
- ReadbackTestConfig(LayerTreeTest::RENDERER_SKIA_GL, READBACK_BITMAP),
- ReadbackTestConfig(LayerTreeTest::RENDERER_SKIA_GL, READBACK_TEXTURE)));
+INSTANTIATE_TEST_SUITE_P(,
+ LayerTreeHostReadbackColorSpacePixelTest,
+ ::testing::ValuesIn(kTestConfigs));
} // namespace
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc b/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc
index 8955987ba23..b271f513c0c 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc
@@ -13,8 +13,8 @@
#include "cc/paint/paint_flags.h"
#include "cc/test/layer_tree_pixel_test.h"
#include "cc/test/pixel_comparator.h"
-#include "cc/test/test_in_process_context_provider.h"
#include "cc/trees/layer_tree_impl.h"
+#include "components/viz/test/test_in_process_context_provider.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#if !defined(OS_ANDROID)
@@ -30,10 +30,6 @@ class LayerTreeHostScrollbarsPixelTest
RendererType renderer_type() { return GetParam(); }
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->layer_transforms_should_scale_layer_contents = true;
- }
-
void SetupTree() override {
SetInitialDeviceScaleFactor(device_scale_factor_);
LayerTreePixelTest::SetupTree();
@@ -89,10 +85,17 @@ class PaintedScrollbar : public Scrollbar {
gfx::Rect rect_;
};
+LayerTreeTest::RendererType const kRendererTypes[] = {
+ LayerTreeTest::RENDERER_GL,
+ LayerTreeTest::RENDERER_SKIA_GL,
+#if defined(ENABLE_CC_VULKAN_TESTS)
+ LayerTreeTest::RENDERER_SKIA_VK,
+#endif
+};
+
INSTANTIATE_TEST_SUITE_P(,
LayerTreeHostScrollbarsPixelTest,
- ::testing::Values(LayerTreeTest::RENDERER_GL,
- LayerTreeTest::RENDERER_SKIA_GL));
+ ::testing::ValuesIn(kRendererTypes));
TEST_P(LayerTreeHostScrollbarsPixelTest, NoScale) {
scoped_refptr<SolidColorLayer> background =
@@ -167,9 +170,9 @@ TEST_P(LayerTreeHostScrollbarsPixelTest, MAYBE_HugeTransformScale) {
layer->SetBounds(gfx::Size(10, 400));
background->AddChild(layer);
- scoped_refptr<TestInProcessContextProvider> context(
- new TestInProcessContextProvider(/*enable_oop_rasterization=*/false,
- /*support_locking=*/false));
+ auto context = base::MakeRefCounted<viz::TestInProcessContextProvider>(
+ /*enable_oop_rasterization=*/false,
+ /*support_locking=*/false);
gpu::ContextResult result = context->BindToCurrentThread();
DCHECK_EQ(result, gpu::ContextResult::kSuccess);
int max_texture_size = 0;
@@ -189,7 +192,8 @@ TEST_P(LayerTreeHostScrollbarsPixelTest, MAYBE_HugeTransformScale) {
scale_transform.Scale(scale, scale);
layer->SetTransform(scale_transform);
- if (renderer_type() == RENDERER_SKIA_GL)
+ if (renderer_type() == RENDERER_SKIA_GL ||
+ renderer_type() == RENDERER_SKIA_VK)
pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(true);
RunPixelTest(renderer_type(), background,
@@ -256,8 +260,7 @@ class PaintedOverlayScrollbar : public PaintedScrollbar {
INSTANTIATE_TEST_SUITE_P(,
LayerTreeHostOverlayScrollbarsPixelTest,
- ::testing::Values(LayerTreeTest::RENDERER_GL,
- LayerTreeTest::RENDERER_SKIA_GL));
+ ::testing::ValuesIn(kRendererTypes));
// Simulate increasing the thickness of a painted overlay scrollbar. Ensure that
// the scrollbar border remains crisp.
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc b/chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc
index fac28b34708..708eefad33a 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc
@@ -54,10 +54,17 @@ class LayerTreeHostSynchronousPixelTest
bool use_zero_copy_ = false;
};
+LayerTreeTest::RendererType const kRendererTypesGpu[] = {
+ LayerTreeTest::RENDERER_GL,
+ LayerTreeTest::RENDERER_SKIA_GL,
+#if defined(ENABLE_CC_VULKAN_TESTS)
+ LayerTreeTest::RENDERER_SKIA_VK,
+#endif
+};
+
INSTANTIATE_TEST_SUITE_P(,
LayerTreeHostSynchronousPixelTest,
- ::testing::Values(LayerTreeTest::RENDERER_GL,
- LayerTreeTest::RENDERER_SKIA_GL));
+ ::testing::ValuesIn(kRendererTypesGpu));
TEST_P(LayerTreeHostSynchronousPixelTest, OneContentLayerZeroCopy) {
use_zero_copy_ = true;
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc
index ad22f279d6a..0da4873f16f 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc
@@ -11,8 +11,8 @@
#include "cc/paint/paint_flags.h"
#include "cc/paint/paint_op_buffer.h"
#include "cc/test/layer_tree_pixel_test.h"
+#include "cc/test/test_layer_tree_frame_sink.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
-#include "components/viz/test/test_layer_tree_frame_sink.h"
#include "gpu/command_buffer/client/raster_interface.h"
#if !defined(OS_ANDROID)
@@ -172,15 +172,21 @@ class LayerTreeHostTilesTestPartialInvalidation
scoped_refptr<PictureLayer> picture_layer_;
};
-INSTANTIATE_TEST_SUITE_P(
- ,
- LayerTreeHostTilesTestPartialInvalidation,
- ::testing::Values(TilesTestConfig{LayerTreeTest::RENDERER_SOFTWARE, BITMAP},
- TilesTestConfig{LayerTreeTest::RENDERER_GL, ONE_COPY},
- TilesTestConfig{LayerTreeTest::RENDERER_GL, GPU},
- TilesTestConfig{LayerTreeTest::RENDERER_SKIA_GL,
- ONE_COPY},
- TilesTestConfig{LayerTreeTest::RENDERER_SKIA_GL, GPU}));
+std::vector<TilesTestConfig> const kTestCases = {
+ {LayerTreeTest::RENDERER_SOFTWARE, BITMAP},
+ {LayerTreeTest::RENDERER_GL, ONE_COPY},
+ {LayerTreeTest::RENDERER_GL, GPU},
+ {LayerTreeTest::RENDERER_SKIA_GL, ONE_COPY},
+ {LayerTreeTest::RENDERER_SKIA_GL, GPU},
+#if defined(ENABLE_CC_VULKAN_TESTS)
+ {LayerTreeTest::RENDERER_SKIA_VK, ONE_COPY},
+ {LayerTreeTest::RENDERER_SKIA_VK, GPU},
+#endif
+};
+
+INSTANTIATE_TEST_SUITE_P(,
+ LayerTreeHostTilesTestPartialInvalidation,
+ ::testing::ValuesIn(kTestCases));
TEST_P(LayerTreeHostTilesTestPartialInvalidation, PartialRaster) {
use_partial_raster_ = true;
@@ -195,15 +201,20 @@ TEST_P(LayerTreeHostTilesTestPartialInvalidation, FullRaster) {
base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png")));
}
+std::vector<TilesTestConfig> const kTestCasesMultiThread = {
+ {LayerTreeTest::RENDERER_GL, ONE_COPY},
+ {LayerTreeTest::RENDERER_SKIA_GL, ONE_COPY},
+#if defined(ENABLE_CC_VULKAN_TESTS)
+ {LayerTreeTest::RENDERER_SKIA_VK, ONE_COPY},
+#endif
+};
+
using LayerTreeHostTilesTestPartialInvalidationMultiThread =
LayerTreeHostTilesTestPartialInvalidation;
-INSTANTIATE_TEST_SUITE_P(
- ,
- LayerTreeHostTilesTestPartialInvalidationMultiThread,
- ::testing::Values(TilesTestConfig{LayerTreeTest::RENDERER_GL, ONE_COPY},
- TilesTestConfig{LayerTreeTest::RENDERER_SKIA_GL,
- ONE_COPY}));
+INSTANTIATE_TEST_SUITE_P(,
+ LayerTreeHostTilesTestPartialInvalidationMultiThread,
+ ::testing::ValuesIn(kTestCasesMultiThread));
// Flaky on Linux TSAN. https://crbug.com/707711
#if defined(OS_LINUX) && defined(THREAD_SANITIZER)
@@ -227,6 +238,7 @@ TEST_P(LayerTreeHostTilesTestPartialInvalidationMultiThread, FullRaster) {
using LayerTreeHostTilesTestPartialInvalidationLowBitDepth =
LayerTreeHostTilesTestPartialInvalidation;
+// TODO(crbug.com/963446): Enable these tests for Vulkan.
INSTANTIATE_TEST_SUITE_P(
,
LayerTreeHostTilesTestPartialInvalidationLowBitDepth,
diff --git a/chromium/cc/trees/layer_tree_host_unittest.cc b/chromium/cc/trees/layer_tree_host_unittest.cc
index f10dada2a20..023517fc874 100644
--- a/chromium/cc/trees/layer_tree_host_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest.cc
@@ -47,6 +47,7 @@
#include "cc/test/push_properties_counting_layer_impl.h"
#include "cc/test/render_pass_test_utils.h"
#include "cc/test/skia_common.h"
+#include "cc/test/test_layer_tree_frame_sink.h"
#include "cc/trees/clip_node.h"
#include "cc/trees/effect_node.h"
#include "cc/trees/frame_rate_counter.h"
@@ -69,7 +70,6 @@
#include "components/viz/test/begin_frame_args_test.h"
#include "components/viz/test/fake_output_surface.h"
#include "components/viz/test/test_gles2_interface.h"
-#include "components/viz/test/test_layer_tree_frame_sink.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/khronos/GLES2/gl2.h"
@@ -501,7 +501,7 @@ SINGLE_THREAD_TEST_F(LayerTreeHostTestReadyToDrawVisibility);
class LayerTreeHostContextCacheTest : public LayerTreeHostTest {
public:
- std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
+ std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
const viz::RendererSettings& renderer_settings,
double refresh_rate,
scoped_refptr<viz::ContextProvider> compositor_context_provider,
@@ -2468,10 +2468,6 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterDeviceSizeChanged);
class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest {
public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->layer_transforms_should_scale_layer_contents = true;
- }
-
void SetupTree() override {
root_layer_ = Layer::Create();
root_layer_->SetBounds(gfx::Size(10, 20));
@@ -2519,10 +2515,6 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate);
class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate
: public LayerTreeHostTest {
public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->layer_transforms_should_scale_layer_contents = true;
- }
-
void SetupTree() override {
root_layer_ = Layer::Create();
root_layer_->SetBounds(gfx::Size(10, 20));
@@ -2578,10 +2570,6 @@ SINGLE_AND_MULTI_THREAD_TEST_F(
class LayerTreeHostTestDeviceScaleFactorChange : public LayerTreeHostTest {
public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->layer_transforms_should_scale_layer_contents = true;
- }
-
void SetupTree() override {
root_layer_ = Layer::Create();
root_layer_->SetBounds(gfx::Size(10, 20));
@@ -4006,25 +3994,25 @@ class LayerTreeHostTestLCDChange : public LayerTreeHostTest {
// The first draw.
EXPECT_EQ(1, num_tiles_rastered_);
EXPECT_TRUE(can_use_lcd_text);
- EXPECT_TRUE(root_layer->RasterSourceUsesLCDTextForTesting());
+ EXPECT_TRUE(root_layer->can_use_lcd_text());
break;
case 1:
// Nothing changed on the layer.
EXPECT_EQ(1, num_tiles_rastered_);
EXPECT_TRUE(can_use_lcd_text);
- EXPECT_TRUE(root_layer->RasterSourceUsesLCDTextForTesting());
+ EXPECT_TRUE(root_layer->can_use_lcd_text());
break;
case 2:
// LCD text was disabled; it should be re-rastered with LCD text off.
EXPECT_EQ(2, num_tiles_rastered_);
EXPECT_FALSE(can_use_lcd_text);
- EXPECT_FALSE(root_layer->RasterSourceUsesLCDTextForTesting());
+ EXPECT_FALSE(root_layer->can_use_lcd_text());
break;
case 3:
// LCD text was enabled, but it's sticky and stays off.
EXPECT_EQ(2, num_tiles_rastered_);
EXPECT_TRUE(can_use_lcd_text);
- EXPECT_FALSE(root_layer->RasterSourceUsesLCDTextForTesting());
+ EXPECT_FALSE(root_layer->can_use_lcd_text());
break;
}
}
@@ -4106,7 +4094,7 @@ class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest {
int commit_complete_count_;
};
-class OnDrawLayerTreeFrameSink : public viz::TestLayerTreeFrameSink {
+class OnDrawLayerTreeFrameSink : public TestLayerTreeFrameSink {
public:
OnDrawLayerTreeFrameSink(
scoped_refptr<viz::ContextProvider> compositor_context_provider,
@@ -4148,7 +4136,7 @@ class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor
settings->using_synchronous_renderer_compositor = true;
}
- std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
+ std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
const viz::RendererSettings& renderer_settings,
double refresh_rate,
scoped_refptr<viz::ContextProvider> compositor_context_provider,
@@ -4406,37 +4394,36 @@ class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest {
// The scrollbar layer always needs to be pushed.
if (root_->layer_tree_host()) {
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
root_->layer_tree_host()->LayersThatShouldPushProperties(),
root_.get()));
}
if (child2_->layer_tree_host()) {
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
child2_->layer_tree_host()->LayersThatShouldPushProperties(),
child2_.get()));
}
if (leaf_always_pushing_layer_->layer_tree_host()) {
leaf_always_pushing_layer_->SetNeedsPushProperties();
- EXPECT_TRUE(
- base::ContainsKey(leaf_always_pushing_layer_->layer_tree_host()
- ->LayersThatShouldPushProperties(),
- leaf_always_pushing_layer_.get()));
+ EXPECT_TRUE(base::Contains(leaf_always_pushing_layer_->layer_tree_host()
+ ->LayersThatShouldPushProperties(),
+ leaf_always_pushing_layer_.get()));
}
// child_ and grandchild_ don't persist their need to push properties.
if (child_->layer_tree_host()) {
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
child_->layer_tree_host()->LayersThatShouldPushProperties(),
child_.get()));
}
if (grandchild_->layer_tree_host()) {
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
grandchild_->layer_tree_host()->LayersThatShouldPushProperties(),
grandchild_.get()));
}
if (other_root_->layer_tree_host()) {
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
other_root_->layer_tree_host()->LayersThatShouldPushProperties(),
other_root_.get()));
}
@@ -4789,9 +4776,9 @@ class LayerTreeHostTestPropertyChangesDuringUpdateArePushed
scrollbar_layer_->SetBounds(gfx::Size(30, 30));
- EXPECT_TRUE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- scrollbar_layer_.get()));
+ EXPECT_TRUE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ scrollbar_layer_.get()));
layer_tree_host()->SetNeedsCommit();
scrollbar_layer_->reset_push_properties_count();
@@ -4835,9 +4822,9 @@ class LayerTreeHostTestSetDrawableCausesCommit : public LayerTreeHostTest {
// avoid causing a second commit to be scheduled. If a property change
// is made during this, however, it needs to be pushed in the upcoming
// commit.
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
EXPECT_EQ(0, root_->NumDescendantsThatDrawContent());
root_->reset_push_properties_count();
@@ -4846,18 +4833,18 @@ class LayerTreeHostTestSetDrawableCausesCommit : public LayerTreeHostTest {
EXPECT_EQ(1, root_->NumDescendantsThatDrawContent());
EXPECT_EQ(0u, root_->push_properties_count());
EXPECT_EQ(0u, child_->push_properties_count());
- EXPECT_TRUE(base::ContainsKey(
+ EXPECT_TRUE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
- EXPECT_TRUE(base::ContainsKey(
+ EXPECT_TRUE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
break;
}
case 2:
EXPECT_EQ(1u, root_->push_properties_count());
EXPECT_EQ(1u, child_->push_properties_count());
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
EndTest();
break;
@@ -4925,19 +4912,19 @@ class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush
case 0:
// All layers will need push properties as we set their layer tree host
layer_tree_host()->SetRootLayer(root_);
- EXPECT_TRUE(base::ContainsKey(
+ EXPECT_TRUE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
- EXPECT_TRUE(base::ContainsKey(
+ EXPECT_TRUE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
- EXPECT_TRUE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild1_.get()));
- EXPECT_TRUE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild2_.get()));
- EXPECT_TRUE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild3_.get()));
+ EXPECT_TRUE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild1_.get()));
+ EXPECT_TRUE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild2_.get()));
+ EXPECT_TRUE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild3_.get()));
break;
case 1:
EndTest();
@@ -4958,81 +4945,81 @@ class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion
layer_tree_host()->SetRootLayer(root_);
break;
case 1:
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
- EXPECT_FALSE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild1_.get()));
- EXPECT_FALSE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild2_.get()));
- EXPECT_FALSE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild3_.get()));
+ EXPECT_FALSE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild1_.get()));
+ EXPECT_FALSE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild2_.get()));
+ EXPECT_FALSE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild3_.get()));
grandchild1_->RemoveFromParent();
grandchild1_->SetPosition(gfx::PointF(1.f, 1.f));
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
- EXPECT_FALSE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild2_.get()));
- EXPECT_FALSE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild3_.get()));
+ EXPECT_FALSE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild2_.get()));
+ EXPECT_FALSE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild3_.get()));
child_->AddChild(grandchild1_);
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
- EXPECT_TRUE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild1_.get()));
- EXPECT_FALSE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild2_.get()));
- EXPECT_FALSE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild3_.get()));
+ EXPECT_TRUE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild1_.get()));
+ EXPECT_FALSE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild2_.get()));
+ EXPECT_FALSE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild3_.get()));
grandchild2_->SetPosition(gfx::PointF(1.f, 1.f));
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
- EXPECT_TRUE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild1_.get()));
- EXPECT_TRUE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild2_.get()));
- EXPECT_FALSE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild3_.get()));
+ EXPECT_TRUE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild1_.get()));
+ EXPECT_TRUE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild2_.get()));
+ EXPECT_FALSE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild3_.get()));
// grandchild2_ will still need a push properties.
grandchild1_->RemoveFromParent();
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
// grandchild3_ does not need a push properties, so recursing should
// no longer be needed.
grandchild2_->RemoveFromParent();
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
EndTest();
break;
@@ -5057,35 +5044,35 @@ class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence
layer_tree_host()->SetRootLayer(root_);
break;
case 1:
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
- EXPECT_TRUE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild1_.get()));
- EXPECT_TRUE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild2_.get()));
- EXPECT_FALSE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild3_.get()));
+ EXPECT_TRUE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild1_.get()));
+ EXPECT_TRUE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild2_.get()));
+ EXPECT_FALSE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild3_.get()));
// grandchild2_ will still need a push properties.
grandchild1_->RemoveFromParent();
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
// grandchild3_ does not need a push properties, so recursing should
// no longer be needed.
grandchild2_->RemoveFromParent();
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
EndTest();
break;
@@ -5106,19 +5093,19 @@ class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree
layer_tree_host()->SetRootLayer(root_);
break;
case 1:
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
- EXPECT_FALSE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild1_.get()));
- EXPECT_FALSE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild2_.get()));
- EXPECT_FALSE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild3_.get()));
+ EXPECT_FALSE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild1_.get()));
+ EXPECT_FALSE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild2_.get()));
+ EXPECT_FALSE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild3_.get()));
// Change grandchildren while their parent is not in the tree.
child_->RemoveFromParent();
@@ -5126,39 +5113,39 @@ class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree
grandchild2_->SetPosition(gfx::PointF(1.f, 1.f));
root_->AddChild(child_);
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
- EXPECT_TRUE(base::ContainsKey(
+ EXPECT_TRUE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
- EXPECT_TRUE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild1_.get()));
- EXPECT_TRUE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild2_.get()));
- EXPECT_TRUE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild3_.get()));
+ EXPECT_TRUE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild1_.get()));
+ EXPECT_TRUE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild2_.get()));
+ EXPECT_TRUE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild3_.get()));
grandchild1_->RemoveFromParent();
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
- EXPECT_TRUE(base::ContainsKey(
+ EXPECT_TRUE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
grandchild2_->RemoveFromParent();
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
- EXPECT_TRUE(base::ContainsKey(
+ EXPECT_TRUE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
grandchild3_->RemoveFromParent();
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
- EXPECT_TRUE(base::ContainsKey(
+ EXPECT_TRUE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
EndTest();
@@ -5180,55 +5167,55 @@ class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild
layer_tree_host()->SetRootLayer(root_);
break;
case 1:
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
- EXPECT_FALSE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild1_.get()));
- EXPECT_FALSE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild2_.get()));
- EXPECT_FALSE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild3_.get()));
+ EXPECT_FALSE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild1_.get()));
+ EXPECT_FALSE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild2_.get()));
+ EXPECT_FALSE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild3_.get()));
child_->SetPosition(gfx::PointF(1.f, 1.f));
grandchild1_->SetPosition(gfx::PointF(1.f, 1.f));
grandchild2_->SetPosition(gfx::PointF(1.f, 1.f));
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
- EXPECT_TRUE(base::ContainsKey(
+ EXPECT_TRUE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
- EXPECT_TRUE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild1_.get()));
- EXPECT_TRUE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild2_.get()));
- EXPECT_FALSE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild3_.get()));
+ EXPECT_TRUE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild1_.get()));
+ EXPECT_TRUE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild2_.get()));
+ EXPECT_FALSE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild3_.get()));
grandchild1_->RemoveFromParent();
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
- EXPECT_TRUE(base::ContainsKey(
+ EXPECT_TRUE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
grandchild2_->RemoveFromParent();
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
- EXPECT_TRUE(base::ContainsKey(
+ EXPECT_TRUE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
child_->RemoveFromParent();
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
EndTest();
@@ -5250,55 +5237,55 @@ class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent
layer_tree_host()->SetRootLayer(root_);
break;
case 1:
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
- EXPECT_FALSE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild1_.get()));
- EXPECT_FALSE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild2_.get()));
- EXPECT_FALSE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild3_.get()));
+ EXPECT_FALSE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild1_.get()));
+ EXPECT_FALSE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild2_.get()));
+ EXPECT_FALSE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild3_.get()));
grandchild1_->SetPosition(gfx::PointF(1.f, 1.f));
grandchild2_->SetPosition(gfx::PointF(1.f, 1.f));
child_->SetPosition(gfx::PointF(1.f, 1.f));
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
- EXPECT_TRUE(base::ContainsKey(
+ EXPECT_TRUE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
- EXPECT_TRUE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild1_.get()));
- EXPECT_TRUE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild2_.get()));
- EXPECT_FALSE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- grandchild3_.get()));
+ EXPECT_TRUE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild1_.get()));
+ EXPECT_TRUE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild2_.get()));
+ EXPECT_FALSE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ grandchild3_.get()));
grandchild1_->RemoveFromParent();
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
- EXPECT_TRUE(base::ContainsKey(
+ EXPECT_TRUE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
grandchild2_->RemoveFromParent();
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
- EXPECT_TRUE(base::ContainsKey(
+ EXPECT_TRUE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), child_.get()));
child_->RemoveFromParent();
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
layer_tree_host()->LayersThatShouldPushProperties(), root_.get()));
EndTest();
@@ -5460,9 +5447,9 @@ class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest {
switch (layer_tree_host()->SourceFrameNumber()) {
case 1:
// The layer type used does not need to push properties every frame.
- EXPECT_FALSE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- child_layer_.get()));
+ EXPECT_FALSE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ child_layer_.get()));
// Change the bounds of the child layer, but make it skipped
// by CalculateDrawProperties.
@@ -5471,9 +5458,9 @@ class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest {
break;
case 2:
// The bounds of the child layer were pushed to the impl side.
- EXPECT_FALSE(base::ContainsKey(
- layer_tree_host()->LayersThatShouldPushProperties(),
- child_layer_.get()));
+ EXPECT_FALSE(
+ base::Contains(layer_tree_host()->LayersThatShouldPushProperties(),
+ child_layer_.get()));
EndTest();
break;
@@ -6410,7 +6397,7 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestEmptyLayerGpuRasterization);
class LayerTreeHostWithGpuRasterizationTest : public LayerTreeHostTest {
protected:
- std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
+ std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
const viz::RendererSettings& renderer_settings,
double refresh_rate,
scoped_refptr<viz::ContextProvider> ignored_compositor_context_provider,
@@ -6939,7 +6926,7 @@ class LayerTreeHostTestSynchronousCompositeSwapPromise
settings->use_zero_copy = true;
}
- std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
+ std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
const viz::RendererSettings& renderer_settings,
double refresh_rate,
scoped_refptr<viz::ContextProvider> compositor_context_provider,
@@ -6949,7 +6936,7 @@ class LayerTreeHostTestSynchronousCompositeSwapPromise
bool synchronous_composite =
!HasImplThread() &&
!layer_tree_host()->GetSettings().single_thread_proxy_scheduler;
- return std::make_unique<viz::TestLayerTreeFrameSink>(
+ return std::make_unique<TestLayerTreeFrameSink>(
compositor_context_provider, std::move(worker_context_provider),
gpu_memory_buffer_manager(), renderer_settings, ImplThreadTaskRunner(),
synchronous_composite, disable_display_vsync, refresh_rate);
@@ -7807,7 +7794,7 @@ class LayerTreeTestPageScaleFlags : public LayerTreeTest {
layer->IsAffectedByPageScale()
? this->affected_by_page_scale_
: this->not_affected_by_page_scale_;
- EXPECT_TRUE(base::ContainsValue(list, layer->id()));
+ EXPECT_TRUE(base::Contains(list, layer->id()));
});
EndTest();
@@ -8179,7 +8166,7 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSubmitFrameMetadata);
class LayerTreeHostTestSubmitFrameResources : public LayerTreeHostTest {
protected:
- std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
+ std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
const viz::RendererSettings& renderer_settings,
double refresh_rate,
scoped_refptr<viz::ContextProvider> compositor_context_provider,
@@ -8248,33 +8235,6 @@ class LayerTreeHostTestSubmitFrameResources : public LayerTreeHostTest {
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSubmitFrameResources);
-// Ensure that content_source_id is propagated to the frame's metadata.
-class LayerTreeHostTestContentSourceId : public LayerTreeHostTest {
- protected:
- void BeginTest() override {
- layer_tree_host()->SetContentSourceId(5);
- PostSetNeedsCommitToMainThread();
- }
-
- DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
- LayerTreeHostImpl::FrameData* frame_data,
- DrawResult draw_result) override {
- EXPECT_EQ(DRAW_SUCCESS, draw_result);
- EXPECT_EQ(5U, host_impl->active_tree()->content_source_id());
- return draw_result;
- }
-
- void DisplayReceivedCompositorFrameOnThread(
- const viz::CompositorFrame& frame) override {
- EXPECT_EQ(5U, frame.metadata.content_source_id);
- EndTest();
- }
-
- void AfterTest() override {}
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestContentSourceId);
-
class LayerTreeHostTestBeginFrameAcks : public LayerTreeHostTest {
protected:
void BeginTest() override { PostSetNeedsCommitToMainThread(); }
diff --git a/chromium/cc/trees/layer_tree_host_unittest_animation.cc b/chromium/cc/trees/layer_tree_host_unittest_animation.cc
index 47a27fd67c8..d5a0aa983c0 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_animation.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_animation.cc
@@ -369,6 +369,15 @@ class LayerTreeHostAnimationTestAddKeyframeModelWithTimingFunction
if (host_impl->active_tree()->source_frame_number() != 0)
return;
+ // The impl thread may start a second frame before the test finishes. This
+ // can lead to a race as if the main thread has committed a new sync tree
+ // the impl thread can now delete the KeyframeModel as the animation only
+ // lasts a single frame and no longer affects either tree. Only test the
+ // first frame the animation shows up for.
+ if (!first_animation_frame_)
+ return;
+ first_animation_frame_ = false;
+
scoped_refptr<AnimationTimeline> timeline_impl =
GetImplAnimationHost(host_impl)->GetTimelineById(timeline_id_);
scoped_refptr<SingleKeyframeEffectAnimation> animation_child_impl =
@@ -397,6 +406,7 @@ class LayerTreeHostAnimationTestAddKeyframeModelWithTimingFunction
FakeContentLayerClient client_;
scoped_refptr<FakePictureLayer> picture_;
+ bool first_animation_frame_ = true;
};
SINGLE_AND_MULTI_THREAD_TEST_F(
@@ -712,13 +722,6 @@ class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
animation_child_->set_animation_delegate(this);
}
- void InitializeSettings(LayerTreeSettings* settings) override {
- // Make sure that drawing many times doesn't cause a checkerboarded
- // animation to start so we avoid flake in this test.
- settings->timeout_and_draw_when_animation_checkerboards = false;
- LayerTreeHostAnimationTest::InitializeSettings(settings);
- }
-
void BeginTest() override {
prevented_draw_ = 0;
started_times_ = 0;
diff --git a/chromium/cc/trees/layer_tree_host_unittest_capture_content.cc b/chromium/cc/trees/layer_tree_host_unittest_capture_content.cc
index 75f69a3cbef..1b6d70d9527 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_capture_content.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_capture_content.cc
@@ -12,44 +12,42 @@
namespace cc {
namespace {
-class FakeTextHolder : public TextHolder {
+class FakeTextHolder {
public:
- FakeTextHolder(const std::string& text, const gfx::Rect& rect)
- : text_(text), rect_(rect) {}
+ FakeTextHolder(const std::string& text, const gfx::Rect& rect, NodeId node_id)
+ : text_(text), rect_(rect), node_id_(node_id) {}
std::string text() const { return text_; }
gfx::Rect rect() const { return rect_; }
-
- protected:
- ~FakeTextHolder() override = default;
+ NodeId node_id() const { return node_id_; }
private:
std::string text_;
gfx::Rect rect_;
+ NodeId node_id_;
};
class FakeCaptureContentLayerClient : public FakeContentLayerClient {
public:
- void addTextHolder(scoped_refptr<FakeTextHolder> holder) {
+ void addTextHolder(const FakeTextHolder& holder) {
holders_.push_back(holder);
}
scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
PaintingControlSetting painting_control) override {
auto display_list = base::MakeRefCounted<DisplayItemList>();
- for (auto holder : holders_) {
+ for (auto& holder : holders_) {
display_list->StartPaint();
display_list->push<DrawTextBlobOp>(
- SkTextBlob::MakeFromString(holder->text().data(), SkFont()),
- holder->rect().x(), holder->rect().y(), PaintFlags(),
- NodeHolder(holder));
- display_list->EndPaintOfUnpaired(holder->rect());
+ SkTextBlob::MakeFromString(holder.text().data(), SkFont()),
+ holder.rect().x(), holder.rect().y(), holder.node_id(), PaintFlags());
+ display_list->EndPaintOfUnpaired(holder.rect());
}
display_list->Finalize();
return display_list;
}
private:
- std::vector<scoped_refptr<FakeTextHolder>> holders_;
+ std::vector<const FakeTextHolder> holders_;
};
// These tests are for LayerTreeHost::CaptureContent().
@@ -58,8 +56,7 @@ class LayerTreeHostCaptureContentTest : public LayerTreeTest {
~LayerTreeHostCaptureContentTest() override = default;
protected:
- LayerTreeHostCaptureContentTest()
- : device_bounds_(10, 10), weak_factory_(this) {}
+ LayerTreeHostCaptureContentTest() : device_bounds_(10, 10) {}
void BeginTest() override { PostSetNeedsCommitToMainThread(); }
@@ -78,17 +75,13 @@ class LayerTreeHostCaptureContentTest : public LayerTreeTest {
layer_tree_host()->SetViewportVisibleRect(gfx::Rect(device_bounds_));
}
- void VerifyCapturedContent(
- std::vector<scoped_refptr<FakeTextHolder>>* expected_result) {
+ void VerifyCapturedContent(std::vector<FakeTextHolder>* expected_result) {
EXPECT_EQ(expected_result->size(), captured_content_.size());
size_t expected_left_result = expected_result->size();
- for (auto c : captured_content_) {
- EXPECT_EQ(c.type, NodeHolder::Type::kTextHolder);
+ for (auto& c : captured_content_) {
for (auto it = expected_result->begin(); it != expected_result->end();
++it) {
- if (it->get() == c.text_holder.get()) {
- EXPECT_EQ(static_cast<FakeTextHolder*>(c.text_holder.get())->text(),
- it->get()->text());
+ if (it->node_id() == c) {
expected_result->erase(it);
break;
}
@@ -114,23 +107,23 @@ class LayerTreeHostCaptureContentTest : public LayerTreeTest {
}
scoped_refptr<FakePictureLayer> root_picture_layer_;
- std::vector<NodeHolder> captured_content_;
+ std::vector<NodeId> captured_content_;
const gfx::Size device_bounds_;
- base::WeakPtrFactory<LayerTreeHostCaptureContentTest> weak_factory_;
+ base::WeakPtrFactory<LayerTreeHostCaptureContentTest> weak_factory_{this};
};
class LayerTreeHostCaptureContentTestBasic
: public LayerTreeHostCaptureContentTest {
protected:
void SetupTextHolders(const gfx::Rect& rect1, const gfx::Rect& rect2) {
- text_holder_1_ = base::MakeRefCounted<FakeTextHolder>("Text1", rect1);
- client_.addTextHolder(text_holder_1_);
- text_holder_2_ = base::MakeRefCounted<FakeTextHolder>("Text2", rect2);
- client_.addTextHolder(text_holder_2_);
+ text_holder_1_ = std::make_unique<FakeTextHolder>("Text1", rect1, 1);
+ client_.addTextHolder(*text_holder_1_);
+ text_holder_2_ = std::make_unique<FakeTextHolder>("Text2", rect2, 2);
+ client_.addTextHolder(*text_holder_2_);
}
- scoped_refptr<FakeTextHolder> text_holder_1_;
- scoped_refptr<FakeTextHolder> text_holder_2_;
+ std::unique_ptr<FakeTextHolder> text_holder_1_;
+ std::unique_ptr<FakeTextHolder> text_holder_2_;
};
// Test that one DrawTextBlobOp is on-screen, another isn't.
@@ -144,8 +137,8 @@ class LayerTreeHostCaptureContentTestOneVisible
}
void AfterTest() override {
- std::vector<scoped_refptr<FakeTextHolder>> expected_result;
- expected_result.push_back(text_holder_1_);
+ std::vector<FakeTextHolder> expected_result;
+ expected_result.push_back(*text_holder_1_);
VerifyCapturedContent(&expected_result);
}
};
@@ -163,9 +156,9 @@ class LayerTreeHostCaptureContentTestTwoVisible
}
void AfterTest() override {
- std::vector<scoped_refptr<FakeTextHolder>> expected_result;
- expected_result.push_back(text_holder_1_);
- expected_result.push_back(text_holder_2_);
+ std::vector<FakeTextHolder> expected_result;
+ expected_result.push_back(*text_holder_1_);
+ expected_result.push_back(*text_holder_2_);
VerifyCapturedContent(&expected_result);
}
};
@@ -208,11 +201,11 @@ class LayerTreeHostCaptureContentTestTwoLayers
void SetupSecondaryPictureLayer(const gfx::Size& size) {
// Add text to layer.
text_holder_21_ =
- base::MakeRefCounted<FakeTextHolder>("Text21", gfx::Rect(0, 0, 10, 5));
- client2_.addTextHolder(text_holder_21_);
+ std::make_unique<FakeTextHolder>("Text21", gfx::Rect(0, 0, 10, 5), 21);
+ client2_.addTextHolder(*text_holder_21_);
text_holder_22_ =
- base::MakeRefCounted<FakeTextHolder>("Text22", gfx::Rect(0, 5, 10, 5));
- client2_.addTextHolder(text_holder_22_);
+ std::make_unique<FakeTextHolder>("Text22", gfx::Rect(0, 5, 10, 5), 22);
+ client2_.addTextHolder(*text_holder_22_);
client2_.set_bounds(size);
// Create layer.
@@ -223,8 +216,8 @@ class LayerTreeHostCaptureContentTestTwoLayers
}
scoped_refptr<FakePictureLayer> picture_layer;
- scoped_refptr<FakeTextHolder> text_holder_21_;
- scoped_refptr<FakeTextHolder> text_holder_22_;
+ std::unique_ptr<FakeTextHolder> text_holder_21_;
+ std::unique_ptr<FakeTextHolder> text_holder_22_;
FakeCaptureContentLayerClient client2_;
};
@@ -237,9 +230,9 @@ class LayerTreeHostCaptureContentTestOneLayerVisible
}
void AfterTest() override {
- std::vector<scoped_refptr<FakeTextHolder>> expected_result;
- expected_result.push_back(text_holder_1_);
- expected_result.push_back(text_holder_2_);
+ std::vector<FakeTextHolder> expected_result;
+ expected_result.push_back(*text_holder_1_);
+ expected_result.push_back(*text_holder_2_);
VerifyCapturedContent(&expected_result);
}
};
@@ -256,10 +249,10 @@ class LayerTreeHostCaptureContentTestTwoLayersVisible
}
void AfterTest() override {
- std::vector<scoped_refptr<FakeTextHolder>> expected_result;
- expected_result.push_back(text_holder_1_);
- expected_result.push_back(text_holder_2_);
- expected_result.push_back(text_holder_21_);
+ std::vector<FakeTextHolder> expected_result;
+ expected_result.push_back(*text_holder_1_);
+ expected_result.push_back(*text_holder_2_);
+ expected_result.push_back(*text_holder_21_);
VerifyCapturedContent(&expected_result);
}
};
@@ -274,10 +267,10 @@ class LayerTreeHostCaptureContentTestTwoLayersVisibleAndTransparent
void AfterTest() override {
// All 3 TextHolders are returned.
- std::vector<scoped_refptr<FakeTextHolder>> expected_result;
- expected_result.push_back(text_holder_1_);
- expected_result.push_back(text_holder_2_);
- expected_result.push_back(text_holder_21_);
+ std::vector<FakeTextHolder> expected_result;
+ expected_result.push_back(*text_holder_1_);
+ expected_result.push_back(*text_holder_2_);
+ expected_result.push_back(*text_holder_21_);
VerifyCapturedContent(&expected_result);
}
};
@@ -295,11 +288,11 @@ class LayerTreeHostCaptureContentTestUpperLayerPartialOverlay
}
void AfterTest() override {
- std::vector<scoped_refptr<FakeTextHolder>> expected_result;
- expected_result.push_back(text_holder_1_);
- expected_result.push_back(text_holder_2_);
- expected_result.push_back(text_holder_21_);
- expected_result.push_back(text_holder_22_);
+ std::vector<FakeTextHolder> expected_result;
+ expected_result.push_back(*text_holder_1_);
+ expected_result.push_back(*text_holder_2_);
+ expected_result.push_back(*text_holder_21_);
+ expected_result.push_back(*text_holder_22_);
VerifyCapturedContent(&expected_result);
}
};
diff --git a/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc b/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc
index 5ad5e2a6977..dfdecdb3ef6 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc
@@ -7,11 +7,11 @@
#include "cc/test/fake_picture_layer.h"
#include "cc/test/layer_tree_test.h"
#include "cc/test/skia_common.h"
+#include "cc/test/test_layer_tree_frame_sink.h"
#include "cc/trees/layer_tree_impl.h"
#include "components/ukm/test_ukm_recorder.h"
#include "components/viz/test/begin_frame_args_test.h"
#include "components/viz/test/fake_external_begin_frame_source.h"
-#include "components/viz/test/test_layer_tree_frame_sink.h"
namespace cc {
namespace {
diff --git a/chromium/cc/trees/layer_tree_host_unittest_context.cc b/chromium/cc/trees/layer_tree_host_unittest_context.cc
index a06f23dc57f..b658d15f6fe 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_context.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_context.cc
@@ -29,6 +29,7 @@
#include "cc/test/fake_video_frame_provider.h"
#include "cc/test/layer_tree_test.h"
#include "cc/test/render_pass_test_utils.h"
+#include "cc/test/test_layer_tree_frame_sink.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/layer_tree_host_impl.h"
#include "cc/trees/layer_tree_impl.h"
@@ -38,7 +39,6 @@
#include "components/viz/test/fake_output_surface.h"
#include "components/viz/test/test_context_provider.h"
#include "components/viz/test/test_gles2_interface.h"
-#include "components/viz/test/test_layer_tree_frame_sink.h"
#include "components/viz/test/test_shared_bitmap_manager.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/raster_interface.h"
@@ -85,7 +85,7 @@ class LayerTreeHostContextTest : public LayerTreeTest {
gl_ = nullptr;
}
- std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
+ std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
const viz::RendererSettings& renderer_settings,
double refresh_rate,
scoped_refptr<viz::ContextProvider> compositor_context_provider,
@@ -1682,7 +1682,7 @@ SINGLE_AND_MULTI_THREAD_TEST_F(TileResourceFreedIfLostWhileExported);
class SoftwareTileResourceFreedIfLostWhileExported : public LayerTreeTest {
protected:
- std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
+ std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
const viz::RendererSettings& renderer_settings,
double refresh_rate,
scoped_refptr<viz::ContextProvider> compositor_context_provider,
diff --git a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
index 5bac6e88f25..3f335e7d9d5 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
@@ -13,6 +13,7 @@
#include "cc/test/fake_content_layer_client.h"
#include "cc/test/fake_picture_layer.h"
#include "cc/test/layer_tree_test.h"
+#include "cc/test/test_layer_tree_frame_sink.h"
#include "cc/trees/layer_tree_impl.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/copy_output_result.h"
@@ -20,7 +21,6 @@
#include "components/viz/test/fake_output_surface.h"
#include "components/viz/test/fake_skia_output_surface.h"
#include "components/viz/test/test_gles2_interface.h"
-#include "components/viz/test/test_layer_tree_frame_sink.h"
#include "gpu/GLES2/gl2extchromium.h"
namespace cc {
@@ -514,7 +514,7 @@ class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest
client_.set_bounds(root_->bounds());
}
- std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
+ std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
const viz::RendererSettings& renderer_settings,
double refresh_rate,
scoped_refptr<viz::ContextProvider> compositor_context_provider,
@@ -589,7 +589,7 @@ class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest
viz::RenderPassId parent_render_pass_id = 0;
viz::RenderPassId copy_layer_render_pass_id = 0;
- viz::TestLayerTreeFrameSink* frame_sink_ = nullptr;
+ TestLayerTreeFrameSink* frame_sink_ = nullptr;
bool did_swap_ = false;
FakeContentLayerClient client_;
scoped_refptr<FakePictureLayer> root_;
@@ -671,10 +671,6 @@ TEST_P(LayerTreeHostCopyRequestTestClippedOut, Test) {
class LayerTreeHostCopyRequestTestScaledLayer
: public LayerTreeHostCopyRequestTest {
protected:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->layer_transforms_should_scale_layer_contents = true;
- }
-
void SetupTree() override {
root_ = Layer::Create();
root_->SetBounds(gfx::Size(20, 20));
diff --git a/chromium/cc/trees/layer_tree_host_unittest_masks.cc b/chromium/cc/trees/layer_tree_host_unittest_masks.cc
index b0a8b0c9ac2..3870aba8671 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_masks.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_masks.cc
@@ -50,7 +50,7 @@ class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin
gfx::Size mask_size(100, 100);
mask_layer->SetBounds(mask_size);
- mask_layer->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK);
+ mask_layer->SetLayerMaskType(Layer::LayerMaskType::SINGLE_TEXTURE_MASK);
mask_layer_id_ = mask_layer->id();
layer_tree_host()->SetRootLayer(root);
@@ -89,21 +89,9 @@ class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin
render_pass_quad->rect);
EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
rect_in_target_space.ToString());
- if (host_impl->settings().enable_mask_tiling) {
- PictureLayerImpl* mask_layer_impl = static_cast<PictureLayerImpl*>(
- host_impl->active_tree()->LayerById(mask_layer_id_));
- gfx::SizeF texture_size(
- mask_layer_impl->CalculateTileSize(mask_layer_impl->bounds()));
- EXPECT_EQ(
- gfx::RectF(50.f / texture_size.width(), 50.f / texture_size.height(),
- 50.f / texture_size.width(), 50.f / texture_size.height())
- .ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- } else {
- EXPECT_EQ(gfx::ScaleRect(gfx::RectF(50.f, 50.f, 50.f, 50.f), 1.f / 100.f)
- .ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- }
+ EXPECT_EQ(gfx::ScaleRect(gfx::RectF(50.f, 50.f, 50.f, 50.f), 1.f / 100.f)
+ .ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
EndTest();
return draw_result;
}
@@ -114,27 +102,8 @@ class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin
FakeContentLayerClient client_;
};
-class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin_Untiled
- : public LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin {
- public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->enable_mask_tiling = false;
- }
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(
- LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin_Untiled);
-
-class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin_Tiled
- : public LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin {
- public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->enable_mask_tiling = true;
- }
-};
-
SINGLE_AND_MULTI_THREAD_TEST_F(
- LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin_Tiled);
+ LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin);
class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest {
protected:
@@ -191,7 +160,7 @@ class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest {
gfx::Size mask_size(50, 50);
mask_layer->SetBounds(mask_size);
- mask_layer->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK);
+ mask_layer->SetLayerMaskType(Layer::LayerMaskType::SINGLE_TEXTURE_MASK);
mask_layer_id_ = mask_layer->id();
layer_tree_host()->SetRootLayer(root);
@@ -226,21 +195,9 @@ class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest {
// coords in the mask are scaled by 10/50 and 20/50.
// The surface is clipped to (20,10) so the mask texture coords are offset
// by 20/50 and 10/50
- if (host_impl->settings().enable_mask_tiling) {
- PictureLayerImpl* mask_layer_impl = static_cast<PictureLayerImpl*>(
- host_impl->active_tree()->LayerById(mask_layer_id_));
- gfx::SizeF texture_size(
- mask_layer_impl->CalculateTileSize(mask_layer_impl->bounds()));
- EXPECT_EQ(
- gfx::RectF(20.f / texture_size.width(), 10.f / texture_size.height(),
- 10.f / texture_size.width(), 20.f / texture_size.height())
- .ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- } else {
- EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), 1.f / 50.f)
- .ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- }
+ EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), 1.f / 50.f)
+ .ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
EndTest();
return draw_result;
}
@@ -251,27 +208,8 @@ class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest {
FakeContentLayerClient client_;
};
-class LayerTreeTestMaskLayerForSurfaceWithClippedLayer_Untiled
- : public LayerTreeTestMaskLayerForSurfaceWithClippedLayer {
- public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->enable_mask_tiling = false;
- }
-};
-
SINGLE_AND_MULTI_THREAD_TEST_F(
- LayerTreeTestMaskLayerForSurfaceWithClippedLayer_Untiled);
-
-class LayerTreeTestMaskLayerForSurfaceWithClippedLayer_Tiled
- : public LayerTreeTestMaskLayerForSurfaceWithClippedLayer {
- public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->enable_mask_tiling = true;
- }
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(
- LayerTreeTestMaskLayerForSurfaceWithClippedLayer_Tiled);
+ LayerTreeTestMaskLayerForSurfaceWithClippedLayer);
class LayerTreeTestMaskLayerForSurfaceWithDifferentScale
: public LayerTreeTest {
@@ -333,7 +271,7 @@ class LayerTreeTestMaskLayerForSurfaceWithDifferentScale
gfx::Size mask_size(50, 50);
mask_layer->SetBounds(mask_size);
- mask_layer->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK);
+ mask_layer->SetLayerMaskType(Layer::LayerMaskType::SINGLE_TEXTURE_MASK);
// Setting will change transform on mask layer will make it not adjust
// raster scale, which will remain 1. This means the mask_layer and render
// surface will have a scale of 2 during draw time.
@@ -378,21 +316,9 @@ class LayerTreeTestMaskLayerForSurfaceWithDifferentScale
// coords in the mask are scaled by 10/50 and 20/50.
// The surface is clipped to (20,10) so the mask texture coords are offset
// by 20/50 and 10/50
- if (host_impl->settings().enable_mask_tiling) {
- PictureLayerImpl* mask_layer_impl = static_cast<PictureLayerImpl*>(
- host_impl->active_tree()->LayerById(mask_layer_id_));
- gfx::SizeF texture_size(
- mask_layer_impl->CalculateTileSize(mask_layer_impl->bounds()));
- EXPECT_EQ(
- gfx::RectF(20.f / texture_size.width(), 10.f / texture_size.height(),
- 10.f / texture_size.width(), 20.f / texture_size.height())
- .ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- } else {
- EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), 1.f / 50.f)
- .ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- }
+ EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), 1.f / 50.f)
+ .ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
EndTest();
return draw_result;
}
@@ -403,27 +329,8 @@ class LayerTreeTestMaskLayerForSurfaceWithDifferentScale
FakeContentLayerClient client_;
};
-class LayerTreeTestMaskLayerForSurfaceWithDifferentScale_Untiled
- : public LayerTreeTestMaskLayerForSurfaceWithDifferentScale {
- public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->enable_mask_tiling = false;
- }
-};
-
SINGLE_AND_MULTI_THREAD_TEST_F(
- LayerTreeTestMaskLayerForSurfaceWithDifferentScale_Untiled);
-
-class LayerTreeTestMaskLayerForSurfaceWithDifferentScale_Tiled
- : public LayerTreeTestMaskLayerForSurfaceWithDifferentScale {
- public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->enable_mask_tiling = true;
- }
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(
- LayerTreeTestMaskLayerForSurfaceWithDifferentScale_Tiled);
+ LayerTreeTestMaskLayerForSurfaceWithDifferentScale);
class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest {
protected:
@@ -471,7 +378,7 @@ class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest {
content_layer->SetBounds(scaling_layer_size);
mask_layer->SetBounds(scaling_layer_size);
- mask_layer->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK);
+ mask_layer->SetLayerMaskType(Layer::LayerMaskType::SINGLE_TEXTURE_MASK);
layer_tree_host()->SetRootLayer(root);
LayerTreeTest::SetupTree();
@@ -495,34 +402,25 @@ class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest {
root_pass->quad_list.front()->material);
const viz::RenderPassDrawQuad* render_pass_quad =
viz::RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
+ gfx::Rect rect_in_target_space = MathUtil::MapEnclosingClippedRect(
+ render_pass_quad->shared_quad_state->quad_to_target_transform,
+ render_pass_quad->rect);
switch (host_impl->active_tree()->source_frame_number()) {
case 0:
// Check that the tree scaling is correctly taken into account for the
// mask, that should fully map onto the quad.
EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
- render_pass_quad->rect.ToString());
- if (host_impl->settings().enable_mask_tiling) {
- EXPECT_EQ(
- gfx::RectF(0.f, 0.f, 100.f / 128.f, 100.f / 128.f).ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- } else {
- EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- }
+ rect_in_target_space.ToString());
+ EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
break;
case 1:
// Applying a DSF should change the render surface size, but won't
// affect which part of the mask is used.
EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
- render_pass_quad->rect.ToString());
- if (host_impl->settings().enable_mask_tiling) {
- EXPECT_EQ(
- gfx::RectF(0.f, 0.f, 100.f / 128.f, 100.f / 128.f).ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- } else {
- EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- }
+ rect_in_target_space.ToString());
+ EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
EndTest();
break;
}
@@ -544,27 +442,7 @@ class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest {
FakeContentLayerClient client_;
};
-class LayerTreeTestMaskLayerWithScaling_Untiled
- : public LayerTreeTestMaskLayerWithScaling {
- public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->enable_mask_tiling = false;
- settings->layer_transforms_should_scale_layer_contents = true;
- }
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskLayerWithScaling_Untiled);
-
-class LayerTreeTestMaskLayerWithScaling_Tiled
- : public LayerTreeTestMaskLayerWithScaling {
- public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->enable_mask_tiling = true;
- settings->layer_transforms_should_scale_layer_contents = true;
- }
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskLayerWithScaling_Tiled);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskLayerWithScaling);
class LayerTreeTestMaskWithNonExactTextureSize : public LayerTreeTest {
protected:
@@ -642,26 +520,7 @@ class LayerTreeTestMaskWithNonExactTextureSize : public LayerTreeTest {
FakeContentLayerClient client_;
};
-class LayerTreeTestMaskWithNonExactTextureSize_Untiled
- : public LayerTreeTestMaskWithNonExactTextureSize {
- public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->enable_mask_tiling = false;
- }
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(
- LayerTreeTestMaskWithNonExactTextureSize_Untiled);
-
-class LayerTreeTestMaskWithNonExactTextureSize_Tiled
- : public LayerTreeTestMaskWithNonExactTextureSize {
- public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->enable_mask_tiling = true;
- }
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskWithNonExactTextureSize_Tiled);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskWithNonExactTextureSize);
} // namespace
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_unittest_picture.cc b/chromium/cc/trees/layer_tree_host_unittest_picture.cc
index feea9ffa2cb..8c103dfc473 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_picture.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_picture.cc
@@ -439,10 +439,6 @@ class LayerTreeHostPictureTestRSLLMembershipWithScale
client_.set_bounds(picture_->bounds());
}
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->layer_transforms_should_scale_layer_contents = true;
- }
-
void BeginTest() override {
frame_ = 0;
draws_in_frame_ = 0;
@@ -607,10 +603,6 @@ class LayerTreeHostPictureTestForceRecalculateScales
client_.set_bounds(size);
}
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->layer_transforms_should_scale_layer_contents = true;
- }
-
void BeginTest() override { PostSetNeedsCommitToMainThread(); }
void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
diff --git a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc
index 667f67d8909..8ebf210f056 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -25,6 +25,8 @@
#include "cc/test/layer_tree_test.h"
#include "cc/test/test_task_graph_runner.h"
#include "cc/test/test_ukm_recorder_factory.h"
+#include "cc/trees/clip_node.h"
+#include "cc/trees/effect_node.h"
#include "cc/trees/layer_tree_host_common.h"
#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/scroll_node.h"
@@ -977,7 +979,7 @@ class LayerTreeHostScrollTestImplOnlyScroll : public LayerTreeHostScrollTest {
Layer* scroll_layer = layer_tree_host()->outer_viewport_scroll_layer();
switch (layer_tree_host()->SourceFrameNumber()) {
case 0:
- EXPECT_TRUE(base::ContainsKey(
+ EXPECT_TRUE(base::Contains(
scroll_layer->layer_tree_host()->LayersThatShouldPushProperties(),
scroll_layer));
break;
@@ -985,7 +987,7 @@ class LayerTreeHostScrollTestImplOnlyScroll : public LayerTreeHostScrollTest {
// Even if this layer doesn't need push properties, it should
// still pick up scrolls that happen on the active layer during
// commit.
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
scroll_layer->layer_tree_host()->LayersThatShouldPushProperties(),
scroll_layer));
break;
@@ -1155,8 +1157,7 @@ class LayerTreeHostScrollTestScrollZeroMaxScrollOffset
ScrollNode* scroll_node =
scroll_tree.Node(scroll_layer->scroll_tree_index());
InputHandler::ScrollStatus status =
- impl->TryScroll(gfx::PointF(0.0f, 1.0f), InputHandler::TOUCHSCREEN,
- scroll_tree, scroll_node);
+ impl->TryScroll(gfx::PointF(0.0f, 1.0f), scroll_tree, scroll_node);
switch (impl->active_tree()->source_frame_number()) {
case 0:
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
@@ -1206,26 +1207,17 @@ class LayerTreeHostScrollTestScrollNonDrawnLayer
}
void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
- LayerImpl* scroll_layer = impl->OuterViewportScrollLayer();
-
- ScrollTree& scroll_tree =
- impl->active_tree()->property_trees()->scroll_tree;
- ScrollNode* scroll_node =
- scroll_tree.Node(scroll_layer->scroll_tree_index());
-
// Verify that the scroll layer's scroll offset is taken into account when
// checking whether the screen space point is inside the non-fast
// scrollable region.
-
- InputHandler::ScrollStatus status =
- impl->TryScroll(gfx::PointF(1.f, 1.f), InputHandler::TOUCHSCREEN,
- scroll_tree, scroll_node);
+ InputHandler::ScrollStatus status = impl->ScrollBegin(
+ BeginState(gfx::Point(0, 0)).get(), InputHandler::TOUCHSCREEN);
EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion,
status.main_thread_scrolling_reasons);
- status = impl->TryScroll(gfx::PointF(21.f, 21.f), InputHandler::TOUCHSCREEN,
- scroll_tree, scroll_node);
+ status = impl->ScrollBegin(BeginState(gfx::Point(21, 21)).get(),
+ InputHandler::TOUCHSCREEN);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
status.main_thread_scrolling_reasons);
@@ -1265,14 +1257,13 @@ class LayerTreeHostScrollTestImplScrollUnderMainThreadScrollingParent
scroll_tree.Node(outer_scroll_layer->scroll_tree_index());
InputHandler::ScrollStatus status =
- impl->TryScroll(gfx::PointF(1.f, 1.f), InputHandler::TOUCHSCREEN,
- scroll_tree, inner_scroll_node);
+ impl->TryScroll(gfx::PointF(1.f, 1.f), scroll_tree, inner_scroll_node);
EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kScrollbarScrolling,
status.main_thread_scrolling_reasons);
- status = impl->TryScroll(gfx::PointF(1.f, 1.f), InputHandler::TOUCHSCREEN,
- scroll_tree, outer_scroll_node);
+ status =
+ impl->TryScroll(gfx::PointF(1.f, 1.f), scroll_tree, outer_scroll_node);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
status.main_thread_scrolling_reasons);
@@ -1321,12 +1312,18 @@ class ThreadCheckingInputHandlerClient : public InputHandlerClient {
}
}
- void DeliverInputForBeginFrame() override {
+ void DeliverInputForBeginFrame(const viz::BeginFrameArgs& args) override {
if (!task_runner_->BelongsToCurrentThread()) {
ADD_FAILURE() << "DeliverInputForBeginFrame called on wrong thread";
}
}
+ void DeliverInputForHighLatencyMode() override {
+ if (!task_runner_->BelongsToCurrentThread()) {
+ ADD_FAILURE() << "DeliverInputForHighLatencyMode called on wrong thread";
+ }
+ }
+
private:
base::SingleThreadTaskRunner* task_runner_;
bool* received_stop_flinging_;
@@ -1825,7 +1822,8 @@ class MockInputHandlerClient : public InputHandlerClient {
float page_scale_factor,
float min_page_scale_factor,
float max_page_scale_factor) override {}
- void DeliverInputForBeginFrame() override {}
+ void DeliverInputForBeginFrame(const viz::BeginFrameArgs& args) override {}
+ void DeliverInputForHighLatencyMode() override {}
};
// This is a regression test, see crbug.com/639046.
@@ -2233,5 +2231,189 @@ class LayerTreeHostScrollTestImplSideInvalidation
MULTI_THREAD_TEST_F(LayerTreeHostScrollTestImplSideInvalidation);
+// Version of LayerTreeHostScrollTest that uses layer lists which means the
+// property trees and layer list are explicitly specified instead of running
+// the cc property tree builder.
+class LayerListLayerTreeHostScrollTest : public LayerTreeHostScrollTest {
+ public:
+ // The id of the root property tree nodes.
+ static constexpr int kRootNodeId = 1;
+
+ LayerListLayerTreeHostScrollTest() { SetUseLayerList(); }
+
+ void SetupTree() override {
+ // Setup the root transform, effect, clip, and scroll property tree nodes.
+ auto& transform_tree = layer_tree_host()->property_trees()->transform_tree;
+ auto& root_transform_node = *transform_tree.Node(
+ transform_tree.Insert(TransformNode(), kRealRootNodeId));
+ DCHECK_EQ(root_transform_node.id, kRootNodeId);
+ root_transform_node.source_node_id = root_transform_node.parent_id;
+ transform_tree.set_needs_update(true);
+
+ auto& effect_tree = layer_tree_host()->property_trees()->effect_tree;
+ auto& root_effect_node =
+ *effect_tree.Node(effect_tree.Insert(EffectNode(), kRealRootNodeId));
+ DCHECK_EQ(root_effect_node.id, kRootNodeId);
+ root_effect_node.stable_id = 1;
+ root_effect_node.transform_id = kRealRootNodeId;
+ root_effect_node.clip_id = kRealRootNodeId;
+ root_effect_node.render_surface_reason = RenderSurfaceReason::kRoot;
+ effect_tree.set_needs_update(true);
+
+ auto& clip_tree = layer_tree_host()->property_trees()->clip_tree;
+ auto& root_clip_node =
+ *clip_tree.Node(clip_tree.Insert(ClipNode(), kRealRootNodeId));
+ DCHECK_EQ(root_clip_node.id, kRootNodeId);
+ root_clip_node.clip_type = ClipNode::ClipType::APPLIES_LOCAL_CLIP;
+ root_clip_node.clip = gfx::RectF(gfx::SizeF(800, 600));
+ root_clip_node.transform_id = kRealRootNodeId;
+ clip_tree.set_needs_update(true);
+
+ auto& scroll_tree = layer_tree_host()->property_trees()->scroll_tree;
+ auto& root_scroll_node =
+ *scroll_tree.Node(scroll_tree.Insert(ScrollNode(), kRealRootNodeId));
+ DCHECK_EQ(root_scroll_node.id, kRootNodeId);
+ root_scroll_node.transform_id = kRealRootNodeId;
+ scroll_tree.set_needs_update(true);
+
+ // Setup the root Layer which should be used to attach the layer list.
+ root_ = Layer::Create();
+ root_->SetBounds(gfx::Size(800, 600));
+ root_->SetIsDrawable(true);
+ root_->SetHitTestable(true);
+ root_->SetTransformTreeIndex(root_transform_node.id);
+ root_->SetEffectTreeIndex(root_effect_node.id);
+ root_->SetScrollTreeIndex(root_scroll_node.id);
+ root_->SetClipTreeIndex(root_clip_node.id);
+ layer_tree_host()->SetRootLayer(root_);
+
+ layer_tree_host()->SetViewportSizeAndScale(gfx::Size(800, 600), 1.f,
+ viz::LocalSurfaceIdAllocation());
+
+ layer_tree_host()->property_trees()->sequence_number =
+ root_->property_tree_sequence_number();
+
+ root_->SetNeedsCommit();
+ }
+
+ Layer* root() const { return root_.get(); }
+
+ private:
+ // The compositor is hard-coded to use 0 for the root nodes (always non-null).
+ static constexpr int kRealRootNodeId = 0;
+
+ scoped_refptr<Layer> root_;
+};
+
+class NonScrollingNonFastScrollableRegion
+ : public LayerListLayerTreeHostScrollTest {
+ public:
+ // Setup 3 Layers:
+ // 1) bottom_ which has a non-fast region in the bottom-right.
+ // 2) middle_scrollable_ which is scrollable.
+ // 3) top_ which has a non-fast region in the top-left and is offset by
+ // |middle_scrollable_|'s scroll offset.
+ void SetupTree() override {
+ LayerListLayerTreeHostScrollTest::SetupTree();
+
+ fake_content_layer_client_.set_bounds(root()->bounds());
+
+ std::vector<scoped_refptr<Layer>> layer_list;
+
+ bottom_ = FakePictureLayer::Create(&fake_content_layer_client_);
+ bottom_->SetElementId(LayerIdToElementIdForTesting(bottom_->id()));
+ bottom_->SetBounds(gfx::Size(100, 100));
+ bottom_->SetNonFastScrollableRegion(Region(gfx::Rect(50, 50, 50, 50)));
+ bottom_->SetHitTestable(true);
+ bottom_->SetTransformTreeIndex(kRootNodeId);
+ bottom_->SetEffectTreeIndex(kRootNodeId);
+ bottom_->SetScrollTreeIndex(kRootNodeId);
+ bottom_->SetClipTreeIndex(kRootNodeId);
+ bottom_->set_property_tree_sequence_number(
+ root()->property_tree_sequence_number());
+ layer_list.push_back(bottom_);
+
+ auto& scroll_tree = layer_tree_host()->property_trees()->scroll_tree;
+ auto& scroll_node =
+ *scroll_tree.Node(scroll_tree.Insert(ScrollNode(), kRootNodeId));
+ scroll_node.transform_id = kRootNodeId;
+ middle_scrollable_ = FakePictureLayer::Create(&fake_content_layer_client_);
+ middle_scrollable_->SetElementId(
+ LayerIdToElementIdForTesting(middle_scrollable_->id()));
+ scroll_node.element_id = middle_scrollable_->element_id();
+ scroll_node.scrollable = true;
+ scroll_node.bounds = gfx::Size(100, 200);
+ scroll_node.container_bounds = gfx::Size(100, 100);
+ middle_scrollable_->SetBounds(gfx::Size(100, 100));
+ middle_scrollable_->SetIsDrawable(true);
+ middle_scrollable_->SetScrollable(gfx::Size(100, 200));
+ middle_scrollable_->SetHitTestable(true);
+ middle_scrollable_->SetTransformTreeIndex(kRootNodeId);
+ middle_scrollable_->SetEffectTreeIndex(kRootNodeId);
+ middle_scrollable_->SetScrollTreeIndex(scroll_node.id);
+ middle_scrollable_->SetClipTreeIndex(kRootNodeId);
+ middle_scrollable_->set_property_tree_sequence_number(
+ root()->property_tree_sequence_number());
+ layer_list.push_back(middle_scrollable_);
+
+ top_ = FakePictureLayer::Create(&fake_content_layer_client_);
+ top_->SetElementId(LayerIdToElementIdForTesting(top_->id()));
+ top_->SetBounds(gfx::Size(100, 100));
+ top_->SetNonFastScrollableRegion(Region(gfx::Rect(0, 0, 50, 50)));
+ top_->SetHitTestable(true);
+ top_->SetTransformTreeIndex(kRootNodeId);
+ top_->SetEffectTreeIndex(kRootNodeId);
+ top_->SetScrollTreeIndex(scroll_node.id);
+ top_->SetClipTreeIndex(kRootNodeId);
+ top_->set_property_tree_sequence_number(
+ root()->property_tree_sequence_number());
+
+ layer_list.push_back(top_);
+ root()->SetChildLayerList(std::move(layer_list));
+ }
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
+ // The top-left hit should immediately hit the top layer's non-fast region
+ // which forces main-thread scrolling.
+ auto top_left_status = impl->ScrollBegin(
+ BeginState(gfx::Point(20, 20)).get(), InputHandler::TOUCHSCREEN);
+ EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, top_left_status.thread);
+ EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion,
+ top_left_status.main_thread_scrolling_reasons);
+
+ // The top-right hit should hit the top layer but not the non-fast region so
+ // the scroll should continue to scroll on the impl.
+ InputHandler::ScrollStatus top_right_status = impl->ScrollBegin(
+ BeginState(gfx::Point(80, 20)).get(), InputHandler::TOUCHSCREEN);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, top_right_status.thread);
+ EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
+ top_right_status.main_thread_scrolling_reasons);
+
+ // The bottom-right should hit the bottom layer's non-fast region. Though
+ // the middle layer is a composited scroller and is hit first, we cannot do
+ // a fast scroll because an ancestor on the scroll chain has hit a non-fast
+ // region.
+ InputHandler::ScrollStatus bottom_right_status = impl->ScrollBegin(
+ BeginState(gfx::Point(80, 80)).get(), InputHandler::TOUCHSCREEN);
+ EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, bottom_right_status.thread);
+ EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion,
+ bottom_right_status.main_thread_scrolling_reasons);
+
+ EndTest();
+ }
+
+ void AfterTest() override {}
+
+ private:
+ FakeContentLayerClient fake_content_layer_client_;
+ scoped_refptr<Layer> bottom_;
+ scoped_refptr<Layer> middle_scrollable_;
+ scoped_refptr<Layer> top_;
+};
+
+SINGLE_THREAD_TEST_F(NonScrollingNonFastScrollableRegion);
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_impl.cc b/chromium/cc/trees/layer_tree_impl.cc
index fbd783c9798..fe75edcd991 100644
--- a/chromium/cc/trees/layer_tree_impl.cc
+++ b/chromium/cc/trees/layer_tree_impl.cc
@@ -89,7 +89,6 @@ LayerTreeImpl::LayerTreeImpl(
external_page_scale_factor_(1.f),
device_scale_factor_(1.f),
painted_device_scale_factor_(1.f),
- content_source_id_(0),
elastic_overscroll_(elastic_overscroll),
layers_(new OwnedLayerImplList),
needs_update_draw_properties_(true),
@@ -484,8 +483,6 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) {
target_tree->SetRasterColorSpace(raster_color_space_id_, raster_color_space_);
target_tree->elastic_overscroll()->PushPendingToActive();
- target_tree->set_content_source_id(content_source_id());
-
target_tree->set_painted_device_scale_factor(painted_device_scale_factor());
target_tree->SetDeviceScaleFactor(device_scale_factor());
target_tree->SetDeviceViewportSize(device_viewport_size_);
@@ -1290,7 +1287,6 @@ bool LayerTreeImpl::UpdateDrawProperties(
InnerViewportScrollLayer(), OuterViewportScrollLayer(),
elastic_overscroll()->Current(IsActiveTree()),
OverscrollElasticityElementId(), max_texture_size(),
- settings().layer_transforms_should_scale_layer_contents,
&render_surface_list_, &property_trees_, PageScaleTransformNode());
LayerTreeHostCommon::CalculateDrawProperties(&inputs);
if (const char* client_name = GetClientNameForMetrics()) {
@@ -1456,6 +1452,18 @@ LayerImpl* LayerTreeImpl::LayerById(int id) const {
return iter != layer_id_map_.end() ? iter->second : nullptr;
}
+// TODO(masonfreed): If this shows up on profiles, this could use
+// a layer_element_map_ approach similar to LayerById().
+LayerImpl* LayerTreeImpl::LayerByElementId(ElementId element_id) const {
+ auto it = std::find_if(layer_list_.rbegin(), layer_list_.rend(),
+ [&element_id](LayerImpl* layer_impl) {
+ return layer_impl->element_id() == element_id;
+ });
+ if (it == layer_list_.rend())
+ return nullptr;
+ return *it;
+}
+
LayerImpl* LayerTreeImpl::ScrollableLayerByElementId(
ElementId element_id) const {
auto iter = element_id_to_scrollable_layer_.find(element_id);
@@ -1482,7 +1490,7 @@ void LayerTreeImpl::AddLayerShouldPushProperties(LayerImpl* layer) {
DCHECK(!IsActiveTree()) << "The active tree does not push layer properties";
// TODO(crbug.com/303943): PictureLayerImpls always push properties so should
// not go into this set or we'd push them twice.
- DCHECK(!base::ContainsValue(picture_layers_, layer));
+ DCHECK(!base::Contains(picture_layers_, layer));
layers_that_should_push_properties_.insert(layer);
}
@@ -1503,7 +1511,7 @@ void LayerTreeImpl::UnregisterLayer(LayerImpl* layer) {
// These manage ownership of the LayerImpl.
void LayerTreeImpl::AddLayer(std::unique_ptr<LayerImpl> layer) {
- DCHECK(!base::ContainsValue(*layers_, layer));
+ DCHECK(!base::Contains(*layers_, layer));
DCHECK(layer);
layers_->push_back(std::move(layer));
set_needs_update_draw_properties();
@@ -1862,7 +1870,7 @@ void LayerTreeImpl::ProcessUIResourceRequestQueue() {
}
void LayerTreeImpl::RegisterPictureLayerImpl(PictureLayerImpl* layer) {
- DCHECK(!base::ContainsValue(picture_layers_, layer));
+ DCHECK(!base::Contains(picture_layers_, layer));
picture_layers_.push_back(layer);
}
@@ -1870,6 +1878,23 @@ void LayerTreeImpl::UnregisterPictureLayerImpl(PictureLayerImpl* layer) {
auto it = std::find(picture_layers_.begin(), picture_layers_.end(), layer);
DCHECK(it != picture_layers_.end());
picture_layers_.erase(it);
+
+ // Make sure that |picture_layers_with_paint_worklets_| doesn't get left with
+ // dead layers. They should already have been removed (via calling
+ // NotifyLayerHasPaintWorkletsChanged) before the layer was unregistered.
+ DCHECK(!picture_layers_with_paint_worklets_.contains(layer));
+}
+
+void LayerTreeImpl::NotifyLayerHasPaintWorkletsChanged(PictureLayerImpl* layer,
+ bool has_worklets) {
+ if (has_worklets) {
+ auto insert_pair = picture_layers_with_paint_worklets_.insert(layer);
+ DCHECK(insert_pair.second);
+ } else {
+ auto it = picture_layers_with_paint_worklets_.find(layer);
+ DCHECK(it != picture_layers_with_paint_worklets_.end());
+ picture_layers_with_paint_worklets_.erase(it);
+ }
}
void LayerTreeImpl::RegisterScrollbar(ScrollbarLayerImplBase* scrollbar_layer) {
@@ -2179,8 +2204,10 @@ LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPoint(
struct FindTouchEventLayerFunctor {
bool operator()(LayerImpl* layer) const {
+ if (!layer->has_touch_action_regions())
+ return false;
return PointHitsRegion(screen_space_point, layer->ScreenSpaceTransform(),
- layer->touch_action_region().region(), layer);
+ layer->GetAllTouchActionRegions(), layer);
}
const gfx::PointF screen_space_point;
};
@@ -2220,6 +2247,28 @@ LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPointInWheelEventHandlerRegion(
func);
}
+std::vector<const LayerImpl*>
+LayerTreeImpl::FindLayersHitByPointInNonFastScrollableRegion(
+ const gfx::PointF& screen_space_point) {
+ std::vector<const LayerImpl*> layers;
+ if (layer_list_.empty())
+ return layers;
+ if (!UpdateDrawProperties())
+ return layers;
+ for (const auto* layer : *this) {
+ if (layer->non_fast_scrollable_region().IsEmpty())
+ continue;
+ if (!PointHitsLayer(layer, screen_space_point, nullptr))
+ continue;
+ if (PointHitsRegion(screen_space_point, layer->ScreenSpaceTransform(),
+ layer->non_fast_scrollable_region(), layer)) {
+ layers.push_back(layer);
+ }
+ }
+
+ return layers;
+}
+
void LayerTreeImpl::RegisterSelection(const LayerSelection& selection) {
if (selection_ == selection)
return;
diff --git a/chromium/cc/trees/layer_tree_impl.h b/chromium/cc/trees/layer_tree_impl.h
index 21f3f87674a..5efd40a6f8f 100644
--- a/chromium/cc/trees/layer_tree_impl.h
+++ b/chromium/cc/trees/layer_tree_impl.h
@@ -343,9 +343,6 @@ class CC_EXPORT LayerTreeImpl {
return painted_device_scale_factor_;
}
- void set_content_source_id(uint32_t id) { content_source_id_ = id; }
- uint32_t content_source_id() { return content_source_id_; }
-
void SetLocalSurfaceIdAllocationFromParent(
const viz::LocalSurfaceIdAllocation&
local_surface_id_allocation_from_parent);
@@ -460,6 +457,7 @@ class CC_EXPORT LayerTreeImpl {
gfx::Rect RootScrollLayerDeviceViewportBounds() const;
LayerImpl* LayerById(int id) const;
+ LayerImpl* LayerByElementId(ElementId element_id) const;
LayerImpl* ScrollableLayerByElementId(ElementId element_id) const;
bool IsElementInPropertyTree(ElementId element_id) const;
@@ -545,6 +543,13 @@ class CC_EXPORT LayerTreeImpl {
return picture_layers_;
}
+ void NotifyLayerHasPaintWorkletsChanged(PictureLayerImpl* layer,
+ bool has_worklets);
+ const base::flat_set<PictureLayerImpl*>& picture_layers_with_paint_worklets()
+ const {
+ return picture_layers_with_paint_worklets_;
+ }
+
void RegisterScrollbar(ScrollbarLayerImplBase* scrollbar_layer);
void UnregisterScrollbar(ScrollbarLayerImplBase* scrollbar_layer);
ScrollbarSet ScrollbarsFor(ElementId scroll_element_id) const;
@@ -560,6 +565,10 @@ class CC_EXPORT LayerTreeImpl {
LayerImpl* FindLayerThatIsHitByPointInWheelEventHandlerRegion(
const gfx::PointF& screen_space_point);
+ // Return all layers with a hit non-fast scrollable region.
+ std::vector<const LayerImpl*> FindLayersHitByPointInNonFastScrollableRegion(
+ const gfx::PointF& screen_space_point);
+
void RegisterSelection(const LayerSelection& selection);
bool HandleVisibilityChanged() const { return handle_visibility_changed_; }
@@ -704,7 +713,6 @@ class CC_EXPORT LayerTreeImpl {
int raster_color_space_id_ = -1;
gfx::ColorSpace raster_color_space_;
- uint32_t content_source_id_;
viz::LocalSurfaceIdAllocation local_surface_id_allocation_from_parent_;
bool new_local_surface_id_request_ = false;
gfx::Size device_viewport_size_;
@@ -745,6 +753,11 @@ class CC_EXPORT LayerTreeImpl {
std::vector<PictureLayerImpl*> picture_layers_;
+ // After commit (or impl-side invalidation), the LayerTreeHostImpl must walk
+ // all PictureLayerImpls that have PaintWorklets to ensure they are painted.
+ // To avoid unnecessary walking, we track that set here.
+ base::flat_set<PictureLayerImpl*> picture_layers_with_paint_worklets_;
+
base::flat_set<viz::SurfaceRange> surface_layer_ranges_;
// List of render surfaces for the most recently prepared frame.
diff --git a/chromium/cc/trees/layer_tree_impl_unittest.cc b/chromium/cc/trees/layer_tree_impl_unittest.cc
index 4dc46346a58..11d6bbc38d7 100644
--- a/chromium/cc/trees/layer_tree_impl_unittest.cc
+++ b/chromium/cc/trees/layer_tree_impl_unittest.cc
@@ -6,6 +6,7 @@
#include "cc/layers/heads_up_display_layer_impl.h"
#include "cc/test/fake_layer_tree_host_impl.h"
+#include "cc/test/fake_raster_source.h"
#include "cc/test/geometry_test_utils.h"
#include "cc/test/layer_test_common.h"
#include "cc/trees/clip_node.h"
@@ -18,17 +19,10 @@
namespace cc {
namespace {
-class LayerTreeImplTestSettings : public LayerTreeSettings {
- public:
- LayerTreeImplTestSettings() {
- layer_transforms_should_scale_layer_contents = true;
- }
-};
-
class LayerTreeImplTest : public testing::Test {
public:
- LayerTreeImplTest(
- const LayerTreeSettings& settings = LayerTreeImplTestSettings())
+ explicit LayerTreeImplTest(
+ const LayerTreeSettings& settings = LayerTreeSettings())
: impl_test_(settings) {}
FakeLayerTreeHostImpl& host_impl() const { return *impl_test_.host_impl(); }
@@ -47,7 +41,6 @@ class LayerTreeImplTest : public testing::Test {
render_surface_list_impl_.clear();
LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
root_layer, root_layer->bounds(), &render_surface_list_impl_);
- inputs.can_adjust_raster_scales = true;
LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
}
@@ -2468,6 +2461,61 @@ TEST_F(LayerTreeImplTest, NotPersistentSwapPromisesAreDroppedWhenSwapFails) {
}
}
+TEST_F(LayerTreeImplTest, TrackPictureLayersWithPaintWorklets) {
+ host_impl().CreatePendingTree();
+ LayerTreeImpl* pending_tree = host_impl().pending_tree();
+
+ // Initially there are no layers in the set.
+ EXPECT_EQ(pending_tree->picture_layers_with_paint_worklets().size(), 0u);
+
+ // Add three layers; two with PaintWorklets and one without.
+ std::unique_ptr<PictureLayerImpl> child1_owned =
+ PictureLayerImpl::Create(pending_tree, 2, Layer::LayerMaskType::NOT_MASK);
+ child1_owned->SetBounds(gfx::Size(100, 100));
+ std::unique_ptr<PictureLayerImpl> child2_owned =
+ PictureLayerImpl::Create(pending_tree, 3, Layer::LayerMaskType::NOT_MASK);
+ child2_owned->SetBounds(gfx::Size(100, 100));
+ std::unique_ptr<PictureLayerImpl> child3_owned =
+ PictureLayerImpl::Create(pending_tree, 4, Layer::LayerMaskType::NOT_MASK);
+ child3_owned->SetBounds(gfx::Size(100, 100));
+
+ PictureLayerImpl* child1 = child1_owned.get();
+ PictureLayerImpl* child3 = child3_owned.get();
+
+ root_layer()->test_properties()->AddChild(std::move(child1_owned));
+ root_layer()->test_properties()->AddChild(std::move(child2_owned));
+ root_layer()->test_properties()->AddChild(std::move(child3_owned));
+
+ Region empty_invalidation;
+ scoped_refptr<RasterSource> raster_source1(
+ FakeRasterSource::CreateFilledWithPaintWorklet(child1->bounds()));
+ child1->UpdateRasterSource(raster_source1, &empty_invalidation, nullptr,
+ nullptr);
+ scoped_refptr<RasterSource> raster_source3(
+ FakeRasterSource::CreateFilledWithPaintWorklet(child3->bounds()));
+ child3->UpdateRasterSource(raster_source3, &empty_invalidation, nullptr,
+ nullptr);
+
+ // The set should correctly track which layers are in it.
+ const base::flat_set<PictureLayerImpl*>& layers =
+ pending_tree->picture_layers_with_paint_worklets();
+ EXPECT_EQ(layers.size(), 2u);
+ EXPECT_TRUE(layers.contains(child1));
+ EXPECT_TRUE(layers.contains(child3));
+
+ // Test explicitly removing a layer from the set.
+ scoped_refptr<RasterSource> empty_raster_source(
+ FakeRasterSource::CreateFilled(child1->bounds()));
+ child1->UpdateRasterSource(empty_raster_source, &empty_invalidation, nullptr,
+ nullptr);
+ EXPECT_EQ(layers.size(), 1u);
+ EXPECT_FALSE(layers.contains(child1));
+
+ // Deleting a layer should also cause it to be removed from the set.
+ root_layer()->test_properties()->RemoveChild(child3);
+ EXPECT_EQ(layers.size(), 0u);
+}
+
namespace {
class CommitToPendingTreeLayerTreeImplTestSettings : public LayerTreeSettings {
public:
diff --git a/chromium/cc/trees/layer_tree_settings.cc b/chromium/cc/trees/layer_tree_settings.cc
index 047b36948e7..ce4ba0308eb 100644
--- a/chromium/cc/trees/layer_tree_settings.cc
+++ b/chromium/cc/trees/layer_tree_settings.cc
@@ -24,19 +24,11 @@ SchedulerSettings LayerTreeSettings::ToSchedulerSettings() const {
SchedulerSettings scheduler_settings;
scheduler_settings.main_frame_before_activation_enabled =
main_frame_before_activation_enabled;
- scheduler_settings.timeout_and_draw_when_animation_checkerboards =
- timeout_and_draw_when_animation_checkerboards;
scheduler_settings.using_synchronous_renderer_compositor =
using_synchronous_renderer_compositor;
scheduler_settings.enable_latency_recovery = enable_latency_recovery;
- scheduler_settings.background_frame_interval =
- base::TimeDelta::FromSecondsD(1.0 / background_animation_rate);
scheduler_settings.wait_for_all_pipeline_stages_before_draw =
wait_for_all_pipeline_stages_before_draw;
- scheduler_settings.enable_surface_synchronization =
- enable_surface_synchronization;
- scheduler_settings.compositor_threaded_scrollbar_scrolling =
- compositor_threaded_scrollbar_scrolling;
return scheduler_settings;
}
diff --git a/chromium/cc/trees/layer_tree_settings.h b/chromium/cc/trees/layer_tree_settings.h
index 092fb1b7ea3..d62c52b5326 100644
--- a/chromium/cc/trees/layer_tree_settings.h
+++ b/chromium/cc/trees/layer_tree_settings.h
@@ -62,13 +62,11 @@ class CC_EXPORT LayerTreeSettings {
SkColor solid_color_scrollbar_color = SK_ColorWHITE;
base::TimeDelta scroll_animation_duration_for_testing;
bool timeout_and_draw_when_animation_checkerboards = true;
- bool layer_transforms_should_scale_layer_contents = false;
bool layers_always_allowed_lcd_text = false;
float minimum_contents_scale = 0.0625f;
float low_res_contents_scale_factor = 0.25f;
float top_controls_show_threshold = 0.5f;
float top_controls_hide_threshold = 0.5f;
- double background_animation_rate = 1.0;
gfx::Size default_tile_size;
gfx::Size max_untiled_layer_size;
// If set, indicates the largest tile size we will use for GPU Raster. If not
@@ -97,8 +95,6 @@ class CC_EXPORT LayerTreeSettings {
bool use_rgba_4444 = false;
bool unpremultiply_and_dither_low_bit_depth_tiles = false;
- bool enable_mask_tiling = true;
-
// If set to true, the compositor may selectively defer image decodes to the
// Image Decode Service and raster tiles without images until the decode is
// ready.
diff --git a/chromium/cc/trees/mutator_host.h b/chromium/cc/trees/mutator_host.h
index 03e3ce4d4a0..c52ce403301 100644
--- a/chromium/cc/trees/mutator_host.h
+++ b/chromium/cc/trees/mutator_host.h
@@ -9,7 +9,7 @@
#include "base/callback_forward.h"
#include "base/time/time.h"
-#include "cc/trees/element_id.h"
+#include "cc/paint/element_id.h"
#include "cc/trees/layer_tree_mutator.h"
#include "cc/trees/mutator_host_client.h"
#include "ui/gfx/geometry/box_f.h"
@@ -131,6 +131,13 @@ class MutatorHost {
virtual bool HasTickingKeyframeModelForTesting(
ElementId element_id) const = 0;
+ virtual void ImplOnlyAutoScrollAnimationCreate(
+ ElementId element_id,
+ const gfx::ScrollOffset& target_offset,
+ const gfx::ScrollOffset& current_offset,
+ float autoscroll_velocity,
+ base::TimeDelta animation_start_offset) = 0;
+
virtual void ImplOnlyScrollAnimationCreate(
ElementId element_id,
const gfx::ScrollOffset& target_offset,
diff --git a/chromium/cc/trees/mutator_host_client.h b/chromium/cc/trees/mutator_host_client.h
index 5d221f3051c..406b10abfc5 100644
--- a/chromium/cc/trees/mutator_host_client.h
+++ b/chromium/cc/trees/mutator_host_client.h
@@ -5,7 +5,7 @@
#ifndef CC_TREES_MUTATOR_HOST_CLIENT_H_
#define CC_TREES_MUTATOR_HOST_CLIENT_H_
-#include "cc/trees/element_id.h"
+#include "cc/paint/element_id.h"
#include "cc/trees/property_animation_state.h"
#include "cc/trees/target_property.h"
diff --git a/chromium/cc/trees/occlusion_tracker_unittest.cc b/chromium/cc/trees/occlusion_tracker_unittest.cc
index 04827454e5e..638a253ceb6 100644
--- a/chromium/cc/trees/occlusion_tracker_unittest.cc
+++ b/chromium/cc/trees/occlusion_tracker_unittest.cc
@@ -203,7 +203,6 @@ class OcclusionTrackerTest : public testing::Test {
LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
root, root->bounds(), &render_surface_list_impl_);
- inputs.can_adjust_raster_scales = true;
LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
layer_iterator_ = std::make_unique<EffectTreeLayerListIterator>(
diff --git a/chromium/cc/trees/property_tree.cc b/chromium/cc/trees/property_tree.cc
index 5d6b0b82fa1..f91deac77f3 100644
--- a/chromium/cc/trees/property_tree.cc
+++ b/chromium/cc/trees/property_tree.cc
@@ -233,6 +233,8 @@ void TransformTree::UpdateTransforms(int id) {
UpdateNodeAndAncestorsHaveIntegerTranslations(node, parent_node);
UpdateTransformChanged(node, parent_node, source_node);
UpdateNodeAndAncestorsAreAnimatedOrInvertible(node, parent_node);
+
+ DCHECK(!node->needs_local_transform_update);
}
bool TransformTree::IsDescendant(int desc_id, int source_id) const {
@@ -374,7 +376,7 @@ gfx::Vector2dF StickyPositionOffset(TransformTree* tree, TransformNode* node) {
scroll_position -= transform_node->snap_amount;
}
- gfx::RectF clip = constraint.constraint_box_rect;
+ gfx::Rect clip = constraint.constraint_box_rect;
clip.Offset(scroll_position.x(), scroll_position.y());
// The clip region may need to be offset by the outer viewport bounds, e.g. if
@@ -831,7 +833,6 @@ void EffectTree::UpdateHasMaskingChild(EffectNode* node,
// when we actually encounter a masking child.
node->has_masking_child = false;
if (node->blend_mode == SkBlendMode::kDstIn) {
- DCHECK(parent_node->HasRenderSurface());
parent_node->has_masking_child = true;
}
}
@@ -850,16 +851,10 @@ void EffectTree::UpdateSurfaceContentsScale(EffectNode* effect_node) {
if (transform_node->in_subtree_of_page_scale_layer)
layer_scale_factor *= transform_tree.page_scale_factor();
- // Note: Copy requests currently expect transform to effect output size.
- bool use_transform_for_contents_scale =
- property_trees()->can_adjust_raster_scales ||
- effect_node->has_copy_request;
const gfx::Vector2dF old_scale = effect_node->surface_contents_scale;
effect_node->surface_contents_scale =
- use_transform_for_contents_scale
- ? MathUtil::ComputeTransform2dScaleComponents(
- transform_tree.ToScreen(transform_node->id), layer_scale_factor)
- : gfx::Vector2dF(layer_scale_factor, layer_scale_factor);
+ MathUtil::ComputeTransform2dScaleComponents(
+ transform_tree.ToScreen(transform_node->id), layer_scale_factor);
// If surface contents scale changes, draw transforms are no longer valid.
// Invalidates the draw transform cache and updates the clip for the surface.
@@ -1757,7 +1752,6 @@ PropertyTreesCachedData::~PropertyTreesCachedData() = default;
PropertyTrees::PropertyTrees()
: needs_rebuild(true),
- can_adjust_raster_scales(true),
changed(false),
full_tree_damaged(false),
sequence_number(0),
@@ -1785,7 +1779,6 @@ bool PropertyTrees::operator==(const PropertyTrees& other) const {
full_tree_damaged == other.full_tree_damaged &&
is_main_thread == other.is_main_thread &&
is_active == other.is_active &&
- can_adjust_raster_scales == other.can_adjust_raster_scales &&
sequence_number == other.sequence_number;
}
@@ -1800,7 +1793,6 @@ PropertyTrees& PropertyTrees::operator=(const PropertyTrees& from) {
needs_rebuild = from.needs_rebuild;
changed = from.changed;
full_tree_damaged = from.full_tree_damaged;
- can_adjust_raster_scales = from.can_adjust_raster_scales;
sequence_number = from.sequence_number;
is_main_thread = from.is_main_thread;
is_active = from.is_active;
@@ -1830,7 +1822,6 @@ void PropertyTrees::clear() {
needs_rebuild = true;
full_tree_damaged = false;
changed = false;
- can_adjust_raster_scales = true;
sequence_number++;
#if DCHECK_IS_ON()
@@ -2077,17 +2068,6 @@ CombinedAnimationScale PropertyTrees::GetAnimationScales(
&cached_data_.animation_scales[transform_node_id];
if (animation_scales->update_number !=
cached_data_.transform_tree_update_number) {
- if (!layer_tree_impl->settings()
- .layer_transforms_should_scale_layer_contents) {
- animation_scales->update_number =
- cached_data_.transform_tree_update_number;
- animation_scales->combined_maximum_animation_target_scale = kNotScaled;
- animation_scales->combined_starting_animation_scale = kNotScaled;
- return CombinedAnimationScale(
- animation_scales->combined_maximum_animation_target_scale,
- animation_scales->combined_starting_animation_scale);
- }
-
TransformNode* node = transform_tree.Node(transform_node_id);
TransformNode* parent_node = transform_tree.parent(node);
bool ancestor_is_animating_scale = false;
diff --git a/chromium/cc/trees/property_tree.h b/chromium/cc/trees/property_tree.h
index f61d2c26a84..75b972dd86c 100644
--- a/chromium/cc/trees/property_tree.h
+++ b/chromium/cc/trees/property_tree.h
@@ -15,8 +15,8 @@
#include "cc/base/synced_property.h"
#include "cc/cc_export.h"
#include "cc/layers/layer_sticky_position_constraint.h"
+#include "cc/paint/element_id.h"
#include "cc/paint/filter_operations.h"
-#include "cc/trees/element_id.h"
#include "cc/trees/mutator_host_client.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/scroll_offset.h"
@@ -631,7 +631,6 @@ class CC_EXPORT PropertyTrees final {
ClipTree clip_tree;
ScrollTree scroll_tree;
bool needs_rebuild;
- bool can_adjust_raster_scales;
// Change tracking done on property trees needs to be preserved across commits
// (when they are not rebuild). We cache a global bool which stores whether
// we did any change tracking so that we can skip copying the change status
diff --git a/chromium/cc/trees/property_tree_builder.cc b/chromium/cc/trees/property_tree_builder.cc
index bd5882ee4f9..44a2033de9a 100644
--- a/chromium/cc/trees/property_tree_builder.cc
+++ b/chromium/cc/trees/property_tree_builder.cc
@@ -180,6 +180,14 @@ static LayerImpl* ClipParent(LayerImpl* layer) {
return layer->test_properties()->clip_parent;
}
+static bool HasClipRect(Layer* layer) {
+ return !layer->clip_rect().IsEmpty();
+}
+
+static bool HasClipRect(LayerImpl* layer) {
+ return false;
+}
+
static inline const FilterOperations& Filters(Layer* layer) {
return layer->filters();
}
@@ -204,15 +212,6 @@ static bool HasRoundedCorner(LayerImpl* layer) {
return !layer->test_properties()->rounded_corner_bounds.IsEmpty();
}
-static gfx::RRectF RoundedCornerBounds(Layer* layer) {
- return gfx::RRectF(gfx::RectF(gfx::Rect(layer->bounds())),
- layer->corner_radii());
-}
-
-static gfx::RRectF RoundedCornerBounds(LayerImpl* layer) {
- return layer->test_properties()->rounded_corner_bounds;
-}
-
static PictureLayer* MaskLayer(Layer* layer) {
return layer->mask_layer();
}
@@ -310,9 +309,30 @@ static int GetTransformParent(const DataForRecursion& data, LayerType* layer) {
}
template <typename LayerType>
+static bool LayerClipsSubtreeToItsBounds(LayerType* layer) {
+ return layer->masks_to_bounds() || MaskLayer(layer);
+}
+
+template <typename LayerType>
static bool LayerClipsSubtree(LayerType* layer) {
- return layer->masks_to_bounds() || MaskLayer(layer) ||
- HasRoundedCorner(layer);
+ return LayerClipsSubtreeToItsBounds(layer) || HasRoundedCorner(layer) ||
+ HasClipRect(layer);
+}
+
+gfx::RectF EffectiveClipRect(Layer* layer) {
+ return layer->EffectiveClipRect();
+}
+
+gfx::RectF EffectiveClipRect(LayerImpl* layer) {
+ return gfx::RectF(gfx::PointF(), gfx::SizeF(layer->bounds()));
+}
+
+static gfx::RRectF RoundedCornerBounds(Layer* layer) {
+ return gfx::RRectF(EffectiveClipRect(layer), layer->corner_radii());
+}
+
+static gfx::RRectF RoundedCornerBounds(LayerImpl* layer) {
+ return layer->test_properties()->rounded_corner_bounds;
}
template <typename LayerType>
@@ -355,6 +375,12 @@ static inline bool HasLatestSequenceNumber(const LayerImpl*, int) {
return true;
}
+static inline void SetHasClipNode(Layer* layer, bool val) {
+ layer->SetHasClipNode(val);
+}
+
+static inline void SetHasClipNode(LayerImpl* layer, bool val) {}
+
template <typename LayerType>
void PropertyTreeBuilderContext<LayerType>::AddClipNodeIfNeeded(
const DataForRecursion& data_from_ancestor,
@@ -376,8 +402,11 @@ void PropertyTreeBuilderContext<LayerType>::AddClipNodeIfNeeded(
data_for_children->clip_tree_parent = parent_id;
} else {
ClipNode node;
- node.clip = gfx::RectF(gfx::PointF() + layer->offset_to_transform_parent(),
- gfx::SizeF(layer->bounds()));
+ node.clip = EffectiveClipRect(layer);
+
+ // Move the clip bounds so that it is relative to the transform parent.
+ node.clip += layer->offset_to_transform_parent();
+
node.transform_id = created_transform_node
? data_for_children->transform_tree_parent
: GetTransformParent(data_from_ancestor, layer);
@@ -391,6 +420,7 @@ void PropertyTreeBuilderContext<LayerType>::AddClipNodeIfNeeded(
data_for_children->clip_tree_parent = clip_tree_.Insert(node, parent_id);
}
+ SetHasClipNode(layer, requires_node);
layer->SetClipTreeIndex(data_for_children->clip_tree_parent);
}
@@ -797,6 +827,14 @@ static inline const base::Optional<gfx::RRectF>& BackdropFilterBounds(
return layer->test_properties()->backdrop_filter_bounds;
}
+static inline ElementId BackdropMaskElementId(Layer* layer) {
+ return layer->backdrop_mask_element_id();
+}
+
+static inline ElementId BackdropMaskElementId(LayerImpl* layer) {
+ return layer->test_properties()->backdrop_mask_element_id;
+}
+
static inline float BackdropFilterQuality(Layer* layer) {
return layer->backdrop_filter_quality();
}
@@ -821,6 +859,14 @@ static inline bool HasCopyRequest(LayerImpl* layer) {
return !layer->test_properties()->copy_requests.empty();
}
+static inline int MirrorCount(Layer* layer) {
+ return layer->mirror_count();
+}
+
+static inline int MirrorCount(LayerImpl* layer) {
+ return 0;
+}
+
static inline bool PropertyChanged(Layer* layer) {
return layer->subtree_property_changed();
}
@@ -933,6 +979,10 @@ RenderSurfaceReason ComputeRenderSurfaceReason(const MutatorHost& mutator_host,
if (HasCopyRequest(layer))
return RenderSurfaceReason::kCopyRequest;
+ // If the layer is mirrored.
+ if (MirrorCount(layer))
+ return RenderSurfaceReason::kMirrored;
+
return RenderSurfaceReason::kNone;
}
@@ -1040,6 +1090,7 @@ bool PropertyTreeBuilderContext<LayerType>::AddEffectNodeIfNeeded(
node->backdrop_filters = BackdropFilters(layer);
node->backdrop_filter_bounds = BackdropFilterBounds(layer);
node->backdrop_filter_quality = BackdropFilterQuality(layer);
+ node->backdrop_mask_element_id = BackdropMaskElementId(layer);
node->filters_origin = FiltersOrigin(layer);
node->trilinear_filtering = TrilinearFiltering(layer);
node->has_potential_opacity_animation = has_potential_opacity_animation;
diff --git a/chromium/cc/trees/proxy.h b/chromium/cc/trees/proxy.h
index 10a58a32998..0fe7a90fe3f 100644
--- a/chromium/cc/trees/proxy.h
+++ b/chromium/cc/trees/proxy.h
@@ -39,10 +39,6 @@ class CC_EXPORT Proxy {
virtual bool IsStarted() const = 0;
- // This function retruns true if the commits go directly to active tree by
- // skipping commit to pending tree.
- virtual bool CommitToActiveTree() const = 0;
-
virtual void SetLayerTreeFrameSink(
LayerTreeFrameSink* layer_tree_frame_sink) = 0;
virtual void ReleaseLayerTreeFrameSink() = 0;
diff --git a/chromium/cc/trees/proxy_impl.cc b/chromium/cc/trees/proxy_impl.cc
index cdfd8d3a135..2e69eddc64e 100644
--- a/chromium/cc/trees/proxy_impl.cc
+++ b/chromium/cc/trees/proxy_impl.cc
@@ -191,7 +191,9 @@ void ProxyImpl::BeginMainFrameAbortedOnImpl(
DCHECK(IsImplThread());
DCHECK(scheduler_->CommitPending());
- host_impl_->BeginMainFrameAborted(reason, std::move(swap_promises));
+ host_impl_->BeginMainFrameAborted(
+ reason, std::move(swap_promises),
+ scheduler_->last_dispatched_begin_main_frame_args());
scheduler_->NotifyBeginMainFrameStarted(main_thread_start_time);
scheduler_->BeginMainFrameAborted(reason);
}
@@ -365,7 +367,7 @@ void ProxyImpl::PostAnimationEventsToMainThreadOnImplThread(
DCHECK(IsImplThread());
MainThreadTaskRunner()->PostTask(
FROM_HERE, base::BindOnce(&ProxyMain::SetAnimationEvents,
- proxy_main_weak_ptr_, base::Passed(&events)));
+ proxy_main_weak_ptr_, std::move(events)));
}
size_t ProxyImpl::CompositedAnimationsCount() const {
@@ -388,6 +390,14 @@ bool ProxyImpl::IsInsideDraw() {
return inside_draw_;
}
+bool ProxyImpl::IsBeginMainFrameExpected() {
+ // Check whether the main-thread has requested for updates. If main-thread has
+ // not responded to a previously dispatched BeginMainFrame, then assume that
+ // main-thread would want to produce an update for the current frame too.
+ return scheduler_->needs_begin_main_frame() ||
+ scheduler_->IsBeginMainFrameSent();
+}
+
void ProxyImpl::RenewTreePriority() {
DCHECK(IsImplThread());
const bool user_interaction_in_progress =
@@ -495,6 +505,8 @@ void ProxyImpl::DidPresentCompositorFrameOnImplThread(
FROM_HERE, base::BindOnce(&ProxyMain::DidPresentCompositorFrame,
proxy_main_weak_ptr_, frame_token,
std::move(callbacks), feedback));
+ if (scheduler_)
+ scheduler_->DidPresentCompositorFrame(frame_token, feedback.timestamp);
}
void ProxyImpl::NotifyAnimationWorkletStateChange(
@@ -512,6 +524,12 @@ void ProxyImpl::NotifyAnimationWorkletStateChange(
tree_type);
}
+void ProxyImpl::NotifyPaintWorkletStateChange(
+ Scheduler::PaintWorkletState state) {
+ DCHECK(IsImplThread());
+ scheduler_->NotifyPaintWorkletStateChange(state);
+}
+
bool ProxyImpl::WillBeginImplFrame(const viz::BeginFrameArgs& args) {
DCHECK(IsImplThread());
return host_impl_->WillBeginImplFrame(args);
@@ -551,8 +569,8 @@ void ProxyImpl::ScheduledActionSendBeginMainFrame(
MainThreadTaskRunner()->PostTask(
FROM_HERE,
base::BindOnce(&ProxyMain::BeginMainFrame, proxy_main_weak_ptr_,
- base::Passed(&begin_main_frame_state)));
- host_impl_->DidSendBeginMainFrame();
+ std::move(begin_main_frame_state)));
+ host_impl_->DidSendBeginMainFrame(args);
devtools_instrumentation::DidRequestMainThreadFrame(layer_tree_host_id_);
}
@@ -685,6 +703,8 @@ DrawResult ProxyImpl::DrawInternal(bool forced_draw) {
LayerTreeHostImpl::FrameData frame;
frame.begin_frame_ack = scheduler_->CurrentBeginFrameAckForActiveTree();
+ frame.origin_begin_main_frame_args =
+ scheduler_->last_activate_origin_frame_args();
bool draw_frame = false;
DrawResult result;
@@ -696,9 +716,11 @@ DrawResult ProxyImpl::DrawInternal(bool forced_draw) {
}
if (draw_frame) {
- if (host_impl_->DrawLayers(&frame))
+ if (host_impl_->DrawLayers(&frame)) {
+ DCHECK_NE(frame.frame_token, 0u);
// Drawing implies we submitted a frame to the LayerTreeFrameSink.
- scheduler_->DidSubmitCompositorFrame();
+ scheduler_->DidSubmitCompositorFrame(frame.frame_token);
+ }
result = DRAW_SUCCESS;
} else {
DCHECK_NE(DRAW_SUCCESS, result);
@@ -709,7 +731,7 @@ DrawResult ProxyImpl::DrawInternal(bool forced_draw) {
bool start_ready_animations = draw_frame;
host_impl_->UpdateAnimationState(start_ready_animations);
- // Tell the main thread that the the newly-commited frame was drawn.
+ // Tell the main thread that the newly-commited frame was drawn.
if (next_frame_is_newly_committed_frame_) {
next_frame_is_newly_committed_frame_ = false;
MainThreadTaskRunner()->PostTask(
diff --git a/chromium/cc/trees/proxy_impl.h b/chromium/cc/trees/proxy_impl.h
index 62636b88386..d8222df2013 100644
--- a/chromium/cc/trees/proxy_impl.h
+++ b/chromium/cc/trees/proxy_impl.h
@@ -94,6 +94,7 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient,
void PostAnimationEventsToMainThreadOnImplThread(
std::unique_ptr<MutatorEvents> events) override;
bool IsInsideDraw() override;
+ bool IsBeginMainFrameExpected() override;
void RenewTreePriority() override;
void PostDelayedAnimationTaskOnImplThread(base::OnceClosure task,
base::TimeDelta delay) override;
@@ -112,6 +113,8 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient,
void NotifyAnimationWorkletStateChange(
AnimationWorkletMutationState state,
ElementListType element_list_type) override;
+ void NotifyPaintWorkletStateChange(
+ Scheduler::PaintWorkletState state) override;
// SchedulerClient implementation
bool WillBeginImplFrame(const viz::BeginFrameArgs& args) override;
diff --git a/chromium/cc/trees/proxy_main.cc b/chromium/cc/trees/proxy_main.cc
index 20299713e6a..dc7b697ae2b 100644
--- a/chromium/cc/trees/proxy_main.cc
+++ b/chromium/cc/trees/proxy_main.cc
@@ -39,9 +39,7 @@ ProxyMain::ProxyMain(LayerTreeHost* layer_tree_host,
commit_waits_for_activation_(false),
started_(false),
defer_main_frame_update_(false),
- defer_commits_(true),
- frame_sink_bound_weak_factory_(this),
- weak_factory_(this) {
+ defer_commits_(true) {
TRACE_EVENT0("cc", "ProxyMain::ProxyMain");
DCHECK(task_runner_provider_);
DCHECK(IsMainThread());
@@ -157,7 +155,7 @@ void ProxyMain::BeginMainFrame(
base::Unretained(proxy_impl_.get()),
CommitEarlyOutReason::ABORTED_NOT_VISIBLE,
begin_main_frame_start_time,
- base::Passed(&empty_swap_promises)));
+ std::move(empty_swap_promises)));
return;
}
@@ -188,7 +186,7 @@ void ProxyMain::BeginMainFrame(
base::Unretained(proxy_impl_.get()),
CommitEarlyOutReason::ABORTED_DEFERRED_MAIN_FRAME_UPDATE,
begin_main_frame_start_time,
- base::Passed(&empty_swap_promises)));
+ std::move(empty_swap_promises)));
// When we stop deferring main frame updates, we should resume any
// previously requested pipeline stages.
deferred_final_pipeline_stage_ =
@@ -202,11 +200,22 @@ void ProxyMain::BeginMainFrame(
current_pipeline_stage_ = ANIMATE_PIPELINE_STAGE;
- // Synchronizes scroll offsets and page scale deltas (for pinch zoom) from the
- // compositor thread thread to the main thread for both cc and and its
- // client (e.g. Blink).
- layer_tree_host_->ApplyScrollAndScale(
- begin_main_frame_state->scroll_info.get());
+ // Check now if we should stop deferring commits due to a timeout. We
+ // may also stop deferring in BeginMainFrame, but maintain the status
+ // from this point to keep scroll in sync.
+ if (defer_commits_ && base::TimeTicks::Now() > commits_restart_time_) {
+ StopDeferringCommits(PaintHoldingCommitTrigger::kTimeout);
+ }
+ skip_commit |= defer_commits_;
+
+ if (!skip_commit) {
+ // Synchronizes scroll offsets and page scale deltas (for pinch zoom) from
+ // the compositor thread to the main thread for both cc and and its client
+ // (e.g. Blink). Do not do this if we explicitly plan to not commit the
+ // layer tree, to prevent scroll offsets getting out of sync.
+ layer_tree_host_->ApplyScrollAndScale(
+ begin_main_frame_state->scroll_info.get());
+ }
layer_tree_host_->WillBeginMainFrame();
layer_tree_host_->RecordStartOfFrameMetrics();
@@ -230,14 +239,10 @@ void ProxyMain::BeginMainFrame(
// what this does.
layer_tree_host_->RequestMainFrameUpdate();
- // Check now if we should stop deferring commits
- if (defer_commits_ && base::TimeTicks::Now() > commits_restart_time_) {
- StopDeferringCommits(PaintHoldingCommitTrigger::kTimeout);
- }
-
- // At this point the main frame may have deferred commits to avoid committing
- // right now, or we may be deferring commits but not deferring main
- // frame updates.
+ // At this point the main frame may have deferred main frame updates to
+ // avoid committing right now, or we may be deferring commits but not
+ // deferring main frame updates. Either may have changed the status
+ // of the defer... flags, so re-evaluate skip_commit.
skip_commit |= defer_main_frame_update_ || defer_commits_;
if (skip_commit) {
@@ -252,7 +257,7 @@ void ProxyMain::BeginMainFrame(
base::Unretained(proxy_impl_.get()),
CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT,
begin_main_frame_start_time,
- base::Passed(&empty_swap_promises)));
+ std::move(empty_swap_promises)));
// We intentionally don't report CommitComplete() here since it was aborted
// prematurely and we're waiting to do another commit in the future.
// When we stop deferring commits, we should resume any previously requested
@@ -295,11 +300,11 @@ void ProxyMain::BeginMainFrame(
std::vector<std::unique_ptr<SwapPromise>> swap_promises =
layer_tree_host_->GetSwapPromiseManager()->TakeSwapPromises();
ImplThreadTaskRunner()->PostTask(
- FROM_HERE, base::BindOnce(&ProxyImpl::BeginMainFrameAbortedOnImpl,
- base::Unretained(proxy_impl_.get()),
- CommitEarlyOutReason::FINISHED_NO_UPDATES,
- begin_main_frame_start_time,
- base::Passed(&swap_promises)));
+ FROM_HERE,
+ base::BindOnce(&ProxyImpl::BeginMainFrameAbortedOnImpl,
+ base::Unretained(proxy_impl_.get()),
+ CommitEarlyOutReason::FINISHED_NO_UPDATES,
+ begin_main_frame_start_time, std::move(swap_promises)));
// Although the commit is internally aborted, this is because it has been
// detected to be a no-op. From the perspective of an embedder, this commit
@@ -315,7 +320,7 @@ void ProxyMain::BeginMainFrame(
ui::LatencyInfo new_latency_info(ui::SourceEventType::FRAME);
new_latency_info.AddLatencyNumberWithTimestamp(
ui::LATENCY_BEGIN_FRAME_RENDERER_MAIN_COMPONENT,
- begin_main_frame_state->begin_frame_args.frame_time, 1);
+ begin_main_frame_state->begin_frame_args.frame_time);
layer_tree_host_->QueueSwapPromise(
std::make_unique<LatencyInfoSwapPromise>(new_latency_info));
@@ -365,12 +370,6 @@ bool ProxyMain::IsStarted() const {
return started_;
}
-bool ProxyMain::CommitToActiveTree() const {
- // With ProxyMain, we use a pending tree and activate it once it's ready to
- // draw to allow input to modify the active tree and draw during raster.
- return false;
-}
-
void ProxyMain::SetLayerTreeFrameSink(
LayerTreeFrameSink* layer_tree_frame_sink) {
ImplThreadTaskRunner()->PostTask(
diff --git a/chromium/cc/trees/proxy_main.h b/chromium/cc/trees/proxy_main.h
index 7b110c08a7d..515f1e10de9 100644
--- a/chromium/cc/trees/proxy_main.h
+++ b/chromium/cc/trees/proxy_main.h
@@ -72,7 +72,6 @@ class CC_EXPORT ProxyMain : public Proxy {
private:
// Proxy implementation.
bool IsStarted() const override;
- bool CommitToActiveTree() const override;
void SetLayerTreeFrameSink(
LayerTreeFrameSink* layer_tree_frame_sink) override;
void SetVisible(bool visible) override;
@@ -156,9 +155,9 @@ class CC_EXPORT ProxyMain : public Proxy {
// WeakPtrs generated by this factory will be invalidated when
// LayerTreeFrameSink is released.
- base::WeakPtrFactory<ProxyMain> frame_sink_bound_weak_factory_;
+ base::WeakPtrFactory<ProxyMain> frame_sink_bound_weak_factory_{this};
- base::WeakPtrFactory<ProxyMain> weak_factory_;
+ base::WeakPtrFactory<ProxyMain> weak_factory_{this};
};
} // namespace cc
diff --git a/chromium/cc/trees/scroll_node.cc b/chromium/cc/trees/scroll_node.cc
index 69b7b3318f5..50227da93d4 100644
--- a/chromium/cc/trees/scroll_node.cc
+++ b/chromium/cc/trees/scroll_node.cc
@@ -7,7 +7,7 @@
#include "cc/base/math_util.h"
#include "cc/input/main_thread_scrolling_reason.h"
#include "cc/layers/layer.h"
-#include "cc/trees/element_id.h"
+#include "cc/paint/element_id.h"
#include "cc/trees/property_tree.h"
#include "base/trace_event/traced_value.h"
diff --git a/chromium/cc/trees/scroll_node.h b/chromium/cc/trees/scroll_node.h
index de9f9343c8d..1d2e6fa789e 100644
--- a/chromium/cc/trees/scroll_node.h
+++ b/chromium/cc/trees/scroll_node.h
@@ -9,8 +9,8 @@
#include "cc/cc_export.h"
#include "cc/input/overscroll_behavior.h"
#include "cc/input/scroll_snap_data.h"
+#include "cc/paint/element_id.h"
#include "cc/paint/filter_operations.h"
-#include "cc/trees/element_id.h"
#include "ui/gfx/geometry/size.h"
namespace base {
diff --git a/chromium/cc/trees/single_thread_proxy.cc b/chromium/cc/trees/single_thread_proxy.cc
index d74fe26e408..0bc215ea7c4 100644
--- a/chromium/cc/trees/single_thread_proxy.cc
+++ b/chromium/cc/trees/single_thread_proxy.cc
@@ -27,6 +27,7 @@
#include "cc/trees/scoped_abort_remaining_swap_promises.h"
#include "components/viz/common/frame_sinks/delay_based_time_source.h"
#include "components/viz/common/gpu/context_provider.h"
+#include "ui/gfx/presentation_feedback.h"
namespace cc {
@@ -56,9 +57,7 @@ SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host,
inside_synchronous_composite_(false),
needs_impl_frame_(false),
layer_tree_frame_sink_creation_requested_(false),
- layer_tree_frame_sink_lost_(true),
- frame_sink_bound_weak_factory_(this),
- weak_factory_(this) {
+ layer_tree_frame_sink_lost_(true) {
TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy");
DCHECK(task_runner_provider_);
DCHECK(task_runner_provider_->IsMainThread());
@@ -75,7 +74,7 @@ void SingleThreadProxy::Start() {
host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this);
if (settings.single_thread_proxy_scheduler && !scheduler_on_impl_thread_) {
SchedulerSettings scheduler_settings(settings.ToSchedulerSettings());
- scheduler_settings.commit_to_active_tree = CommitToActiveTree();
+ scheduler_settings.commit_to_active_tree = true;
std::unique_ptr<CompositorTimingHistory> compositor_timing_history(
new CompositorTimingHistory(
@@ -102,12 +101,6 @@ bool SingleThreadProxy::IsStarted() const {
return !!host_impl_;
}
-bool SingleThreadProxy::CommitToActiveTree() const {
- // With SingleThreadProxy we skip the pending tree and commit directly to the
- // active tree.
- return true;
-}
-
void SingleThreadProxy::SetVisible(bool visible) {
TRACE_EVENT1("cc", "SingleThreadProxy::SetVisible", "visible", visible);
DebugScopedSetImplThread impl(task_runner_provider_);
@@ -436,6 +429,10 @@ bool SingleThreadProxy::IsInsideDraw() {
return inside_draw_;
}
+bool SingleThreadProxy::IsBeginMainFrameExpected() {
+ return true;
+}
+
void SingleThreadProxy::DidActivateSyncTree() {
CommitComplete();
}
@@ -525,6 +522,11 @@ void SingleThreadProxy::DidPresentCompositorFrameOnImplThread(
const gfx::PresentationFeedback& feedback) {
layer_tree_host_->DidPresentCompositorFrame(frame_token, std::move(callbacks),
feedback);
+
+ if (scheduler_on_impl_thread_) {
+ scheduler_on_impl_thread_->DidPresentCompositorFrame(frame_token,
+ feedback.timestamp);
+ }
}
void SingleThreadProxy::NotifyAnimationWorkletStateChange(
@@ -533,6 +535,12 @@ void SingleThreadProxy::NotifyAnimationWorkletStateChange(
layer_tree_host_->NotifyAnimationWorkletStateChange(state, element_list_type);
}
+void SingleThreadProxy::NotifyPaintWorkletStateChange(
+ Scheduler::PaintWorkletState state) {
+ // Off-Thread PaintWorklet is only supported on the threaded compositor.
+ NOTREACHED();
+}
+
void SingleThreadProxy::RequestBeginMainFrameNotExpected(bool new_state) {
if (scheduler_on_impl_thread_) {
scheduler_on_impl_thread_->SetMainThreadWantsBeginMainFrameNotExpected(
@@ -605,6 +613,7 @@ void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time,
if (raster) {
LayerTreeHostImpl::FrameData frame;
frame.begin_frame_ack = viz::BeginFrameAck(begin_frame_args, true);
+ frame.origin_begin_main_frame_args = begin_frame_args;
DoComposite(&frame);
}
@@ -666,9 +675,11 @@ DrawResult SingleThreadProxy::DoComposite(LayerTreeHostImpl::FrameData* frame) {
draw_frame = draw_result == DRAW_SUCCESS;
if (draw_frame) {
if (host_impl_->DrawLayers(frame)) {
- if (scheduler_on_impl_thread_)
+ if (scheduler_on_impl_thread_) {
// Drawing implies we submitted a frame to the LayerTreeFrameSink.
- scheduler_on_impl_thread_->DidSubmitCompositorFrame();
+ scheduler_on_impl_thread_->DidSubmitCompositorFrame(
+ frame->frame_token);
+ }
single_thread_client_->DidSubmitCompositorFrame();
}
}
@@ -744,7 +755,7 @@ void SingleThreadProxy::ScheduledActionSendBeginMainFrame(
task_runner_provider_->MainThreadTaskRunner()->PostTask(
FROM_HERE, base::BindOnce(&SingleThreadProxy::BeginMainFrame,
weak_factory_.GetWeakPtr(), begin_frame_args));
- host_impl_->DidSendBeginMainFrame();
+ host_impl_->DidSendBeginMainFrame(begin_frame_args);
}
void SingleThreadProxy::FrameIntervalUpdated(base::TimeDelta interval) {
@@ -823,8 +834,7 @@ void SingleThreadProxy::BeginMainFrame(
// know we will commit since QueueSwapPromise itself requests a commit.
ui::LatencyInfo new_latency_info(ui::SourceEventType::FRAME);
new_latency_info.AddLatencyNumberWithTimestamp(
- ui::LATENCY_BEGIN_FRAME_UI_MAIN_COMPONENT, begin_frame_args.frame_time,
- 1);
+ ui::LATENCY_BEGIN_FRAME_UI_MAIN_COMPONENT, begin_frame_args.frame_time);
layer_tree_host_->QueueSwapPromise(
std::make_unique<LatencyInfoSwapPromise>(new_latency_info));
@@ -863,7 +873,9 @@ void SingleThreadProxy::BeginMainFrameAbortedOnImplThread(
DCHECK(!host_impl_->pending_tree());
std::vector<std::unique_ptr<SwapPromise>> empty_swap_promises;
- host_impl_->BeginMainFrameAborted(reason, std::move(empty_swap_promises));
+ host_impl_->BeginMainFrameAborted(
+ reason, std::move(empty_swap_promises),
+ scheduler_on_impl_thread_->last_dispatched_begin_main_frame_args());
scheduler_on_impl_thread_->BeginMainFrameAborted(reason);
}
@@ -872,6 +884,8 @@ DrawResult SingleThreadProxy::ScheduledActionDrawIfPossible() {
LayerTreeHostImpl::FrameData frame;
frame.begin_frame_ack =
scheduler_on_impl_thread_->CurrentBeginFrameAckForActiveTree();
+ frame.origin_begin_main_frame_args =
+ scheduler_on_impl_thread_->last_activate_origin_frame_args();
return DoComposite(&frame);
}
diff --git a/chromium/cc/trees/single_thread_proxy.h b/chromium/cc/trees/single_thread_proxy.h
index 97a449b3442..320688ea79b 100644
--- a/chromium/cc/trees/single_thread_proxy.h
+++ b/chromium/cc/trees/single_thread_proxy.h
@@ -41,7 +41,6 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
// Proxy implementation
bool IsStarted() const override;
- bool CommitToActiveTree() const override;
void SetLayerTreeFrameSink(
LayerTreeFrameSink* layer_tree_frame_sink) override;
void ReleaseLayerTreeFrameSink() override;
@@ -115,6 +114,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
void PostAnimationEventsToMainThreadOnImplThread(
std::unique_ptr<MutatorEvents> events) override;
bool IsInsideDraw() override;
+ bool IsBeginMainFrameExpected() override;
void RenewTreePriority() override {}
void PostDelayedAnimationTaskOnImplThread(base::OnceClosure task,
base::TimeDelta delay) override {}
@@ -134,6 +134,8 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
void NotifyAnimationWorkletStateChange(
AnimationWorkletMutationState state,
ElementListType element_list_type) override;
+ void NotifyPaintWorkletStateChange(
+ Scheduler::PaintWorkletState state) override;
void RequestNewLayerTreeFrameSink();
@@ -206,9 +208,9 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
// WeakPtrs generated by this factory will be invalidated when
// LayerTreeFrameSink is released.
- base::WeakPtrFactory<SingleThreadProxy> frame_sink_bound_weak_factory_;
+ base::WeakPtrFactory<SingleThreadProxy> frame_sink_bound_weak_factory_{this};
- base::WeakPtrFactory<SingleThreadProxy> weak_factory_;
+ base::WeakPtrFactory<SingleThreadProxy> weak_factory_{this};
};
// For use in the single-threaded case. In debug builds, it pretends that the
diff --git a/chromium/cc/trees/transform_node.h b/chromium/cc/trees/transform_node.h
index 5a19ccec9e0..4f123a6390f 100644
--- a/chromium/cc/trees/transform_node.h
+++ b/chromium/cc/trees/transform_node.h
@@ -6,7 +6,7 @@
#define CC_TREES_TRANSFORM_NODE_H_
#include "cc/cc_export.h"
-#include "cc/trees/element_id.h"
+#include "cc/paint/element_id.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/geometry/scroll_offset.h"
#include "ui/gfx/transform.h"
@@ -67,7 +67,8 @@ struct CC_EXPORT TransformNode {
// context.
int sorting_context_id;
- // TODO(vollick): will be moved when accelerated effects are implemented.
+ // True if |TransformTree::UpdateLocalTransform| needs to be called which
+ // will update |to_parent| and |source_to_parent| (if possible).
bool needs_local_transform_update : 1;
// Whether this node or any ancestor has a potentially running
diff --git a/chromium/cc/trees/tree_synchronizer.cc b/chromium/cc/trees/tree_synchronizer.cc
index 9e329f02eaa..393e45b1167 100644
--- a/chromium/cc/trees/tree_synchronizer.cc
+++ b/chromium/cc/trees/tree_synchronizer.cc
@@ -41,14 +41,14 @@ static bool LayerHasValidPropertyTreeIndices(LayerImpl* layer) {
}
static bool LayerWillPushProperties(LayerTreeHost* host, Layer* layer) {
- return base::ContainsKey(host->LayersThatShouldPushProperties(), layer);
+ return base::Contains(host->LayersThatShouldPushProperties(), layer);
}
static bool LayerWillPushProperties(LayerTreeImpl* tree, LayerImpl* layer) {
- return base::ContainsKey(tree->LayersThatShouldPushProperties(), layer) ||
+ return base::Contains(tree->LayersThatShouldPushProperties(), layer) ||
// TODO(crbug.com/303943): Stop always pushing PictureLayerImpl
// properties.
- base::ContainsValue(tree->picture_layers(), layer);
+ base::Contains(tree->picture_layers(), layer);
}
#endif
diff --git a/chromium/cc/trees/tree_synchronizer_unittest.cc b/chromium/cc/trees/tree_synchronizer_unittest.cc
index b7a3dc02eee..6d0d4e5688e 100644
--- a/chromium/cc/trees/tree_synchronizer_unittest.cc
+++ b/chromium/cc/trees/tree_synchronizer_unittest.cc
@@ -200,7 +200,7 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeFromEmpty) {
host_->pending_tree());
LayerImpl* root = host_->pending_tree()->root_layer_for_testing();
- EXPECT_TRUE(base::ContainsKey(
+ EXPECT_TRUE(base::Contains(
host_->pending_tree()->LayersThatShouldPushProperties(), root));
ExpectTreesAreIdentical(layer_tree_root.get(),
@@ -226,7 +226,7 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndPushPropertiesFromEmpty) {
// layers are created on pending tree and they all need to push properties to
// active tree.
LayerImpl* root = host_->pending_tree()->root_layer_for_testing();
- EXPECT_TRUE(base::ContainsKey(
+ EXPECT_TRUE(base::Contains(
host_->pending_tree()->LayersThatShouldPushProperties(), root));
ExpectTreesAreIdentical(layer_tree_root.get(),
@@ -242,20 +242,20 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndPushPropertiesFromEmpty) {
host_->active_tree());
TreeSynchronizer::PushLayerProperties(host_->pending_tree(),
host_->active_tree());
- EXPECT_FALSE(base::ContainsKey(
+ EXPECT_FALSE(base::Contains(
host_->pending_tree()->LayersThatShouldPushProperties(), root));
// Set the main thread root layer needs push properties.
layer_tree_root->SetNeedsPushProperties();
- EXPECT_TRUE(base::ContainsKey(host_->LayersThatShouldPushProperties(),
- layer_tree_root.get()));
+ EXPECT_TRUE(base::Contains(host_->LayersThatShouldPushProperties(),
+ layer_tree_root.get()));
// When sync from main thread, the needs push properties status is carried
// over to pending tree.
TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
host_->pending_tree());
TreeSynchronizer::PushLayerProperties(host_.get(), host_->pending_tree());
- EXPECT_TRUE(base::ContainsKey(
+ EXPECT_TRUE(base::Contains(
host_->pending_tree()->LayersThatShouldPushProperties(), root));
}
@@ -278,8 +278,8 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeReusingLayers) {
LayerImpl* layer_impl_tree_root =
host_->pending_tree()->root_layer_for_testing();
EXPECT_TRUE(
- base::ContainsKey(host_->pending_tree()->LayersThatShouldPushProperties(),
- layer_impl_tree_root));
+ base::Contains(host_->pending_tree()->LayersThatShouldPushProperties(),
+ layer_impl_tree_root));
ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
host_->pending_tree());
@@ -522,12 +522,12 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeThenDestroy) {
ASSERT_EQ(3u, layer_impl_destruction_list.size());
- EXPECT_TRUE(base::ContainsValue(layer_impl_destruction_list,
- old_tree_root_layer_id));
- EXPECT_TRUE(base::ContainsValue(layer_impl_destruction_list,
- old_tree_first_child_layer_id));
- EXPECT_TRUE(base::ContainsValue(layer_impl_destruction_list,
- old_tree_second_child_layer_id));
+ EXPECT_TRUE(
+ base::Contains(layer_impl_destruction_list, old_tree_root_layer_id));
+ EXPECT_TRUE(base::Contains(layer_impl_destruction_list,
+ old_tree_first_child_layer_id));
+ EXPECT_TRUE(base::Contains(layer_impl_destruction_list,
+ old_tree_second_child_layer_id));
}
// Constructs+syncs a tree with mask layer.
diff --git a/chromium/cc/trees/viewport_layers.h b/chromium/cc/trees/viewport_layers.h
index 7cdb88bd27e..b92d1190bc1 100644
--- a/chromium/cc/trees/viewport_layers.h
+++ b/chromium/cc/trees/viewport_layers.h
@@ -6,7 +6,8 @@
#define CC_TREES_VIEWPORT_LAYERS_H_
#include "base/memory/ref_counted.h"
-#include "cc/trees/element_id.h"
+#include "cc/cc_export.h"
+#include "cc/paint/element_id.h"
namespace cc {
class Layer;