summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authorskaslev@chromium.org <skaslev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-30 18:24:57 +0000
committerskaslev@chromium.org <skaslev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-30 18:24:57 +0000
commit498ec6e0ebe1a042f35dc51c000a80de34eb17ef (patch)
treeab0fc2f9684b5df9afdb325d8b105dd9c45f53b7 /cc
parent4e28d8043881bff74b1473d622513c8cb07fe35d (diff)
downloadchromium_src-498ec6e0ebe1a042f35dc51c000a80de34eb17ef.zip
chromium_src-498ec6e0ebe1a042f35dc51c000a80de34eb17ef.tar.gz
chromium_src-498ec6e0ebe1a042f35dc51c000a80de34eb17ef.tar.bz2
Don't create render passes for transparent images.
That patch speeds up Google Maps use-case smoke test by a factor of 10x. It also reduces memory pressure on the GPU. See the related bugs for more info. BUG=161434,160871 Review URL: https://chromiumcodereview.appspot.com/11316171 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@170487 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r--cc/damage_tracker_unittest.cc3
-rw-r--r--cc/delegated_renderer_layer_impl.cc4
-rw-r--r--cc/delegated_renderer_layer_impl.h2
-rw-r--r--cc/layer.cc12
-rw-r--r--cc/layer.h6
-rw-r--r--cc/layer_impl.cc12
-rw-r--r--cc/layer_impl.h12
-rw-r--r--cc/layer_iterator_unittest.cc3
-rw-r--r--cc/layer_tree_host_common.cc13
-rw-r--r--cc/layer_tree_host_common_unittest.cc29
-rw-r--r--cc/layer_tree_host_impl_unittest.cc7
11 files changed, 77 insertions, 26 deletions
diff --git a/cc/damage_tracker_unittest.cc b/cc/damage_tracker_unittest.cc
index 42eaaaf..167c4c1 100644
--- a/cc/damage_tracker_unittest.cc
+++ b/cc/damage_tracker_unittest.cc
@@ -113,6 +113,7 @@ scoped_ptr<LayerImpl> createTestTreeWithTwoSurfaces()
child1->setContentBounds(gfx::Size(30, 30));
child1->setOpacity(0.5); // with a child that drawsContent, this will cause the layer to create its own renderSurface.
child1->setDrawsContent(false); // this layer does not draw, but is intended to create its own renderSurface.
+ child1->setForceRenderSurface(true);
child2->setPosition(gfx::PointF(11, 11));
child2->setAnchorPoint(gfx::PointF());
@@ -723,6 +724,7 @@ TEST_F(DamageTrackerTest, verifyDamageForAddingAndRemovingRenderSurfaces)
//
clearDamageForAllSurfaces(root.get());
child1->setOpacity(1);
+ child1->setForceRenderSurface(false);
emulateDrawingOneFrame(root.get());
// Sanity check that there is only one surface now.
@@ -743,6 +745,7 @@ TEST_F(DamageTrackerTest, verifyDamageForAddingAndRemovingRenderSurfaces)
// Then change the tree so that the render surface is added back.
clearDamageForAllSurfaces(root.get());
child1->setOpacity(0.5);
+ child1->setForceRenderSurface(true);
emulateDrawingOneFrame(root.get());
// Sanity check that there is a new surface now.
diff --git a/cc/delegated_renderer_layer_impl.cc b/cc/delegated_renderer_layer_impl.cc
index 8528edf..7907454 100644
--- a/cc/delegated_renderer_layer_impl.cc
+++ b/cc/delegated_renderer_layer_impl.cc
@@ -22,14 +22,14 @@ DelegatedRendererLayerImpl::~DelegatedRendererLayerImpl()
clearRenderPasses();
}
-bool DelegatedRendererLayerImpl::descendantDrawsContent()
+int DelegatedRendererLayerImpl::descendantsDrawContent()
{
// FIXME: This could possibly return false even though there are some
// quads present as they could all be from a single layer (or set of
// layers without children). If this happens, then make a test that
// ensures the opacity is being changed on quads in the root RenderPass
// when this layer doesn't own a RenderSurfaceImpl.
- return !m_renderPassesInDrawOrder.isEmpty();
+ return m_renderPassesInDrawOrder.isEmpty() ? 0 : 2;
}
bool DelegatedRendererLayerImpl::hasContributingDelegatedRenderPasses() const
diff --git a/cc/delegated_renderer_layer_impl.h b/cc/delegated_renderer_layer_impl.h
index 7e7caa5..0e1dfd9 100644
--- a/cc/delegated_renderer_layer_impl.h
+++ b/cc/delegated_renderer_layer_impl.h
@@ -16,7 +16,7 @@ public:
static scoped_ptr<DelegatedRendererLayerImpl> create(int id) { return make_scoped_ptr(new DelegatedRendererLayerImpl(id)); }
virtual ~DelegatedRendererLayerImpl();
- virtual bool descendantDrawsContent() OVERRIDE;
+ virtual int descendantsDrawContent() OVERRIDE;
virtual bool hasContributingDelegatedRenderPasses() const OVERRIDE;
// This gives ownership of the RenderPasses to the layer.
diff --git a/cc/layer.cc b/cc/layer.cc
index c7b7ebc..242ad76 100644
--- a/cc/layer.cc
+++ b/cc/layer.cc
@@ -698,13 +698,17 @@ void Layer::createRenderSurface()
setRenderTarget(this);
}
-bool Layer::descendantDrawsContent()
+int Layer::descendantsDrawContent()
{
+ int result = 0;
for (size_t i = 0; i < m_children.size(); ++i) {
- if (m_children[i]->drawsContent() || m_children[i]->descendantDrawsContent())
- return true;
+ if (m_children[i]->drawsContent())
+ ++result;
+ result += m_children[i]->descendantsDrawContent();
+ if (result > 1)
+ return result;
}
- return false;
+ return result;
}
int Layer::id() const
diff --git a/cc/layer.h b/cc/layer.h
index 67f3932..f850650 100644
--- a/cc/layer.h
+++ b/cc/layer.h
@@ -267,8 +267,10 @@ public:
void setBoundsContainPageScale(bool);
bool boundsContainPageScale() const { return m_boundsContainPageScale; }
- // Returns true if any of the layer's descendants has content to draw.
- bool descendantDrawsContent();
+ // Returns 0 if none of the layer's descendants has content to draw,
+ // 1 if exactly one descendant has content to draw, or a number >1
+ // (but necessary the exact number of descendants) otherwise.
+ int descendantsDrawContent();
LayerTreeHost* layerTreeHost() const { return m_layerTreeHost; }
diff --git a/cc/layer_impl.cc b/cc/layer_impl.cc
index feee4f4..a1dffea 100644
--- a/cc/layer_impl.cc
+++ b/cc/layer_impl.cc
@@ -112,13 +112,17 @@ void LayerImpl::createRenderSurface()
setRenderTarget(this);
}
-bool LayerImpl::descendantDrawsContent()
+int LayerImpl::descendantsDrawContent()
{
+ int result = 0;
for (size_t i = 0; i < m_children.size(); ++i) {
- if (m_children[i]->drawsContent() || m_children[i]->descendantDrawsContent())
- return true;
+ if (m_children[i]->drawsContent())
+ ++result;
+ result += m_children[i]->descendantsDrawContent();
+ if (result > 1)
+ return result;
}
- return false;
+ return result;
}
scoped_ptr<SharedQuadState> LayerImpl::createSharedQuadState() const
diff --git a/cc/layer_impl.h b/cc/layer_impl.h
index 6cc4d12..3e72d20 100644
--- a/cc/layer_impl.h
+++ b/cc/layer_impl.h
@@ -38,6 +38,8 @@ struct AppendQuadsData;
class CC_EXPORT LayerImpl : public LayerAnimationControllerClient {
public:
+ typedef ScopedPtrVector<LayerImpl> LayerList;
+
static scoped_ptr<LayerImpl> create(int id)
{
return make_scoped_ptr(new LayerImpl(id));
@@ -55,7 +57,7 @@ public:
// Tree structure.
LayerImpl* parent() { return m_parent; }
const LayerImpl* parent() const { return m_parent; }
- const ScopedPtrVector<LayerImpl>& children() const { return m_children; }
+ const LayerList& children() const { return m_children; }
void addChild(scoped_ptr<LayerImpl>);
void removeFromParent();
void removeAllChildren();
@@ -97,8 +99,10 @@ public:
bool forceRenderSurface() const { return m_forceRenderSurface; }
void setForceRenderSurface(bool force) { m_forceRenderSurface = force; }
- // Returns true if any of the layer's descendants has content to draw.
- virtual bool descendantDrawsContent();
+ // Returns 0 if none of the layer's descendants has content to draw,
+ // 1 if exactly one descendant has content to draw, or a number >1
+ // (but necessary the exact number of descendants) otherwise.
+ virtual int descendantsDrawContent();
void setAnchorPoint(const gfx::PointF&);
const gfx::PointF& anchorPoint() const { return m_anchorPoint; }
@@ -314,7 +318,7 @@ private:
// Properties internal to LayerImpl
LayerImpl* m_parent;
- ScopedPtrVector<LayerImpl> m_children;
+ LayerList m_children;
// m_maskLayer can be temporarily stolen during tree sync, we need this ID to confirm newly assigned layer is still the previous one
int m_maskLayerId;
scoped_ptr<LayerImpl> m_maskLayer;
diff --git a/cc/layer_iterator_unittest.cc b/cc/layer_iterator_unittest.cc
index cdcbec1..1dfe9b2 100644
--- a/cc/layer_iterator_unittest.cc
+++ b/cc/layer_iterator_unittest.cc
@@ -214,7 +214,8 @@ TEST(LayerIteratorTest, complexTreeMultiSurface)
rootLayer->addChild(root2);
rootLayer->addChild(root3);
root2->setDrawsContent(false);
- root2->setOpacity(0.5); // Force the layer to own a new surface.
+ root2->setOpacity(0.5);
+ root2->setForceRenderSurface(true); // Force the layer to own a new surface.
root2->addChild(root21);
root2->addChild(root22);
root2->addChild(root23);
diff --git a/cc/layer_tree_host_common.cc b/cc/layer_tree_host_common.cc
index 0d6909c..8aff202 100644
--- a/cc/layer_tree_host_common.cc
+++ b/cc/layer_tree_host_common.cc
@@ -250,19 +250,20 @@ static bool subtreeShouldRenderToSeparateSurface(LayerType* layer, bool axisAlig
return true;
// Cache this value, because otherwise it walks the entire subtree several times.
- bool descendantDrawsContent = layer->descendantDrawsContent();
+ int descendantsDrawContent = layer->descendantsDrawContent();
// If the layer flattens its subtree (i.e. the layer doesn't preserve-3d), but it is
// treated as a 3D object by its parent (i.e. parent does preserve-3d).
- if (layerIsInExisting3DRenderingContext(layer) && !layer->preserves3D() && descendantDrawsContent)
+ if (layerIsInExisting3DRenderingContext(layer) && !layer->preserves3D() && descendantsDrawContent > 0)
return true;
// If the layer clips its descendants but it is not axis-aligned with respect to its parent.
- if (layerClipsSubtree(layer) && !axisAlignedWithRespectToParent && descendantDrawsContent)
+ if (layerClipsSubtree(layer) && !axisAlignedWithRespectToParent && descendantsDrawContent > 0)
return true;
// If the layer has opacity != 1 and does not have a preserves-3d transform style.
- if (layer->opacity() != 1 && !layer->preserves3D() && descendantDrawsContent)
+ if (layer->opacity() != 1 && !layer->preserves3D() && descendantsDrawContent > 0
+ && (layer->drawsContent() || descendantsDrawContent > 1))
return true;
return false;
@@ -487,10 +488,10 @@ static void calculateDrawTransformsInternal(LayerType* layer, const gfx::Transfo
gfx::Rect clipRectForSubtree;
bool subtreeShouldBeClipped = false;
-
+
float drawOpacity = layer->opacity();
bool drawOpacityIsAnimating = layer->opacityIsAnimating();
- if (layer->parent() && layer->parent()->preserves3D()) {
+ if (layer->parent()) {
drawOpacity *= layer->parent()->drawOpacity();
drawOpacityIsAnimating |= layer->parent()->drawOpacityIsAnimating();
}
diff --git a/cc/layer_tree_host_common_unittest.cc b/cc/layer_tree_host_common_unittest.cc
index 6933335..a1f6923 100644
--- a/cc/layer_tree_host_common_unittest.cc
+++ b/cc/layer_tree_host_common_unittest.cc
@@ -327,6 +327,7 @@ TEST(LayerTreeHostCommonTest, verifyTransformsForSingleRenderSurface)
// Child is set up so that a new render surface should be created.
child->setOpacity(0.5);
+ child->setForceRenderSurface(true);
gfx::Transform parentLayerTransform;
parentLayerTransform.Scale3d(1, 0.9, 1);
@@ -1355,6 +1356,7 @@ TEST(LayerTreeHostCommonTest, verifyClipRectCullsRenderSurfaces)
child->setMasksToBounds(true);
child->setOpacity(0.4f);
+ child->setForceRenderSurface(true);
grandChild->setOpacity(0.5);
greatGrandChild->setOpacity(0.4f);
@@ -1401,7 +1403,9 @@ TEST(LayerTreeHostCommonTest, verifyClipRectCullsSurfaceWithoutVisibleContent)
parent->setMasksToBounds(true);
child->setOpacity(0.4f);
+ child->setForceRenderSurface(true);
grandChild->setOpacity(0.4f);
+ grandChild->setForceRenderSurface(true);
std::vector<scoped_refptr<Layer> > renderSurfaceLayerList;
int dummyMaxTextureSize = 512;
@@ -1629,10 +1633,15 @@ TEST(LayerTreeHostCommonTest, verifyClipRectIsPropagatedCorrectlyToSurfaces)
// Force everyone to be a render surface.
child->setOpacity(0.4f);
+ child->setForceRenderSurface(true);
grandChild1->setOpacity(0.5);
+ grandChild1->setForceRenderSurface(true);
grandChild2->setOpacity(0.5);
+ grandChild2->setForceRenderSurface(true);
grandChild3->setOpacity(0.5);
+ grandChild3->setForceRenderSurface(true);
grandChild4->setOpacity(0.5);
+ grandChild4->setForceRenderSurface(true);
std::vector<scoped_refptr<Layer> > renderSurfaceLayerList;
int dummyMaxTextureSize = 512;
@@ -4611,5 +4620,25 @@ TEST(LayerTreeHostCommonTest, verifySubtreeSearch)
EXPECT_EQ(0, LayerTreeHostCommon::findLayerInSubtree(root.get(), nonexistentId));
}
+TEST(LayerTreeHostCommonTest, verifyTransparentChildRenderSurfaceCreation)
+{
+ scoped_refptr<Layer> root = Layer::create();
+ scoped_refptr<Layer> child = Layer::create();
+ scoped_refptr<LayerWithForcedDrawsContent> grandChild = make_scoped_refptr(new LayerWithForcedDrawsContent());
+
+ const gfx::Transform identityMatrix;
+ setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, gfx::PointF(), gfx::PointF(), gfx::Size(100, 100), false);
+ setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, gfx::PointF(), gfx::PointF(), gfx::Size(10, 10), false);
+ setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, gfx::PointF(), gfx::PointF(), gfx::Size(10, 10), false);
+
+ root->addChild(child);
+ child->addChild(grandChild);
+ child->setOpacity(0.5f);
+
+ executeCalculateDrawTransformsAndVisibility(root.get());
+
+ EXPECT_FALSE(child->renderSurface());
+}
+
} // namespace
} // namespace cc
diff --git a/cc/layer_tree_host_impl_unittest.cc b/cc/layer_tree_host_impl_unittest.cc
index a85ff1d..58e361e 100644
--- a/cc/layer_tree_host_impl_unittest.cc
+++ b/cc/layer_tree_host_impl_unittest.cc
@@ -2389,6 +2389,7 @@ static scoped_ptr<LayerTreeHostImpl> setupLayersForOpacity(bool partialSwap, Lay
child->setContentBounds(child->bounds());
child->setVisibleContentRect(childRect);
child->setDrawsContent(false);
+ child->setForceRenderSurface(true);
grandChild->setAnchorPoint(gfx::PointF(0, 0));
grandChild->setPosition(gfx::Point(grandChildRect.x(), grandChildRect.y()));
@@ -3138,7 +3139,8 @@ static void setupLayersForTextureCaching(LayerTreeHostImpl* layerTreeHostImpl, L
// It will contain other layers that draw content.
addDrawingLayerTo(intermediateLayerPtr, 3, gfx::Rect(10, 10, rootSize.width(), rootSize.height()), &surfaceLayerPtr);
surfaceLayerPtr->setDrawsContent(false); // only children draw content
- surfaceLayerPtr->setOpacity(0.5f); // This will cause it to have a surface
+ surfaceLayerPtr->setOpacity(0.5f);
+ surfaceLayerPtr->setForceRenderSurface(true); // This will cause it to have a surface
// Child of the surface layer will produce some quads
addDrawingLayerTo(surfaceLayerPtr, 4, gfx::Rect(5, 5, rootSize.width() - 25, rootSize.height() - 25), &childPtr);
@@ -3182,7 +3184,8 @@ TEST_P(LayerTreeHostImplTest, textureCachingWithClipping)
// Surface layer is the layer that changes its opacity
// It will contain other layers that draw content.
- surfaceLayerPtr->setOpacity(0.5f); // This will cause it to have a surface
+ surfaceLayerPtr->setOpacity(0.5f);
+ surfaceLayerPtr->setForceRenderSurface(true); // This will cause it to have a surface
addDrawingLayerTo(surfaceLayerPtr, 4, gfx::Rect(0, 0, 100, 3), 0);
addDrawingLayerTo(surfaceLayerPtr, 5, gfx::Rect(0, 97, 100, 3), 0);