summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cc/BUILD.gn1
-rw-r--r--cc/base/synced_property.h172
-rw-r--r--cc/cc.gyp1
-rw-r--r--cc/input/top_controls_manager_unittest.cc3
-rw-r--r--cc/layers/layer_impl.cc19
-rw-r--r--cc/layers/picture_layer_impl_unittest.cc2
-rw-r--r--cc/test/fake_layer_tree_host_impl.cc2
-rw-r--r--cc/trees/layer_tree_host.cc9
-rw-r--r--cc/trees/layer_tree_host_common_perftest.cc2
-rw-r--r--cc/trees/layer_tree_host_impl.cc54
-rw-r--r--cc/trees/layer_tree_host_impl.h3
-rw-r--r--cc/trees/layer_tree_host_impl_unittest.cc95
-rw-r--r--cc/trees/layer_tree_host_unittest.cc24
-rw-r--r--cc/trees/layer_tree_host_unittest_scroll.cc28
-rw-r--r--cc/trees/layer_tree_impl.cc140
-rw-r--r--cc/trees/layer_tree_impl.h47
-rw-r--r--cc/trees/layer_tree_impl_unittest.cc6
17 files changed, 400 insertions, 208 deletions
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index c744c5b..3c1f7bc 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -62,6 +62,7 @@ component("cc") {
"base/swap_promise_monitor.h",
"base/switches.cc",
"base/switches.h",
+ "base/synced_property.h",
"base/tiling_data.cc",
"base/tiling_data.h",
"base/time_util.h",
diff --git a/cc/base/synced_property.h b/cc/base/synced_property.h
new file mode 100644
index 0000000..5c47932
--- /dev/null
+++ b/cc/base/synced_property.h
@@ -0,0 +1,172 @@
+// Copyright 2014 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_BASE_SYNCED_PROPERTY_H_
+#define CC_BASE_SYNCED_PROPERTY_H_
+
+#include "base/memory/ref_counted.h"
+
+namespace cc {
+
+// This class is the basic primitive used for impl-thread scrolling. Its job is
+// to sanely resolve the case where both the main and impl thread are
+// concurrently updating the same value (for example, when Javascript sets the
+// scroll offset during an ongoing impl-side scroll).
+//
+// There are three trees (main, pending, and active) and therefore also three
+// places with their own idea of the scroll offsets (and analogous properties
+// like page scale). Objects of this class are meant to be held on the Impl
+// side, and contain the canonical reference for the pending and active trees,
+// as well as keeping track of the latest delta sent to the main thread (which
+// is necessary for conflict resolution).
+
+template <typename T>
+class SyncedProperty : public base::RefCounted<SyncedProperty<T>> {
+ public:
+ SyncedProperty() {}
+
+ // Returns the canonical value for the specified tree, including the sum of
+ // all deltas. The pending tree should use this for activation purposes and
+ // the active tree should use this for drawing.
+ typename T::ValueType Current(bool is_active_tree) const {
+ if (is_active_tree)
+ return active_base_.Combine(active_delta_).get();
+ else
+ return pending_base_.Combine(PendingDelta()).get();
+ }
+
+ // Sets the value on the impl thread, due to an impl-thread-originating
+ // action. Returns true if this had any effect. This will remain
+ // impl-thread-only information at first, and will get pulled back to the main
+ // thread on the next call of PullDeltaToMainThread (which happens right
+ // before the commit).
+ bool SetCurrent(typename T::ValueType current) {
+ T delta = T(current).InverseCombine(active_base_);
+ if (active_delta_.get() == delta.get())
+ return false;
+
+ active_delta_ = delta;
+ return true;
+ }
+
+ // Returns the difference between the last value that was committed and
+ // activated from the main thread, and the current total value.
+ typename T::ValueType Delta() const { return active_delta_.get(); }
+
+ // Returns the latest active tree delta and also makes a note that this value
+ // was sent to the main thread.
+ typename T::ValueType PullDeltaForMainThread() {
+ sent_delta_ = active_delta_;
+ return active_delta_.get();
+ }
+
+ // Push the latest value from the main thread onto pending tree-associated
+ // state. Returns true if this had any effect.
+ bool PushFromMainThread(typename T::ValueType main_thread_value) {
+ if (pending_base_.get() == main_thread_value)
+ return false;
+
+ pending_base_ = T(main_thread_value);
+
+ return true;
+ }
+
+ // Push the value associated with the pending tree to be the active base
+ // value. As part of this, subtract the last sent value from the active tree
+ // delta (which will make the delta zero at steady state, or make it contain
+ // only the difference since the last send).
+ bool PushPendingToActive() {
+ if (active_base_.get() == pending_base_.get() &&
+ sent_delta_.get() == T::Identity().get())
+ return false;
+
+ active_base_ = pending_base_;
+ active_delta_ = PendingDelta();
+ sent_delta_ = T::Identity();
+
+ return true;
+ }
+
+ // This simulates the consequences of the sent value getting committed and
+ // activated. The value sent to the main thread ends up combined with the
+ // active value, and the sent_delta is subtracted from the delta.
+ void AbortCommit() {
+ active_base_ = active_base_.Combine(sent_delta_);
+ active_delta_ = PendingDelta();
+ sent_delta_ = T::Identity();
+ }
+
+ private:
+ // The new delta we would use if we decide to activate now. This delta
+ // excludes the amount that we expect the main thread to reflect back at the
+ // impl thread during the commit.
+ T PendingDelta() const { return active_delta_.InverseCombine(sent_delta_); }
+
+ // Value last committed to the pending tree.
+ T pending_base_;
+ // Value last committed to the active tree (on the last activation).
+ T active_base_;
+ // The difference between the active_base_ and the user-perceived value.
+ T active_delta_;
+ // The value sent to the main thread (on the last BeginFrame); this is always
+ // identity outside of the BeginFrame-to-activation interval.
+ T sent_delta_;
+
+ friend class base::RefCounted<SyncedProperty<T>>;
+ ~SyncedProperty() {}
+};
+
+// SyncedProperty's delta-based conflict resolution logic makes sense for any
+// mathematical group. In practice, there are two that are useful:
+// 1. Numbers/vectors with addition and identity = 0 (like scroll offsets)
+// 2. Real numbers with multiplication and identity = 1 (like page scale)
+
+template <class V>
+class AdditionGroup {
+ public:
+ typedef V ValueType;
+
+ AdditionGroup() : value_(Identity().get()) {}
+ explicit AdditionGroup(V value) : value_(value) {}
+
+ V& get() { return value_; }
+ const V& get() const { return value_; }
+
+ static AdditionGroup<V> Identity() { return AdditionGroup(V()); } // zero
+ AdditionGroup<V> Combine(AdditionGroup<V> p) const {
+ return AdditionGroup<V>(value_ + p.value_);
+ }
+ AdditionGroup<V> InverseCombine(AdditionGroup<V> p) const {
+ return AdditionGroup<V>(value_ - p.value_);
+ }
+
+ private:
+ V value_;
+};
+
+class ScaleGroup {
+ public:
+ typedef float ValueType;
+
+ ScaleGroup() : value_(Identity().get()) {}
+ explicit ScaleGroup(float value) : value_(value) {}
+
+ float& get() { return value_; }
+ const float& get() const { return value_; }
+
+ static ScaleGroup Identity() { return ScaleGroup(1.f); }
+ ScaleGroup Combine(ScaleGroup p) const {
+ return ScaleGroup(value_ * p.value_);
+ }
+ ScaleGroup InverseCombine(ScaleGroup p) const {
+ return ScaleGroup(value_ / p.value_);
+ }
+
+ private:
+ float value_;
+};
+
+} // namespace cc
+
+#endif // CC_BASE_SYNCED_PROPERTY_H_
diff --git a/cc/cc.gyp b/cc/cc.gyp
index 3374251..732bc0d 100644
--- a/cc/cc.gyp
+++ b/cc/cc.gyp
@@ -88,6 +88,7 @@
'base/swap_promise.h',
'base/swap_promise_monitor.cc',
'base/swap_promise_monitor.h',
+ 'base/synced_property.h',
'base/switches.cc',
'base/switches.h',
'base/tiling_data.cc',
diff --git a/cc/input/top_controls_manager_unittest.cc b/cc/input/top_controls_manager_unittest.cc
index 77b40c9..b64cb9e 100644
--- a/cc/input/top_controls_manager_unittest.cc
+++ b/cc/input/top_controls_manager_unittest.cc
@@ -31,7 +31,8 @@ class MockTopControlsManagerClient : public TopControlsManagerClient {
top_controls_top_offset_(0.f),
top_controls_show_threshold_(top_controls_show_threshold),
top_controls_hide_threshold_(top_controls_hide_threshold) {
- active_tree_ = LayerTreeImpl::create(&host_impl_);
+ active_tree_ =
+ LayerTreeImpl::create(&host_impl_, new SyncedProperty<ScaleGroup>);
root_scroll_layer_ = LayerImpl::Create(active_tree_.get(), 1);
}
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc
index a99ede8..066d26c 100644
--- a/cc/layers/layer_impl.cc
+++ b/cc/layers/layer_impl.cc
@@ -621,9 +621,6 @@ gfx::Vector2dF LayerImpl::FixedContainerSizeDelta() const {
if (!scroll_clip_layer_)
return gfx::Vector2dF();
- float scale_delta = layer_tree_impl()->page_scale_delta();
- float scale = layer_tree_impl()->page_scale_factor();
-
gfx::Vector2dF delta_from_scroll = scroll_clip_layer_->bounds_delta();
// In virtual-viewport mode, we don't need to compensate for pinch zoom or
@@ -632,6 +629,10 @@ gfx::Vector2dF LayerImpl::FixedContainerSizeDelta() const {
if (layer_tree_impl()->settings().use_pinch_virtual_viewport)
return delta_from_scroll;
+ float scale_delta = layer_tree_impl()->page_scale_delta();
+ float scale = layer_tree_impl()->current_page_scale_factor() /
+ layer_tree_impl()->page_scale_delta();
+
delta_from_scroll.Scale(1.f / scale);
// The delta-from-pinch component requires some explanation: A viewport of
@@ -1213,7 +1214,7 @@ gfx::ScrollOffset LayerImpl::MaxScrollOffset() const {
const gfx::Transform& layer_transform = current_layer->transform();
if (current_layer == page_scale_layer) {
DCHECK(layer_transform.IsIdentity());
- current_layer_scale = layer_tree_impl()->total_page_scale_factor();
+ current_layer_scale = layer_tree_impl()->current_page_scale_factor();
} else {
// TODO(wjmaclean) Should we allow for translation too?
DCHECK(layer_transform.IsScale2d());
@@ -1230,7 +1231,7 @@ gfx::ScrollOffset LayerImpl::MaxScrollOffset() const {
// page scale layer may coincide with the clip layer, and so this is
// necessary.
if (page_scale_layer == scroll_clip_layer_)
- scale_factor *= layer_tree_impl()->total_page_scale_factor();
+ scale_factor *= layer_tree_impl()->current_page_scale_factor();
scaled_scroll_bounds.SetSize(scale_factor * scaled_scroll_bounds.width(),
scale_factor * scaled_scroll_bounds.height());
@@ -1289,7 +1290,7 @@ void LayerImpl::SetScrollbarPosition(ScrollbarLayerImplBase* scrollbar_layer,
const gfx::Transform& layer_transform = current_layer->transform();
if (current_layer == page_scale_layer) {
DCHECK(layer_transform.IsIdentity());
- float scale_factor = layer_tree_impl()->total_page_scale_factor();
+ float scale_factor = layer_tree_impl()->current_page_scale_factor();
current_offset.Scale(scale_factor);
scroll_rect.Scale(scale_factor);
} else {
@@ -1307,8 +1308,8 @@ void LayerImpl::SetScrollbarPosition(ScrollbarLayerImplBase* scrollbar_layer,
// page scale layer may coincide with the clip layer, and so this is
// necessary.
if (page_scale_layer == scrollbar_clip_layer) {
- scroll_rect.Scale(layer_tree_impl()->total_page_scale_factor());
- current_offset.Scale(layer_tree_impl()->total_page_scale_factor());
+ scroll_rect.Scale(layer_tree_impl()->current_page_scale_factor());
+ current_offset.Scale(layer_tree_impl()->current_page_scale_factor());
}
bool scrollbar_needs_animation = false;
@@ -1343,7 +1344,7 @@ void LayerImpl::SetScrollbarPosition(ScrollbarLayerImplBase* scrollbar_layer,
// Non-overlay scrollbars also shouldn't trigger animations.
bool is_animatable_scrollbar =
scrollbar_layer->is_overlay_scrollbar() &&
- ((layer_tree_impl()->total_page_scale_factor() >
+ ((layer_tree_impl()->current_page_scale_factor() >
layer_tree_impl()->min_page_scale_factor()) ||
!layer_tree_impl()->settings().use_pinch_zoom_scrollbars);
if (is_animatable_scrollbar)
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc
index ce66675..7c2dbcb 100644
--- a/cc/layers/picture_layer_impl_unittest.cc
+++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -134,7 +134,7 @@ class PictureLayerImplTest : public testing::Test {
void SetupPendingTree(scoped_refptr<RasterSource> raster_source) {
host_impl_.CreatePendingTree();
- host_impl_.pending_tree()->SetPageScaleFactorAndLimits(1.f, 0.25f, 100.f);
+ host_impl_.pending_tree()->PushPageScaleFromMainThread(1.f, 0.25f, 100.f);
LayerTreeImpl* pending_tree = host_impl_.pending_tree();
// Steal from the recycled tree.
diff --git a/cc/test/fake_layer_tree_host_impl.cc b/cc/test/fake_layer_tree_host_impl.cc
index 305b856..bfac501 100644
--- a/cc/test/fake_layer_tree_host_impl.cc
+++ b/cc/test/fake_layer_tree_host_impl.cc
@@ -52,7 +52,7 @@ FakeLayerTreeHostImpl::~FakeLayerTreeHostImpl() {}
void FakeLayerTreeHostImpl::CreatePendingTree() {
LayerTreeHostImpl::CreatePendingTree();
float arbitrary_large_page_scale = 100000.f;
- pending_tree()->SetPageScaleFactorAndLimits(
+ pending_tree()->PushPageScaleFromMainThread(
1.f, 1.f / arbitrary_large_page_scale, arbitrary_large_page_scale);
}
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 6c7cfe0..bb90650 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -360,13 +360,8 @@ void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl* host_impl) {
sync_tree->RegisterSelection(selection_start_, selection_end_);
- float page_scale_delta =
- sync_tree->page_scale_delta() / sync_tree->sent_page_scale_delta();
- sync_tree->SetPageScaleValues(page_scale_factor_,
- min_page_scale_factor_,
- max_page_scale_factor_,
- page_scale_delta);
- sync_tree->set_sent_page_scale_delta(1.f);
+ sync_tree->PushPageScaleFromMainThread(
+ page_scale_factor_, min_page_scale_factor_, max_page_scale_factor_);
sync_tree->PassSwapPromises(&swap_promise_list_);
diff --git a/cc/trees/layer_tree_host_common_perftest.cc b/cc/trees/layer_tree_host_common_perftest.cc
index 39bcbe6..2fd2146 100644
--- a/cc/trees/layer_tree_host_common_perftest.cc
+++ b/cc/trees/layer_tree_host_common_perftest.cc
@@ -147,7 +147,7 @@ class CalcDrawPropsImplTest : public LayerTreeHostCommonPerfTest {
LayerTreeHostCommon::CalcDrawPropsImplInputs inputs(
active_tree->root_layer(), active_tree->DrawViewportSize(),
host_impl->DrawTransform(), active_tree->device_scale_factor(),
- active_tree->total_page_scale_factor(),
+ active_tree->current_page_scale_factor(),
active_tree->InnerViewportContainerLayer(), max_texture_size,
host_impl->settings().can_use_lcd_text,
host_impl->settings().layers_always_allowed_lcd_text,
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 0a45cb7..e9c8d88 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -237,7 +237,8 @@ LayerTreeHostImpl::LayerTreeHostImpl(
SetDebugState(settings.initial_debug_state);
// LTHI always has an active tree.
- active_tree_ = LayerTreeImpl::create(this);
+ active_tree_ = LayerTreeImpl::create(this, new SyncedProperty<ScaleGroup>());
+
TRACE_EVENT_OBJECT_CREATED_WITH_ID(
TRACE_DISABLED_BY_DEFAULT("cc.debug"), "cc::LayerTreeHostImpl", id_);
@@ -417,12 +418,10 @@ void LayerTreeHostImpl::StartPageScaleAnimation(
CubicBezierTimingFunction::Create(.8, 0, .3, .9);
// TODO(miletus) : Pass in ScrollOffset.
- page_scale_animation_ =
- PageScaleAnimation::Create(ScrollOffsetToVector2dF(scroll_total),
- active_tree_->total_page_scale_factor(),
- viewport_size,
- scaled_scrollable_size,
- timing_function.Pass());
+ page_scale_animation_ = PageScaleAnimation::Create(
+ ScrollOffsetToVector2dF(scroll_total),
+ active_tree_->current_page_scale_factor(), viewport_size,
+ scaled_scrollable_size, timing_function.Pass());
if (anchor_point) {
gfx::Vector2dF anchor(target_offset);
@@ -1108,7 +1107,8 @@ void LayerTreeHostImpl::BlockNotifyReadyToActivateForTesting(bool block) {
void LayerTreeHostImpl::ResetTreesForTesting() {
if (active_tree_)
active_tree_->DetachLayerTree();
- active_tree_ = LayerTreeImpl::create(this);
+ active_tree_ =
+ LayerTreeImpl::create(this, active_tree()->page_scale_factor());
if (pending_tree_)
pending_tree_->DetachLayerTree();
pending_tree_ = nullptr;
@@ -1432,7 +1432,7 @@ void LayerTreeHostImpl::OnCanDrawStateChangedForTree() {
CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() const {
CompositorFrameMetadata metadata;
metadata.device_scale_factor = device_scale_factor_;
- metadata.page_scale_factor = active_tree_->total_page_scale_factor();
+ metadata.page_scale_factor = active_tree_->current_page_scale_factor();
metadata.scrollable_viewport_size = active_tree_->ScrollableViewportSize();
metadata.root_layer_size = active_tree_->ScrollableSize();
metadata.min_page_scale_factor = active_tree_->min_page_scale_factor();
@@ -1758,14 +1758,12 @@ void LayerTreeHostImpl::CreatePendingTree() {
if (recycle_tree_)
recycle_tree_.swap(pending_tree_);
else
- pending_tree_ = LayerTreeImpl::create(this);
+ pending_tree_ =
+ LayerTreeImpl::create(this, active_tree()->page_scale_factor());
// Update the delta from the active tree, which may have
// adjusted its delta prior to the pending tree being created.
- DCHECK_EQ(1.f, pending_tree_->sent_page_scale_delta());
DCHECK_EQ(0.f, pending_tree_->sent_top_controls_delta());
- pending_tree_->SetPageScaleDelta(active_tree_->page_scale_delta() /
- active_tree_->sent_page_scale_delta());
pending_tree_->set_top_controls_delta(
active_tree_->top_controls_delta() -
active_tree_->sent_top_controls_delta());
@@ -2232,6 +2230,10 @@ void LayerTreeHostImpl::SetDeviceScaleFactor(float device_scale_factor) {
SetFullRootLayerDamage();
}
+void LayerTreeHostImpl::SetPageScaleOnActiveTree(float page_scale_factor) {
+ active_tree_->SetPageScaleOnActiveTree(page_scale_factor);
+}
+
const gfx::Rect LayerTreeHostImpl::ViewportRectForTilePriority() const {
if (viewport_rect_for_tile_priority_.IsEmpty())
return DeviceViewport();
@@ -2647,7 +2649,7 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy(
viewport_point, pending_delta);
} else {
applied_delta = ScrollLayerWithLocalDelta(
- layer_impl, pending_delta, active_tree_->total_page_scale_factor());
+ layer_impl, pending_delta, active_tree_->current_page_scale_factor());
}
const float kEpsilon = 0.1f;
@@ -2951,18 +2953,15 @@ void LayerTreeHostImpl::PinchGestureUpdate(float magnify_delta,
// Keep the center-of-pinch anchor specified by (x, y) in a stable
// position over the course of the magnify.
- float page_scale_delta = active_tree_->page_scale_delta();
- gfx::PointF previous_scale_anchor =
- gfx::ScalePoint(anchor, 1.f / page_scale_delta);
- active_tree_->SetPageScaleDelta(page_scale_delta * magnify_delta);
- page_scale_delta = active_tree_->page_scale_delta();
- gfx::PointF new_scale_anchor =
- gfx::ScalePoint(anchor, 1.f / page_scale_delta);
+ float page_scale = active_tree_->current_page_scale_factor();
+ gfx::PointF previous_scale_anchor = gfx::ScalePoint(anchor, 1.f / page_scale);
+ active_tree_->SetPageScaleOnActiveTree(page_scale * magnify_delta);
+ page_scale = active_tree_->current_page_scale_factor();
+ gfx::PointF new_scale_anchor = gfx::ScalePoint(anchor, 1.f / page_scale);
gfx::Vector2dF move = previous_scale_anchor - new_scale_anchor;
previous_pinch_anchor_ = anchor;
- move.Scale(1 / active_tree_->page_scale_factor());
// If clamping the inner viewport scroll offset causes a change, it should
// be accounted for from the intended move.
move -= InnerViewportScrollLayer()->ClampScrollToMaxScrollOffset();
@@ -3029,8 +3028,8 @@ scoped_ptr<ScrollAndScaleSet> LayerTreeHostImpl::ProcessScrollDeltas() {
scoped_ptr<ScrollAndScaleSet> scroll_info(new ScrollAndScaleSet());
CollectScrollDeltas(scroll_info.get(), active_tree_->root_layer());
- scroll_info->page_scale_delta = active_tree_->page_scale_delta();
- active_tree_->set_sent_page_scale_delta(scroll_info->page_scale_delta);
+ scroll_info->page_scale_delta =
+ active_tree_->page_scale_factor()->PullDeltaForMainThread();
scroll_info->swap_promises.swap(swap_promises_for_main_thread_scroll_update_);
scroll_info->top_controls_delta = active_tree()->top_controls_delta();
active_tree_->set_sent_top_controls_delta(scroll_info->top_controls_delta);
@@ -3072,9 +3071,8 @@ void LayerTreeHostImpl::AnimatePageScale(base::TimeTicks monotonic_time) {
if (!page_scale_animation_->IsAnimationStarted())
page_scale_animation_->StartAnimation(monotonic_time);
- active_tree_->SetPageScaleDelta(
- page_scale_animation_->PageScaleFactorAtTime(monotonic_time) /
- active_tree_->page_scale_factor());
+ active_tree_->SetPageScaleOnActiveTree(
+ page_scale_animation_->PageScaleFactorAtTime(monotonic_time));
gfx::ScrollOffset next_scroll = gfx::ScrollOffset(
page_scale_animation_->ScrollOffsetAtTime(monotonic_time));
@@ -3106,7 +3104,7 @@ void LayerTreeHostImpl::AnimateTopControls(base::TimeTicks time) {
return;
ScrollViewportBy(gfx::ScaleVector2d(
- scroll, 1.f / active_tree_->total_page_scale_factor()));
+ scroll, 1.f / active_tree_->current_page_scale_factor()));
SetNeedsRedraw();
client_->SetNeedsCommitOnImplThread();
client_->RenewTreePriority();
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index c248a21..39b0221 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -18,6 +18,7 @@
#include "cc/animation/animation_registrar.h"
#include "cc/animation/scrollbar_animation_controller.h"
#include "cc/base/cc_export.h"
+#include "cc/base/synced_property.h"
#include "cc/debug/micro_benchmark_controller_impl.h"
#include "cc/input/input_handler.h"
#include "cc/input/layer_scroll_offset_delegate.h"
@@ -359,6 +360,8 @@ class CC_EXPORT LayerTreeHostImpl
void SetDeviceScaleFactor(float device_scale_factor);
float device_scale_factor() const { return device_scale_factor_; }
+ void SetPageScaleOnActiveTree(float page_scale_factor);
+
const gfx::Transform& DrawTransform() const;
scoped_ptr<ScrollAndScaleSet> ProcessScrollDeltas();
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index f31cde0..24960e8 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -924,9 +924,9 @@ TEST_F(LayerTreeHostImplTest, ImplPinchZoom) {
// The impl-based pinch zoom should adjust the max scroll position.
{
- host_impl_->active_tree()->SetPageScaleFactorAndLimits(
+ host_impl_->active_tree()->PushPageScaleFromMainThread(
page_scale_factor, min_page_scale, max_page_scale);
- host_impl_->active_tree()->SetPageScaleDelta(1.f);
+ host_impl_->SetPageScaleOnActiveTree(page_scale_factor);
scroll_layer->SetScrollDelta(gfx::Vector2d());
float page_scale_delta = 2.f;
@@ -952,9 +952,9 @@ TEST_F(LayerTreeHostImplTest, ImplPinchZoom) {
// Scrolling after a pinch gesture should always be in local space. The
// scroll deltas have the page scale factor applied.
{
- host_impl_->active_tree()->SetPageScaleFactorAndLimits(
+ host_impl_->active_tree()->PushPageScaleFromMainThread(
page_scale_factor, min_page_scale, max_page_scale);
- host_impl_->active_tree()->SetPageScaleDelta(1.f);
+ host_impl_->SetPageScaleOnActiveTree(page_scale_factor);
scroll_layer->SetScrollDelta(gfx::Vector2d());
float page_scale_delta = 2.f;
@@ -1009,8 +1009,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) {
// Basic pinch zoom in gesture
{
- host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
- min_page_scale,
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
max_page_scale);
scroll_layer->SetScrollDelta(gfx::Vector2d());
@@ -1031,8 +1030,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) {
// Zoom-in clamping
{
- host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
- min_page_scale,
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
max_page_scale);
scroll_layer->SetScrollDelta(gfx::Vector2d());
float page_scale_delta = 10.f;
@@ -1050,8 +1048,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) {
// Zoom-out clamping
{
- host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
- min_page_scale,
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
max_page_scale);
scroll_layer->SetScrollDelta(gfx::Vector2d());
scroll_layer->SetScrollOffset(gfx::ScrollOffset(50, 50));
@@ -1072,8 +1069,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) {
// Two-finger panning should not happen based on pinch events only
{
- host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
- min_page_scale,
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
max_page_scale);
scroll_layer->SetScrollDelta(gfx::Vector2d());
scroll_layer->SetScrollOffset(gfx::ScrollOffset(20, 20));
@@ -1094,8 +1090,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) {
// Two-finger panning should work with interleaved scroll events
{
- host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
- min_page_scale,
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
max_page_scale);
scroll_layer->SetScrollDelta(gfx::Vector2d());
scroll_layer->SetScrollOffset(gfx::ScrollOffset(20, 20));
@@ -1117,9 +1112,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) {
// Two-finger panning should work when starting fully zoomed out.
{
- host_impl_->active_tree()->SetPageScaleFactorAndLimits(0.5f,
- 0.5f,
- 4.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(0.5f, 0.5f, 4.f);
scroll_layer->SetScrollDelta(gfx::Vector2d());
scroll_layer->SetScrollOffset(gfx::ScrollOffset(0, 0));
@@ -1157,8 +1150,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimation) {
// Non-anchor zoom-in
{
- host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
- min_page_scale,
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
max_page_scale);
scroll_layer->SetScrollOffset(gfx::ScrollOffset(50, 50));
@@ -1201,8 +1193,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimation) {
// Anchor zoom-out
{
- host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
- min_page_scale,
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
max_page_scale);
scroll_layer->SetScrollOffset(gfx::ScrollOffset(50, 50));
@@ -1258,8 +1249,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationNoOp) {
// Anchor zoom with unchanged page scale should not change scroll or scale.
{
- host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
- min_page_scale,
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
max_page_scale);
scroll_layer->SetScrollOffset(gfx::ScrollOffset(50, 50));
@@ -1296,8 +1286,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationTransferedOnSyncTreeActivate) {
float min_page_scale = 0.5f;
float max_page_scale = 4.f;
- host_impl_->sync_tree()->SetPageScaleFactorAndLimits(1.f,
- min_page_scale,
+ host_impl_->sync_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
max_page_scale);
host_impl_->ActivateSyncTree();
@@ -1527,7 +1516,7 @@ TEST_F(LayerTreeHostImplTest, ScrollbarFadePinchZoomScrollbars) {
base::TimeTicks fake_now = gfx::FrameTime::Now();
- host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 4.f);
EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
EXPECT_FALSE(did_request_animate_);
@@ -1554,7 +1543,7 @@ TEST_F(LayerTreeHostImplTest, ScrollbarFadePinchZoomScrollbars) {
EXPECT_FALSE(did_request_animate_);
// Make page scale > min so that subsequent scrolls will trigger fades.
- host_impl_->active_tree()->SetPageScaleDelta(1.1f);
+ host_impl_->SetPageScaleOnActiveTree(1.1f);
// After a scroll, a fade animation should be scheduled about 20ms from now.
host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel);
@@ -1669,7 +1658,7 @@ TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf2) {
TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) {
SetupScrollAndContentsLayers(gfx::Size(100, 100));
host_impl_->SetViewportSize(gfx::Size(50, 50));
- host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f);
DrawFrame();
{
CompositorFrameMetadata metadata =
@@ -1717,8 +1706,8 @@ TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) {
// Likewise if set from the main thread.
host_impl_->ProcessScrollDeltas();
- host_impl_->active_tree()->SetPageScaleFactorAndLimits(4.f, 0.5f, 4.f);
- host_impl_->active_tree()->SetPageScaleDelta(1.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(4.f, 0.5f, 4.f);
+ host_impl_->SetPageScaleOnActiveTree(4.f);
{
CompositorFrameMetadata metadata =
host_impl_->MakeCompositorFrameMetadata();
@@ -2438,7 +2427,7 @@ TEST_F(LayerTreeHostImplTopControlsTest,
// Need SetDrawsContent so ScrollBegin's hit test finds an actual layer.
outer_scroll->SetDrawsContent(true);
- host_impl_->active_tree()->SetPageScaleFactorAndLimits(2.f, 1.f, 2.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(2.f, 1.f, 2.f);
EXPECT_EQ(InputHandler::ScrollStarted,
host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
@@ -2507,7 +2496,7 @@ TEST_F(LayerTreeHostImplTopControlsTest, FixedContainerDelta) {
// Zoom in, since the fixed container is the outer viewport, the delta should
// not be scaled.
- host_impl_->active_tree()->SetPageScaleFactorAndLimits(page_scale, 1.f, 2.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(page_scale, 1.f, 2.f);
EXPECT_EQ(InputHandler::ScrollStarted,
host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
@@ -3022,8 +3011,7 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnMainThread) {
host_impl_->ScrollEnd();
// Set new page scale from main thread.
- host_impl_->active_tree()->SetPageScaleFactorAndLimits(page_scale,
- page_scale,
+ host_impl_->active_tree()->PushPageScaleFromMainThread(page_scale, page_scale,
page_scale);
scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
@@ -3057,7 +3045,7 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) {
Layer::INVALID_ID);
host_impl_->active_tree()->DidBecomeActive();
host_impl_->SetViewportSize(viewport_size);
- host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 1.f, page_scale);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, page_scale);
DrawFrame();
LayerImpl* root_scroll =
@@ -3089,7 +3077,7 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) {
EXPECT_EQ(expected_max_scroll, root_scroll->MaxScrollOffset());
// The page scale delta should match the new scale on the impl side.
- EXPECT_EQ(page_scale, host_impl_->active_tree()->total_page_scale_factor());
+ EXPECT_EQ(page_scale, host_impl_->active_tree()->current_page_scale_factor());
}
TEST_F(LayerTreeHostImplTest, PageScaleDeltaAppliedToRootScrollLayerOnly) {
@@ -3185,8 +3173,7 @@ TEST_F(LayerTreeHostImplTest, ScrollChildAndChangePageScaleOnMainThread) {
host_impl_->ScrollEnd();
float page_scale = 2.f;
- host_impl_->active_tree()->SetPageScaleFactorAndLimits(page_scale,
- 1.f,
+ host_impl_->active_tree()->PushPageScaleFromMainThread(page_scale, 1.f,
page_scale);
DrawOneFrame();
@@ -3341,8 +3328,8 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) {
// Scrolling should be adjusted from viewport space.
- host_impl_->active_tree()->SetPageScaleFactorAndLimits(2.f, 2.f, 2.f);
- host_impl_->active_tree()->SetPageScaleDelta(1.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(2.f, 2.f, 2.f);
+ host_impl_->SetPageScaleOnActiveTree(2.f);
scroll_delta = gfx::Vector2d(0, -2);
EXPECT_EQ(InputHandler::ScrollStarted,
@@ -3616,7 +3603,7 @@ TEST_F(LayerTreeHostImplTest, ScrollViewportRounding) {
host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds(
gfx::Size(width * scale - 1, height * scale));
host_impl_->SetDeviceScaleFactor(scale);
- host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f);
LayerImpl* inner_viewport_scroll_layer =
host_impl_->active_tree()->InnerViewportScrollLayer();
@@ -3717,16 +3704,16 @@ TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) {
EXPECT_EQ(0.f, scroll_delegate.max_page_scale_factor());
// Updating page scale immediately updates the delegate.
- host_impl_->active_tree()->SetPageScaleFactorAndLimits(2.f, 0.5f, 4.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(2.f, 0.5f, 4.f);
EXPECT_EQ(2.f, scroll_delegate.page_scale_factor());
EXPECT_EQ(0.5f, scroll_delegate.min_page_scale_factor());
EXPECT_EQ(4.f, scroll_delegate.max_page_scale_factor());
- host_impl_->active_tree()->SetPageScaleDelta(1.5f);
+ host_impl_->SetPageScaleOnActiveTree(2.f * 1.5f);
EXPECT_EQ(3.f, scroll_delegate.page_scale_factor());
EXPECT_EQ(0.5f, scroll_delegate.min_page_scale_factor());
EXPECT_EQ(4.f, scroll_delegate.max_page_scale_factor());
- host_impl_->active_tree()->SetPageScaleDelta(1.f);
- host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f);
+ host_impl_->SetPageScaleOnActiveTree(2.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f);
EXPECT_EQ(1.f, scroll_delegate.page_scale_factor());
EXPECT_EQ(0.5f, scroll_delegate.min_page_scale_factor());
EXPECT_EQ(4.f, scroll_delegate.max_page_scale_factor());
@@ -3823,7 +3810,7 @@ TEST_F(LayerTreeHostImplTest, OverscrollRoot) {
InputHandlerScrollResult scroll_result;
SetupScrollAndContentsLayers(gfx::Size(100, 100));
host_impl_->SetViewportSize(gfx::Size(50, 50));
- host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f);
DrawFrame();
EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
@@ -4042,7 +4029,7 @@ TEST_F(LayerTreeHostImplTest, OverscrollAlways) {
LayerImpl* clip_layer = scroll_layer->parent()->parent();
clip_layer->SetBounds(gfx::Size(50, 50));
host_impl_->SetViewportSize(gfx::Size(50, 50));
- host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f);
DrawFrame();
EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
@@ -4065,9 +4052,9 @@ TEST_F(LayerTreeHostImplTest, NoOverscrollOnFractionalDeviceScale) {
scoped_ptr<LayerImpl> child =
CreateScrollableLayer(2, content_size, root_clip.get());
root->scroll_clip_layer()->SetBounds(gfx::Size(320, 469));
- host_impl_->active_tree()->SetPageScaleFactorAndLimits(
- 0.326531f, 0.326531f, 5.f);
- host_impl_->active_tree()->SetPageScaleDelta(1.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(0.326531f, 0.326531f,
+ 5.f);
+ host_impl_->SetPageScaleOnActiveTree(0.326531f);
child->SetScrollClipLayer(Layer::INVALID_ID);
root->AddChild(child.Pass());
root_clip->AddChild(root.Pass());
@@ -6159,8 +6146,8 @@ TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) {
host_impl_->SetViewportSize(device_viewport_size);
host_impl_->CreatePendingTree();
- host_impl_->pending_tree()
- ->SetPageScaleFactorAndLimits(1.f, 1.f / 16.f, 16.f);
+ host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f / 16.f,
+ 16.f);
scoped_ptr<LayerImpl> scoped_root =
LayerImpl::Create(host_impl_->pending_tree(), 1);
@@ -7839,9 +7826,9 @@ TEST_F(LayerTreeHostImplTest, WheelScrollWithPageScaleFactorOnInnerLayer) {
// The scroll deltas should have the page scale factor applied.
{
- host_impl_->active_tree()->SetPageScaleFactorAndLimits(
+ host_impl_->active_tree()->PushPageScaleFromMainThread(
page_scale_factor, min_page_scale, max_page_scale);
- host_impl_->active_tree()->SetPageScaleDelta(1.f);
+ host_impl_->SetPageScaleOnActiveTree(page_scale_factor);
scroll_layer->SetScrollDelta(gfx::Vector2d());
float page_scale_delta = 2.f;
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index 712909f..60c5675 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -1041,14 +1041,14 @@ class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest {
// until the second draw.
switch (impl->active_tree()->source_frame_number()) {
case 0:
- EXPECT_EQ(1.f, impl->active_tree()->page_scale_factor());
+ EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
// We'll start an animation when we get back to the main thread.
break;
case 1:
- EXPECT_EQ(1.f, impl->active_tree()->page_scale_factor());
+ EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
break;
case 2:
- EXPECT_EQ(1.25f, impl->active_tree()->page_scale_factor());
+ EXPECT_EQ(1.25f, impl->active_tree()->current_page_scale_factor());
EndTest();
break;
default:
@@ -5571,7 +5571,7 @@ class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest {
switch (frame_) {
case 1:
// Drew at page scale 1 before any pinching.
- EXPECT_EQ(1.f, host_impl->active_tree()->total_page_scale_factor());
+ EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
EXPECT_EQ(1.f, quad_scale_delta);
PostNextAfterDraw(host_impl);
break;
@@ -5579,7 +5579,7 @@ class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest {
if (quad_scale_delta != 1.f)
break;
// Drew at page scale 1.5 after pinching in.
- EXPECT_EQ(1.5f, host_impl->active_tree()->total_page_scale_factor());
+ EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
EXPECT_EQ(1.f, quad_scale_delta);
PostNextAfterDraw(host_impl);
break;
@@ -5590,7 +5590,7 @@ class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest {
if (frame_data->has_no_damage)
break;
// Drew at page scale 1 with the 1.5 tiling while pinching out.
- EXPECT_EQ(1.f, host_impl->active_tree()->total_page_scale_factor());
+ EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
EXPECT_EQ(1.5f, quad_scale_delta);
// We don't PostNextAfterDraw here, instead we wait for the new tiling
// to finish rastering so we don't get any noise in further steps.
@@ -5598,7 +5598,7 @@ class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest {
case 4:
// Drew at page scale 1 with the 1.5 tiling after pinching out completed
// while waiting for texture uploads to complete.
- EXPECT_EQ(1.f, host_impl->active_tree()->total_page_scale_factor());
+ EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
// This frame will not have any damage, since it's actually the same as
// the last frame, and should contain no incomplete tiles. We just want
// to make sure we drew here at least once after the pinch ended to be
@@ -5610,7 +5610,7 @@ class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest {
if (quad_scale_delta != 1.f)
break;
// Drew at scale 1 after texture uploads are done.
- EXPECT_EQ(1.f, host_impl->active_tree()->total_page_scale_factor());
+ EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
EXPECT_EQ(1.f, quad_scale_delta);
EndTest();
break;
@@ -5781,19 +5781,19 @@ class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles
switch (step_) {
case 1:
// Drew at scale 1 before any pinching.
- EXPECT_EQ(1.f, host_impl->active_tree()->total_page_scale_factor());
+ EXPECT_EQ(1.f, host_impl->active_tree()->current_page_scale_factor());
EXPECT_EQ(1.f, quad_scale_delta);
break;
case 2:
if (quad_scale_delta != 1.f / 1.5f)
break;
// Drew at scale 1 still though the ideal is 1.5.
- EXPECT_EQ(1.5f, host_impl->active_tree()->total_page_scale_factor());
+ EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
EXPECT_EQ(1.f / 1.5f, quad_scale_delta);
break;
case 3:
// Continuous draws are attempted.
- EXPECT_EQ(1.5f, host_impl->active_tree()->total_page_scale_factor());
+ EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
if (!frame_data->has_no_damage)
EXPECT_EQ(1.f / 1.5f, quad_scale_delta);
break;
@@ -5801,7 +5801,7 @@ class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles
if (quad_scale_delta != 1.f)
break;
// Drew at scale 1.5 when all the tiles completed.
- EXPECT_EQ(1.5f, host_impl->active_tree()->total_page_scale_factor());
+ EXPECT_EQ(1.5f, host_impl->active_tree()->current_page_scale_factor());
EXPECT_EQ(1.f, quad_scale_delta);
break;
case 5:
diff --git a/cc/trees/layer_tree_host_unittest_scroll.cc b/cc/trees/layer_tree_host_unittest_scroll.cc
index 8015bda..bd09d6a 100644
--- a/cc/trees/layer_tree_host_unittest_scroll.cc
+++ b/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -306,10 +306,10 @@ class LayerTreeHostScrollTestScrollAbortedCommit
EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(), initial_scroll_);
EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
- EXPECT_EQ(1.f, impl->active_tree()->total_page_scale_factor());
- impl->active_tree()->SetPageScaleDelta(impl_scale_);
+ EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
+ impl->SetPageScaleOnActiveTree(impl_scale_);
EXPECT_EQ(impl_scale_, impl->active_tree()->page_scale_delta());
- EXPECT_EQ(impl_scale_, impl->active_tree()->total_page_scale_factor());
+ EXPECT_EQ(impl_scale_, impl->active_tree()->current_page_scale_factor());
// To simplify the testing flow, don't redraw here, just commit.
impl->SetNeedsCommit();
@@ -326,11 +326,11 @@ class LayerTreeHostScrollTestScrollAbortedCommit
gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_));
EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
- EXPECT_EQ(impl_scale_, impl->active_tree()->total_page_scale_factor());
- impl->active_tree()->SetPageScaleDelta(impl_scale_);
+ EXPECT_EQ(impl_scale_, impl->active_tree()->current_page_scale_factor());
+ impl->SetPageScaleOnActiveTree(impl_scale_ * impl_scale_);
EXPECT_EQ(impl_scale_, impl->active_tree()->page_scale_delta());
EXPECT_EQ(impl_scale_ * impl_scale_,
- impl->active_tree()->total_page_scale_factor());
+ impl->active_tree()->current_page_scale_factor());
impl->SetNeedsCommit();
} else if (impl->active_tree()->source_frame_number() == 1) {
@@ -897,7 +897,7 @@ class ImplSidePaintingScrollTestImplOnlyScroll
: public ImplSidePaintingScrollTest {
public:
ImplSidePaintingScrollTestImplOnlyScroll()
- : initial_scroll_(20, 10), impl_thread_scroll_(-2, 3) {}
+ : initial_scroll_(20, 10), impl_thread_scroll_(-2, 3), impl_scale_(2.f) {}
void SetupTree() override {
LayerTreeHostScrollTest::SetupTree();
@@ -943,6 +943,7 @@ class ImplSidePaintingScrollTestImplOnlyScroll
ASSERT_TRUE(active_root);
ASSERT_TRUE(active_scroll_layer);
active_scroll_layer->ScrollBy(impl_thread_scroll_);
+ impl->SetPageScaleOnActiveTree(impl_scale_);
}
}
@@ -990,7 +991,6 @@ class ImplSidePaintingScrollTestImplOnlyScroll
EXPECT_VECTOR_EQ(pending_scroll_layer->ScrollDelta(), gfx::Vector2d());
EXPECT_VECTOR_EQ(pending_scroll_layer->sent_scroll_delta(),
gfx::Vector2d());
- EndTest();
break;
}
}
@@ -1006,14 +1006,25 @@ class ImplSidePaintingScrollTestImplOnlyScroll
EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_);
EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2d());
EXPECT_VECTOR_EQ(scroll_layer->sent_scroll_delta(), gfx::Vector2d());
+ EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
+ EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
PostSetNeedsCommitToMainThread();
break;
case 1:
EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_);
EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), impl_thread_scroll_);
EXPECT_VECTOR_EQ(scroll_layer->sent_scroll_delta(), gfx::Vector2d());
+ EXPECT_EQ(impl_scale_, impl->active_tree()->page_scale_delta());
+ EXPECT_EQ(impl_scale_,
+ impl->active_tree()->current_page_scale_factor());
PostSetNeedsCommitToMainThread();
break;
+ case 2:
+ EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
+ EXPECT_EQ(impl_scale_,
+ impl->active_tree()->current_page_scale_factor());
+ EndTest();
+ break;
}
}
@@ -1022,6 +1033,7 @@ class ImplSidePaintingScrollTestImplOnlyScroll
private:
gfx::ScrollOffset initial_scroll_;
gfx::Vector2dF impl_thread_scroll_;
+ float impl_scale_;
};
MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestImplOnlyScroll);
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index a278fbf..52a5436 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -14,6 +14,7 @@
#include "cc/animation/scrollbar_animation_controller_linear_fade.h"
#include "cc/animation/scrollbar_animation_controller_thinning.h"
#include "cc/base/math_util.h"
+#include "cc/base/synced_property.h"
#include "cc/base/util.h"
#include "cc/debug/devtools_instrumentation.h"
#include "cc/debug/traced_value.h"
@@ -72,7 +73,9 @@ class LayerScrollOffsetDelegateProxy : public LayerImpl::ScrollOffsetDelegate {
gfx::ScrollOffset last_set_scroll_offset_;
};
-LayerTreeImpl::LayerTreeImpl(LayerTreeHostImpl* layer_tree_host_impl)
+LayerTreeImpl::LayerTreeImpl(
+ LayerTreeHostImpl* layer_tree_host_impl,
+ scoped_refptr<SyncedProperty<ScaleGroup>> page_scale_factor)
: layer_tree_host_impl_(layer_tree_host_impl),
source_frame_number_(-1),
hud_layer_(0),
@@ -83,9 +86,7 @@ LayerTreeImpl::LayerTreeImpl(LayerTreeHostImpl* layer_tree_host_impl)
page_scale_layer_(NULL),
inner_viewport_scroll_layer_(NULL),
outer_viewport_scroll_layer_(NULL),
- page_scale_factor_(1),
- page_scale_delta_(1),
- sent_page_scale_delta_(1),
+ page_scale_factor_(page_scale_factor),
min_page_scale_factor_(0),
max_page_scale_factor_(0),
scrolling_layer_id_from_previous_tree_(0),
@@ -216,10 +217,10 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) {
target_tree->sent_top_controls_delta_;
target_tree->sent_top_controls_delta_ = 0.f;
- target_tree->SetPageScaleValues(
- page_scale_factor(), min_page_scale_factor(), max_page_scale_factor(),
- target_tree->page_scale_delta() / target_tree->sent_page_scale_delta());
- target_tree->set_sent_page_scale_delta(1);
+ // Active tree already shares the page_scale_factor object with pending
+ // tree so only the limits need to be provided.
+ target_tree->PushPageScaleFactorAndLimits(nullptr, min_page_scale_factor(),
+ max_page_scale_factor());
target_tree->pending_page_scale_animation_ =
pending_page_scale_animation_.Pass();
@@ -312,72 +313,91 @@ void ForceScrollbarParameterUpdateAfterScaleChange(LayerImpl* current_layer) {
} // namespace
-void LayerTreeImpl::SetPageScaleFactorAndLimits(float page_scale_factor,
- float min_page_scale_factor, float max_page_scale_factor) {
- SetPageScaleValues(page_scale_factor, min_page_scale_factor,
- max_page_scale_factor, page_scale_delta_);
+float LayerTreeImpl::ClampPageScaleFactorToLimits(
+ float page_scale_factor) const {
+ if (min_page_scale_factor_ && page_scale_factor < min_page_scale_factor_)
+ page_scale_factor = min_page_scale_factor_;
+ else if (max_page_scale_factor_ && page_scale_factor > max_page_scale_factor_)
+ page_scale_factor = max_page_scale_factor_;
+ return page_scale_factor;
}
-void LayerTreeImpl::SetPageScaleDelta(float delta) {
- SetPageScaleValues(page_scale_factor_, min_page_scale_factor_,
- max_page_scale_factor_, delta);
+void LayerTreeImpl::SetPageScaleOnActiveTree(float active_page_scale) {
+ DCHECK(IsActiveTree());
+ if (page_scale_factor()->SetCurrent(
+ ClampPageScaleFactorToLimits(active_page_scale)))
+ DidUpdatePageScale();
+}
+
+void LayerTreeImpl::PushPageScaleFromMainThread(float page_scale_factor,
+ float min_page_scale_factor,
+ float max_page_scale_factor) {
+ PushPageScaleFactorAndLimits(&page_scale_factor, min_page_scale_factor,
+ max_page_scale_factor);
+}
+
+void LayerTreeImpl::PushPageScaleFactorAndLimits(const float* page_scale_factor,
+ float min_page_scale_factor,
+ float max_page_scale_factor) {
+ DCHECK(page_scale_factor || IsActiveTree());
+ bool changed_page_scale = false;
+ if (page_scale_factor) {
+ DCHECK(!IsActiveTree() || !layer_tree_host_impl_->pending_tree());
+ changed_page_scale |=
+ page_scale_factor_->PushFromMainThread(*page_scale_factor);
+ }
+ if (IsActiveTree())
+ changed_page_scale |= page_scale_factor_->PushPendingToActive();
+ changed_page_scale |=
+ SetPageScaleFactorLimits(min_page_scale_factor, max_page_scale_factor);
+
+ if (changed_page_scale)
+ DidUpdatePageScale();
}
-void LayerTreeImpl::SetPageScaleValues(float page_scale_factor,
- float min_page_scale_factor, float max_page_scale_factor,
- float page_scale_delta) {
- bool page_scale_changed =
- min_page_scale_factor != min_page_scale_factor_ ||
- max_page_scale_factor != max_page_scale_factor_ ||
- page_scale_factor != page_scale_factor_;
+bool LayerTreeImpl::SetPageScaleFactorLimits(float min_page_scale_factor,
+ float max_page_scale_factor) {
+ if (min_page_scale_factor == min_page_scale_factor_ &&
+ max_page_scale_factor == max_page_scale_factor_)
+ return false;
min_page_scale_factor_ = min_page_scale_factor;
max_page_scale_factor_ = max_page_scale_factor;
- page_scale_factor_ = page_scale_factor;
-
- float total = page_scale_factor_ * page_scale_delta;
- if (min_page_scale_factor_ && total < min_page_scale_factor_)
- page_scale_delta = min_page_scale_factor_ / page_scale_factor_;
- else if (max_page_scale_factor_ && total > max_page_scale_factor_)
- page_scale_delta = max_page_scale_factor_ / page_scale_factor_;
- if (page_scale_delta_ == page_scale_delta && !page_scale_changed)
- return;
+ return true;
+}
- if (page_scale_delta_ != page_scale_delta) {
- page_scale_delta_ = page_scale_delta;
+void LayerTreeImpl::DidUpdatePageScale() {
+ if (IsActiveTree())
+ page_scale_factor()->SetCurrent(
+ ClampPageScaleFactorToLimits(current_page_scale_factor()));
- if (IsActiveTree()) {
- LayerTreeImpl* pending_tree = layer_tree_host_impl_->pending_tree();
- if (pending_tree) {
- DCHECK_EQ(1, pending_tree->sent_page_scale_delta());
- pending_tree->SetPageScaleDelta(
- page_scale_delta_ / sent_page_scale_delta_);
- }
- }
-
- set_needs_update_draw_properties();
- }
+ set_needs_update_draw_properties();
if (root_layer_scroll_offset_delegate_) {
root_layer_scroll_offset_delegate_->UpdateRootLayerState(
- TotalScrollOffset(),
- TotalMaxScrollOffset(),
- ScrollableSize(),
- total_page_scale_factor(),
- min_page_scale_factor_,
+ TotalScrollOffset(), TotalMaxScrollOffset(), ScrollableSize(),
+ current_page_scale_factor(), min_page_scale_factor_,
max_page_scale_factor_);
}
ForceScrollbarParameterUpdateAfterScaleChange(page_scale_layer());
}
+SyncedProperty<ScaleGroup>* LayerTreeImpl::page_scale_factor() {
+ return page_scale_factor_.get();
+}
+
+const SyncedProperty<ScaleGroup>* LayerTreeImpl::page_scale_factor() const {
+ return page_scale_factor_.get();
+}
+
gfx::SizeF LayerTreeImpl::ScrollableViewportSize() const {
if (!InnerViewportContainerLayer())
return gfx::SizeF();
return gfx::ScaleSize(InnerViewportContainerLayer()->BoundsForScrolling(),
- 1.0f / total_page_scale_factor());
+ 1.0f / current_page_scale_factor());
}
gfx::Rect LayerTreeImpl::RootScrollLayerDeviceViewportBounds() const {
@@ -398,9 +418,7 @@ static void ApplySentScrollDeltasFromAbortedCommitTo(LayerImpl* layer) {
void LayerTreeImpl::ApplySentScrollAndScaleDeltasFromAbortedCommit() {
DCHECK(IsActiveTree());
- page_scale_factor_ *= sent_page_scale_delta_;
- page_scale_delta_ /= sent_page_scale_delta_;
- sent_page_scale_delta_ = 1.f;
+ page_scale_factor()->AbortCommit();
top_controls_content_offset_ += sent_top_controls_delta_;
top_controls_delta_ -= sent_top_controls_delta_;
@@ -496,7 +514,7 @@ bool LayerTreeImpl::UpdateDrawProperties() {
LayerTreeHostCommon::CalcDrawPropsImplInputs inputs(
root_layer(), DrawViewportSize(),
layer_tree_host_impl_->DrawTransform(), device_scale_factor(),
- total_page_scale_factor(), page_scale_layer,
+ current_page_scale_factor(), page_scale_layer,
resource_provider()->max_texture_size(), settings().can_use_lcd_text,
settings().layers_always_allowed_lcd_text,
can_render_to_separate_surface,
@@ -910,11 +928,8 @@ void LayerTreeImpl::SetRootLayerScrollOffsetDelegate(
if (root_layer_scroll_offset_delegate_) {
root_layer_scroll_offset_delegate_->UpdateRootLayerState(
- TotalScrollOffset(),
- TotalMaxScrollOffset(),
- ScrollableSize(),
- total_page_scale_factor(),
- min_page_scale_factor(),
+ TotalScrollOffset(), TotalMaxScrollOffset(), ScrollableSize(),
+ current_page_scale_factor(), min_page_scale_factor(),
max_page_scale_factor());
if (inner_viewport_scroll_layer_) {
@@ -962,11 +977,8 @@ void LayerTreeImpl::UpdateScrollOffsetDelegate() {
offset += outer_viewport_scroll_delegate_proxy_->last_set_scroll_offset();
root_layer_scroll_offset_delegate_->UpdateRootLayerState(
- offset,
- TotalMaxScrollOffset(),
- ScrollableSize(),
- total_page_scale_factor(),
- min_page_scale_factor(),
+ offset, TotalMaxScrollOffset(), ScrollableSize(),
+ current_page_scale_factor(), min_page_scale_factor(),
max_page_scale_factor());
}
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h
index ef4f877..d88cd48 100644
--- a/cc/trees/layer_tree_impl.h
+++ b/cc/trees/layer_tree_impl.h
@@ -14,6 +14,7 @@
#include "base/values.h"
#include "cc/base/scoped_ptr_vector.h"
#include "cc/base/swap_promise.h"
+#include "cc/base/synced_property.h"
#include "cc/layers/layer_impl.h"
#include "cc/output/renderer.h"
#include "cc/resources/ui_resource_client.h"
@@ -53,8 +54,10 @@ typedef std::list<UIResourceRequest> UIResourceRequestQueue;
class CC_EXPORT LayerTreeImpl {
public:
static scoped_ptr<LayerTreeImpl> create(
- LayerTreeHostImpl* layer_tree_host_impl) {
- return make_scoped_ptr(new LayerTreeImpl(layer_tree_host_impl));
+ LayerTreeHostImpl* layer_tree_host_impl,
+ scoped_refptr<SyncedProperty<ScaleGroup>> page_scale_factor) {
+ return make_scoped_ptr(
+ new LayerTreeImpl(layer_tree_host_impl, page_scale_factor));
}
virtual ~LayerTreeImpl();
@@ -161,23 +164,20 @@ class CC_EXPORT LayerTreeImpl {
has_transparent_background_ = transparent;
}
- void SetPageScaleFactorAndLimits(float page_scale_factor,
- float min_page_scale_factor, float max_page_scale_factor);
- void SetPageScaleDelta(float delta);
- void SetPageScaleValues(float page_scale_factor,
- float min_page_scale_factor, float max_page_scale_factor,
- float page_scale_delta);
- float total_page_scale_factor() const {
- return page_scale_factor_ * page_scale_delta_;
+ void SetPageScaleOnActiveTree(float active_page_scale);
+ void PushPageScaleFromMainThread(float page_scale_factor,
+ float min_page_scale_factor,
+ float max_page_scale_factor);
+ float current_page_scale_factor() const {
+ return page_scale_factor()->Current(IsActiveTree());
}
- float page_scale_factor() const { return page_scale_factor_; }
float min_page_scale_factor() const { return min_page_scale_factor_; }
float max_page_scale_factor() const { return max_page_scale_factor_; }
- float page_scale_delta() const { return page_scale_delta_; }
- void set_sent_page_scale_delta(float delta) {
- sent_page_scale_delta_ = delta;
- }
- float sent_page_scale_delta() const { return sent_page_scale_delta_; }
+
+ float page_scale_delta() const { return page_scale_factor()->Delta(); }
+
+ SyncedProperty<ScaleGroup>* page_scale_factor();
+ const SyncedProperty<ScaleGroup>* page_scale_factor() const;
// Updates draw properties and render surface layer list, as well as tile
// priorities. Returns false if it was unable to update.
@@ -321,8 +321,17 @@ class CC_EXPORT LayerTreeImpl {
scoped_ptr<PendingPageScaleAnimation> TakePendingPageScaleAnimation();
protected:
- explicit LayerTreeImpl(LayerTreeHostImpl* layer_tree_host_impl);
+ explicit LayerTreeImpl(
+ LayerTreeHostImpl* layer_tree_host_impl,
+ scoped_refptr<SyncedProperty<ScaleGroup>> page_scale_factor);
void ReleaseResourcesRecursive(LayerImpl* current);
+ float ClampPageScaleFactorToLimits(float page_scale_factor) const;
+ void PushPageScaleFactorAndLimits(const float* page_scale_factor,
+ float min_page_scale_factor,
+ float max_page_scale_factor);
+ bool SetPageScaleFactorLimits(float min_page_scale_factor,
+ float max_page_scale_factor);
+ void DidUpdatePageScale();
LayerTreeHostImpl* layer_tree_host_impl_;
int source_frame_number_;
@@ -345,9 +354,7 @@ class CC_EXPORT LayerTreeImpl {
LayerSelectionBound selection_start_;
LayerSelectionBound selection_end_;
- float page_scale_factor_;
- float page_scale_delta_;
- float sent_page_scale_delta_;
+ scoped_refptr<SyncedProperty<ScaleGroup>> page_scale_factor_;
float min_page_scale_factor_;
float max_page_scale_factor_;
diff --git a/cc/trees/layer_tree_impl_unittest.cc b/cc/trees/layer_tree_impl_unittest.cc
index 52f8e0a..2131d4c 100644
--- a/cc/trees/layer_tree_impl_unittest.cc
+++ b/cc/trees/layer_tree_impl_unittest.cc
@@ -1795,8 +1795,9 @@ TEST_F(LayerTreeImplTest,
host_impl().SetViewportSize(scaled_bounds_for_root);
host_impl().SetDeviceScaleFactor(device_scale_factor);
- host_impl().active_tree()->SetPageScaleFactorAndLimits(
+ host_impl().active_tree()->PushPageScaleFromMainThread(
page_scale_factor, page_scale_factor, page_scale_factor);
+ host_impl().SetPageScaleOnActiveTree(page_scale_factor);
host_impl().active_tree()->SetRootLayer(root.Pass());
host_impl().active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 1, 1,
Layer::INVALID_ID);
@@ -2299,8 +2300,9 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForScaledLayers) {
host_impl().SetViewportSize(scaled_bounds_for_root);
host_impl().SetDeviceScaleFactor(device_scale_factor);
- host_impl().active_tree()->SetPageScaleFactorAndLimits(
+ host_impl().active_tree()->PushPageScaleFromMainThread(
page_scale_factor, page_scale_factor, page_scale_factor);
+ host_impl().SetPageScaleOnActiveTree(page_scale_factor);
host_impl().active_tree()->SetRootLayer(root.Pass());
host_impl().active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 1, 1,
Layer::INVALID_ID);