summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authorenne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-09 09:14:39 +0000
committerenne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-09 09:14:39 +0000
commit0ede3bb4bbf901207feff960743d9dd03cee8b11 (patch)
treed37b46ed76a3326ad832388b8722a08a4e495ee4 /cc
parentc2164b29fd999e3d693aa2cc20fc03b2dd33094f (diff)
downloadchromium_src-0ede3bb4bbf901207feff960743d9dd03cee8b11.zip
chromium_src-0ede3bb4bbf901207feff960743d9dd03cee8b11.tar.gz
chromium_src-0ede3bb4bbf901207feff960743d9dd03cee8b11.tar.bz2
cc: Split out calcDrawEtc from drawLayers
Previously, calcDrawEtc was coupled to drawLayers. Immediately before drawing, it would get called to update layer state based on any impl-side input that came in after the commit. Impl-side painting needs to update layer transforms / visible content rect state prior to rasterizing contents. And, if input comes in, it might also need to re-update prior to drawing. LayerTreeHostImpl then gets a needsUpdateLayers() flag, and updateLayers() (which calls calcDraw) is a no-op if nothing has changed on the tree. Additionally, the calculate render surface layer list is persisted since the last updateLayers() call. The LayerTreeHostImpl now sets the needsUpdate flag after commit, scroll, pinch zoom, and animation. These are the easy ones. Unfortunately, this creates an amazing foot gun where you can manipulate the impl tree on the impl thread and updateLayers won't get called, because the needsUpdate flag hasn't been called explicitly. This mostly happens in tests, but could happen elsewhere. To fix this, setFoo calls on LayerImpl now calls setNeedsUpdate() on its host. BUG=155209 Review URL: https://chromiumcodereview.appspot.com/11447028 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@172005 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r--cc/layer_impl.cc42
-rw-r--r--cc/layer_impl.h5
-rw-r--r--cc/layer_impl_unittest.cc94
-rw-r--r--cc/layer_tree_host_impl.cc64
-rw-r--r--cc/layer_tree_host_impl.h7
-rw-r--r--cc/layer_tree_host_impl_unittest.cc7
-rw-r--r--cc/test/fake_layer_tree_host_impl.h2
7 files changed, 193 insertions, 28 deletions
diff --git a/cc/layer_impl.cc b/cc/layer_impl.cc
index 7a7965b..48cdec0 100644
--- a/cc/layer_impl.cc
+++ b/cc/layer_impl.cc
@@ -69,6 +69,7 @@ void LayerImpl::addChild(scoped_ptr<LayerImpl> child)
child->setParent(this);
DCHECK_EQ(layerTreeHostImpl(), child->layerTreeHostImpl());
m_children.append(child.Pass());
+ m_layerTreeHostImpl->setNeedsUpdateDrawProperties();
}
void LayerImpl::removeFromParent()
@@ -81,6 +82,8 @@ void LayerImpl::removeFromParent()
for (size_t i = 0; i < parent->m_children.size(); ++i) {
if (parent->m_children[i] == this) {
+ m_layerTreeHostImpl->setNeedsUpdateDrawProperties();
+ // This remove call deletes |this|, so don't touch it anymore.
parent->m_children.remove(i);
return;
}
@@ -95,7 +98,11 @@ void LayerImpl::removeAllChildren()
void LayerImpl::clearChildList()
{
+ if (m_children.isEmpty())
+ return;
+
m_children.clear();
+ m_layerTreeHostImpl->setNeedsUpdateDrawProperties();
}
void LayerImpl::createRenderSurface()
@@ -404,14 +411,27 @@ bool LayerImpl::layerSurfacePropertyChanged() const
return false;
}
-void LayerImpl::noteLayerPropertyChangedForSubtree()
+void LayerImpl::noteLayerSurfacePropertyChanged()
+{
+ m_layerSurfacePropertyChanged = true;
+ m_layerTreeHostImpl->setNeedsUpdateDrawProperties();
+}
+
+void LayerImpl::noteLayerPropertyChanged()
{
m_layerPropertyChanged = true;
+ m_layerTreeHostImpl->setNeedsUpdateDrawProperties();
+}
+
+void LayerImpl::noteLayerPropertyChangedForSubtree()
+{
+ noteLayerPropertyChanged();
noteLayerPropertyChangedForDescendants();
}
void LayerImpl::noteLayerPropertyChangedForDescendants()
{
+ m_layerTreeHostImpl->setNeedsUpdateDrawProperties();
for (size_t i = 0; i < m_children.size(); ++i)
m_children[i]->noteLayerPropertyChangedForSubtree();
}
@@ -481,7 +501,7 @@ void LayerImpl::setBounds(const gfx::Size& bounds)
if (masksToBounds())
noteLayerPropertyChangedForSubtree();
else
- m_layerPropertyChanged = true;
+ noteLayerPropertyChanged();
}
void LayerImpl::setMaskLayer(scoped_ptr<LayerImpl> maskLayer)
@@ -518,7 +538,7 @@ void LayerImpl::setDrawsContent(bool drawsContent)
return;
m_drawsContent = drawsContent;
- m_layerPropertyChanged = true;
+ noteLayerPropertyChanged();
}
void LayerImpl::setAnchorPoint(const gfx::PointF& anchorPoint)
@@ -545,7 +565,7 @@ void LayerImpl::setBackgroundColor(SkColor backgroundColor)
return;
m_backgroundColor = backgroundColor;
- m_layerPropertyChanged = true;
+ noteLayerPropertyChanged();
}
void LayerImpl::setFilters(const WebKit::WebFilterOperations& filters)
@@ -564,7 +584,7 @@ void LayerImpl::setBackgroundFilters(const WebKit::WebFilterOperations& backgrou
return;
m_backgroundFilters = backgroundFilters;
- m_layerPropertyChanged = true;
+ noteLayerPropertyChanged();
}
void LayerImpl::setFilter(const skia::RefPtr<SkImageFilter>& filter)
@@ -601,7 +621,7 @@ void LayerImpl::setOpacity(float opacity)
return;
m_opacity = opacity;
- m_layerSurfacePropertyChanged = true;
+ noteLayerSurfacePropertyChanged();
}
bool LayerImpl::opacityIsAnimating() const
@@ -643,7 +663,7 @@ void LayerImpl::setTransform(const gfx::Transform& transform)
return;
m_transform = transform;
- m_layerSurfacePropertyChanged = true;
+ noteLayerSurfacePropertyChanged();
}
bool LayerImpl::transformIsAnimating() const
@@ -657,7 +677,7 @@ void LayerImpl::setContentBounds(const gfx::Size& contentBounds)
return;
m_contentBounds = contentBounds;
- m_layerPropertyChanged = true;
+ noteLayerPropertyChanged();
}
void LayerImpl::setContentsScale(float contentsScaleX, float contentsScaleY)
@@ -667,7 +687,7 @@ void LayerImpl::setContentsScale(float contentsScaleX, float contentsScaleY)
m_contentsScaleX = contentsScaleX;
m_contentsScaleY = contentsScaleY;
- m_layerPropertyChanged = true;
+ noteLayerPropertyChanged();
}
void LayerImpl::setScrollOffset(gfx::Vector2d scrollOffset)
@@ -719,8 +739,12 @@ void LayerImpl::didLoseOutputSurface()
void LayerImpl::setMaxScrollOffset(gfx::Vector2d maxScrollOffset)
{
+ if (m_maxScrollOffset == maxScrollOffset)
+ return;
m_maxScrollOffset = maxScrollOffset;
+ m_layerTreeHostImpl->setNeedsUpdateDrawProperties();
+
if (!m_scrollbarAnimationController)
return;
m_scrollbarAnimationController->updateScrollOffset(this);
diff --git a/cc/layer_impl.h b/cc/layer_impl.h
index addcced..cb90958 100644
--- a/cc/layer_impl.h
+++ b/cc/layer_impl.h
@@ -163,6 +163,9 @@ public:
bool showDebugBorders() const;
+ // These invalidate the host's render surface layer list. The caller
+ // is responsible for calling setNeedsUpdateDrawProperties on the host
+ // so that its list can be recreated.
void createRenderSurface();
void clearRenderSurface() { m_drawProperties.render_surface.reset(); }
@@ -298,6 +301,8 @@ private:
friend class TreeSynchronizer;
void clearChildList(); // Warning: This does not preserve tree structure invariants and so is only exposed to the tree synchronizer.
+ void noteLayerSurfacePropertyChanged();
+ void noteLayerPropertyChanged();
void noteLayerPropertyChangedForSubtree();
// Note carefully this does not affect the current layer.
diff --git a/cc/layer_impl_unittest.cc b/cc/layer_impl_unittest.cc
index bf8e96e..f355da6 100644
--- a/cc/layer_impl_unittest.cc
+++ b/cc/layer_impl_unittest.cc
@@ -51,6 +51,18 @@ namespace {
EXPECT_FALSE(grandChild->layerPropertyChanged()); \
EXPECT_TRUE(root->layerSurfacePropertyChanged())
+#define VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(codeToTest) \
+ root->resetAllChangeTrackingForSubtree(); \
+ hostImpl.resetNeedsUpdateDrawPropertiesForTesting(); \
+ codeToTest; \
+ EXPECT_TRUE(hostImpl.needsUpdateDrawProperties());
+
+#define VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(codeToTest) \
+ root->resetAllChangeTrackingForSubtree(); \
+ hostImpl.resetNeedsUpdateDrawPropertiesForTesting(); \
+ codeToTest; \
+ EXPECT_FALSE(hostImpl.needsUpdateDrawProperties());
+
TEST(LayerImplTest, verifyLayerChangesAreTrackedProperly)
{
//
@@ -154,5 +166,87 @@ TEST(LayerImplTest, verifyLayerChangesAreTrackedProperly)
EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->setBounds(arbitrarySize));
}
+TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties)
+{
+ FakeImplProxy proxy;
+ FakeLayerTreeHostImpl hostImpl(&proxy);
+ scoped_ptr<LayerImpl> root = LayerImpl::create(&hostImpl, 1);
+
+ gfx::PointF arbitraryPointF = gfx::PointF(0.125f, 0.25f);
+ float arbitraryNumber = 0.352f;
+ gfx::Size arbitrarySize = gfx::Size(111, 222);
+ gfx::Point arbitraryPoint = gfx::Point(333, 444);
+ gfx::Vector2d arbitraryVector2d = gfx::Vector2d(111, 222);
+ gfx::Vector2d largeVector2d = gfx::Vector2d(1000, 1000);
+ gfx::Rect arbitraryRect = gfx::Rect(arbitraryPoint, arbitrarySize);
+ gfx::RectF arbitraryRectF = gfx::RectF(arbitraryPointF, gfx::SizeF(1.234f, 5.678f));
+ SkColor arbitraryColor = SkColorSetRGB(10, 20, 30);
+ gfx::Transform arbitraryTransform;
+ arbitraryTransform.Scale3d(0.1, 0.2, 0.3);
+ WebFilterOperations arbitraryFilters;
+ arbitraryFilters.append(WebFilterOperation::createOpacityFilter(0.5));
+ skia::RefPtr<SkImageFilter> arbitraryFilter = skia::AdoptRef(new SkBlurImageFilter(SK_Scalar1, SK_Scalar1));
+
+ // Related filter functions.
+ VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->setFilters(arbitraryFilters));
+ VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->setFilters(arbitraryFilters));
+ VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->setFilters(WebFilterOperations()));
+ VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->setFilter(arbitraryFilter));
+ VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->setFilter(arbitraryFilter));
+
+ // Related scrolling functions.
+ VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->setMaxScrollOffset(largeVector2d));
+ VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->setMaxScrollOffset(largeVector2d));
+ VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->scrollBy(arbitraryVector2d));
+ VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->scrollBy(gfx::Vector2d()));
+ root->setScrollDelta(gfx::Vector2d(0, 0));
+ hostImpl.resetNeedsUpdateDrawPropertiesForTesting();
+ VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->setScrollDelta(arbitraryVector2d));
+ VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->setScrollDelta(arbitraryVector2d));
+ VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->setScrollOffset(arbitraryVector2d));
+ VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->setScrollOffset(arbitraryVector2d));
+
+ // Unrelated functions, always set to new values, always set needs update.
+ VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->setAnchorPointZ(arbitraryNumber));
+ VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->setMaskLayer(LayerImpl::create(&hostImpl, 4)));
+ VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->setMasksToBounds(true));
+ VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->setContentsOpaque(true));
+ VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->setReplicaLayer(LayerImpl::create(&hostImpl, 5)));
+ VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->setPosition(arbitraryPointF));
+ VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->setPreserves3D(true));
+ VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->setDoubleSided(false)); // constructor initializes it to "true".
+ VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->setImplTransform(arbitraryTransform));
+ VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->setContentBounds(arbitrarySize));
+ VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->setContentsScale(arbitraryNumber, arbitraryNumber));
+ VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->setDrawsContent(true));
+ VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->setBackgroundColor(SK_ColorGRAY));
+ VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->setBackgroundFilters(arbitraryFilters));
+ VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->setOpacity(arbitraryNumber));
+ VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->setTransform(arbitraryTransform));
+ VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->setSublayerTransform(arbitraryTransform));
+ VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(root->setBounds(arbitrarySize));
+
+ // Unrelated functions, set to the same values, no needs update.
+ VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->setAnchorPointZ(arbitraryNumber));
+ VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->setFilter(arbitraryFilter));
+ VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->setMaskLayer(LayerImpl::create(&hostImpl, 4)));
+ VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->setMasksToBounds(true));
+ VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->setContentsOpaque(true));
+ VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->setReplicaLayer(LayerImpl::create(&hostImpl, 5)));
+ VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->setPosition(arbitraryPointF));
+ VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->setPreserves3D(true));
+ VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->setDoubleSided(false)); // constructor initializes it to "true".
+ VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->setImplTransform(arbitraryTransform));
+ VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->setContentBounds(arbitrarySize));
+ VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->setContentsScale(arbitraryNumber, arbitraryNumber));
+ VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->setDrawsContent(true));
+ VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->setBackgroundColor(SK_ColorGRAY));
+ VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->setBackgroundFilters(arbitraryFilters));
+ VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->setOpacity(arbitraryNumber));
+ VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->setTransform(arbitraryTransform));
+ VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->setSublayerTransform(arbitraryTransform));
+ VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(root->setBounds(arbitrarySize));
+}
+
} // namespace
} // namespace cc
diff --git a/cc/layer_tree_host_impl.cc b/cc/layer_tree_host_impl.cc
index 3050ec22..f6b7539 100644
--- a/cc/layer_tree_host_impl.cc
+++ b/cc/layer_tree_host_impl.cc
@@ -219,6 +219,7 @@ LayerTreeHostImpl::LayerTreeHostImpl(const LayerTreeSettings& settings, LayerTre
, m_backgroundColor(0)
, m_hasTransparentBackground(false)
, m_needsAnimateLayers(false)
+ , m_needsUpdateDrawProperties(false)
, m_pinchGestureActive(false)
, m_fpsCounter(FrameRateCounter::create(m_proxy->hasImplThread()))
, m_debugRectHistory(DebugRectHistory::create())
@@ -254,6 +255,14 @@ void LayerTreeHostImpl::beginCommit()
void LayerTreeHostImpl::commitComplete()
{
TRACE_EVENT0("cc", "LayerTreeHostImpl::commitComplete");
+
+ // Impl-side painting needs an update immediately post-commit to have the
+ // opportunity to create tilings. Other paths can call updateDrawProperties
+ // more lazily when needed prior to drawing.
+ setNeedsUpdateDrawProperties();
+ if (m_settings.implSidePainting)
+ updateDrawProperties();
+
// Recompute max scroll position; must be after layer content bounds are
// updated.
updateMaxScrollOffset();
@@ -331,6 +340,7 @@ void LayerTreeHostImpl::startPageScaleAnimation(gfx::Vector2d targetOffset, bool
m_pageScaleAnimation->zoomTo(scaledTargetOffset, pageScale, duration.InSecondsF());
}
+ setNeedsUpdateDrawProperties();
m_client->setNeedsRedrawOnImplThread();
m_client->setNeedsCommitOnImplThread();
}
@@ -376,20 +386,31 @@ void LayerTreeHostImpl::updateRootScrollLayerImplTransform()
}
}
+void LayerTreeHostImpl::updateDrawProperties()
+{
+ if (!needsUpdateDrawProperties())
+ return;
+
+ m_renderSurfaceLayerList.clear();
+ m_needsUpdateDrawProperties = false;
+
+ if (!rootLayer())
+ return;
+
+ calculateRenderSurfaceLayerList(m_renderSurfaceLayerList);
+}
+
void LayerTreeHostImpl::calculateRenderSurfaceLayerList(LayerList& renderSurfaceLayerList)
{
DCHECK(renderSurfaceLayerList.empty());
DCHECK(rootLayer());
DCHECK(m_renderer); // For maxTextureSize.
-
{
updateRootScrollLayerImplTransform();
TRACE_EVENT0("cc", "LayerTreeHostImpl::calcDrawEtc");
float pageScaleFactor = m_pinchZoomViewport.pageScaleFactor();
LayerTreeHostCommon::calculateDrawProperties(rootLayer(), deviceViewportSize(), m_deviceScaleFactor, pageScaleFactor, rendererCapabilities().maxTextureSize, renderSurfaceLayerList);
-
- trackDamageForAllSurfaces(rootLayer(), renderSurfaceLayerList);
}
}
@@ -489,7 +510,8 @@ bool LayerTreeHostImpl::calculateRenderPasses(FrameData& frame)
{
DCHECK(frame.renderPasses.empty());
- calculateRenderSurfaceLayerList(*frame.renderSurfaceLayerList);
+ updateDrawProperties();
+ trackDamageForAllSurfaces(rootLayer(), *frame.renderSurfaceLayerList);
TRACE_EVENT1("cc", "LayerTreeHostImpl::calculateRenderPasses", "renderSurfaceLayerList.size()", static_cast<long long unsigned>(frame.renderSurfaceLayerList->size()));
@@ -535,6 +557,7 @@ bool LayerTreeHostImpl::calculateRenderPasses(FrameData& frame)
if (occlusionTracker.occluded(it->renderTarget(), it->visibleContentRect(), it->drawTransform(), implDrawTransformIsUnknown, it->drawableContentRect(), &hasOcclusionFromOutsideTargetSurface))
appendQuadsData.hadOcclusionFromOutsideTargetSurface |= hasOcclusionFromOutsideTargetSurface;
else {
+ DCHECK_EQ(this, it->layerTreeHostImpl());
it->willDraw(m_resourceProvider.get());
frame.willDrawLayers.push_back(*it);
@@ -750,7 +773,6 @@ bool LayerTreeHostImpl::prepareToDraw(FrameData& frame)
frame.renderSurfaceLayerList = &m_renderSurfaceLayerList;
frame.renderPasses.clear();
frame.renderPassesById.clear();
- frame.renderSurfaceLayerList->clear();
frame.willDrawLayers.clear();
if (!calculateRenderPasses(frame))
@@ -952,14 +974,16 @@ static LayerImpl* findScrollLayerForContentLayer(LayerImpl* layerImpl)
void LayerTreeHostImpl::setRootLayer(scoped_ptr<LayerImpl> layer)
{
- m_activeTree->SetRootLayer(layer.Pass());
+ m_activeTree->SetRootLayer(layer.Pass());
+ setNeedsUpdateDrawProperties();
}
scoped_ptr<LayerImpl> LayerTreeHostImpl::detachLayerTree()
{
- scoped_ptr<LayerImpl> layer = m_activeTree->DetachLayerTree();
- m_renderSurfaceLayerList.clear();
- return layer.Pass();
+ scoped_ptr<LayerImpl> layer = m_activeTree->DetachLayerTree();
+ m_renderSurfaceLayerList.clear();
+ setNeedsUpdateDrawProperties();
+ return layer.Pass();
}
void LayerTreeHostImpl::setVisible(bool visible)
@@ -1094,10 +1118,8 @@ void LayerTreeHostImpl::setPageScaleFactorAndLimits(float pageScaleFactor, float
float pageScaleChange = pageScaleFactor / m_pinchZoomViewport.pageScaleFactor();
m_pinchZoomViewport.setPageScaleFactorAndLimits(pageScaleFactor, minPageScaleFactor, maxPageScaleFactor);
- if (!m_settings.pageScalePinchZoomEnabled) {
- if (pageScaleChange != 1)
- adjustScrollsForPageScaleChange(rootScrollLayer(), pageScaleChange);
- }
+ if (!m_settings.pageScalePinchZoomEnabled && pageScaleChange != 1)
+ adjustScrollsForPageScaleChange(rootScrollLayer(), pageScaleChange);
// Clamp delta to limits and refresh display matrix.
setPageScaleDelta(m_pinchZoomViewport.pageScaleDelta() / m_pinchZoomViewport.sentPageScaleDelta());
@@ -1152,6 +1174,9 @@ void LayerTreeHostImpl::setNeedsRedraw()
bool LayerTreeHostImpl::ensureRenderSurfaceLayerList()
{
+ // TODO(enne): See http://crbug.com/164949. This function should really
+ // just call updateDrawProperties(), but that breaks a number of
+ // impl transform tests that don't expect the tree to be updated.
if (!rootLayer())
return false;
if (!m_renderer)
@@ -1165,8 +1190,8 @@ bool LayerTreeHostImpl::ensureRenderSurfaceLayerList()
// If we are called after setRootLayer() but before prepareToDraw(), we need
// to recalculate the visible layers. This prevents being unable to scroll
// during part of a commit.
- m_renderSurfaceLayerList.clear();
- calculateRenderSurfaceLayerList(m_renderSurfaceLayerList);
+ setNeedsUpdateDrawProperties();
+ updateDrawProperties();
return m_renderSurfaceLayerList.size();
}
@@ -1219,6 +1244,7 @@ InputHandlerClient::ScrollStatus LayerTreeHostImpl::scrollBegin(gfx::Point viewp
// events are already in local layer coordinates so we can just apply them directly.
m_scrollDeltaIsInViewportSpace = (type == Gesture);
m_numImplThreadScrolls++;
+ setNeedsUpdateDrawProperties();
return ScrollStarted;
}
return ScrollIgnored;
@@ -1333,6 +1359,7 @@ bool LayerTreeHostImpl::scrollBy(const gfx::Point& viewportPoint,
if (didScroll) {
m_client->setNeedsCommitOnImplThread();
m_client->setNeedsRedrawOnImplThread();
+ setNeedsUpdateDrawProperties();
}
return didScroll;
}
@@ -1387,6 +1414,7 @@ void LayerTreeHostImpl::pinchGestureUpdate(float magnifyDelta, gfx::Point anchor
m_client->setNeedsCommitOnImplThread();
m_client->setNeedsRedrawOnImplThread();
+ setNeedsUpdateDrawProperties();
}
void LayerTreeHostImpl::pinchGestureEnd()
@@ -1523,6 +1551,7 @@ void LayerTreeHostImpl::animatePageScale(base::TimeTicks time)
nextScroll.Scale(m_pinchZoomViewport.pageScaleFactor());
rootScrollLayer()->scrollBy(nextScroll - scrollTotal);
m_client->setNeedsRedrawOnImplThread();
+ setNeedsUpdateDrawProperties();
if (m_pageScaleAnimation->isAnimationCompleteAtTime(monotonicTime)) {
m_pageScaleAnimation.reset();
@@ -1545,8 +1574,10 @@ void LayerTreeHostImpl::animateLayers(base::TimeTicks monotonicTime, base::Time
if (!events->empty())
m_client->postAnimationEventsToMainThreadOnImplThread(events.Pass(), wallClockTime);
- if (didAnimate)
+ if (didAnimate) {
m_client->setNeedsRedrawOnImplThread();
+ setNeedsUpdateDrawProperties();
+ }
setBackgroundTickingEnabled(!m_visible && m_needsAnimateLayers);
}
@@ -1580,6 +1611,7 @@ void LayerTreeHostImpl::clearRenderSurfaces()
{
clearRenderSurfacesOnLayerImplRecursive(rootLayer());
m_renderSurfaceLayerList.clear();
+ setNeedsUpdateDrawProperties();
}
std::string LayerTreeHostImpl::layerTreeAsText() const
diff --git a/cc/layer_tree_host_impl.h b/cc/layer_tree_host_impl.h
index 71049a8..efd368b 100644
--- a/cc/layer_tree_host_impl.h
+++ b/cc/layer_tree_host_impl.h
@@ -249,6 +249,9 @@ public:
bool needsAnimateLayers() const { return m_needsAnimateLayers; }
void setNeedsAnimateLayers() { m_needsAnimateLayers = true; }
+ bool needsUpdateDrawProperties() const { return m_needsUpdateDrawProperties; }
+ void setNeedsUpdateDrawProperties() { m_needsUpdateDrawProperties = true; }
+
void setNeedsRedraw();
void renderingStats(RenderingStats*) const;
@@ -304,8 +307,11 @@ protected:
void animatePageScale(base::TimeTicks monotonicTime);
void animateScrollbars(base::TimeTicks monotonicTime);
+ void updateDrawProperties();
+
// Exposed for testing.
void calculateRenderSurfaceLayerList(LayerList&);
+ void resetNeedsUpdateDrawPropertiesForTesting() { m_needsUpdateDrawProperties = false; }
// Virtual for testing.
virtual void animateLayers(base::TimeTicks monotonicTime, base::Time wallClockTime);
@@ -364,6 +370,7 @@ private:
// If this is true, it is necessary to traverse the layer tree ticking the animators.
bool m_needsAnimateLayers;
+ bool m_needsUpdateDrawProperties;
bool m_pinchGestureActive;
gfx::Point m_previousPinchAnchor;
diff --git a/cc/layer_tree_host_impl_unittest.cc b/cc/layer_tree_host_impl_unittest.cc
index 7e9f281..5ce07fc 100644
--- a/cc/layer_tree_host_impl_unittest.cc
+++ b/cc/layer_tree_host_impl_unittest.cc
@@ -415,6 +415,8 @@ TEST_P(LayerTreeHostImplTest, clearRootRenderSurfaceAndScroll)
// We should be able to scroll even if the root layer loses its render surface after the most
// recent render.
m_hostImpl->rootLayer()->clearRenderSurface();
+ m_hostImpl->setNeedsUpdateDrawProperties();
+
EXPECT_EQ(m_hostImpl->scrollBegin(gfx::Point(0, 0), InputHandlerClient::Wheel), InputHandlerClient::ScrollStarted);
}
@@ -1931,7 +1933,6 @@ TEST_P(LayerTreeHostImplTest, viewportCovered)
LayerTreeHostImpl::FrameData frame;
EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
ASSERT_EQ(1u, frame.renderPasses.size());
- m_hostImpl->didDrawAllLayers(frame);
size_t numGutterQuads = 0;
for (size_t i = 0; i < frame.renderPasses[0]->quad_list.size(); ++i)
@@ -2050,8 +2051,8 @@ TEST_P(LayerTreeHostImplTest, partialSwapReceivesDamageRect)
layerTreeHostImpl->initializeRenderer(outputSurface.Pass());
layerTreeHostImpl->setViewportSize(gfx::Size(500, 500), gfx::Size(500, 500));
- scoped_ptr<LayerImpl> root = FakeDrawableLayerImpl::create(m_hostImpl.get(), 1);
- scoped_ptr<LayerImpl> child = FakeDrawableLayerImpl::create(m_hostImpl.get(), 2);
+ scoped_ptr<LayerImpl> root = FakeDrawableLayerImpl::create(layerTreeHostImpl.get(), 1);
+ scoped_ptr<LayerImpl> child = FakeDrawableLayerImpl::create(layerTreeHostImpl.get(), 2);
child->setPosition(gfx::PointF(12, 13));
child->setAnchorPoint(gfx::PointF(0, 0));
child->setBounds(gfx::Size(14, 15));
diff --git a/cc/test/fake_layer_tree_host_impl.h b/cc/test/fake_layer_tree_host_impl.h
index c21c998..73ff9ed 100644
--- a/cc/test/fake_layer_tree_host_impl.h
+++ b/cc/test/fake_layer_tree_host_impl.h
@@ -16,6 +16,8 @@ class FakeLayerTreeHostImpl : public LayerTreeHostImpl {
FakeLayerTreeHostImpl(Proxy* proxy);
virtual ~FakeLayerTreeHostImpl();
+ using LayerTreeHostImpl::resetNeedsUpdateDrawPropertiesForTesting;
+
private:
FakeLayerTreeHostImplClient client_;
LayerTreeSettings settings_;