diff options
author | vmpstr <vmpstr@chromium.org> | 2015-11-24 11:43:15 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-11-24 19:44:45 +0000 |
commit | e1564a50ab8f218c6383ea6c7d2a60b1bbe61d0d (patch) | |
tree | b6adcb4bfff2f5f5aab07096100405df4bf8bf2d /cc | |
parent | e1c54ad21b1925deffe344d7079501669147a118 (diff) | |
download | chromium_src-e1564a50ab8f218c6383ea6c7d2a60b1bbe61d0d.zip chromium_src-e1564a50ab8f218c6383ea6c7d2a60b1bbe61d0d.tar.gz chromium_src-e1564a50ab8f218c6383ea6c7d2a60b1bbe61d0d.tar.bz2 |
cc: Skip animation-checkerboard frames even when animation is done
This patch ensures that we continue to skip checkerboard frames that
were checkerboarding since the last animation. This means that even if
animation is over, we will continue to drop frames since those checker-
boards were the result of the animation.
BUG=554924
R=danakj@chromium.org, ajuma@chromium.org
CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel
Review URL: https://codereview.chromium.org/1461243003
Cr-Commit-Position: refs/heads/master@{#361413}
Diffstat (limited to 'cc')
-rw-r--r-- | cc/layers/layer_impl.cc | 3 | ||||
-rw-r--r-- | cc/layers/layer_impl.h | 12 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl.cc | 10 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl_unittest.cc | 101 |
4 files changed, 121 insertions, 5 deletions
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index 93e6b55..024ba5a 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc @@ -70,6 +70,7 @@ LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, transform_is_invertible_(true), is_container_for_fixed_position_layers_(false), is_affected_by_page_scale_(true), + was_ever_ready_since_last_transform_animation_(true), background_color_(0), opacity_(1.0), blend_mode_(SkXfermode::kSrcOver_Mode), @@ -933,6 +934,7 @@ void LayerImpl::OnOpacityAnimated(float opacity) { void LayerImpl::OnTransformAnimated(const gfx::Transform& transform) { SetTransform(transform); UpdatePropertyTreeTransform(); + was_ever_ready_since_last_transform_animation_ = false; } void LayerImpl::OnScrollOffsetAnimated(const gfx::ScrollOffset& scroll_offset) { @@ -951,6 +953,7 @@ void LayerImpl::OnAnimationWaitingForDeletion() {} void LayerImpl::OnTransformIsPotentiallyAnimatingChanged(bool is_animating) { UpdatePropertyTreeTransformIsAnimated(is_animating); + was_ever_ready_since_last_transform_animation_ = false; } bool LayerImpl::IsActive() const { diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h index d5669ca..bae7421 100644 --- a/cc/layers/layer_impl.h +++ b/cc/layers/layer_impl.h @@ -679,6 +679,14 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver, float GetIdealContentsScale() const; + bool was_ever_ready_since_last_transform_animation() const { + return was_ever_ready_since_last_transform_animation_; + } + + void set_was_ever_ready_since_last_transform_animation(bool was_ready) { + was_ever_ready_since_last_transform_animation_ = was_ready; + } + protected: LayerImpl(LayerTreeImpl* layer_impl, int id, @@ -784,6 +792,10 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver, bool is_affected_by_page_scale_ : 1; + // This is true if and only if the layer was ever ready since it last animated + // (all content was complete). + bool was_ever_ready_since_last_transform_animation_ : 1; + Region non_fast_scrollable_region_; Region touch_event_handler_region_; SkColor background_color_; diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 8643dbc..042365b 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc @@ -954,12 +954,12 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses( append_quads_data.checkerboarded_no_recording_content_area; checkerboarded_needs_raster_content_area += append_quads_data.checkerboarded_needs_raster_content_area; - - if (append_quads_data.num_missing_tiles) { - bool layer_has_animating_transform = + if (append_quads_data.num_missing_tiles > 0) { + have_missing_animated_tiles |= + !it->was_ever_ready_since_last_transform_animation() || it->screen_space_transform_is_animating(); - if (layer_has_animating_transform) - have_missing_animated_tiles = true; + } else { + it->set_was_ever_ready_since_last_transform_animation(true); } } diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 74e184c..e7697931 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc @@ -1182,6 +1182,107 @@ TEST_F(LayerTreeHostImplTest, AnimationSchedulingActiveTree) { EXPECT_FALSE(did_request_commit_); } +class MissingTilesLayer : public LayerImpl { + public: + MissingTilesLayer(LayerTreeImpl* layer_tree_impl, int id) + : LayerImpl(layer_tree_impl, id), has_missing_tiles_(true) {} + + void set_has_missing_tiles(bool has_missing_tiles) { + has_missing_tiles_ = has_missing_tiles; + } + + void AppendQuads(RenderPass* render_pass, + AppendQuadsData* append_quads_data) override { + append_quads_data->num_missing_tiles += has_missing_tiles_; + } + + private: + bool has_missing_tiles_; +}; + +TEST_F(LayerTreeHostImplTest, AnimationSchedulingMarksLayerNotReady) { + host_impl_->SetViewportSize(gfx::Size(50, 50)); + + host_impl_->active_tree()->SetRootLayer( + LayerImpl::Create(host_impl_->active_tree(), 1)); + LayerImpl* root = host_impl_->active_tree()->root_layer(); + root->SetBounds(gfx::Size(50, 50)); + root->SetHasRenderSurface(true); + + root->AddChild(scoped_ptr<MissingTilesLayer>( + new MissingTilesLayer(host_impl_->active_tree(), 2))); + MissingTilesLayer* child = + static_cast<MissingTilesLayer*>(root->children()[0].get()); + child->SetBounds(gfx::Size(10, 10)); + child->draw_properties().visible_layer_rect = gfx::Rect(10, 10); + child->SetDrawsContent(true); + + EXPECT_TRUE(child->was_ever_ready_since_last_transform_animation()); + + // Add a translate from 6,7 to 8,9. + TransformOperations start; + start.AppendTranslate(6.f, 7.f, 0.f); + TransformOperations end; + end.AppendTranslate(8.f, 9.f, 0.f); + int animation_id = AddAnimatedTransformToLayer(child, 4.0, start, end); + + base::TimeTicks now = base::TimeTicks::Now(); + host_impl_->WillBeginImplFrame( + CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now)); + + host_impl_->ActivateAnimations(); + host_impl_->Animate(); + + EXPECT_FALSE(child->was_ever_ready_since_last_transform_animation()); + + host_impl_->active_tree()->property_trees()->needs_rebuild = true; + host_impl_->active_tree()->BuildPropertyTreesForTesting(); + host_impl_->ResetRequiresHighResToDraw(); + + // Child layer has an animating transform but missing tiles. + FakeLayerTreeHostImpl::FrameData frame; + DrawResult result = host_impl_->PrepareToDraw(&frame); + EXPECT_EQ(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS, result); + host_impl_->DidDrawAllLayers(frame); + + child->set_has_missing_tiles(false); + + // Child layer has an animating and no missing tiles. + result = host_impl_->PrepareToDraw(&frame); + EXPECT_EQ(DRAW_SUCCESS, result); + EXPECT_TRUE(child->was_ever_ready_since_last_transform_animation()); + host_impl_->DidDrawAllLayers(frame); + + // Remove the animation. + child->set_has_missing_tiles(true); + child->layer_animation_controller()->RemoveAnimation(animation_id); + child->draw_properties().screen_space_transform_is_animating = false; + + // Child layer doesn't have an animation, but was never ready since the last + // time it animated (and has missing tiles). + result = host_impl_->PrepareToDraw(&frame); + EXPECT_EQ(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS, result); + EXPECT_FALSE(child->was_ever_ready_since_last_transform_animation()); + host_impl_->DidDrawAllLayers(frame); + + child->set_has_missing_tiles(false); + + // Child layer doesn't have an animation and all tiles are ready. + result = host_impl_->PrepareToDraw(&frame); + EXPECT_EQ(DRAW_SUCCESS, result); + EXPECT_TRUE(child->was_ever_ready_since_last_transform_animation()); + host_impl_->DidDrawAllLayers(frame); + + child->set_has_missing_tiles(true); + + // Child layer doesn't have an animation, and was ready at least once since + // the last time it animated. + result = host_impl_->PrepareToDraw(&frame); + EXPECT_EQ(DRAW_SUCCESS, result); + EXPECT_TRUE(child->was_ever_ready_since_last_transform_animation()); + host_impl_->DidDrawAllLayers(frame); +} + TEST_F(LayerTreeHostImplTest, ImplPinchZoom) { LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); host_impl_->SetViewportSize(gfx::Size(50, 50)); |