Update from https://crrev.com/318214
TBR=qsr@chromium.org
Review URL: https://codereview.chromium.org/960873002
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index cffee57..c29cda8 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -337,6 +337,8 @@
"resources/clip_display_item.h",
"resources/clip_path_display_item.cc",
"resources/clip_path_display_item.h",
+ "resources/compositing_display_item.cc",
+ "resources/compositing_display_item.h",
"resources/content_layer_updater.cc",
"resources/content_layer_updater.h",
"resources/display_item.cc",
@@ -466,8 +468,6 @@
"resources/transferable_resource.h",
"resources/transform_display_item.cc",
"resources/transform_display_item.h",
- "resources/transparency_display_item.cc",
- "resources/transparency_display_item.h",
"resources/ui_resource_bitmap.cc",
"resources/ui_resource_bitmap.h",
"resources/ui_resource_client.h",
diff --git a/cc/animation/scrollbar_animation_controller.cc b/cc/animation/scrollbar_animation_controller.cc
index ffb2287..48b199d 100644
--- a/cc/animation/scrollbar_animation_controller.cc
+++ b/cc/animation/scrollbar_animation_controller.cc
@@ -7,15 +7,18 @@
#include <algorithm>
#include "base/time/time.h"
+#include "cc/trees/layer_tree_impl.h"
namespace cc {
ScrollbarAnimationController::ScrollbarAnimationController(
+ LayerImpl* scroll_layer,
ScrollbarAnimationControllerClient* client,
base::TimeDelta delay_before_starting,
base::TimeDelta resize_delay_before_starting,
base::TimeDelta duration)
- : client_(client),
+ : scroll_layer_(scroll_layer),
+ client_(client),
delay_before_starting_(delay_before_starting),
resize_delay_before_starting_(resize_delay_before_starting),
duration_(duration),
@@ -26,6 +29,8 @@
}
ScrollbarAnimationController::~ScrollbarAnimationController() {
+ if (is_animating_)
+ client_->StopAnimatingScrollbarAnimationController(this);
}
void ScrollbarAnimationController::Animate(base::TimeTicks now) {
@@ -37,11 +42,6 @@
float progress = AnimationProgressAtTime(now);
RunAnimationFrame(progress);
-
- if (is_animating_) {
- delayed_scrollbar_fade_.Cancel();
- client_->SetNeedsScrollbarAnimationFrame();
- }
}
float ScrollbarAnimationController::AnimationProgressAtTime(
@@ -62,38 +62,40 @@
// As an optimization, we avoid spamming fade delay tasks during active fast
// scrolls. But if we're not within one, we need to post every scroll update.
if (!currently_scrolling_)
- PostDelayedFade(on_resize);
+ PostDelayedAnimationTask(on_resize);
else
scroll_gesture_has_scrolled_ = true;
}
void ScrollbarAnimationController::DidScrollEnd() {
if (scroll_gesture_has_scrolled_) {
- PostDelayedFade(false);
+ PostDelayedAnimationTask(false);
scroll_gesture_has_scrolled_ = false;
}
currently_scrolling_ = false;
}
-void ScrollbarAnimationController::PostDelayedFade(bool on_resize) {
+void ScrollbarAnimationController::PostDelayedAnimationTask(bool on_resize) {
base::TimeDelta delay =
on_resize ? resize_delay_before_starting_ : delay_before_starting_;
delayed_scrollbar_fade_.Reset(
base::Bind(&ScrollbarAnimationController::StartAnimation,
weak_factory_.GetWeakPtr()));
- client_->PostDelayedScrollbarFade(delayed_scrollbar_fade_.callback(), delay);
+ client_->PostDelayedScrollbarAnimationTask(delayed_scrollbar_fade_.callback(),
+ delay);
}
void ScrollbarAnimationController::StartAnimation() {
delayed_scrollbar_fade_.Cancel();
is_animating_ = true;
last_awaken_time_ = base::TimeTicks();
- client_->SetNeedsScrollbarAnimationFrame();
+ client_->StartAnimatingScrollbarAnimationController(this);
}
void ScrollbarAnimationController::StopAnimation() {
is_animating_ = false;
+ client_->StopAnimatingScrollbarAnimationController(this);
}
} // namespace cc
diff --git a/cc/animation/scrollbar_animation_controller.h b/cc/animation/scrollbar_animation_controller.h
index 92efe75..795c7c1 100644
--- a/cc/animation/scrollbar_animation_controller.h
+++ b/cc/animation/scrollbar_animation_controller.h
@@ -9,17 +9,25 @@
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "cc/base/cc_export.h"
+#include "cc/layers/layer_impl.h"
#include "ui/gfx/geometry/vector2d_f.h"
namespace cc {
+class ScrollbarAnimationController;
+
class CC_EXPORT ScrollbarAnimationControllerClient {
public:
- virtual ~ScrollbarAnimationControllerClient() {}
+ virtual void StartAnimatingScrollbarAnimationController(
+ ScrollbarAnimationController* controller) = 0;
+ virtual void StopAnimatingScrollbarAnimationController(
+ ScrollbarAnimationController* controller) = 0;
+ virtual void PostDelayedScrollbarAnimationTask(const base::Closure& task,
+ base::TimeDelta delay) = 0;
+ virtual void SetNeedsRedrawForScrollbarAnimation() = 0;
- virtual void PostDelayedScrollbarFade(const base::Closure& start_fade,
- base::TimeDelta delay) = 0;
- virtual void SetNeedsScrollbarAnimationFrame() = 0;
+ protected:
+ virtual ~ScrollbarAnimationControllerClient() {}
};
// This abstract class represents the compositor-side analogy of
@@ -38,7 +46,8 @@
virtual void DidMouseMoveNear(float distance) {}
protected:
- ScrollbarAnimationController(ScrollbarAnimationControllerClient* client,
+ ScrollbarAnimationController(LayerImpl* scroll_layer,
+ ScrollbarAnimationControllerClient* client,
base::TimeDelta delay_before_starting,
base::TimeDelta resize_delay_before_starting,
base::TimeDelta duration);
@@ -48,18 +57,21 @@
void StartAnimation();
void StopAnimation();
+ LayerImpl* scroll_layer_;
+ ScrollbarAnimationControllerClient* client_;
+
private:
// Returns how far through the animation we are as a progress value from
// 0 to 1.
float AnimationProgressAtTime(base::TimeTicks now);
- void PostDelayedFade(bool on_resize);
+ void PostDelayedAnimationTask(bool on_resize);
- ScrollbarAnimationControllerClient* client_;
base::TimeTicks last_awaken_time_;
base::TimeDelta delay_before_starting_;
base::TimeDelta resize_delay_before_starting_;
base::TimeDelta duration_;
+
bool is_animating_;
bool currently_scrolling_;
diff --git a/cc/animation/scrollbar_animation_controller_linear_fade.cc b/cc/animation/scrollbar_animation_controller_linear_fade.cc
index 1b5dfd9..d1049bd 100644
--- a/cc/animation/scrollbar_animation_controller_linear_fade.cc
+++ b/cc/animation/scrollbar_animation_controller_linear_fade.cc
@@ -17,12 +17,9 @@
base::TimeDelta delay_before_starting,
base::TimeDelta resize_delay_before_starting,
base::TimeDelta duration) {
- return make_scoped_ptr(
- new ScrollbarAnimationControllerLinearFade(scroll_layer,
- client,
- delay_before_starting,
- resize_delay_before_starting,
- duration));
+ return make_scoped_ptr(new ScrollbarAnimationControllerLinearFade(
+ scroll_layer, client, delay_before_starting, resize_delay_before_starting,
+ duration));
}
ScrollbarAnimationControllerLinearFade::ScrollbarAnimationControllerLinearFade(
@@ -31,18 +28,20 @@
base::TimeDelta delay_before_starting,
base::TimeDelta resize_delay_before_starting,
base::TimeDelta duration)
- : ScrollbarAnimationController(client,
+ : ScrollbarAnimationController(scroll_layer,
+ client,
delay_before_starting,
resize_delay_before_starting,
- duration),
- scroll_layer_(scroll_layer) {
+ duration) {
}
ScrollbarAnimationControllerLinearFade::
- ~ScrollbarAnimationControllerLinearFade() {}
+ ~ScrollbarAnimationControllerLinearFade() {
+}
void ScrollbarAnimationControllerLinearFade::RunAnimationFrame(float progress) {
ApplyOpacityToScrollbars(1.f - progress);
+ client_->SetNeedsRedrawForScrollbarAnimation();
if (progress == 1.f)
StopAnimation();
}
@@ -59,8 +58,7 @@
LayerImpl::ScrollbarSet* scrollbars = scroll_layer_->scrollbars();
for (LayerImpl::ScrollbarSet::iterator it = scrollbars->begin();
- it != scrollbars->end();
- ++it) {
+ it != scrollbars->end(); ++it) {
ScrollbarLayerImplBase* scrollbar = *it;
if (scrollbar->is_overlay_scrollbar())
diff --git a/cc/animation/scrollbar_animation_controller_linear_fade.h b/cc/animation/scrollbar_animation_controller_linear_fade.h
index 73d6031..05940a0 100644
--- a/cc/animation/scrollbar_animation_controller_linear_fade.h
+++ b/cc/animation/scrollbar_animation_controller_linear_fade.h
@@ -40,8 +40,6 @@
float OpacityAtTime(base::TimeTicks now) const;
void ApplyOpacityToScrollbars(float opacity);
- LayerImpl* scroll_layer_;
-
DISALLOW_COPY_AND_ASSIGN(ScrollbarAnimationControllerLinearFade);
};
diff --git a/cc/animation/scrollbar_animation_controller_linear_fade_unittest.cc b/cc/animation/scrollbar_animation_controller_linear_fade_unittest.cc
index 2295124..f7a5878 100644
--- a/cc/animation/scrollbar_animation_controller_linear_fade_unittest.cc
+++ b/cc/animation/scrollbar_animation_controller_linear_fade_unittest.cc
@@ -20,14 +20,24 @@
public ScrollbarAnimationControllerClient {
public:
ScrollbarAnimationControllerLinearFadeTest()
- : host_impl_(&proxy_, &shared_bitmap_manager_), needs_frame_count_(0) {}
+ : host_impl_(&proxy_, &shared_bitmap_manager_) {}
- void PostDelayedScrollbarFade(const base::Closure& start_fade,
- base::TimeDelta delay) override {
+ void StartAnimatingScrollbarAnimationController(
+ ScrollbarAnimationController* controller) override {
+ is_animating_ = true;
+ }
+ void StopAnimatingScrollbarAnimationController(
+ ScrollbarAnimationController* controller) override {
+ is_animating_ = false;
+ }
+ void PostDelayedScrollbarAnimationTask(const base::Closure& start_fade,
+ base::TimeDelta delay) override {
start_fade_ = start_fade;
delay_ = delay;
}
- void SetNeedsScrollbarAnimationFrame() override { needs_frame_count_++; }
+ void SetNeedsRedrawForScrollbarAnimation() override {
+ did_request_redraw_ = true;
+ }
protected:
void SetUp() override {
@@ -57,11 +67,8 @@
scroll_layer_ptr->SetBounds(gfx::Size(200, 200));
scrollbar_controller_ = ScrollbarAnimationControllerLinearFade::Create(
- scroll_layer_ptr,
- this,
- base::TimeDelta::FromSeconds(2),
- base::TimeDelta::FromSeconds(5),
- base::TimeDelta::FromSeconds(3));
+ scroll_layer_ptr, this, base::TimeDelta::FromSeconds(2),
+ base::TimeDelta::FromSeconds(5), base::TimeDelta::FromSeconds(3));
}
virtual ScrollbarOrientation orientation() const { return HORIZONTAL; }
@@ -75,7 +82,8 @@
base::Closure start_fade_;
base::TimeDelta delay_;
- int needs_frame_count_;
+ bool is_animating_;
+ bool did_request_redraw_;
};
class VerticalScrollbarAnimationControllerLinearFadeTest
@@ -104,7 +112,6 @@
scrollbar_layer_->SetOpacity(0.0f);
scrollbar_controller_->Animate(base::TimeTicks());
EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->opacity());
- EXPECT_EQ(0, needs_frame_count_);
}
TEST_F(ScrollbarAnimationControllerLinearFadeTest,
@@ -123,8 +130,6 @@
time += base::TimeDelta::FromSeconds(100);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->opacity());
-
- EXPECT_EQ(0, needs_frame_count_);
}
TEST_F(ScrollbarAnimationControllerLinearFadeTest, HideOnResize) {
@@ -263,20 +268,24 @@
EXPECT_TRUE(start_fade_.Equals(base::Closure()));
time += base::TimeDelta::FromSeconds(100);
+
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
scrollbar_controller_->DidScrollEnd();
start_fade_.Run();
time += base::TimeDelta::FromSeconds(2);
+ EXPECT_TRUE(is_animating_);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
time += base::TimeDelta::FromSeconds(1);
+ EXPECT_TRUE(is_animating_);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity());
time += base::TimeDelta::FromSeconds(1);
+ EXPECT_TRUE(is_animating_);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(1.0f / 3.0f, scrollbar_layer_->opacity());
@@ -285,50 +294,60 @@
scrollbar_controller_->DidScrollBegin();
scrollbar_controller_->DidScrollUpdate(false);
scrollbar_controller_->DidScrollEnd();
+
start_fade_.Run();
time += base::TimeDelta::FromSeconds(2);
+ EXPECT_TRUE(is_animating_);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
time += base::TimeDelta::FromSeconds(1);
+ EXPECT_TRUE(is_animating_);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity());
time += base::TimeDelta::FromSeconds(1);
+ EXPECT_TRUE(is_animating_);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(1.0f / 3.0f, scrollbar_layer_->opacity());
time += base::TimeDelta::FromSeconds(1);
+ EXPECT_TRUE(is_animating_);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->opacity());
-
- EXPECT_EQ(8, needs_frame_count_);
+ EXPECT_FALSE(is_animating_);
}
TEST_F(ScrollbarAnimationControllerLinearFadeTest, AwakenByProgrammaticScroll) {
base::TimeTicks time;
time += base::TimeDelta::FromSeconds(1);
scrollbar_controller_->DidScrollUpdate(false);
+
start_fade_.Run();
+ EXPECT_TRUE(is_animating_);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
time += base::TimeDelta::FromSeconds(1);
+ EXPECT_TRUE(is_animating_);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity());
scrollbar_controller_->DidScrollUpdate(false);
- start_fade_.Run();
- time += base::TimeDelta::FromSeconds(1);
+ start_fade_.Run();
+ time += base::TimeDelta::FromSeconds(2);
+ EXPECT_TRUE(is_animating_);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
time += base::TimeDelta::FromSeconds(1);
+ EXPECT_TRUE(is_animating_);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity());
time += base::TimeDelta::FromSeconds(1);
+ EXPECT_TRUE(is_animating_);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(1.0f / 3.0f, scrollbar_layer_->opacity());
@@ -336,22 +355,25 @@
scrollbar_controller_->DidScrollUpdate(false);
start_fade_.Run();
time += base::TimeDelta::FromSeconds(1);
+ EXPECT_TRUE(is_animating_);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
time += base::TimeDelta::FromSeconds(1);
+ EXPECT_TRUE(is_animating_);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity());
time += base::TimeDelta::FromSeconds(1);
+ EXPECT_TRUE(is_animating_);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(1.0f / 3.0f, scrollbar_layer_->opacity());
time += base::TimeDelta::FromSeconds(1);
+ EXPECT_TRUE(is_animating_);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->opacity());
-
- EXPECT_EQ(11, needs_frame_count_);
+ EXPECT_FALSE(is_animating_);
}
TEST_F(ScrollbarAnimationControllerLinearFadeTest,
@@ -360,10 +382,12 @@
time += base::TimeDelta::FromSeconds(1);
scrollbar_controller_->DidScrollUpdate(false);
start_fade_.Run();
+ EXPECT_TRUE(is_animating_);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
time += base::TimeDelta::FromSeconds(1);
+ EXPECT_TRUE(is_animating_);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity());
@@ -371,6 +395,7 @@
EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity());
time += base::TimeDelta::FromSeconds(1);
+ EXPECT_TRUE(is_animating_);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(1.0f / 3.0f, scrollbar_layer_->opacity());
@@ -378,12 +403,10 @@
EXPECT_FLOAT_EQ(1.0f / 3.0f, scrollbar_layer_->opacity());
time += base::TimeDelta::FromSeconds(1);
+ EXPECT_TRUE(is_animating_);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->opacity());
-
- scrollbar_controller_->Animate(time);
-
- EXPECT_EQ(4, needs_frame_count_);
+ EXPECT_FALSE(is_animating_);
}
TEST_F(ScrollbarAnimationControllerLinearFadeTest,
@@ -392,10 +415,12 @@
time += base::TimeDelta::FromSeconds(1);
scrollbar_controller_->DidScrollUpdate(false);
start_fade_.Run();
+ EXPECT_TRUE(is_animating_);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
time += base::TimeDelta::FromSeconds(1);
+ EXPECT_TRUE(is_animating_);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity());
@@ -403,6 +428,7 @@
EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity());
time += base::TimeDelta::FromSeconds(1);
+ EXPECT_TRUE(is_animating_);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(1.0f / 3.0f, scrollbar_layer_->opacity());
diff --git a/cc/animation/scrollbar_animation_controller_thinning.cc b/cc/animation/scrollbar_animation_controller_thinning.cc
index 0405074..af6987e 100644
--- a/cc/animation/scrollbar_animation_controller_thinning.cc
+++ b/cc/animation/scrollbar_animation_controller_thinning.cc
@@ -7,6 +7,7 @@
#include "base/time/time.h"
#include "cc/layers/layer_impl.h"
#include "cc/layers/scrollbar_layer_impl_base.h"
+#include "cc/trees/layer_tree_impl.h"
namespace {
const float kIdleThicknessScale = 0.4f;
@@ -23,12 +24,9 @@
base::TimeDelta delay_before_starting,
base::TimeDelta resize_delay_before_starting,
base::TimeDelta duration) {
- return make_scoped_ptr(
- new ScrollbarAnimationControllerThinning(scroll_layer,
- client,
- delay_before_starting,
- resize_delay_before_starting,
- duration));
+ return make_scoped_ptr(new ScrollbarAnimationControllerThinning(
+ scroll_layer, client, delay_before_starting, resize_delay_before_starting,
+ duration));
}
ScrollbarAnimationControllerThinning::ScrollbarAnimationControllerThinning(
@@ -37,11 +35,11 @@
base::TimeDelta delay_before_starting,
base::TimeDelta resize_delay_before_starting,
base::TimeDelta duration)
- : ScrollbarAnimationController(client,
+ : ScrollbarAnimationController(scroll_layer,
+ client,
delay_before_starting,
resize_delay_before_starting,
duration),
- scroll_layer_(scroll_layer),
mouse_is_over_scrollbar_(false),
mouse_is_near_scrollbar_(false),
thickness_change_(NONE),
@@ -56,9 +54,10 @@
void ScrollbarAnimationControllerThinning::RunAnimationFrame(float progress) {
float opacity = OpacityAtAnimationProgress(progress);
- float thumb_thickness_scale = ThumbThicknessScaleAtAnimationProgress(
- progress);
+ float thumb_thickness_scale =
+ ThumbThicknessScaleAtAnimationProgress(progress);
ApplyOpacityAndThumbThicknessScale(opacity, thumb_thickness_scale);
+ client_->SetNeedsRedrawForScrollbarAnimation();
if (progress == 1.f) {
opacity_change_ = NONE;
thickness_change_ = NONE;
@@ -77,7 +76,7 @@
void ScrollbarAnimationControllerThinning::DidScrollUpdate(bool on_resize) {
ScrollbarAnimationController::DidScrollUpdate(on_resize);
ApplyOpacityAndThumbThicknessScale(
- 1, mouse_is_near_scrollbar_ ? 1.f : kIdleThicknessScale);
+ 1, mouse_is_near_scrollbar_ ? 1.f : kIdleThicknessScale);
if (!mouse_is_over_scrollbar_)
opacity_change_ = DECREASE;
@@ -114,9 +113,8 @@
return ret;
}
-float
-ScrollbarAnimationControllerThinning::ThumbThicknessScaleAtAnimationProgress(
- float progress) {
+float ScrollbarAnimationControllerThinning::
+ ThumbThicknessScaleAtAnimationProgress(float progress) {
if (thickness_change_ == NONE)
return mouse_is_near_scrollbar_ ? 1.f : kIdleThicknessScale;
float factor = thickness_change_ == INCREASE ? progress : (1.f - progress);
@@ -135,14 +133,14 @@
}
void ScrollbarAnimationControllerThinning::ApplyOpacityAndThumbThicknessScale(
- float opacity, float thumb_thickness_scale) {
+ float opacity,
+ float thumb_thickness_scale) {
if (!scroll_layer_->scrollbars())
return;
LayerImpl::ScrollbarSet* scrollbars = scroll_layer_->scrollbars();
for (LayerImpl::ScrollbarSet::iterator it = scrollbars->begin();
- it != scrollbars->end();
- ++it) {
+ it != scrollbars->end(); ++it) {
ScrollbarLayerImplBase* scrollbar = *it;
if (scrollbar->is_overlay_scrollbar()) {
float effectiveOpacity =
@@ -151,10 +149,9 @@
: 0;
scrollbar->SetOpacity(effectiveOpacity);
- scrollbar->SetThumbThicknessScaleFactor(
- AdjustScale(thumb_thickness_scale,
- scrollbar->thumb_thickness_scale_factor(),
- thickness_change_));
+ scrollbar->SetThumbThicknessScaleFactor(AdjustScale(
+ thumb_thickness_scale, scrollbar->thumb_thickness_scale_factor(),
+ thickness_change_));
}
}
}
diff --git a/cc/animation/scrollbar_animation_controller_thinning.h b/cc/animation/scrollbar_animation_controller_thinning.h
index 2cf30f5..f22d94c 100644
--- a/cc/animation/scrollbar_animation_controller_thinning.h
+++ b/cc/animation/scrollbar_animation_controller_thinning.h
@@ -62,8 +62,6 @@
void ApplyOpacityAndThumbThicknessScale(float opacity,
float thumb_thickness_scale);
- LayerImpl* scroll_layer_;
-
bool mouse_is_over_scrollbar_;
bool mouse_is_near_scrollbar_;
// Are we narrowing or thickening the bars.
diff --git a/cc/animation/scrollbar_animation_controller_thinning_unittest.cc b/cc/animation/scrollbar_animation_controller_thinning_unittest.cc
index 04036ba..01763c9 100644
--- a/cc/animation/scrollbar_animation_controller_thinning_unittest.cc
+++ b/cc/animation/scrollbar_animation_controller_thinning_unittest.cc
@@ -22,11 +22,22 @@
ScrollbarAnimationControllerThinningTest()
: host_impl_(&proxy_, &shared_bitmap_manager_) {}
- void PostDelayedScrollbarFade(const base::Closure& start_fade,
- base::TimeDelta delay) override {
- start_fade_ = start_fade;
+ void StartAnimatingScrollbarAnimationController(
+ ScrollbarAnimationController* controller) override {
+ is_animating_ = true;
}
- void SetNeedsScrollbarAnimationFrame() override {}
+ void StopAnimatingScrollbarAnimationController(
+ ScrollbarAnimationController* controller) override {
+ is_animating_ = false;
+ }
+ void PostDelayedScrollbarAnimationTask(const base::Closure& start_fade,
+ base::TimeDelta delay) override {
+ start_fade_ = start_fade;
+ delay_ = delay;
+ }
+ void SetNeedsRedrawForScrollbarAnimation() override {
+ did_request_redraw_ = true;
+ }
protected:
void SetUp() override {
@@ -57,11 +68,8 @@
scroll_layer_ptr->SetBounds(gfx::Size(200, 200));
scrollbar_controller_ = ScrollbarAnimationControllerThinning::Create(
- scroll_layer_ptr,
- this,
- base::TimeDelta::FromSeconds(2),
- base::TimeDelta::FromSeconds(5),
- base::TimeDelta::FromSeconds(3));
+ scroll_layer_ptr, this, base::TimeDelta::FromSeconds(2),
+ base::TimeDelta::FromSeconds(5), base::TimeDelta::FromSeconds(3));
}
FakeImplProxy proxy_;
@@ -72,6 +80,9 @@
scoped_ptr<SolidColorScrollbarLayerImpl> scrollbar_layer_;
base::Closure start_fade_;
+ base::TimeDelta delay_;
+ bool is_animating_;
+ bool did_request_redraw_;
};
// Check initialization of scrollbar.
diff --git a/cc/base/switches.cc b/cc/base/switches.cc
index c3fad97..504e787 100644
--- a/cc/base/switches.cc
+++ b/cc/base/switches.cc
@@ -58,6 +58,11 @@
const char kEnablePinchVirtualViewport[] = "enable-pinch-virtual-viewport";
const char kDisablePinchVirtualViewport[] = "disable-pinch-virtual-viewport";
+// Ensures that the draw properties computed via the property trees match those
+// computed by CalcDrawProperties.
+const char kEnablePropertyTreeVerification[] =
+ "enable-property-tree-verification";
+
// Disable partial swap which is needed for some OpenGL drivers / emulators.
const char kUIDisablePartialSwap[] = "ui-disable-partial-swap";
diff --git a/cc/base/switches.h b/cc/base/switches.h
index 5b7c92e..90caef8 100644
--- a/cc/base/switches.h
+++ b/cc/base/switches.h
@@ -31,6 +31,7 @@
CC_EXPORT extern const char kEnablePinchVirtualViewport[];
CC_EXPORT extern const char kDisablePinchVirtualViewport[];
CC_EXPORT extern const char kStrictLayerPropertyChangeChecking[];
+CC_EXPORT extern const char kEnablePropertyTreeVerification[];
// Switches for both the renderer and ui compositors.
CC_EXPORT extern const char kUIDisablePartialSwap[];
diff --git a/cc/blink/BUILD.gn b/cc/blink/BUILD.gn
index efbf0f1..9d4007b 100644
--- a/cc/blink/BUILD.gn
+++ b/cc/blink/BUILD.gn
@@ -9,6 +9,7 @@
output_name = "cc_blink"
sources = [
+ "context_provider_web_context.h",
"cc_blink_export.h",
"scrollbar_impl.cc",
"scrollbar_impl.h",
diff --git a/cc/blink/cc_blink.gyp b/cc/blink/cc_blink.gyp
index 892082c..e9934bf 100644
--- a/cc/blink/cc_blink.gyp
+++ b/cc/blink/cc_blink.gyp
@@ -26,6 +26,7 @@
# This sources list is duplicated in //cc/blink/BUILD.gn
'sources': [
'cc_blink_export.h',
+ 'context_provider_web_context.h',
'scrollbar_impl.cc',
'scrollbar_impl.h',
'web_animation_curve_common.cc',
diff --git a/cc/blink/web_display_item_list_impl.cc b/cc/blink/web_display_item_list_impl.cc
index 4941afe..6a4ab90 100644
--- a/cc/blink/web_display_item_list_impl.cc
+++ b/cc/blink/web_display_item_list_impl.cc
@@ -10,14 +10,15 @@
#include "cc/blink/web_filter_operations_impl.h"
#include "cc/resources/clip_display_item.h"
#include "cc/resources/clip_path_display_item.h"
+#include "cc/resources/compositing_display_item.h"
#include "cc/resources/drawing_display_item.h"
#include "cc/resources/filter_display_item.h"
#include "cc/resources/float_clip_display_item.h"
#include "cc/resources/transform_display_item.h"
-#include "cc/resources/transparency_display_item.h"
#include "skia/ext/refptr.h"
#include "third_party/WebKit/public/platform/WebFloatRect.h"
#include "third_party/WebKit/public/platform/WebRect.h"
+#include "third_party/skia/include/core/SkColorFilter.h"
#include "third_party/skia/include/core/SkImageFilter.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/utils/SkMatrix44.h"
@@ -79,19 +80,29 @@
display_item_list_->AppendItem(cc::TransformDisplayItem::Create(transform));
}
-void WebDisplayItemListImpl::appendTransparencyItem(
- float opacity,
- blink::WebBlendMode blend_mode) {
- display_item_list_->AppendItem(cc::TransparencyDisplayItem::Create(
- opacity, BlendModeToSkia(blend_mode)));
-}
-
void WebDisplayItemListImpl::appendEndTransformItem() {
display_item_list_->AppendItem(cc::EndTransformDisplayItem::Create());
}
-void WebDisplayItemListImpl::appendEndTransparencyItem() {
- display_item_list_->AppendItem(cc::EndTransparencyDisplayItem::Create());
+// TODO(pdr): Remove this once the blink-side callers have been removed.
+void WebDisplayItemListImpl::appendCompositingItem(
+ float opacity,
+ SkXfermode::Mode xfermode,
+ SkColorFilter* color_filter) {
+ appendCompositingItem(opacity, xfermode, nullptr, color_filter);
+}
+
+void WebDisplayItemListImpl::appendCompositingItem(
+ float opacity,
+ SkXfermode::Mode xfermode,
+ SkRect* bounds,
+ SkColorFilter* color_filter) {
+ display_item_list_->AppendItem(cc::CompositingDisplayItem::Create(
+ opacity, xfermode, bounds, skia::SharePtr(color_filter)));
+}
+
+void WebDisplayItemListImpl::appendEndCompositingItem() {
+ display_item_list_->AppendItem(cc::EndCompositingDisplayItem::Create());
}
void WebDisplayItemListImpl::appendFilterItem(
diff --git a/cc/blink/web_display_item_list_impl.h b/cc/blink/web_display_item_list_impl.h
index 8ec7a15..2bb1b90 100644
--- a/cc/blink/web_display_item_list_impl.h
+++ b/cc/blink/web_display_item_list_impl.h
@@ -14,8 +14,10 @@
#include "third_party/WebKit/public/platform/WebFloatPoint.h"
#include "third_party/WebKit/public/platform/WebVector.h"
#include "third_party/skia/include/core/SkRegion.h"
+#include "third_party/skia/include/core/SkXfermode.h"
#include "ui/gfx/geometry/point_f.h"
+class SkColorFilter;
class SkImageFilter;
class SkMatrix44;
class SkPath;
@@ -45,9 +47,15 @@
virtual void appendEndFloatClipItem();
virtual void appendTransformItem(const SkMatrix44& matrix);
virtual void appendEndTransformItem();
- virtual void appendTransparencyItem(float opacity,
- blink::WebBlendMode blend_mode);
- virtual void appendEndTransparencyItem();
+ // TODO(pdr): Remove this once the blink-side callers have been removed.
+ virtual void appendCompositingItem(float opacity,
+ SkXfermode::Mode,
+ SkColorFilter*);
+ virtual void appendCompositingItem(float opacity,
+ SkXfermode::Mode,
+ SkRect* bounds,
+ SkColorFilter*);
+ virtual void appendEndCompositingItem();
virtual void appendFilterItem(const blink::WebFilterOperations& filters,
const blink::WebFloatRect& bounds);
virtual void appendEndFilterItem();
diff --git a/cc/blink/web_layer_impl.cc b/cc/blink/web_layer_impl.cc
index 0ef5ae7..3c688a6 100644
--- a/cc/blink/web_layer_impl.cc
+++ b/cc/blink/web_layer_impl.cc
@@ -256,7 +256,7 @@
void WebLayerImpl::removeAnimation(
int animation_id,
blink::WebCompositorAnimation::TargetProperty target_property) {
- layer_->layer_animation_controller()->RemoveAnimation(
+ layer_->RemoveAnimation(
animation_id, static_cast<Animation::TargetProperty>(target_property));
}
diff --git a/cc/cc.gyp b/cc/cc.gyp
index 84a0930..0c4ee74 100644
--- a/cc/cc.gyp
+++ b/cc/cc.gyp
@@ -370,6 +370,8 @@
'resources/clip_display_item.h',
'resources/clip_path_display_item.cc',
'resources/clip_path_display_item.h',
+ 'resources/compositing_display_item.cc',
+ 'resources/compositing_display_item.h',
'resources/content_layer_updater.cc',
'resources/content_layer_updater.h',
'resources/display_item.cc',
@@ -500,8 +502,6 @@
'resources/transferable_resource.h',
'resources/transform_display_item.cc',
'resources/transform_display_item.h',
- 'resources/transparency_display_item.cc',
- 'resources/transparency_display_item.h',
'resources/ui_resource_bitmap.cc',
'resources/ui_resource_bitmap.h',
'resources/ui_resource_client.h',
diff --git a/cc/input/top_controls_manager.cc b/cc/input/top_controls_manager.cc
index 615afb0..7362805 100644
--- a/cc/input/top_controls_manager.cc
+++ b/cc/input/top_controls_manager.cc
@@ -39,8 +39,8 @@
: client_(client),
animation_direction_(NO_ANIMATION),
permitted_state_(BOTH),
- current_scroll_delta_(0.f),
- controls_scroll_begin_offset_(0.f),
+ accumulated_scroll_delta_(0.f),
+ baseline_content_offset_(0.f),
top_controls_show_threshold_(top_controls_hide_threshold),
top_controls_hide_threshold_(top_controls_show_threshold),
pinch_gesture_active_(false) {
@@ -96,8 +96,7 @@
void TopControlsManager::ScrollBegin() {
DCHECK(!pinch_gesture_active_);
ResetAnimations();
- current_scroll_delta_ = 0.f;
- controls_scroll_begin_offset_ = ContentTopOffset();
+ ResetBaseline();
}
gfx::Vector2dF TopControlsManager::ScrollBy(
@@ -110,19 +109,17 @@
else if (permitted_state_ == HIDDEN && pending_delta.y() < 0)
return pending_delta;
- current_scroll_delta_ += pending_delta.y();
+ accumulated_scroll_delta_ += pending_delta.y();
float old_offset = ContentTopOffset();
client_->SetCurrentTopControlsShownRatio(
- (controls_scroll_begin_offset_ - current_scroll_delta_) /
+ (baseline_content_offset_ - accumulated_scroll_delta_) /
TopControlsHeight());
// If the controls are fully visible, treat the current position as the
// new baseline even if the gesture didn't end.
- if (TopControlsShownRatio() == 1.f) {
- current_scroll_delta_ = 0.f;
- controls_scroll_begin_offset_ = ContentTopOffset();
- }
+ if (TopControlsShownRatio() == 1.f)
+ ResetBaseline();
ResetAnimations();
@@ -149,6 +146,10 @@
ScrollBegin();
}
+void TopControlsManager::MainThreadHasStoppedFlinging() {
+ StartAnimationIfNecessary();
+}
+
gfx::Vector2dF TopControlsManager::Animate(base::TimeTicks monotonic_time) {
if (!top_controls_animation_ || !client_->HaveRootScrollLayer())
return gfx::Vector2dF();
@@ -206,8 +207,8 @@
// If we could be either showing or hiding, we determine which one to
// do based on whether or not the total scroll delta was moving up or
// down.
- SetupAnimation(current_scroll_delta_ <= 0.f ? SHOWING_CONTROLS
- : HIDING_CONTROLS);
+ SetupAnimation(accumulated_scroll_delta_ <= 0.f ? SHOWING_CONTROLS
+ : HIDING_CONTROLS);
}
}
@@ -225,4 +226,9 @@
return false;
}
+void TopControlsManager::ResetBaseline() {
+ accumulated_scroll_delta_ = 0.f;
+ baseline_content_offset_ = ContentTopOffset();
+}
+
} // namespace cc
diff --git a/cc/input/top_controls_manager.h b/cc/input/top_controls_manager.h
index 06f623d..fc40378 100644
--- a/cc/input/top_controls_manager.h
+++ b/cc/input/top_controls_manager.h
@@ -61,6 +61,8 @@
void PinchBegin();
void PinchEnd();
+ void MainThreadHasStoppedFlinging();
+
gfx::Vector2dF Animate(base::TimeTicks monotonic_time);
protected:
@@ -73,6 +75,7 @@
void SetupAnimation(AnimationDirection direction);
void StartAnimationIfNecessary();
bool IsAnimationCompleteAtTime(base::TimeTicks time);
+ void ResetBaseline();
TopControlsManagerClient* client_; // The client manages the lifecycle of
// this.
@@ -81,8 +84,11 @@
AnimationDirection animation_direction_;
TopControlsState permitted_state_;
- float current_scroll_delta_;
- float controls_scroll_begin_offset_;
+ // Accumulated scroll delta since last baseline reset
+ float accumulated_scroll_delta_;
+
+ // Content offset when last baseline reset occurred
+ float baseline_content_offset_;
// The percent height of the visible top control such that it must be shown
// when the user stops the scroll.
diff --git a/cc/layers/draw_properties.h b/cc/layers/draw_properties.h
index 7cf89e7..ff5abd9 100644
--- a/cc/layers/draw_properties.h
+++ b/cc/layers/draw_properties.h
@@ -34,6 +34,7 @@
layer_or_descendant_has_input_handler(false),
has_child_with_a_scroll_parent(false),
sorted_for_recursion(false),
+ visited(false),
index_of_first_descendants_addition(0),
num_descendants_added(0),
index_of_first_render_surface_layer_list_addition(0),
@@ -123,6 +124,9 @@
// layer will be visited while computing draw properties has been determined.
bool sorted_for_recursion;
+ // This is used to sanity-check CDP and ensure that we don't revisit a layer.
+ bool visited;
+
// If this layer is visited out of order, its contribution to the descendant
// and render surface layer lists will be put aside in a temporary list.
// These values will allow for an efficient reordering of these additions.
diff --git a/cc/layers/heads_up_display_layer_impl.cc b/cc/layers/heads_up_display_layer_impl.cc
index 19217c9..2ed00a6 100644
--- a/cc/layers/heads_up_display_layer_impl.cc
+++ b/cc/layers/heads_up_display_layer_impl.cc
@@ -70,6 +70,8 @@
HeadsUpDisplayLayerImpl::HeadsUpDisplayLayerImpl(LayerTreeImpl* tree_impl,
int id)
: LayerImpl(tree_impl, id),
+ typeface_(skia::AdoptRef(
+ SkTypeface::CreateFromName("monospace", SkTypeface::kBold))),
internal_contents_scale_(1.f),
fps_graph_(60.0, 80.0),
paint_time_graph_(16.0, 48.0),
@@ -303,7 +305,7 @@
paint->setTextSize(size);
paint->setTextAlign(align);
- paint->setTypeface(layer_tree_impl()->settings().hud_typeface.get());
+ paint->setTypeface(typeface_.get());
canvas->drawText(text.c_str(), text.length(), x, y, *paint);
paint->setAntiAlias(anti_alias);
@@ -710,7 +712,7 @@
SkPaint label_paint = CreatePaint();
label_paint.setTextSize(kFontHeight);
- label_paint.setTypeface(layer_tree_impl()->settings().hud_typeface.get());
+ label_paint.setTypeface(typeface_.get());
label_paint.setColor(stroke_color);
const SkScalar label_text_width =
diff --git a/cc/layers/heads_up_display_layer_impl.h b/cc/layers/heads_up_display_layer_impl.h
index 5c3720e..54bf153 100644
--- a/cc/layers/heads_up_display_layer_impl.h
+++ b/cc/layers/heads_up_display_layer_impl.h
@@ -127,6 +127,8 @@
ScopedPtrVector<ScopedResource> resources_;
skia::RefPtr<SkSurface> hud_surface_;
+ skia::RefPtr<SkTypeface> typeface_;
+
float internal_contents_scale_;
gfx::Size internal_content_bounds_;
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc
index ca0e3b8..bf2f26a 100644
--- a/cc/layers/layer.cc
+++ b/cc/layers/layer.cc
@@ -1204,6 +1204,12 @@
SetNeedsCommit();
}
+void Layer::RemoveAnimation(int animation_id,
+ Animation::TargetProperty property) {
+ layer_animation_controller_->RemoveAnimation(animation_id, property);
+ SetNeedsCommit();
+}
+
void Layer::SetLayerAnimationControllerForTest(
scoped_refptr<LayerAnimationController> controller) {
layer_animation_controller_->RemoveValueObserver(this);
@@ -1318,6 +1324,24 @@
return xform;
}
+float Layer::DrawOpacityFromPropertyTrees(const OpacityTree& tree) const {
+ if (!render_target())
+ return 0.f;
+
+ const OpacityNode* target_node =
+ tree.Node(render_target()->opacity_tree_index());
+ const OpacityNode* node = tree.Node(opacity_tree_index());
+ if (node == target_node)
+ return 1.f;
+
+ float draw_opacity = 1.f;
+ while (node != target_node) {
+ draw_opacity *= node->data;
+ node = tree.parent(node);
+ }
+ return draw_opacity;
+}
+
void Layer::SetFrameTimingRequests(
const std::vector<FrameTimingRequest>& requests) {
frame_timing_requests_ = requests;
diff --git a/cc/layers/layer.h b/cc/layers/layer.h
index 8eb7c3d..a82da24 100644
--- a/cc/layers/layer.h
+++ b/cc/layers/layer.h
@@ -410,6 +410,7 @@
bool AddAnimation(scoped_ptr<Animation> animation);
void PauseAnimation(int animation_id, double time_offset);
void RemoveAnimation(int animation_id);
+ void RemoveAnimation(int animation_id, Animation::TargetProperty property);
LayerAnimationController* layer_animation_controller() {
return layer_animation_controller_.get();
@@ -472,8 +473,10 @@
void set_transform_tree_index(int index) { transform_tree_index_ = index; }
void set_clip_tree_index(int index) { clip_tree_index_ = index; }
+ void set_opacity_tree_index(int index) { opacity_tree_index_ = index; }
int clip_tree_index() const { return clip_tree_index_; }
int transform_tree_index() const { return transform_tree_index_; }
+ int opacity_tree_index() const { return opacity_tree_index_; }
void set_offset_to_transform_parent(gfx::Vector2dF offset) {
offset_to_transform_parent_ = offset;
@@ -499,6 +502,7 @@
const TransformTree& tree) const;
gfx::Transform draw_transform_from_property_trees(
const TransformTree& tree) const;
+ float DrawOpacityFromPropertyTrees(const OpacityTree& tree) const;
// TODO(vollick): These values are temporary and will be removed as soon as
// render surface determinations are moved out of CDP. They only exist because
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc
index 63fd4dc..0c6ddf5 100644
--- a/cc/layers/layer_impl.cc
+++ b/cc/layers/layer_impl.cc
@@ -83,7 +83,7 @@
DCHECK_GT(layer_id_, 0);
DCHECK(layer_tree_impl_);
layer_tree_impl_->RegisterLayer(this);
- AnimationRegistrar* registrar = layer_tree_impl_->animationRegistrar();
+ AnimationRegistrar* registrar = layer_tree_impl_->GetAnimationRegistrar();
layer_animation_controller_ =
registrar->GetAnimationControllerForId(layer_id_);
layer_animation_controller_->AddValueObserver(this);
diff --git a/cc/resources/compositing_display_item.cc b/cc/resources/compositing_display_item.cc
new file mode 100644
index 0000000..c33d4ca
--- /dev/null
+++ b/cc/resources/compositing_display_item.cc
@@ -0,0 +1,93 @@
+// Copyright 2015 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/resources/compositing_display_item.h"
+
+#include "base/strings/stringprintf.h"
+#include "base/trace_event/trace_event_argument.h"
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkPaint.h"
+#include "third_party/skia/include/core/SkXfermode.h"
+#include "ui/gfx/skia_util.h"
+
+namespace cc {
+
+CompositingDisplayItem::CompositingDisplayItem(float opacity,
+ SkXfermode::Mode xfermode,
+ SkRect* bounds,
+ skia::RefPtr<SkColorFilter> cf)
+ : opacity_(opacity),
+ xfermode_(xfermode),
+ has_bounds_(!!bounds),
+ color_filter_(cf) {
+ if (bounds)
+ bounds_ = SkRect(*bounds);
+}
+
+CompositingDisplayItem::~CompositingDisplayItem() {
+}
+
+void CompositingDisplayItem::Raster(SkCanvas* canvas,
+ SkDrawPictureCallback* callback) const {
+ SkPaint paint;
+ paint.setXfermodeMode(xfermode_);
+ paint.setAlpha(opacity_ * 255);
+ paint.setColorFilter(color_filter_.get());
+ canvas->saveLayer(has_bounds_ ? &bounds_ : nullptr, &paint);
+}
+
+bool CompositingDisplayItem::IsSuitableForGpuRasterization() const {
+ return true;
+}
+
+int CompositingDisplayItem::ApproximateOpCount() const {
+ return 1;
+}
+
+size_t CompositingDisplayItem::PictureMemoryUsage() const {
+ // TODO(pdr): Include color_filter's memory here.
+ return sizeof(float) + sizeof(bool) + sizeof(SkRect) +
+ sizeof(SkXfermode::Mode);
+}
+
+void CompositingDisplayItem::AsValueInto(
+ base::trace_event::TracedValue* array) const {
+ array->AppendString(base::StringPrintf(
+ "CompositingDisplayItem opacity: %f, xfermode: %d", opacity_, xfermode_));
+ if (has_bounds_)
+ array->AppendString(base::StringPrintf(
+ ", bounds: [%f, %f, %f, %f]", static_cast<float>(bounds_.x()),
+ static_cast<float>(bounds_.y()), static_cast<float>(bounds_.width()),
+ static_cast<float>(bounds_.height())));
+}
+
+EndCompositingDisplayItem::EndCompositingDisplayItem() {
+}
+
+EndCompositingDisplayItem::~EndCompositingDisplayItem() {
+}
+
+void EndCompositingDisplayItem::Raster(SkCanvas* canvas,
+ SkDrawPictureCallback* callback) const {
+ canvas->restore();
+}
+
+bool EndCompositingDisplayItem::IsSuitableForGpuRasterization() const {
+ return true;
+}
+
+int EndCompositingDisplayItem::ApproximateOpCount() const {
+ return 0;
+}
+
+size_t EndCompositingDisplayItem::PictureMemoryUsage() const {
+ return 0;
+}
+
+void EndCompositingDisplayItem::AsValueInto(
+ base::trace_event::TracedValue* array) const {
+ array->AppendString("EndCompositingDisplayItem");
+}
+
+} // namespace cc
diff --git a/cc/resources/compositing_display_item.h b/cc/resources/compositing_display_item.h
new file mode 100644
index 0000000..fd42a37
--- /dev/null
+++ b/cc/resources/compositing_display_item.h
@@ -0,0 +1,77 @@
+// Copyright 2015 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_RESOURCES_COMPOSITING_DISPLAY_ITEM_H_
+#define CC_RESOURCES_COMPOSITING_DISPLAY_ITEM_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "cc/base/cc_export.h"
+#include "cc/resources/display_item.h"
+#include "skia/ext/refptr.h"
+#include "third_party/skia/include/core/SkColorFilter.h"
+#include "third_party/skia/include/core/SkRect.h"
+#include "third_party/skia/include/core/SkXfermode.h"
+#include "ui/gfx/geometry/rect_f.h"
+
+class SkCanvas;
+class SkDrawPictureCallback;
+
+namespace cc {
+
+class CC_EXPORT CompositingDisplayItem : public DisplayItem {
+ public:
+ ~CompositingDisplayItem() override;
+
+ static scoped_ptr<CompositingDisplayItem> Create(
+ float opacity,
+ SkXfermode::Mode xfermode,
+ SkRect* bounds,
+ skia::RefPtr<SkColorFilter> color_filter) {
+ return make_scoped_ptr(
+ new CompositingDisplayItem(opacity, xfermode, bounds, color_filter));
+ }
+
+ void Raster(SkCanvas* canvas, SkDrawPictureCallback* callback) const override;
+
+ bool IsSuitableForGpuRasterization() const override;
+ int ApproximateOpCount() const override;
+ size_t PictureMemoryUsage() const override;
+ void AsValueInto(base::trace_event::TracedValue* array) const override;
+
+ protected:
+ CompositingDisplayItem(float opacity,
+ SkXfermode::Mode,
+ SkRect* bounds,
+ skia::RefPtr<SkColorFilter>);
+
+ private:
+ float opacity_;
+ SkXfermode::Mode xfermode_;
+ bool has_bounds_;
+ SkRect bounds_;
+ skia::RefPtr<SkColorFilter> color_filter_;
+};
+
+class CC_EXPORT EndCompositingDisplayItem : public DisplayItem {
+ public:
+ ~EndCompositingDisplayItem() override;
+
+ static scoped_ptr<EndCompositingDisplayItem> Create() {
+ return make_scoped_ptr(new EndCompositingDisplayItem());
+ }
+
+ void Raster(SkCanvas* canvas, SkDrawPictureCallback* callback) const override;
+
+ bool IsSuitableForGpuRasterization() const override;
+ int ApproximateOpCount() const override;
+ size_t PictureMemoryUsage() const override;
+ void AsValueInto(base::trace_event::TracedValue* array) const override;
+
+ protected:
+ EndCompositingDisplayItem();
+};
+
+} // namespace cc
+
+#endif // CC_RESOURCES_COMPOSITING_DISPLAY_ITEM_H_
diff --git a/cc/resources/one_copy_tile_task_worker_pool.cc b/cc/resources/one_copy_tile_task_worker_pool.cc
index e6a367a..1139fbe 100644
--- a/cc/resources/one_copy_tile_task_worker_pool.cc
+++ b/cc/resources/one_copy_tile_task_worker_pool.cc
@@ -78,7 +78,7 @@
const int kCopyFlushPeriod = 4;
// Number of in-flight copy operations to allow.
-const int kMaxCopyOperations = 16;
+const int kMaxCopyOperations = 32;
// Delay been checking for copy operations to complete.
const int kCheckForCompletedCopyOperationsTickRateMs = 1;
diff --git a/cc/resources/transparency_display_item.cc b/cc/resources/transparency_display_item.cc
deleted file mode 100644
index 1c37b73..0000000
--- a/cc/resources/transparency_display_item.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-// 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.
-
-#include "cc/resources/transparency_display_item.h"
-
-#include "base/strings/stringprintf.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "third_party/skia/include/core/SkCanvas.h"
-#include "third_party/skia/include/core/SkPaint.h"
-#include "third_party/skia/include/core/SkXfermode.h"
-#include "ui/gfx/skia_util.h"
-
-namespace cc {
-
-TransparencyDisplayItem::TransparencyDisplayItem(float opacity,
- SkXfermode::Mode blend_mode)
- : opacity_(opacity), blend_mode_(blend_mode) {
-}
-
-TransparencyDisplayItem::~TransparencyDisplayItem() {
-}
-
-void TransparencyDisplayItem::Raster(SkCanvas* canvas,
- SkDrawPictureCallback* callback) const {
- SkPaint paint;
- paint.setXfermodeMode(blend_mode_);
- paint.setAlpha(opacity_ * 255);
- canvas->saveLayer(NULL, &paint);
-}
-
-bool TransparencyDisplayItem::IsSuitableForGpuRasterization() const {
- return true;
-}
-
-int TransparencyDisplayItem::ApproximateOpCount() const {
- return 1;
-}
-
-size_t TransparencyDisplayItem::PictureMemoryUsage() const {
- return sizeof(float) + sizeof(SkXfermode::Mode);
-}
-
-void TransparencyDisplayItem::AsValueInto(
- base::trace_event::TracedValue* array) const {
- array->AppendString(
- base::StringPrintf("TransparencyDisplayItem opacity: %f, blend_mode: %d",
- opacity_, blend_mode_));
-}
-
-EndTransparencyDisplayItem::EndTransparencyDisplayItem() {
-}
-
-EndTransparencyDisplayItem::~EndTransparencyDisplayItem() {
-}
-
-void EndTransparencyDisplayItem::Raster(SkCanvas* canvas,
- SkDrawPictureCallback* callback) const {
- canvas->restore();
-}
-
-bool EndTransparencyDisplayItem::IsSuitableForGpuRasterization() const {
- return true;
-}
-
-int EndTransparencyDisplayItem::ApproximateOpCount() const {
- return 0;
-}
-
-size_t EndTransparencyDisplayItem::PictureMemoryUsage() const {
- return 0;
-}
-
-void EndTransparencyDisplayItem::AsValueInto(
- base::trace_event::TracedValue* array) const {
- array->AppendString("EndTransparencyDisplayItem");
-}
-
-} // namespace cc
diff --git a/cc/resources/transparency_display_item.h b/cc/resources/transparency_display_item.h
deleted file mode 100644
index d7ae7be..0000000
--- a/cc/resources/transparency_display_item.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// 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_RESOURCES_TRANSPARENCY_DISPLAY_ITEM_H_
-#define CC_RESOURCES_TRANSPARENCY_DISPLAY_ITEM_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "cc/base/cc_export.h"
-#include "cc/resources/display_item.h"
-#include "skia/ext/refptr.h"
-#include "third_party/skia/include/core/SkXfermode.h"
-#include "ui/gfx/geometry/rect_f.h"
-
-class SkCanvas;
-class SkDrawPictureCallback;
-
-namespace cc {
-
-class CC_EXPORT TransparencyDisplayItem : public DisplayItem {
- public:
- ~TransparencyDisplayItem() override;
-
- static scoped_ptr<TransparencyDisplayItem> Create(
- float opacity,
- SkXfermode::Mode blend_mode) {
- return make_scoped_ptr(new TransparencyDisplayItem(opacity, blend_mode));
- }
-
- void Raster(SkCanvas* canvas, SkDrawPictureCallback* callback) const override;
-
- bool IsSuitableForGpuRasterization() const override;
- int ApproximateOpCount() const override;
- size_t PictureMemoryUsage() const override;
- void AsValueInto(base::trace_event::TracedValue* array) const override;
-
- protected:
- TransparencyDisplayItem(float opacity, SkXfermode::Mode blend_mode);
-
- private:
- float opacity_;
- SkXfermode::Mode blend_mode_;
-};
-
-class CC_EXPORT EndTransparencyDisplayItem : public DisplayItem {
- public:
- ~EndTransparencyDisplayItem() override;
-
- static scoped_ptr<EndTransparencyDisplayItem> Create() {
- return make_scoped_ptr(new EndTransparencyDisplayItem());
- }
-
- void Raster(SkCanvas* canvas, SkDrawPictureCallback* callback) const override;
-
- bool IsSuitableForGpuRasterization() const override;
- int ApproximateOpCount() const override;
- size_t PictureMemoryUsage() const override;
- void AsValueInto(base::trace_event::TracedValue* array) const override;
-
- protected:
- EndTransparencyDisplayItem();
-};
-
-} // namespace cc
-
-#endif // CC_RESOURCES_TRANSPARENCY_DISPLAY_ITEM_H_
diff --git a/cc/resources/video_resource_updater.cc b/cc/resources/video_resource_updater.cc
index 1b089df..ed57e6f 100644
--- a/cc/resources/video_resource_updater.cc
+++ b/cc/resources/video_resource_updater.cc
@@ -14,7 +14,7 @@
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "media/base/video_frame.h"
-#include "media/filters/skcanvas_video_renderer.h"
+#include "media/blink/skcanvas_video_renderer.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/khronos/GLES2/gl2ext.h"
#include "ui/gfx/geometry/size_conversions.h"
diff --git a/cc/surfaces/surface_display_output_surface.cc b/cc/surfaces/surface_display_output_surface.cc
index b99e2b4..88e166c 100644
--- a/cc/surfaces/surface_display_output_surface.cc
+++ b/cc/surfaces/surface_display_output_surface.cc
@@ -46,7 +46,7 @@
void SurfaceDisplayOutputSurface::SwapBuffers(CompositorFrame* frame) {
gfx::Size frame_size =
frame->delegated_frame_data->render_pass_list.back()->output_rect.size();
- if (frame_size != display_size_) {
+ if (frame_size.IsEmpty() || frame_size != display_size_) {
if (!surface_id_.is_null()) {
factory_.Destroy(surface_id_);
}
diff --git a/cc/test/fake_layer_tree_host_impl_client.h b/cc/test/fake_layer_tree_host_impl_client.h
index d7a785b..63d7f43 100644
--- a/cc/test/fake_layer_tree_host_impl_client.h
+++ b/cc/test/fake_layer_tree_host_impl_client.h
@@ -35,7 +35,7 @@
int priority_cutoff) override;
bool IsInsideDraw() override;
void RenewTreePriority() override {}
- void PostDelayedScrollbarFadeOnImplThread(const base::Closure& start_fade,
+ void PostDelayedAnimationTaskOnImplThread(const base::Closure& task,
base::TimeDelta delay) override {}
void DidActivateSyncTree() override {}
void DidPrepareTiles() override {}
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc
index 129a27d..9690362 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -349,10 +349,9 @@
void UpdateAnimationState(bool start_ready_animations) override {
LayerTreeHostImpl::UpdateAnimationState(start_ready_animations);
bool has_unfinished_animation = false;
- AnimationRegistrar::AnimationControllerMap::const_iterator iter =
- active_animation_controllers().begin();
- for (; iter != active_animation_controllers().end(); ++iter) {
- if (iter->second->HasActiveAnimation()) {
+ for (const auto& it :
+ animation_registrar()->active_animation_controllers()) {
+ if (it.second->HasActiveAnimation()) {
has_unfinished_animation = true;
break;
}
diff --git a/cc/test/test_gpu_memory_buffer_manager.cc b/cc/test/test_gpu_memory_buffer_manager.cc
index 196922f..7430051 100644
--- a/cc/test/test_gpu_memory_buffer_manager.cc
+++ b/cc/test/test_gpu_memory_buffer_manager.cc
@@ -12,6 +12,14 @@
size_t StrideInBytes(size_t width, gfx::GpuMemoryBuffer::Format format) {
switch (format) {
+ case gfx::GpuMemoryBuffer::ATCIA:
+ case gfx::GpuMemoryBuffer::DXT5:
+ return width;
+ case gfx::GpuMemoryBuffer::ATC:
+ case gfx::GpuMemoryBuffer::DXT1:
+ case gfx::GpuMemoryBuffer::ETC1:
+ DCHECK_EQ(width % 2, 0U);
+ return width / 2;
case gfx::GpuMemoryBuffer::RGBA_8888:
case gfx::GpuMemoryBuffer::RGBX_8888:
case gfx::GpuMemoryBuffer::BGRA_8888:
diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc
index c9ead98..1e6d2c7 100644
--- a/cc/trees/draw_property_utils.cc
+++ b/cc/trees/draw_property_utils.cc
@@ -157,11 +157,14 @@
const TransformTree& tree,
bool subtree_is_visible_from_ancestor,
std::vector<Layer*>* layers_to_update) {
- const bool subtree_is_invisble =
- layer->opacity() == 0.0f ||
+ const bool layer_is_invisible =
+ (!layer->opacity() && !layer->OpacityIsAnimating() &&
+ !layer->OpacityCanAnimateOnImplThread());
+ const bool layer_is_backfacing =
(layer->has_render_surface() && !layer->double_sided() &&
IsSurfaceBackFaceExposed(layer, tree));
+ const bool subtree_is_invisble = layer_is_invisible || layer_is_backfacing;
if (subtree_is_invisble)
return;
@@ -262,10 +265,11 @@
const gfx::Rect& viewport,
const gfx::Transform& device_transform,
TransformTree* transform_tree,
- ClipTree* clip_tree) {
+ ClipTree* clip_tree,
+ OpacityTree* opacity_tree) {
PropertyTreeBuilder::BuildPropertyTrees(
root_layer, page_scale_layer, page_scale_factor, device_scale_factor,
- viewport, device_transform, transform_tree, clip_tree);
+ viewport, device_transform, transform_tree, clip_tree, opacity_tree);
ComputeTransforms(transform_tree);
ComputeClips(clip_tree, *transform_tree);
diff --git a/cc/trees/draw_property_utils.h b/cc/trees/draw_property_utils.h
index 6da912b..78c3c53 100644
--- a/cc/trees/draw_property_utils.h
+++ b/cc/trees/draw_property_utils.h
@@ -16,6 +16,7 @@
class ClipTree;
class Layer;
+class OpacityTree;
class TransformTree;
// Computes combined clips for every node in |clip_tree|. This function requires
@@ -40,7 +41,8 @@
const gfx::Rect& viewport,
const gfx::Transform& device_transform,
TransformTree* transform_tree,
- ClipTree* clip_tree);
+ ClipTree* clip_tree,
+ OpacityTree* opacity_tree);
} // namespace cc
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 49e374d..abc63fc 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -558,8 +558,7 @@
// controllers may still receive events for impl-only animations.
const AnimationRegistrar::AnimationControllerMap& animation_controllers =
animation_registrar_->all_animation_controllers();
- AnimationRegistrar::AnimationControllerMap::const_iterator iter =
- animation_controllers.find(event_layer_id);
+ auto iter = animation_controllers.find(event_layer_id);
if (iter != animation_controllers.end()) {
switch ((*events)[event_index].type) {
case AnimationEvent::STARTED:
@@ -668,19 +667,13 @@
SetNeedsCommit();
}
-void LayerTreeHost::SetTopControlsShrinkBlinkSize(bool shrink) {
- if (top_controls_shrink_blink_size_ == shrink)
- return;
-
- top_controls_shrink_blink_size_ = shrink;
- SetNeedsCommit();
-}
-
-void LayerTreeHost::SetTopControlsHeight(float height) {
- if (top_controls_height_ == height)
+void LayerTreeHost::SetTopControlsHeight(float height, bool shrink) {
+ if (top_controls_height_ == height &&
+ top_controls_shrink_blink_size_ == shrink)
return;
top_controls_height_ = height;
+ top_controls_shrink_blink_size_ = shrink;
SetNeedsCommit();
}
@@ -1200,14 +1193,12 @@
TRACE_EVENT0("cc", "LayerTreeHost::AnimateLayers");
- AnimationRegistrar::AnimationControllerMap copy =
+ AnimationRegistrar::AnimationControllerMap active_controllers_copy =
animation_registrar_->active_animation_controllers();
- for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin();
- iter != copy.end();
- ++iter) {
- (*iter).second->Animate(monotonic_time);
+ for (auto& it : active_controllers_copy) {
+ it.second->Animate(monotonic_time);
bool start_ready_animations = true;
- (*iter).second->UpdateState(start_ready_animations, NULL);
+ it.second->UpdateState(start_ready_animations, NULL);
}
}
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h
index d41e73d..e677f89 100644
--- a/cc/trees/layer_tree_host.h
+++ b/cc/trees/layer_tree_host.h
@@ -211,8 +211,7 @@
GpuRasterizationStatus GetGpuRasterizationStatus() const;
void SetViewportSize(const gfx::Size& device_viewport_size);
- void SetTopControlsShrinkBlinkSize(bool shrink);
- void SetTopControlsHeight(float height);
+ void SetTopControlsHeight(float height, bool shrink);
void SetTopControlsShownRatio(float ratio);
gfx::Size device_viewport_size() const { return device_viewport_size_; }
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc
index 7a3b5ad..a84cae6 100644
--- a/cc/trees/layer_tree_host_common.cc
+++ b/cc/trees/layer_tree_host_common.cc
@@ -31,7 +31,7 @@
ScrollAndScaleSet::~ScrollAndScaleSet() {}
-static void SortLayers(LayerList::iterator forst,
+static void SortLayers(LayerList::iterator first,
LayerList::iterator end,
void* layer_sorter) {
NOTREACHED();
@@ -337,7 +337,8 @@
template <typename LayerType>
static inline bool LayerIsInExisting3DRenderingContext(LayerType* layer) {
return layer->Is3dSorted() && layer->parent() &&
- layer->parent()->Is3dSorted();
+ layer->parent()->Is3dSorted() &&
+ (layer->parent()->sorting_context_id() == layer->sorting_context_id());
}
template <typename LayerType>
@@ -590,6 +591,13 @@
return true;
}
+ // If the layer will use a CSS filter. In this case, the animation
+ // will start and add a filter to this layer, so it needs a surface.
+ if (layer->FilterIsAnimating()) {
+ DCHECK(!is_root);
+ return true;
+ }
+
int num_descendants_that_draw_content =
layer->NumDescendantsThatDrawContent();
@@ -1197,20 +1205,22 @@
}
};
-static bool ValidateRenderSurface(LayerImpl* layer) {
+static void ValidateRenderSurface(LayerImpl* layer) {
// This test verifies that there are no cases where a LayerImpl needs
// a render surface, but doesn't have one.
if (layer->render_surface())
- return true;
+ return;
- return layer->filters().IsEmpty() && layer->background_filters().IsEmpty() &&
- !layer->mask_layer() && !layer->replica_layer() &&
- !IsRootLayer(layer) && !layer->is_root_for_isolated_group() &&
- !layer->HasCopyRequest();
+ DCHECK(layer->filters().IsEmpty()) << "layer: " << layer->id();
+ DCHECK(layer->background_filters().IsEmpty()) << "layer: " << layer->id();
+ DCHECK(!layer->mask_layer()) << "layer: " << layer->id();
+ DCHECK(!layer->replica_layer()) << "layer: " << layer->id();
+ DCHECK(!IsRootLayer(layer)) << "layer: " << layer->id();
+ DCHECK(!layer->is_root_for_isolated_group()) << "layer: " << layer->id();
+ DCHECK(!layer->HasCopyRequest()) << "layer: " << layer->id();
}
-static bool ValidateRenderSurface(Layer* layer) {
- return true;
+static void ValidateRenderSurface(Layer* layer) {
}
// Recursively walks the layer tree to compute any information that is needed
@@ -1219,10 +1229,11 @@
static void PreCalculateMetaInformation(
LayerType* layer,
PreCalculateMetaInformationRecursiveData* recursive_data) {
- DCHECK(ValidateRenderSurface(layer));
+ ValidateRenderSurface(layer);
layer->draw_properties().sorted_for_recursion = false;
layer->draw_properties().has_child_with_a_scroll_parent = false;
+ layer->draw_properties().visited = false;
if (!HasInvertibleOrAnimatedTransform(layer)) {
// Layers with singular transforms should not be drawn, the whole subtree
@@ -1590,6 +1601,9 @@
DCHECK(globals.page_scale_application_layer ||
(globals.page_scale_factor == 1.f));
+ CHECK(!layer->draw_properties().visited);
+ layer->draw_properties().visited = true;
+
DataForRecursion<LayerType> data_for_children;
typename LayerType::RenderSurfaceType*
nearest_occlusion_immune_ancestor_surface =
@@ -2501,13 +2515,9 @@
PreCalculateMetaInformation(inputs->root_layer, &recursive_data);
std::vector<AccumulatedSurfaceState<Layer>> accumulated_surface_state;
CalculateDrawPropertiesInternal<Layer>(
- inputs->root_layer,
- globals,
- data_for_recursion,
- inputs->render_surface_layer_list,
- &dummy_layer_list,
- &accumulated_surface_state,
- inputs->current_render_surface_layer_list_id);
+ inputs->root_layer, globals, data_for_recursion,
+ inputs->render_surface_layer_list, &dummy_layer_list,
+ &accumulated_surface_state, inputs->current_render_surface_layer_list_id);
// The dummy layer list should not have been used.
DCHECK_EQ(0u, dummy_layer_list.size());
@@ -2520,11 +2530,12 @@
// will eventually get these data passed directly to the compositor.
TransformTree transform_tree;
ClipTree clip_tree;
+ OpacityTree opacity_tree;
ComputeVisibleRectsUsingPropertyTrees(
inputs->root_layer, inputs->page_scale_application_layer,
inputs->page_scale_factor, inputs->device_scale_factor,
gfx::Rect(inputs->device_viewport_size), inputs->device_transform,
- &transform_tree, &clip_tree);
+ &transform_tree, &clip_tree, &opacity_tree);
LayerIterator<Layer> it, end;
for (it = LayerIterator<Layer>::Begin(inputs->render_surface_layer_list),
@@ -2543,6 +2554,11 @@
current_layer->draw_transform(),
current_layer->draw_transform_from_property_trees(transform_tree));
CHECK(draw_transforms_match);
+
+ const bool draw_opacities_match =
+ current_layer->draw_opacity() ==
+ current_layer->DrawOpacityFromPropertyTrees(opacity_tree);
+ CHECK(draw_opacities_match);
}
}
}
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc
index 30cc15a..6f05035 100644
--- a/cc/trees/layer_tree_host_common_unittest.cc
+++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -2975,6 +2975,78 @@
EXPECT_FALSE(child->draw_properties().sorted_for_recursion);
}
+TEST_F(LayerTreeHostCommonTest, WillSortAtContextBoundary) {
+ // Creates a layer tree that looks as follows:
+ // * root (sorting-context-id1)
+ // * parent (sorting-context-id2)
+ // * child1 (sorting-context-id2)
+ // * child2 (sorting-context-id2)
+ //
+ // This test ensures that we sort at |parent| even though both it and root are
+ // set to be 3d sorted.
+ FakeImplProxy proxy;
+ TestSharedBitmapManager shared_bitmap_manager;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
+
+ scoped_ptr<LayerImpl> root_ptr(LayerImpl::Create(host_impl.active_tree(), 1));
+ LayerImpl* root = root_ptr.get();
+ scoped_ptr<LayerImpl> parent_ptr(
+ LayerImpl::Create(host_impl.active_tree(), 2));
+ LayerImpl* parent = parent_ptr.get();
+ scoped_ptr<LayerImpl> child1_ptr(
+ LayerImpl::Create(host_impl.active_tree(), 3));
+ LayerImpl* child1 = child1_ptr.get();
+ scoped_ptr<LayerImpl> child2_ptr(
+ LayerImpl::Create(host_impl.active_tree(), 4));
+ LayerImpl* child2 = child2_ptr.get();
+
+ gfx::Transform identity_matrix;
+ gfx::Transform below_matrix;
+ below_matrix.Translate3d(0.f, 0.f, -10.f);
+ gfx::Transform above_matrix;
+ above_matrix.Translate3d(0.f, 0.f, 10.f);
+
+ SetLayerPropertiesForTesting(root, identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), true, true,
+ true);
+ SetLayerPropertiesForTesting(parent, identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(50, 50), true, true,
+ true);
+ SetLayerPropertiesForTesting(child1, above_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(50, 50), true, true,
+ false);
+ SetLayerPropertiesForTesting(child2, below_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(50, 50), true, true,
+ false);
+
+ root->Set3dSortingContextId(3);
+ root->SetDrawsContent(true);
+ parent->Set3dSortingContextId(7);
+ parent->SetDrawsContent(true);
+ child1->Set3dSortingContextId(7);
+ child1->SetDrawsContent(true);
+ child2->Set3dSortingContextId(7);
+ child2->SetDrawsContent(true);
+
+ parent->AddChild(child1_ptr.Pass());
+ parent->AddChild(child2_ptr.Pass());
+ root->AddChild(parent_ptr.Pass());
+
+ LayerImplList render_surface_layer_list;
+ LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
+ root_ptr.get(), root->bounds(), &render_surface_layer_list);
+ inputs.can_adjust_raster_scales = true;
+ LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+
+ EXPECT_TRUE(root->render_surface());
+ EXPECT_EQ(2u, render_surface_layer_list.size());
+
+ EXPECT_EQ(3u, parent->render_surface()->layer_list().size());
+ EXPECT_EQ(child2->id(), parent->render_surface()->layer_list().at(0)->id());
+ EXPECT_EQ(parent->id(), parent->render_surface()->layer_list().at(1)->id());
+ EXPECT_EQ(child1->id(), parent->render_surface()->layer_list().at(2)->id());
+}
+
TEST_F(LayerTreeHostCommonTest,
SingularNonAnimatingTransformDoesNotPreventClearingDrawProperties) {
scoped_refptr<Layer> root = Layer::Create();
@@ -8675,5 +8747,70 @@
EXPECT_EQ(affected_by_delta, sublayer->visible_content_rect());
}
+TEST_F(LayerTreeHostCommonTest, VisibleContentRectForAnimatedLayer) {
+ const gfx::Transform identity_matrix;
+ scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<LayerWithForcedDrawsContent> animated =
+ make_scoped_refptr(new LayerWithForcedDrawsContent());
+
+ root->AddChild(animated);
+
+ scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
+ host->SetRootLayer(root);
+
+ SetLayerPropertiesForTesting(root.get(), identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), true, false);
+ SetLayerPropertiesForTesting(animated.get(), identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(20, 20), true, false);
+
+ root->SetMasksToBounds(true);
+ root->SetForceRenderSurface(true);
+ animated->SetOpacity(0.f);
+
+ AddOpacityTransitionToController(animated->layer_animation_controller(), 10.0,
+ 0.f, 1.f, false);
+
+ ExecuteCalculateDrawProperties(root.get());
+
+ EXPECT_FALSE(animated->visible_rect_from_property_trees().IsEmpty());
+}
+
+// Verify that having an animated filter (but no current filter, as these
+// are mutually exclusive) correctly creates a render surface.
+TEST_F(LayerTreeHostCommonTest, AnimatedFilterCreatesRenderSurface) {
+ scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> child = Layer::Create();
+ scoped_refptr<Layer> grandchild = Layer::Create();
+ root->AddChild(child);
+ child->AddChild(grandchild);
+
+ gfx::Transform identity_transform;
+ SetLayerPropertiesForTesting(root.get(), identity_transform, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(50, 50), true, false);
+ SetLayerPropertiesForTesting(child.get(), identity_transform, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(50, 50), true, false);
+ SetLayerPropertiesForTesting(grandchild.get(), identity_transform,
+ gfx::Point3F(), gfx::PointF(), gfx::Size(50, 50),
+ true, false);
+ scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
+ host->SetRootLayer(root);
+
+ AddAnimatedFilterToLayer(child.get(), 10.0, 0.1f, 0.2f);
+
+ ExecuteCalculateDrawProperties(root.get());
+
+ EXPECT_TRUE(root->render_surface());
+ EXPECT_TRUE(child->render_surface());
+ EXPECT_FALSE(grandchild->render_surface());
+
+ EXPECT_TRUE(root->filters().IsEmpty());
+ EXPECT_TRUE(child->filters().IsEmpty());
+ EXPECT_TRUE(grandchild->filters().IsEmpty());
+
+ EXPECT_FALSE(root->FilterIsAnimating());
+ EXPECT_TRUE(child->FilterIsAnimating());
+ EXPECT_FALSE(grandchild->FilterIsAnimating());
+}
+
} // namespace
} // namespace cc
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index eef1cc3..eddbc60 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -916,6 +916,8 @@
}
void LayerTreeHostImpl::MainThreadHasStoppedFlinging() {
+ if (top_controls_manager_)
+ top_controls_manager_->MainThreadHasStoppedFlinging();
if (input_handler_client_)
input_handler_client_->MainThreadHasStoppedFlinging();
}
@@ -3112,6 +3114,19 @@
client_->RenewTreePriority();
}
+void LayerTreeHostImpl::AnimateScrollbars(base::TimeTicks monotonic_time) {
+ if (scrollbar_animation_controllers_.empty())
+ return;
+
+ TRACE_EVENT0("cc", "LayerTreeHostImpl::AnimateScrollbars");
+ std::set<ScrollbarAnimationController*> controllers_copy =
+ scrollbar_animation_controllers_;
+ for (auto& it : controllers_copy)
+ it->Animate(monotonic_time);
+
+ SetNeedsAnimate();
+}
+
void LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time) {
if (!settings_.accelerated_animation_enabled ||
!needs_animate_layers() ||
@@ -3119,31 +3134,26 @@
return;
TRACE_EVENT0("cc", "LayerTreeHostImpl::AnimateLayers");
- AnimationRegistrar::AnimationControllerMap copy =
+ AnimationRegistrar::AnimationControllerMap controllers_copy =
animation_registrar_->active_animation_controllers();
- for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin();
- iter != copy.end();
- ++iter)
- (*iter).second->Animate(monotonic_time);
+ for (auto& it : controllers_copy)
+ it.second->Animate(monotonic_time);
SetNeedsAnimate();
}
void LayerTreeHostImpl::UpdateAnimationState(bool start_ready_animations) {
- if (!settings_.accelerated_animation_enabled ||
- !needs_animate_layers() ||
+ if (!settings_.accelerated_animation_enabled || !needs_animate_layers() ||
!active_tree_->root_layer())
return;
TRACE_EVENT0("cc", "LayerTreeHostImpl::UpdateAnimationState");
scoped_ptr<AnimationEventsVector> events =
make_scoped_ptr(new AnimationEventsVector);
- AnimationRegistrar::AnimationControllerMap copy =
+ AnimationRegistrar::AnimationControllerMap active_controllers_copy =
animation_registrar_->active_animation_controllers();
- for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin();
- iter != copy.end();
- ++iter)
- (*iter).second->UpdateState(start_ready_animations, events.get());
+ for (auto& it : active_controllers_copy)
+ it.second->UpdateState(start_ready_animations, events.get());
if (!events->empty()) {
client_->PostAnimationEventsToMainThreadOnImplThread(events.Pass());
@@ -3158,12 +3168,10 @@
return;
TRACE_EVENT0("cc", "LayerTreeHostImpl::ActivateAnimations");
- AnimationRegistrar::AnimationControllerMap copy =
+ AnimationRegistrar::AnimationControllerMap active_controllers_copy =
animation_registrar_->active_animation_controllers();
- for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin();
- iter != copy.end();
- ++iter)
- (*iter).second->ActivateAnimations();
+ for (auto& it : active_controllers_copy)
+ it.second->ActivateAnimations();
SetNeedsAnimate();
}
@@ -3182,38 +3190,27 @@
return fps_counter_->current_frame_number();
}
-void LayerTreeHostImpl::AnimateScrollbars(base::TimeTicks time) {
- AnimateScrollbarsRecursive(active_tree_->root_layer(), time);
-}
-
-void LayerTreeHostImpl::AnimateScrollbarsRecursive(LayerImpl* layer,
- base::TimeTicks time) {
- if (!layer)
- return;
-
- ScrollbarAnimationController* scrollbar_controller =
- layer->scrollbar_animation_controller();
- if (scrollbar_controller)
- scrollbar_controller->Animate(time);
-
- for (size_t i = 0; i < layer->children().size(); ++i)
- AnimateScrollbarsRecursive(layer->children()[i], time);
-}
-
-void LayerTreeHostImpl::PostDelayedScrollbarFade(
- const base::Closure& start_fade,
- base::TimeDelta delay) {
- client_->PostDelayedScrollbarFadeOnImplThread(start_fade, delay);
-}
-
-void LayerTreeHostImpl::SetNeedsScrollbarAnimationFrame() {
- TRACE_EVENT_INSTANT0(
- "cc",
- "LayerTreeHostImpl::SetNeedsRedraw due to scrollbar fade",
- TRACE_EVENT_SCOPE_THREAD);
+void LayerTreeHostImpl::StartAnimatingScrollbarAnimationController(
+ ScrollbarAnimationController* controller) {
+ scrollbar_animation_controllers_.insert(controller);
SetNeedsAnimate();
}
+void LayerTreeHostImpl::StopAnimatingScrollbarAnimationController(
+ ScrollbarAnimationController* controller) {
+ scrollbar_animation_controllers_.erase(controller);
+}
+
+void LayerTreeHostImpl::PostDelayedScrollbarAnimationTask(
+ const base::Closure& task,
+ base::TimeDelta delay) {
+ client_->PostDelayedAnimationTaskOnImplThread(task, delay);
+}
+
+void LayerTreeHostImpl::SetNeedsRedrawForScrollbarAnimation() {
+ SetNeedsRedraw();
+}
+
void LayerTreeHostImpl::SetTreePriority(TreePriority priority) {
if (!tile_manager_)
return;
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index 60f4b44..73ed039 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -103,9 +103,8 @@
int priority_cutoff) = 0;
virtual bool IsInsideDraw() = 0;
virtual void RenewTreePriority() = 0;
- virtual void PostDelayedScrollbarFadeOnImplThread(
- const base::Closure& start_fade,
- base::TimeDelta delay) = 0;
+ virtual void PostDelayedAnimationTaskOnImplThread(const base::Closure& task,
+ base::TimeDelta delay) = 0;
virtual void DidActivateSyncTree() = 0;
virtual void DidPrepareTiles() = 0;
@@ -258,9 +257,13 @@
void SetIsLikelyToRequireADraw(bool is_likely_to_require_a_draw) override;
// ScrollbarAnimationControllerClient implementation.
- void PostDelayedScrollbarFade(const base::Closure& start_fade,
- base::TimeDelta delay) override;
- void SetNeedsScrollbarAnimationFrame() override;
+ void StartAnimatingScrollbarAnimationController(
+ ScrollbarAnimationController* controller) override;
+ void StopAnimatingScrollbarAnimationController(
+ ScrollbarAnimationController* controller) override;
+ void PostDelayedScrollbarAnimationTask(const base::Closure& task,
+ base::TimeDelta delay) override;
+ void SetNeedsRedrawForScrollbarAnimation() override;
// OutputSurfaceClient implementation.
void DeferredInitialize() override;
@@ -532,10 +535,6 @@
// Virtual for testing.
virtual void AnimateLayers(base::TimeTicks monotonic_time);
- const AnimationRegistrar::AnimationControllerMap&
- active_animation_controllers() const {
- return animation_registrar_->active_animation_controllers();
- }
LayerTreeHostImplClient* client_;
Proxy* proxy_;
@@ -584,9 +583,6 @@
bool HandleMouseOverScrollbar(LayerImpl* layer_impl,
const gfx::PointF& device_viewport_point);
- void AnimateScrollbarsRecursive(LayerImpl* layer,
- base::TimeTicks time);
-
LayerImpl* FindScrollLayerForDeviceViewportPoint(
const gfx::PointF& device_viewport_point,
InputHandler::ScrollInputType type,
@@ -716,6 +712,7 @@
base::TimeDelta begin_impl_frame_interval_;
scoped_ptr<AnimationRegistrar> animation_registrar_;
+ std::set<ScrollbarAnimationController*> scrollbar_animation_controllers_;
RenderingStatsInstrumentation* rendering_stats_instrumentation_;
MicroBenchmarkControllerImpl micro_benchmark_controller_;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 38b2d66..b5e3a81 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -145,10 +145,10 @@
}
bool IsInsideDraw() override { return false; }
void RenewTreePriority() override {}
- void PostDelayedScrollbarFadeOnImplThread(const base::Closure& start_fade,
+ void PostDelayedAnimationTaskOnImplThread(const base::Closure& task,
base::TimeDelta delay) override {
- scrollbar_fade_start_ = start_fade;
- requested_scrollbar_animation_delay_ = delay;
+ animation_task_ = task;
+ requested_animation_delay_ = delay;
}
void DidActivateSyncTree() override {}
void DidPrepareTiles() override {}
@@ -401,8 +401,8 @@
bool did_request_prepare_tiles_;
bool did_complete_page_scale_animation_;
bool reduce_memory_result_;
- base::Closure scrollbar_fade_start_;
- base::TimeDelta requested_scrollbar_animation_delay_;
+ base::Closure animation_task_;
+ base::TimeDelta requested_animation_delay_;
size_t current_limit_bytes_;
int current_priority_cutoff_value_;
};
@@ -1616,52 +1616,77 @@
base::TimeTicks fake_now = gfx::FrameTime::Now();
- EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
+ EXPECT_FALSE(did_request_animate_);
EXPECT_FALSE(did_request_redraw_);
+ EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
+ EXPECT_TRUE(animation_task_.Equals(base::Closure()));
// If no scroll happened during a scroll gesture, it should have no effect.
host_impl_->ScrollBegin(gfx::Point(), InputHandler::WHEEL);
host_impl_->ScrollEnd();
- EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
+ EXPECT_FALSE(did_request_animate_);
EXPECT_FALSE(did_request_redraw_);
- EXPECT_TRUE(scrollbar_fade_start_.Equals(base::Closure()));
+ EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
+ EXPECT_TRUE(animation_task_.Equals(base::Closure()));
// After a scroll, a fade animation should be scheduled about 20ms from now.
host_impl_->ScrollBegin(gfx::Point(), InputHandler::WHEEL);
host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 5));
- host_impl_->ScrollEnd();
- did_request_redraw_ = false;
- did_request_animate_ = false;
- EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
- requested_scrollbar_animation_delay_);
- EXPECT_FALSE(did_request_redraw_);
EXPECT_FALSE(did_request_animate_);
- requested_scrollbar_animation_delay_ = base::TimeDelta();
- scrollbar_fade_start_.Run();
- host_impl_->Animate(fake_now);
+ EXPECT_TRUE(did_request_redraw_);
+ did_request_redraw_ = false;
+ EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
+ EXPECT_TRUE(animation_task_.Equals(base::Closure()));
+
+ host_impl_->ScrollEnd();
+ EXPECT_FALSE(did_request_animate_);
+ EXPECT_FALSE(did_request_redraw_);
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(20), requested_animation_delay_);
+ EXPECT_FALSE(animation_task_.Equals(base::Closure()));
+
+ fake_now += requested_animation_delay_;
+ requested_animation_delay_ = base::TimeDelta();
+ animation_task_.Run();
+ animation_task_ = base::Closure();
+ EXPECT_TRUE(did_request_animate_);
+ did_request_animate_ = false;
+ EXPECT_FALSE(did_request_redraw_);
// After the fade begins, we should start getting redraws instead of a
// scheduled animation.
- fake_now += base::TimeDelta::FromMilliseconds(25);
- EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
+ host_impl_->Animate(fake_now);
EXPECT_TRUE(did_request_animate_);
did_request_animate_ = false;
+ EXPECT_TRUE(did_request_redraw_);
+ did_request_redraw_ = false;
+ EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
+ EXPECT_TRUE(animation_task_.Equals(base::Closure()));
// Setting the scroll offset outside a scroll should also cause the scrollbar
// to appear and to schedule a fade.
host_impl_->InnerViewportScrollLayer()->PushScrollOffsetFromMainThread(
gfx::ScrollOffset(5, 5));
- EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
- requested_scrollbar_animation_delay_);
- EXPECT_FALSE(did_request_redraw_);
EXPECT_FALSE(did_request_animate_);
- requested_scrollbar_animation_delay_ = base::TimeDelta();
+ EXPECT_FALSE(did_request_redraw_);
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(20), requested_animation_delay_);
+ EXPECT_FALSE(animation_task_.Equals(base::Closure()));
+ requested_animation_delay_ = base::TimeDelta();
+ animation_task_ = base::Closure();
// Unnecessarily Fade animation of solid color scrollbar is not triggered.
host_impl_->ScrollBegin(gfx::Point(), InputHandler::WHEEL);
host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
+ EXPECT_FALSE(did_request_animate_);
+ EXPECT_TRUE(did_request_redraw_);
+ did_request_redraw_ = false;
+ EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
+ EXPECT_TRUE(animation_task_.Equals(base::Closure()));
+
host_impl_->ScrollEnd();
- EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
+ EXPECT_FALSE(did_request_animate_);
+ EXPECT_FALSE(did_request_redraw_);
+ EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
+ EXPECT_TRUE(animation_task_.Equals(base::Closure()));
}
TEST_F(LayerTreeHostImplTest, ScrollbarFadePinchZoomScrollbars) {
@@ -1677,28 +1702,28 @@
host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 4.f);
- EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
+ EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
EXPECT_FALSE(did_request_animate_);
// If no scroll happened during a scroll gesture, it should have no effect.
host_impl_->ScrollBegin(gfx::Point(), InputHandler::WHEEL);
host_impl_->ScrollEnd();
- EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
+ EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
EXPECT_FALSE(did_request_animate_);
- EXPECT_TRUE(scrollbar_fade_start_.Equals(base::Closure()));
+ EXPECT_TRUE(animation_task_.Equals(base::Closure()));
// After a scroll, no fade animation should be scheduled.
host_impl_->ScrollBegin(gfx::Point(), InputHandler::WHEEL);
host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
host_impl_->ScrollEnd();
did_request_redraw_ = false;
- EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
+ EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
EXPECT_FALSE(did_request_animate_);
- requested_scrollbar_animation_delay_ = base::TimeDelta();
+ requested_animation_delay_ = base::TimeDelta();
// We should not see any draw requests.
fake_now += base::TimeDelta::FromMilliseconds(25);
- EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
+ EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
EXPECT_FALSE(did_request_animate_);
// Make page scale > min so that subsequent scrolls will trigger fades.
@@ -1709,11 +1734,10 @@
host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
host_impl_->ScrollEnd();
did_request_redraw_ = false;
- EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
- requested_scrollbar_animation_delay_);
+ EXPECT_LT(base::TimeDelta::FromMilliseconds(19), requested_animation_delay_);
EXPECT_FALSE(did_request_animate_);
- requested_scrollbar_animation_delay_ = base::TimeDelta();
- scrollbar_fade_start_.Run();
+ requested_animation_delay_ = base::TimeDelta();
+ animation_task_.Run();
// After the fade begins, we should start getting redraws instead of a
// scheduled animation.
@@ -7639,6 +7663,69 @@
}
}
EXPECT_FALSE(host_impl_->top_controls_manager()->animation());
+ EXPECT_EQ(-top_controls_height_,
+ host_impl_->top_controls_manager()->ControlsTopOffset());
+}
+
+TEST_F(LayerTreeHostImplWithTopControlsTest,
+ TopControlsAnimationAfterMainThreadFlingStopped) {
+ LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200));
+ host_impl_->SetViewportSize(gfx::Size(100, 100));
+ host_impl_->top_controls_manager()->UpdateTopControlsState(BOTH, SHOWN,
+ false);
+ float initial_scroll_offset = 50;
+ scroll_layer->PushScrollOffsetFromMainThread(
+ gfx::ScrollOffset(0, initial_scroll_offset));
+ DrawFrame();
+
+ EXPECT_EQ(InputHandler::SCROLL_STARTED,
+ host_impl_->ScrollBegin(gfx::Point(), InputHandler::GESTURE));
+ EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
+ EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset).ToString(),
+ scroll_layer->CurrentScrollOffset().ToString());
+
+ // Scroll the top controls partially.
+ const float residue = 15;
+ float offset = top_controls_height_ - residue;
+ EXPECT_TRUE(
+ host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset)).did_scroll);
+ EXPECT_EQ(-offset, host_impl_->top_controls_manager()->ControlsTopOffset());
+ EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset).ToString(),
+ scroll_layer->CurrentScrollOffset().ToString());
+
+ did_request_redraw_ = false;
+ did_request_animate_ = false;
+ did_request_commit_ = false;
+
+ // End the fling while the controls are still offset from the limit.
+ host_impl_->MainThreadHasStoppedFlinging();
+ ASSERT_TRUE(host_impl_->top_controls_manager()->animation());
+ EXPECT_TRUE(did_request_animate_);
+ EXPECT_TRUE(did_request_redraw_);
+ EXPECT_FALSE(did_request_commit_);
+
+ // Animate the top controls to the limit.
+ base::TimeTicks animation_time = gfx::FrameTime::Now();
+ while (did_request_animate_) {
+ did_request_redraw_ = false;
+ did_request_animate_ = false;
+ did_request_commit_ = false;
+
+ float old_offset = host_impl_->top_controls_manager()->ControlsTopOffset();
+
+ animation_time += base::TimeDelta::FromMilliseconds(5);
+ host_impl_->Animate(animation_time);
+
+ float new_offset = host_impl_->top_controls_manager()->ControlsTopOffset();
+
+ if (new_offset != old_offset) {
+ EXPECT_TRUE(did_request_redraw_);
+ EXPECT_TRUE(did_request_commit_);
+ }
+ }
+ EXPECT_FALSE(host_impl_->top_controls_manager()->animation());
+ EXPECT_EQ(-top_controls_height_,
+ host_impl_->top_controls_manager()->ControlsTopOffset());
}
TEST_F(LayerTreeHostImplWithTopControlsTest,
diff --git a/cc/trees/layer_tree_host_unittest_animation.cc b/cc/trees/layer_tree_host_unittest_animation.cc
index b8d0320..c1da07e 100644
--- a/cc/trees/layer_tree_host_unittest_animation.cc
+++ b/cc/trees/layer_tree_host_unittest_animation.cc
@@ -195,8 +195,9 @@
void AnimateLayers(LayerTreeHostImpl* host_impl,
base::TimeTicks monotonic_time) override {
- bool have_animations = !host_impl->animation_registrar()->
- active_animation_controllers().empty();
+ bool have_animations = !host_impl->animation_registrar()
+ ->active_animation_controllers()
+ .empty();
if (!started_animating_ && have_animations) {
started_animating_ = true;
return;
@@ -1241,21 +1242,18 @@
// After both animations have started, verify that they have valid
// start times.
num_swap_buffers_++;
- AnimationRegistrar::AnimationControllerMap copy =
+ AnimationRegistrar::AnimationControllerMap controllers_copy =
host_impl->animation_registrar()->active_animation_controllers();
- if (copy.size() == 2u) {
+ if (controllers_copy.size() == 2u) {
EndTest();
EXPECT_GE(num_swap_buffers_, 3);
- for (AnimationRegistrar::AnimationControllerMap::iterator iter =
- copy.begin();
- iter != copy.end();
- ++iter) {
- int id = ((*iter).second->id());
+ for (auto& it : controllers_copy) {
+ int id = it.first;
if (id == host_impl->RootLayer()->id()) {
- Animation* anim = (*iter).second->GetAnimation(Animation::TRANSFORM);
+ Animation* anim = it.second->GetAnimation(Animation::TRANSFORM);
EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
} else if (id == host_impl->RootLayer()->children()[0]->id()) {
- Animation* anim = (*iter).second->GetAnimation(Animation::OPACITY);
+ Animation* anim = it.second->GetAnimation(Animation::OPACITY);
EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
}
}
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index e86e785..62e4cd3 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -984,7 +984,7 @@
layer_tree_host_impl_->SetNeedsRedraw();
}
-AnimationRegistrar* LayerTreeImpl::animationRegistrar() const {
+AnimationRegistrar* LayerTreeImpl::GetAnimationRegistrar() const {
return layer_tree_host_impl_->animation_registrar();
}
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h
index 5935d29..f7b6ee4 100644
--- a/cc/trees/layer_tree_impl.h
+++ b/cc/trees/layer_tree_impl.h
@@ -239,7 +239,7 @@
size_t NumLayers();
- AnimationRegistrar* animationRegistrar() const;
+ AnimationRegistrar* GetAnimationRegistrar() const;
void PushPersistedState(LayerTreeImpl* pending_tree);
diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h
index a0fbeaa..06c319a 100644
--- a/cc/trees/layer_tree_settings.h
+++ b/cc/trees/layer_tree_settings.h
@@ -9,9 +9,7 @@
#include "cc/base/cc_export.h"
#include "cc/debug/layer_tree_debug_state.h"
#include "cc/output/renderer_settings.h"
-#include "skia/ext/refptr.h"
#include "third_party/skia/include/core/SkColor.h"
-#include "third_party/skia/include/core/SkTypeface.h"
#include "ui/gfx/geometry/size.h"
namespace cc {
@@ -86,7 +84,6 @@
bool record_full_layer;
bool use_display_lists;
bool verify_property_trees;
- skia::RefPtr<SkTypeface> hud_typeface;
LayerTreeDebugState initial_debug_state;
};
diff --git a/cc/trees/property_tree.cc b/cc/trees/property_tree.cc
index 25d42aa..95e4366 100644
--- a/cc/trees/property_tree.cc
+++ b/cc/trees/property_tree.cc
@@ -33,6 +33,7 @@
template class PropertyTree<TransformNode>;
template class PropertyTree<ClipNode>;
+template class PropertyTree<OpacityNode>;
TransformNodeData::TransformNodeData()
: target_id(-1),
@@ -91,7 +92,6 @@
TransformNode* target_node = Node(node->data.target_id);
if (node->data.needs_local_transform_update)
UpdateLocalTransform(node);
- UpdateLocalTransform(node);
UpdateScreenSpaceTransform(node, parent_node, target_node);
UpdateSublayerScale(node);
UpdateTargetSpaceTransform(node, target_node);
diff --git a/cc/trees/property_tree.h b/cc/trees/property_tree.h
index ef47bce..404f498 100644
--- a/cc/trees/property_tree.h
+++ b/cc/trees/property_tree.h
@@ -100,6 +100,8 @@
typedef TreeNode<ClipNodeData> ClipNode;
+typedef TreeNode<float> OpacityNode;
+
template <typename T>
class CC_EXPORT PropertyTree {
public:
@@ -182,6 +184,8 @@
class CC_EXPORT ClipTree final : public PropertyTree<ClipNode> {};
+class CC_EXPORT OpacityTree final : public PropertyTree<OpacityNode> {};
+
} // namespace cc
#endif // CC_TREES_PROPERTY_TREE_H_
diff --git a/cc/trees/property_tree_builder.cc b/cc/trees/property_tree_builder.cc
index 7fe0494..0c080dd 100644
--- a/cc/trees/property_tree_builder.cc
+++ b/cc/trees/property_tree_builder.cc
@@ -21,10 +21,12 @@
struct DataForRecursion {
TransformTree* transform_tree;
ClipTree* clip_tree;
+ OpacityTree* opacity_tree;
Layer* transform_tree_parent;
Layer* transform_fixed_parent;
Layer* render_target;
int clip_tree_parent;
+ int opacity_tree_parent;
gfx::Vector2dF offset_to_transform_tree_parent;
gfx::Vector2dF offset_to_transform_fixed_parent;
const Layer* page_scale_layer;
@@ -120,8 +122,6 @@
layer->layer_animation_controller()->IsAnimatingProperty(
Animation::TRANSFORM);
- const bool has_transform_origin = layer->transform_origin() != gfx::Point3F();
-
const bool has_surface = !!layer->render_surface();
const bool flattening_change = layer->parent() &&
@@ -131,7 +131,7 @@
bool requires_node = is_root || is_scrollable || is_fixed ||
has_significant_transform || has_animated_transform ||
is_page_scale_application_layer || flattening_change ||
- has_transform_origin || has_surface;
+ has_surface;
Layer* transform_parent = GetTransformParent(data_from_ancestor, layer);
@@ -223,6 +223,32 @@
layer->set_offset_to_transform_parent(gfx::Vector2dF());
}
+void AddOpacityNodeIfNeeded(const DataForRecursion& data_from_ancestor,
+ Layer* layer,
+ DataForRecursion* data_for_children) {
+ const bool is_root = !layer->parent();
+ const bool has_transparency = layer->opacity() != 1.f;
+ const bool has_animated_opacity =
+ layer->layer_animation_controller()->IsAnimatingProperty(
+ Animation::OPACITY) ||
+ layer->OpacityCanAnimateOnImplThread();
+ bool requires_node = is_root || has_transparency || has_animated_opacity;
+
+ int parent_id = data_from_ancestor.opacity_tree_parent;
+
+ if (!requires_node) {
+ layer->set_opacity_tree_index(parent_id);
+ data_for_children->opacity_tree_parent = parent_id;
+ return;
+ }
+
+ OpacityNode node;
+ node.data = layer->opacity();
+ data_for_children->opacity_tree_parent =
+ data_for_children->opacity_tree->Insert(node, parent_id);
+ layer->set_opacity_tree_index(data_for_children->opacity_tree_parent);
+}
+
void BuildPropertyTreesInternal(Layer* layer,
const DataForRecursion& data_from_parent) {
DataForRecursion data_for_children(data_from_parent);
@@ -232,6 +258,9 @@
AddTransformNodeIfNeeded(data_from_parent, layer, &data_for_children);
AddClipNodeIfNeeded(data_from_parent, layer, &data_for_children);
+ if (data_from_parent.opacity_tree)
+ AddOpacityNodeIfNeeded(data_from_parent, layer, &data_for_children);
+
if (layer == data_from_parent.page_scale_layer)
data_for_children.in_subtree_of_page_scale_application_layer = true;
@@ -260,14 +289,17 @@
const gfx::Rect& viewport,
const gfx::Transform& device_transform,
TransformTree* transform_tree,
- ClipTree* clip_tree) {
+ ClipTree* clip_tree,
+ OpacityTree* opacity_tree) {
DataForRecursion data_for_recursion;
data_for_recursion.transform_tree = transform_tree;
data_for_recursion.clip_tree = clip_tree;
+ data_for_recursion.opacity_tree = opacity_tree;
data_for_recursion.transform_tree_parent = nullptr;
data_for_recursion.transform_fixed_parent = nullptr;
data_for_recursion.render_target = root_layer;
data_for_recursion.clip_tree_parent = 0;
+ data_for_recursion.opacity_tree_parent = -1;
data_for_recursion.page_scale_layer = page_scale_layer;
data_for_recursion.page_scale_factor = page_scale_factor;
data_for_recursion.device_scale_factor = device_scale_factor;
diff --git a/cc/trees/property_tree_builder.h b/cc/trees/property_tree_builder.h
index f949c9a..7f5f479 100644
--- a/cc/trees/property_tree_builder.h
+++ b/cc/trees/property_tree_builder.h
@@ -16,6 +16,8 @@
class PropertyTreeBuilder {
public:
+ // Building an opacity tree is optional, and can be skipped by passing
+ // in a null |opacity_tree|.
static void BuildPropertyTrees(Layer* root_layer,
const Layer* page_scale_layer,
float page_scale_factor,
@@ -23,7 +25,8 @@
const gfx::Rect& viewport,
const gfx::Transform& device_transform,
TransformTree* transform_tree,
- ClipTree* clip_tree);
+ ClipTree* clip_tree,
+ OpacityTree* opacity_tree);
};
} // namespace cc
diff --git a/cc/trees/single_thread_proxy.h b/cc/trees/single_thread_proxy.h
index f463db1..2612a4d 100644
--- a/cc/trees/single_thread_proxy.h
+++ b/cc/trees/single_thread_proxy.h
@@ -104,7 +104,7 @@
int priority_cutoff) override;
bool IsInsideDraw() override;
void RenewTreePriority() override {}
- void PostDelayedScrollbarFadeOnImplThread(const base::Closure& start_fade,
+ void PostDelayedAnimationTaskOnImplThread(const base::Closure& task,
base::TimeDelta delay) override {}
void DidActivateSyncTree() override;
void DidPrepareTiles() override;
diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc
index 1097805..4efb401 100644
--- a/cc/trees/thread_proxy.cc
+++ b/cc/trees/thread_proxy.cc
@@ -1362,10 +1362,10 @@
}
}
-void ThreadProxy::PostDelayedScrollbarFadeOnImplThread(
- const base::Closure& start_fade,
+void ThreadProxy::PostDelayedAnimationTaskOnImplThread(
+ const base::Closure& task,
base::TimeDelta delay) {
- Proxy::ImplThreadTaskRunner()->PostDelayedTask(FROM_HERE, start_fade, delay);
+ Proxy::ImplThreadTaskRunner()->PostDelayedTask(FROM_HERE, task, delay);
}
void ThreadProxy::DidActivateSyncTree() {
diff --git a/cc/trees/thread_proxy.h b/cc/trees/thread_proxy.h
index 8b4c302..c2dd348 100644
--- a/cc/trees/thread_proxy.h
+++ b/cc/trees/thread_proxy.h
@@ -205,7 +205,7 @@
int priority_cutoff) override;
bool IsInsideDraw() override;
void RenewTreePriority() override;
- void PostDelayedScrollbarFadeOnImplThread(const base::Closure& start_fade,
+ void PostDelayedAnimationTaskOnImplThread(const base::Closure& task,
base::TimeDelta delay) override;
void DidActivateSyncTree() override;
void DidPrepareTiles() override;