diff options
author | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2015-10-27 09:07:56 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2015-10-27 08:12:41 +0000 |
commit | 98ff39cb35ef2bd32bb1af9565628a4a4b0979b2 (patch) | |
tree | 151fe6c7d22b64f237f2f452cc72b581274a02d6 /chromium/cc | |
parent | af3d4809763ef308f08ced947a73b624729ac7ea (diff) | |
download | qtwebengine-chromium-98ff39cb35ef2bd32bb1af9565628a4a4b0979b2.tar.gz |
BASELINE: Update Chromium to 47.0.2526.34 and Ninja to 1.6.0
Change-Id: Ie8863b493c7ff19eb46478935dfe7602679b227e
Reviewed-by: Michael BrĂ¼ning <michael.bruning@theqtcompany.com>
Diffstat (limited to 'chromium/cc')
20 files changed, 253 insertions, 54 deletions
diff --git a/chromium/cc/debug/rendering_stats.cc b/chromium/cc/debug/rendering_stats.cc index 582c76341e2..a3d7a43be2c 100644 --- a/chromium/cc/debug/rendering_stats.cc +++ b/chromium/cc/debug/rendering_stats.cc @@ -38,8 +38,9 @@ RenderingStats::RenderingStats() : frame_count(0), visible_content_area(0), approximated_visible_content_area(0), - checkerboarded_visible_content_area(0) { -} + checkerboarded_visible_content_area(0), + checkerboarded_no_recording_content_area(0), + checkerboarded_needs_raster_content_area(0) {} RenderingStats::~RenderingStats() { } @@ -54,6 +55,10 @@ RenderingStats::AsTraceableData() const { approximated_visible_content_area); record_data->SetInteger("checkerboarded_visible_content_area", checkerboarded_visible_content_area); + record_data->SetInteger("checkerboarded_no_recording_content_area", + checkerboarded_no_recording_content_area); + record_data->SetInteger("checkerboarded_needs_raster_content_area", + checkerboarded_needs_raster_content_area); draw_duration.AddToTracedValue("draw_duration_ms", record_data.get()); draw_duration_estimate.AddToTracedValue("draw_duration_estimate_ms", @@ -79,6 +84,10 @@ void RenderingStats::Add(const RenderingStats& other) { approximated_visible_content_area += other.approximated_visible_content_area; checkerboarded_visible_content_area += other.checkerboarded_visible_content_area; + checkerboarded_no_recording_content_area += + other.checkerboarded_no_recording_content_area; + checkerboarded_needs_raster_content_area += + other.checkerboarded_needs_raster_content_area; draw_duration.Add(other.draw_duration); draw_duration_estimate.Add(other.draw_duration_estimate); diff --git a/chromium/cc/debug/rendering_stats.h b/chromium/cc/debug/rendering_stats.h index cb7ebb2cbab..fbe0d638199 100644 --- a/chromium/cc/debug/rendering_stats.h +++ b/chromium/cc/debug/rendering_stats.h @@ -45,6 +45,8 @@ struct CC_EXPORT RenderingStats { int64 visible_content_area; int64 approximated_visible_content_area; int64 checkerboarded_visible_content_area; + int64 checkerboarded_no_recording_content_area; + int64 checkerboarded_needs_raster_content_area; TimeDeltaList draw_duration; TimeDeltaList draw_duration_estimate; diff --git a/chromium/cc/debug/rendering_stats_instrumentation.cc b/chromium/cc/debug/rendering_stats_instrumentation.cc index 315743b8ffc..e793c5022b9 100644 --- a/chromium/cc/debug/rendering_stats_instrumentation.cc +++ b/chromium/cc/debug/rendering_stats_instrumentation.cc @@ -90,6 +90,24 @@ void RenderingStatsInstrumentation::AddCheckerboardedVisibleContentArea( impl_thread_rendering_stats_.checkerboarded_visible_content_area += area; } +void RenderingStatsInstrumentation::AddCheckerboardedNoRecordingContentArea( + int64 area) { + if (!record_rendering_stats_) + return; + + base::AutoLock scoped_lock(lock_); + impl_thread_rendering_stats_.checkerboarded_no_recording_content_area += area; +} + +void RenderingStatsInstrumentation::AddCheckerboardedNeedsRasterContentArea( + int64 area) { + if (!record_rendering_stats_) + return; + + base::AutoLock scoped_lock(lock_); + impl_thread_rendering_stats_.checkerboarded_needs_raster_content_area += area; +} + void RenderingStatsInstrumentation::AddDrawDuration( base::TimeDelta draw_duration, base::TimeDelta draw_duration_estimate) { diff --git a/chromium/cc/debug/rendering_stats_instrumentation.h b/chromium/cc/debug/rendering_stats_instrumentation.h index 47796887788..92351e60b39 100644 --- a/chromium/cc/debug/rendering_stats_instrumentation.h +++ b/chromium/cc/debug/rendering_stats_instrumentation.h @@ -44,6 +44,8 @@ class CC_EXPORT RenderingStatsInstrumentation { void AddVisibleContentArea(int64 area); void AddApproximatedVisibleContentArea(int64 area); void AddCheckerboardedVisibleContentArea(int64 area); + void AddCheckerboardedNoRecordingContentArea(int64 area); + void AddCheckerboardedNeedsRasterContentArea(int64 area); void AddDrawDuration(base::TimeDelta draw_duration, base::TimeDelta draw_duration_estimate); void AddBeginMainFrameToCommitDuration( diff --git a/chromium/cc/input/input_handler.h b/chromium/cc/input/input_handler.h index 4696fb5ceca..7b09cc16952 100644 --- a/chromium/cc/input/input_handler.h +++ b/chromium/cc/input/input_handler.h @@ -84,7 +84,7 @@ class CC_EXPORT InputHandler { // This must be the last entry. ScrollStatusCount }; - enum ScrollInputType { GESTURE, WHEEL, NON_BUBBLING_GESTURE }; + enum ScrollInputType { GESTURE, WHEEL, ANIMATED_WHEEL, NON_BUBBLING_GESTURE }; // Binds a client to this handler to receive notifications. Only one client // can be bound to an InputHandler. The client must live at least until the @@ -151,9 +151,8 @@ class CC_EXPORT InputHandler { // Request another callback to InputHandlerClient::Animate(). virtual void SetNeedsAnimateInput() = 0; - // If there is a scroll active, this reports whether the scroll is on the - // root layer, or on some other sublayer. - virtual bool IsCurrentlyScrollingRoot() const = 0; + // Returns true if there is an active scroll on the inner viewport layer. + virtual bool IsCurrentlyScrollingInnerViewport() const = 0; // Whether the layer under |viewport_point| is the currently scrolling layer. virtual bool IsCurrentlyScrollingLayerAt(const gfx::Point& viewport_point, diff --git a/chromium/cc/layers/append_quads_data.h b/chromium/cc/layers/append_quads_data.h index 45b0c17b20f..3d05109c176 100644 --- a/chromium/cc/layers/append_quads_data.h +++ b/chromium/cc/layers/append_quads_data.h @@ -16,7 +16,9 @@ struct AppendQuadsData { num_missing_tiles(0), visible_layer_area(0), approximated_visible_content_area(0), - checkerboarded_visible_content_area(0) {} + checkerboarded_visible_content_area(0), + checkerboarded_no_recording_content_area(0), + checkerboarded_needs_raster_content_area(0) {} // Set by the layer appending quads. int64 num_incomplete_tiles; @@ -26,8 +28,12 @@ struct AppendQuadsData { int64 visible_layer_area; // Set by the layer appending quads. int64 approximated_visible_content_area; - // Set by the layer appending quads. + // Set by the layer appending quads. This is total of the following two areas. int64 checkerboarded_visible_content_area; + // Set by the layer appending quads. This is the area outside interest rect. + int64 checkerboarded_no_recording_content_area; + // Set by the layer appending quads. This is the area within interest rect. + int64 checkerboarded_needs_raster_content_area; }; } // namespace cc diff --git a/chromium/cc/layers/layer.cc b/chromium/cc/layers/layer.cc index 4b9162ff5ce..9db52869c0e 100644 --- a/chromium/cc/layers/layer.cc +++ b/chromium/cc/layers/layer.cc @@ -1436,7 +1436,12 @@ void Layer::OnFilterAnimated(const FilterOperations& filters) { } void Layer::OnOpacityAnimated(float opacity) { + if (opacity_ == opacity) + return; opacity_ = opacity; + // Changing the opacity may make a previously hidden layer visible, so a new + // recording may be needed. + SetNeedsUpdate(); if (layer_tree_host_) { if (EffectNode* node = layer_tree_host_->property_trees()->effect_tree.Node( effect_tree_index())) { @@ -1453,6 +1458,9 @@ void Layer::OnTransformAnimated(const gfx::Transform& transform) { return; transform_ = transform; transform_is_invertible_ = transform.IsInvertible(); + // Changing the transform may change the visible part of this layer, so a new + // recording may be needed. + SetNeedsUpdate(); if (layer_tree_host_) { if (TransformNode* node = layer_tree_host_->property_trees()->transform_tree.Node( diff --git a/chromium/cc/layers/layer.h b/chromium/cc/layers/layer.h index 800deff5ce2..2fec3636457 100644 --- a/chromium/cc/layers/layer.h +++ b/chromium/cc/layers/layer.h @@ -503,6 +503,18 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>, void set_sorted_for_recursion(bool sorted_for_recursion); bool sorted_for_recursion(); + // LayerAnimationValueProvider implementation. + gfx::ScrollOffset ScrollOffsetForAnimation() const override; + + // LayerAnimationValueObserver implementation. + void OnFilterAnimated(const FilterOperations& filters) override; + void OnOpacityAnimated(float opacity) override; + void OnTransformAnimated(const gfx::Transform& transform) override; + void OnScrollOffsetAnimated(const gfx::ScrollOffset& scroll_offset) override; + void OnAnimationWaitingForDeletion() override; + void OnTransformIsPotentiallyAnimatingChanged(bool is_animating) override; + bool IsActive() const override; + protected: friend class LayerImpl; friend class TreeSynchronizer; @@ -594,18 +606,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>, // This should only be called from RemoveFromParent(). void RemoveChildOrDependent(Layer* child); - // LayerAnimationValueProvider implementation. - gfx::ScrollOffset ScrollOffsetForAnimation() const override; - - // LayerAnimationValueObserver implementation. - void OnFilterAnimated(const FilterOperations& filters) override; - void OnOpacityAnimated(float opacity) override; - void OnTransformAnimated(const gfx::Transform& transform) override; - void OnScrollOffsetAnimated(const gfx::ScrollOffset& scroll_offset) override; - void OnAnimationWaitingForDeletion() override; - void OnTransformIsPotentiallyAnimatingChanged(bool is_animating) override; - bool IsActive() const override; - // If this layer has a scroll parent, it removes |this| from its list of // scroll children. void RemoveFromScrollTree(); diff --git a/chromium/cc/layers/layer_impl.cc b/chromium/cc/layers/layer_impl.cc index afacef86551..4feff4e3d68 100644 --- a/chromium/cc/layers/layer_impl.cc +++ b/chromium/cc/layers/layer_impl.cc @@ -513,7 +513,8 @@ InputHandler::ScrollStatus LayerImpl::TryScroll( return InputHandler::SCROLL_ON_MAIN_THREAD; } - if (type == InputHandler::WHEEL && have_wheel_event_handlers() && + if ((type == InputHandler::WHEEL || type == InputHandler::ANIMATED_WHEEL) && + have_wheel_event_handlers() && effective_block_mode & SCROLL_BLOCKS_ON_WHEEL_EVENT) { TRACE_EVENT0("cc", "LayerImpl::tryScroll: Failed WheelEventHandlers"); return InputHandler::SCROLL_ON_MAIN_THREAD; diff --git a/chromium/cc/layers/layer_unittest.cc b/chromium/cc/layers/layer_unittest.cc index 10b1d147eaf..6f81e8e8483 100644 --- a/chromium/cc/layers/layer_unittest.cc +++ b/chromium/cc/layers/layer_unittest.cc @@ -867,7 +867,7 @@ TEST_F(LayerTest, MaskAndReplicaHasParent) { EXPECT_EQ(replica.get(), replica->mask_layer()->parent()); } -TEST_F(LayerTest, CheckTranformIsInvertible) { +TEST_F(LayerTest, CheckTransformIsInvertible) { scoped_refptr<Layer> layer = Layer::Create(layer_settings_); scoped_ptr<LayerImpl> impl_layer = LayerImpl::Create(host_impl_.active_tree(), 1); @@ -898,7 +898,7 @@ TEST_F(LayerTest, CheckTranformIsInvertible) { Mock::VerifyAndClearExpectations(layer_tree_host_.get()); } -TEST_F(LayerTest, TranformIsInvertibleAnimation) { +TEST_F(LayerTest, TransformIsInvertibleAnimation) { scoped_refptr<Layer> layer = Layer::Create(layer_settings_); scoped_ptr<LayerImpl> impl_layer = LayerImpl::Create(host_impl_.active_tree(), 1); @@ -920,9 +920,9 @@ TEST_F(LayerTest, TranformIsInvertibleAnimation) { gfx::Transform identity_transform; + EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(1); layer->SetTransform(identity_transform); - static_cast<LayerAnimationValueObserver*>(layer.get()) - ->OnTransformAnimated(singular_transform); + layer->OnTransformAnimated(singular_transform); layer->PushPropertiesTo(impl_layer.get()); EXPECT_FALSE(layer->transform_is_invertible()); EXPECT_FALSE(impl_layer->transform_is_invertible()); @@ -1326,5 +1326,26 @@ TEST_F(LayerTest, DedupesCopyOutputRequestsBySource) { EXPECT_EQ(1, did_receive_second_result_from_this_source); } +TEST_F(LayerTest, AnimationSchedulesLayerUpdate) { + scoped_refptr<Layer> layer = Layer::Create(layer_settings_); + EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(layer)); + + EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(1); + layer->OnOpacityAnimated(0.5f); + Mock::VerifyAndClearExpectations(layer_tree_host_.get()); + + EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(1); + gfx::Transform transform; + transform.Rotate(45.0); + layer->OnTransformAnimated(transform); + Mock::VerifyAndClearExpectations(layer_tree_host_.get()); + + // Scroll offset animation should not schedule a layer update since it is + // handled similarly to normal compositor scroll updates. + EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(0); + layer->OnScrollOffsetAnimated(gfx::ScrollOffset(10, 10)); + Mock::VerifyAndClearExpectations(layer_tree_host_.get()); +} + } // namespace } // namespace cc diff --git a/chromium/cc/layers/painted_scrollbar_layer.cc b/chromium/cc/layers/painted_scrollbar_layer.cc index 67f83c650cf..6fd58623fbf 100644 --- a/chromium/cc/layers/painted_scrollbar_layer.cc +++ b/chromium/cc/layers/painted_scrollbar_layer.cc @@ -97,7 +97,7 @@ float PaintedScrollbarLayer::ClampScaleToMaxTextureSize(float scale) { gfx::Size scaled_bounds = gfx::ScaleToCeiledSize(bounds(), scale); if (scaled_bounds.width() > MaxTextureSize() || scaled_bounds.height() > MaxTextureSize()) { - if (scaled_bounds.width() > scaled_bounds.height()) + if (bounds().width() > bounds().height()) return (MaxTextureSize() - 1) / static_cast<float>(bounds().width()); else return (MaxTextureSize() - 1) / static_cast<float>(bounds().height()); diff --git a/chromium/cc/layers/picture_layer_impl.cc b/chromium/cc/layers/picture_layer_impl.cc index a550968e69f..f8aa213a925 100644 --- a/chromium/cc/layers/picture_layer_impl.cc +++ b/chromium/cc/layers/picture_layer_impl.cc @@ -270,6 +270,8 @@ void PictureLayerImpl::AppendQuads(RenderPass* render_pass, size_t missing_tile_count = 0u; size_t on_demand_missing_tile_count = 0u; only_used_low_res_last_append_quads_ = true; + gfx::Rect scaled_recorded_viewport = gfx::ScaleToEnclosingRect( + raster_source_->RecordedViewport(), max_contents_scale); for (PictureLayerTilingSet::CoverageIterator iter( tilings_.get(), max_contents_scale, shared_quad_state->visible_quad_layer_rect, ideal_contents_scale_); @@ -346,8 +348,23 @@ void PictureLayerImpl::AppendQuads(RenderPass* render_pass, append_quads_data->num_missing_tiles++; ++missing_tile_count; } - append_quads_data->checkerboarded_visible_content_area += + int64 checkerboarded_area = visible_geometry_rect.width() * visible_geometry_rect.height(); + append_quads_data->checkerboarded_visible_content_area += + checkerboarded_area; + // Intersect checkerboard rect with interest rect to generate rect where + // we checkerboarded and has recording. The area where we don't have + // recording is not necessarily a Rect, and its area is calculated using + // subtraction. + gfx::Rect visible_rect_has_recording = visible_geometry_rect; + visible_rect_has_recording.Intersect(scaled_recorded_viewport); + int64 checkerboarded_has_recording_area = + visible_rect_has_recording.width() * + visible_rect_has_recording.height(); + append_quads_data->checkerboarded_needs_raster_content_area += + checkerboarded_has_recording_area; + append_quads_data->checkerboarded_no_recording_content_area += + checkerboarded_area - checkerboarded_has_recording_area; continue; } diff --git a/chromium/cc/layers/picture_layer_impl_unittest.cc b/chromium/cc/layers/picture_layer_impl_unittest.cc index 78f56fd90f5..93c1f1f823f 100644 --- a/chromium/cc/layers/picture_layer_impl_unittest.cc +++ b/chromium/cc/layers/picture_layer_impl_unittest.cc @@ -2067,6 +2067,34 @@ TEST_F(PictureLayerImplTest, EXPECT_FALSE(active_layer_->only_used_low_res_last_append_quads()); } +TEST_F(PictureLayerImplTest, AppendQuadsDataForCheckerboard) { + host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + + gfx::Size tile_size(100, 100); + gfx::Size layer_bounds(200, 200); + gfx::Rect recorded_viewport(0, 0, 150, 150); + + scoped_refptr<FakeDisplayListRasterSource> pending_raster_source = + FakeDisplayListRasterSource::CreatePartiallyFilled(layer_bounds, + recorded_viewport); + SetupPendingTreeWithFixedTileSize(pending_raster_source, tile_size, Region()); + ActivateTree(); + + scoped_ptr<RenderPass> render_pass = RenderPass::Create(); + AppendQuadsData data; + active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr); + active_layer_->AppendQuads(render_pass.get(), &data); + active_layer_->DidDraw(nullptr); + + EXPECT_EQ(1u, render_pass->quad_list.size()); + EXPECT_EQ(1u, data.num_missing_tiles); + EXPECT_EQ(0u, data.num_incomplete_tiles); + EXPECT_EQ(40000, data.checkerboarded_visible_content_area); + EXPECT_EQ(17500, data.checkerboarded_no_recording_content_area); + EXPECT_EQ(22500, data.checkerboarded_needs_raster_content_area); + EXPECT_TRUE(active_layer_->only_used_low_res_last_append_quads()); +} + TEST_F(PictureLayerImplTest, HighResRequiredWhenActiveAllReady) { gfx::Size layer_bounds(400, 400); gfx::Size tile_size(100, 100); diff --git a/chromium/cc/layers/scrollbar_layer_unittest.cc b/chromium/cc/layers/scrollbar_layer_unittest.cc index f631fcea0f7..a0d20a58ba4 100644 --- a/chromium/cc/layers/scrollbar_layer_unittest.cc +++ b/chromium/cc/layers/scrollbar_layer_unittest.cc @@ -939,6 +939,14 @@ class ScaledScrollbarLayerTestResourceCreation : public ScrollbarLayerTest { scrollbar_layer->internal_content_bounds().width()); EXPECT_LE(thumb_size.height(), scrollbar_layer->internal_content_bounds().height()); + EXPECT_LE(track_size.width(), + layer_tree_host_->GetRendererCapabilities().max_texture_size); + EXPECT_LE(track_size.height(), + layer_tree_host_->GetRendererCapabilities().max_texture_size); + EXPECT_LE(thumb_size.width(), + layer_tree_host_->GetRendererCapabilities().max_texture_size); + EXPECT_LE(thumb_size.height(), + layer_tree_host_->GetRendererCapabilities().max_texture_size); testing::Mock::VerifyAndClearExpectations(layer_tree_host_.get()); } @@ -950,6 +958,9 @@ TEST_F(ScaledScrollbarLayerTestResourceCreation, ScaledResourceUpload) { TestResourceUpload(.041f); TestResourceUpload(1.41f); TestResourceUpload(4.1f); + + // Try something extreme to make sure it gets clamped. + TestResourceUpload(2147483647.0f); } class ScaledScrollbarLayerTestScaledRasterization : public ScrollbarLayerTest { diff --git a/chromium/cc/layers/viewport.cc b/chromium/cc/layers/viewport.cc index 80e711fd027..4b68de5376e 100644 --- a/chromium/cc/layers/viewport.cc +++ b/chromium/cc/layers/viewport.cc @@ -50,17 +50,11 @@ Viewport::ScrollResult Viewport::ScrollBy(const gfx::Vector2dF& delta, ScrollResult result; - // TODO(bokan): This shouldn't be needed but removing it causes subtle - // viewport movement during top controls manipulation. - if (gfx::ToRoundedVector2d(pending_content_delta).IsZero()) { - result.consumed_delta = delta; - } else { - pending_content_delta -= host_impl_->ScrollLayer(OuterScrollLayer(), - pending_content_delta, - viewport_point, - is_direct_manipulation); - result.consumed_delta = delta - AdjustOverscroll(pending_content_delta); - } + pending_content_delta -= host_impl_->ScrollLayer(OuterScrollLayer(), + pending_content_delta, + viewport_point, + is_direct_manipulation); + result.consumed_delta = delta - AdjustOverscroll(pending_content_delta); result.content_scrolled_delta = content_delta - pending_content_delta; return result; diff --git a/chromium/cc/output/copy_output_request.cc b/chromium/cc/output/copy_output_request.cc index d70bac1bfca..fce92a32216 100644 --- a/chromium/cc/output/copy_output_request.cc +++ b/chromium/cc/output/copy_output_request.cc @@ -27,7 +27,11 @@ scoped_ptr<CopyOutputRequest> CopyOutputRequest::CreateRelayRequest( return relay.Pass(); } -CopyOutputRequest::CopyOutputRequest() {} +CopyOutputRequest::CopyOutputRequest() + : source_(nullptr), + force_bitmap_result_(false), + has_area_(false), + has_texture_mailbox_(false) {} CopyOutputRequest::CopyOutputRequest( bool force_bitmap_result, diff --git a/chromium/cc/trees/layer_tree_host_impl.cc b/chromium/cc/trees/layer_tree_host_impl.cc index ab75b9c0c11..4b77084b9b0 100644 --- a/chromium/cc/trees/layer_tree_host_impl.cc +++ b/chromium/cc/trees/layer_tree_host_impl.cc @@ -419,8 +419,8 @@ void LayerTreeHostImpl::Animate() { if (input_handler_client_) { // This animates fling scrolls. But on Android WebView root flings are // controlled by the application, so the compositor does not animate them. - bool ignore_fling = - settings_.ignore_root_layer_flings && IsCurrentlyScrollingRoot(); + bool ignore_fling = settings_.ignore_root_layer_flings && + IsCurrentlyScrollingInnerViewport(); if (!ignore_fling) input_handler_client_->Animate(monotonic_time); } @@ -488,12 +488,12 @@ void LayerTreeHostImpl::StartPageScaleAnimation( } void LayerTreeHostImpl::SetNeedsAnimateInput() { - DCHECK_IMPLIES(IsCurrentlyScrollingRoot(), + DCHECK_IMPLIES(IsCurrentlyScrollingInnerViewport(), !settings_.ignore_root_layer_flings); SetNeedsAnimate(); } -bool LayerTreeHostImpl::IsCurrentlyScrollingRoot() const { +bool LayerTreeHostImpl::IsCurrentlyScrollingInnerViewport() const { LayerImpl* scrolling_layer = CurrentlyScrollingLayer(); if (!scrolling_layer) return false; @@ -847,6 +847,8 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses( int num_missing_tiles = 0; int num_incomplete_tiles = 0; + int64 checkerboarded_no_recording_content_area = 0; + int64 checkerboarded_needs_raster_content_area = 0; bool have_copy_request = false; bool have_missing_animated_tiles = false; @@ -923,9 +925,17 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses( append_quads_data.approximated_visible_content_area); rendering_stats_instrumentation_->AddCheckerboardedVisibleContentArea( append_quads_data.checkerboarded_visible_content_area); + rendering_stats_instrumentation_->AddCheckerboardedNoRecordingContentArea( + append_quads_data.checkerboarded_no_recording_content_area); + rendering_stats_instrumentation_->AddCheckerboardedNeedsRasterContentArea( + append_quads_data.checkerboarded_needs_raster_content_area); num_missing_tiles += append_quads_data.num_missing_tiles; num_incomplete_tiles += append_quads_data.num_incomplete_tiles; + checkerboarded_no_recording_content_area += + 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 = @@ -995,6 +1005,14 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses( UMA_HISTOGRAM_COUNTS_100( "Compositing.RenderPass.AppendQuadData.NumIncompleteTiles", num_incomplete_tiles); + UMA_HISTOGRAM_COUNTS( + "Compositing.RenderPass.AppendQuadData." + "CheckerboardedNoRecordingContentArea", + checkerboarded_no_recording_content_area); + UMA_HISTOGRAM_COUNTS( + "Compositing.RenderPass.AppendQuadData." + "CheckerboardedNeedRasterContentArea", + checkerboarded_needs_raster_content_area); } // Should only have one render pass in resourceless software mode. @@ -1849,7 +1867,7 @@ bool LayerTreeHostImpl::IsActivelyScrolling() const { // On Android WebView root flings are controlled by the application, // so the compositor does not animate them and can't tell if they // are actually animating. So assume there are none. - if (settings_.ignore_root_layer_flings && IsCurrentlyScrollingRoot()) + if (settings_.ignore_root_layer_flings && IsCurrentlyScrollingInnerViewport()) return false; return did_lock_scrolling_layer_; } @@ -2379,6 +2397,14 @@ LayerImpl* LayerTreeHostImpl::FindScrollLayerForDeviceViewportPoint( if (potentially_scrolling_layer_impl == OuterViewportScrollLayer()) potentially_scrolling_layer_impl = InnerViewportScrollLayer(); + // Animated wheel scrolls need to scroll the outer viewport layer, and do not + // go through Viewport::ScrollBy which would normally handle the distribution. + // NOTE: This will need refactoring if we want smooth scrolling on Android. + if (type == ANIMATED_WHEEL && + potentially_scrolling_layer_impl == InnerViewportScrollLayer()) { + potentially_scrolling_layer_impl = OuterViewportScrollLayer(); + } + return potentially_scrolling_layer_impl; } @@ -2402,7 +2428,7 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl( top_controls_manager_->ScrollBegin(); active_tree_->SetCurrentlyScrollingLayer(scrolling_layer_impl); - wheel_scrolling_ = (type == WHEEL); + wheel_scrolling_ = (type == WHEEL || type == ANIMATED_WHEEL); client_->RenewTreePriority(); UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", false); return SCROLL_STARTED; @@ -2460,16 +2486,17 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated( ? SCROLL_STARTED : SCROLL_IGNORED; } - // ScrollAnimated is only used for wheel scrolls. We use the same bubbling - // behavior as ScrollBy to determine which layer to animate, but we do not - // do the Android-specific things in ScrollBy like showing top controls. - InputHandler::ScrollStatus scroll_status = ScrollBegin(viewport_point, WHEEL); + // ScrollAnimated is used for animated wheel scrolls. We find the first layer + // that can scroll and set up an animation of its scroll offset. Note that + // this does not currently go through the scroll customization and viewport + // machinery that ScrollBy uses for non-animated wheel scrolls. + InputHandler::ScrollStatus scroll_status = + ScrollBegin(viewport_point, ANIMATED_WHEEL); if (scroll_status == SCROLL_STARTED) { gfx::Vector2dF pending_delta = scroll_delta; for (LayerImpl* layer_impl = CurrentlyScrollingLayer(); layer_impl; layer_impl = NextLayerInScrollOrder(layer_impl)) { - // The inner viewport layer represents the viewport. - if (!layer_impl->scrollable() || layer_impl == OuterViewportScrollLayer()) + if (!layer_impl->scrollable()) continue; gfx::ScrollOffset current_offset = layer_impl->CurrentScrollOffset(); diff --git a/chromium/cc/trees/layer_tree_host_impl.h b/chromium/cc/trees/layer_tree_host_impl.h index f2d5dfaa305..b5f24fd4bc1 100644 --- a/chromium/cc/trees/layer_tree_host_impl.h +++ b/chromium/cc/trees/layer_tree_host_impl.h @@ -187,7 +187,7 @@ class CC_EXPORT LayerTreeHostImpl float page_scale, base::TimeDelta duration); void SetNeedsAnimateInput() override; - bool IsCurrentlyScrollingRoot() const override; + bool IsCurrentlyScrollingInnerViewport() const override; bool IsCurrentlyScrollingLayerAt( const gfx::Point& viewport_point, InputHandler::ScrollInputType type) const override; diff --git a/chromium/cc/trees/layer_tree_host_impl_unittest.cc b/chromium/cc/trees/layer_tree_host_impl_unittest.cc index 3d47528b9bc..0f2204fa223 100644 --- a/chromium/cc/trees/layer_tree_host_impl_unittest.cc +++ b/chromium/cc/trees/layer_tree_host_impl_unittest.cc @@ -1310,6 +1310,54 @@ TEST_F(LayerTreeHostImplTest, ViewportScrollOrder) { outer_scroll_layer->CurrentScrollOffset()); } +// Make sure scrolls smaller than a unit applied to the viewport don't get +// dropped. crbug.com/539334. +TEST_F(LayerTreeHostImplTest, ScrollViewportWithFractionalAmounts) { + LayerTreeSettings settings = DefaultSettings(); + CreateHostImpl(settings, CreateOutputSurface()); + host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f); + + const gfx::Size content_size(1000, 1000); + const gfx::Size viewport_size(500, 500); + CreateBasicVirtualViewportLayers(viewport_size, content_size); + + LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer(); + LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer(); + + // Sanity checks. + EXPECT_VECTOR_EQ( + gfx::Vector2dF(500, 500), + outer_scroll_layer->MaxScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(), outer_scroll_layer->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(), inner_scroll_layer->CurrentScrollOffset()); + + RebuildPropertyTrees(); + + // Scroll only the layout viewport. + host_impl_->ScrollBegin(gfx::Point(250, 250), InputHandler::GESTURE); + host_impl_->ScrollBy(gfx::Point(250, 250), gfx::Vector2dF(0.125f, 0.125f)); + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(0.125f, 0.125f), + outer_scroll_layer->CurrentScrollOffset()); + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(0, 0), + inner_scroll_layer->CurrentScrollOffset()); + host_impl_->ScrollEnd(); + + host_impl_->active_tree()->PushPageScaleFromMainThread(2.f, 1.f, 2.f); + + // Now that we zoomed in, the scroll should be applied to the inner viewport. + host_impl_->ScrollBegin(gfx::Point(250, 250), InputHandler::GESTURE); + host_impl_->ScrollBy(gfx::Point(250, 250), gfx::Vector2dF(0.5f, 0.5f)); + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(0.125f, 0.125f), + outer_scroll_layer->CurrentScrollOffset()); + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(0.25f, 0.25f), + inner_scroll_layer->CurrentScrollOffset()); + host_impl_->ScrollEnd(); +} + // Tests that scrolls during a pinch gesture (i.e. "two-finger" scrolls) work // as expected. That is, scrolling during a pinch should bubble from the inner // to the outer viewport. @@ -8024,6 +8072,11 @@ TEST_F(LayerTreeHostImplTest, ExternalTransformReflectedInNextDraw) { TEST_F(LayerTreeHostImplTest, ScrollAnimated) { SetupScrollAndContentsLayers(gfx::Size(100, 200)); + + // Shrink the outer viewport clip layer so that the outer viewport can scroll. + host_impl_->OuterViewportScrollLayer()->parent()->SetBounds( + gfx::Size(50, 100)); + DrawFrame(); base::TimeTicks start_time = @@ -8036,6 +8089,7 @@ TEST_F(LayerTreeHostImplTest, ScrollAnimated) { host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50))); LayerImpl* scrolling_layer = host_impl_->CurrentlyScrollingLayer(); + EXPECT_EQ(host_impl_->OuterViewportScrollLayer(), scrolling_layer); begin_frame_args.frame_time = start_time; host_impl_->WillBeginImplFrame(begin_frame_args); diff --git a/chromium/cc/trees/layer_tree_impl.cc b/chromium/cc/trees/layer_tree_impl.cc index 7cf7ddbce64..90efa38e676 100644 --- a/chromium/cc/trees/layer_tree_impl.cc +++ b/chromium/cc/trees/layer_tree_impl.cc @@ -266,8 +266,6 @@ LayerImpl* LayerTreeImpl::CurrentlyScrollingLayer() const { } void LayerTreeImpl::SetCurrentlyScrollingLayer(LayerImpl* layer) { - DCHECK_IMPLIES(layer, layer != OuterViewportScrollLayer()); - int new_id = layer ? layer->id() : Layer::INVALID_ID; if (currently_scrolling_layer_id_ == new_id) return; |