Skip to content

Commit

Permalink
Prevent TextureLayer from triggering commits and texture acquisitions…
Browse files Browse the repository at this point in the history
… when

the layer does not draw its contents.

BUG=138448
TEST=cc_unittests TextureLayerTest.syncImplWhenDrawing


Review URL: https://chromiumcodereview.appspot.com/11226061

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@164228 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
junov@chromium.org committed Oct 26, 2012
1 parent 574ef63 commit 031ccff
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 4 deletions.
3 changes: 2 additions & 1 deletion cc/layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,8 @@ void Layer::setNeedsDisplayRect(const FloatRect& dirtyRect)
if (!dirtyRect.isEmpty())
m_needsDisplay = true;

setNeedsCommit();
if (drawsContent())
setNeedsCommit();
}

bool Layer::descendantIsFixedToContainerLayer() const
Expand Down
14 changes: 13 additions & 1 deletion cc/layer_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,6 @@ TEST_F(LayerTest, addAndRemoveChild)
EXPECT_FALSE(child->parent());

EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, m_layerTreeHost->setRootLayer(parent));

EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, parent->addChild(child));

ASSERT_EQ(static_cast<size_t>(1), parent->children().size());
Expand Down Expand Up @@ -421,6 +420,7 @@ TEST_F(LayerTest, checkSetNeedsDisplayCausesCorrectBehavior)

scoped_refptr<Layer> testLayer = Layer::create();
testLayer->setLayerTreeHost(m_layerTreeHost.get());
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setIsDrawable(true));

IntSize testBounds = IntSize(501, 508);

Expand All @@ -436,6 +436,7 @@ TEST_F(LayerTest, checkSetNeedsDisplayCausesCorrectBehavior)
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setBounds(testBounds));
testLayer = Layer::create();
testLayer->setLayerTreeHost(m_layerTreeHost.get());
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setIsDrawable(true));
EXPECT_FALSE(testLayer->needsDisplay());

// The real test begins here.
Expand All @@ -455,22 +456,32 @@ TEST_F(LayerTest, checkSetNeedsDisplayCausesCorrectBehavior)
// Case 4: Layer should accept dirty rects that go beyond its bounds.
testLayer = Layer::create();
testLayer->setLayerTreeHost(m_layerTreeHost.get());
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setIsDrawable(true));
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setBounds(testBounds));
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setNeedsDisplayRect(outOfBoundsDirtyRect));
EXPECT_TRUE(testLayer->needsDisplay());

// Case 5: setNeedsDisplay() without the dirty rect arg.
testLayer = Layer::create();
testLayer->setLayerTreeHost(m_layerTreeHost.get());
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setIsDrawable(true));
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setBounds(testBounds));
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setNeedsDisplay());
EXPECT_TRUE(testLayer->needsDisplay());

// Case 6: setNeedsDisplay() with a non-drawable layer
testLayer = Layer::create();
testLayer->setLayerTreeHost(m_layerTreeHost.get());
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(0, testLayer->setBounds(testBounds));
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(0, testLayer->setNeedsDisplayRect(dirty1));
EXPECT_TRUE(testLayer->needsDisplay());
}

TEST_F(LayerTest, checkPropertyChangeCausesCorrectBehavior)
{
scoped_refptr<Layer> testLayer = Layer::create();
testLayer->setLayerTreeHost(m_layerTreeHost.get());
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setIsDrawable(true));

scoped_refptr<Layer> dummyLayer = Layer::create(); // just a dummy layer for this test case.

Expand Down Expand Up @@ -577,6 +588,7 @@ class LayerWithContentScaling : public Layer {
TEST_F(LayerTest, checkContentsScaleChangeTriggersNeedsDisplay)
{
scoped_refptr<LayerWithContentScaling> testLayer = make_scoped_refptr(new LayerWithContentScaling());
testLayer->setIsDrawable(true);
testLayer->setLayerTreeHost(m_layerTreeHost.get());

IntSize testBounds = IntSize(320, 240);
Expand Down
8 changes: 6 additions & 2 deletions cc/texture_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ TextureLayer::TextureLayer(TextureLayerClient* client)
, m_rateLimitContext(false)
, m_contextLost(false)
, m_textureId(0)
, m_contentCommitted(false)
{
}

Expand Down Expand Up @@ -83,15 +84,17 @@ void TextureLayer::setTextureId(unsigned id)

void TextureLayer::willModifyTexture()
{
if (layerTreeHost())
if (layerTreeHost() && (drawsContent() || m_contentCommitted)) {
layerTreeHost()->acquireLayerTextures();
m_contentCommitted = false;
}
}

void TextureLayer::setNeedsDisplayRect(const FloatRect& dirtyRect)
{
Layer::setNeedsDisplayRect(dirtyRect);

if (m_rateLimitContext && m_client && layerTreeHost())
if (m_rateLimitContext && m_client && layerTreeHost() && drawsContent())
layerTreeHost()->startRateLimiter(m_client->context());
}

Expand Down Expand Up @@ -126,6 +129,7 @@ void TextureLayer::pushPropertiesTo(LayerImpl* layer)
textureLayer->setUVRect(m_uvRect);
textureLayer->setPremultipliedAlpha(m_premultipliedAlpha);
textureLayer->setTextureId(m_textureId);
m_contentCommitted = drawsContent();
}

}
1 change: 1 addition & 0 deletions cc/texture_layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class TextureLayer : public Layer {
bool m_premultipliedAlpha;
bool m_rateLimitContext;
bool m_contextLost;
bool m_contentCommitted;

unsigned m_textureId;
};
Expand Down
74 changes: 74 additions & 0 deletions cc/texture_layer_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include "cc/texture_layer.h"

#include "cc/layer_tree_host.h"
#include "cc/single_thread_proxy.h"
#include "cc/texture_layer_impl.h"
#include "cc/test/fake_layer_tree_host_client.h"
#include "cc/test/web_compositor_initializer.h"
#include "testing/gmock/include/gmock/gmock.h"
Expand All @@ -29,6 +31,7 @@ class MockLayerImplTreeHost : public LayerTreeHost {
}

MOCK_METHOD0(acquireLayerTextures, void());
MOCK_METHOD0(setNeedsCommit, void());

private:
FakeLayerImplTreeHostClient m_fakeClient;
Expand All @@ -52,6 +55,7 @@ class TextureLayerTest : public testing::Test {
{
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());
EXPECT_CALL(*m_layerTreeHost, acquireLayerTextures()).Times(AnyNumber());
EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(AnyNumber());

m_layerTreeHost->setRootLayer(0);
m_layerTreeHost.reset();
Expand All @@ -68,23 +72,88 @@ TEST_F(TextureLayerTest, syncImplWhenChangingTextureId)
ASSERT_TRUE(testLayer);

EXPECT_CALL(*m_layerTreeHost, acquireLayerTextures()).Times(AnyNumber());
EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(AnyNumber());
m_layerTreeHost->setRootLayer(testLayer);
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());
EXPECT_EQ(testLayer->layerTreeHost(), m_layerTreeHost.get());

EXPECT_CALL(*m_layerTreeHost, acquireLayerTextures()).Times(0);
EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(AtLeast(1));
testLayer->setTextureId(1);
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());

EXPECT_CALL(*m_layerTreeHost, acquireLayerTextures()).Times(AtLeast(1));
EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(AtLeast(1));
testLayer->setTextureId(2);
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());

EXPECT_CALL(*m_layerTreeHost, acquireLayerTextures()).Times(AtLeast(1));
EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(AtLeast(1));
testLayer->setTextureId(0);
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());
}

TEST_F(TextureLayerTest, syncImplWhenDrawing)
{
FloatRect dirtyRect(0, 0, 1, 1);

scoped_refptr<TextureLayer> testLayer = TextureLayer::create(0);
ASSERT_TRUE(testLayer);
scoped_ptr<TextureLayerImpl> implLayer;
{
DebugScopedSetImplThread setImplThread;
implLayer = TextureLayerImpl::create(1);
}
ASSERT_TRUE(implLayer);

EXPECT_CALL(*m_layerTreeHost, acquireLayerTextures()).Times(AnyNumber());
EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(AnyNumber());
m_layerTreeHost->setRootLayer(testLayer);
testLayer->setTextureId(1);
testLayer->setIsDrawable(true);
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());
EXPECT_EQ(testLayer->layerTreeHost(), m_layerTreeHost.get());

EXPECT_CALL(*m_layerTreeHost, acquireLayerTextures()).Times(1);
EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(0);
testLayer->willModifyTexture();
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());

EXPECT_CALL(*m_layerTreeHost, acquireLayerTextures()).Times(0);
EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(1);
testLayer->setNeedsDisplayRect(dirtyRect);
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());

EXPECT_CALL(*m_layerTreeHost, acquireLayerTextures()).Times(0);
EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(1);
testLayer->pushPropertiesTo(implLayer.get()); // fake commit
testLayer->setIsDrawable(false);
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());

// Verify that non-drawable layers don't signal the compositor,
// except for the first draw after last commit, which must acquire
// the texture.
EXPECT_CALL(*m_layerTreeHost, acquireLayerTextures()).Times(1);
EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(0);
testLayer->willModifyTexture();
testLayer->setNeedsDisplayRect(dirtyRect);
testLayer->pushPropertiesTo(implLayer.get()); // fake commit
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());

// Second draw with layer in non-drawable state: no texture
// acquisition.
EXPECT_CALL(*m_layerTreeHost, acquireLayerTextures()).Times(0);
EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(0);
testLayer->willModifyTexture();
testLayer->setNeedsDisplayRect(dirtyRect);
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());

{
DebugScopedSetImplThread setImplThread;
delete implLayer.release();
}
}

TEST_F(TextureLayerTest, syncImplWhenRemovingFromTree)
{
scoped_refptr<Layer> rootLayer = Layer::create();
Expand All @@ -98,22 +167,27 @@ TEST_F(TextureLayerTest, syncImplWhenRemovingFromTree)
childLayer->addChild(testLayer);

EXPECT_CALL(*m_layerTreeHost, acquireLayerTextures()).Times(AnyNumber());
EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(AnyNumber());
m_layerTreeHost->setRootLayer(rootLayer);
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());

EXPECT_CALL(*m_layerTreeHost, acquireLayerTextures()).Times(0);
EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(AtLeast(1));
testLayer->removeFromParent();
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());

EXPECT_CALL(*m_layerTreeHost, acquireLayerTextures()).Times(0);
EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(AtLeast(1));
childLayer->addChild(testLayer);
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());

EXPECT_CALL(*m_layerTreeHost, acquireLayerTextures()).Times(0);
EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(AtLeast(1));
testLayer->setTextureId(1);
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());

EXPECT_CALL(*m_layerTreeHost, acquireLayerTextures()).Times(AtLeast(1));
EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(AtLeast(1));
testLayer->removeFromParent();
Mock::VerifyAndClearExpectations(m_layerTreeHost.get());
}
Expand Down
1 change: 1 addition & 0 deletions webkit/compositor_bindings/web_layer_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ TEST_F(WebLayerTest, Client)
// Base layer.
EXPECT_CALL(m_client, scheduleComposite()).Times(AnyNumber());
scoped_ptr<WebLayer> layer(WebLayer::create());
layer->setDrawsContent(true);
m_rootLayer->addChild(layer.get());
Mock::VerifyAndClearExpectations(&m_client);

Expand Down

0 comments on commit 031ccff

Please sign in to comment.