Index: cc/layers/texture_layer_unittest.cc |
diff --git a/cc/layers/texture_layer_unittest.cc b/cc/layers/texture_layer_unittest.cc |
index f4482ac0d5ae103c8ddfbed9e4417557a7abff5f..8d4b0d45c8179708aec0a829170dad90613e2f95 100644 |
--- a/cc/layers/texture_layer_unittest.cc |
+++ b/cc/layers/texture_layer_unittest.cc |
@@ -7,6 +7,7 @@ |
#include <string> |
#include "base/callback.h" |
+#include "base/run_loop.h" |
#include "cc/layers/texture_layer_client.h" |
#include "cc/layers/texture_layer_impl.h" |
#include "cc/test/fake_impl_proxy.h" |
@@ -25,6 +26,7 @@ using ::testing::Mock; |
using ::testing::_; |
using ::testing::AtLeast; |
using ::testing::AnyNumber; |
+using ::testing::InvokeWithoutArgs; |
namespace cc { |
namespace { |
@@ -42,6 +44,100 @@ class MockLayerTreeHost : public LayerTreeHost { |
MOCK_METHOD1(StopRateLimiter, void(WebKit::WebGraphicsContext3D* context)); |
}; |
+class FakeTextureLayerClient : public TextureLayerClient { |
+ public: |
+ FakeTextureLayerClient() |
+ : context_(TestWebGraphicsContext3D::Create()), |
+ texture_(0), |
+ mailbox_changed_(true) {} |
+ |
+ virtual unsigned PrepareTexture() OVERRIDE { |
+ return texture_; |
+ } |
+ |
+ virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE { |
+ return context_.get(); |
+ } |
+ |
+ virtual bool PrepareTextureMailbox(TextureMailbox* mailbox, |
+ bool use_shared_memory) OVERRIDE { |
+ if (!mailbox_changed_) |
+ return false; |
+ |
+ *mailbox = mailbox_; |
+ mailbox_changed_ = false; |
+ return true; |
+ } |
+ |
+ void set_texture(unsigned texture) { |
+ texture_ = texture; |
+ } |
+ |
+ void set_mailbox(const TextureMailbox& mailbox) { |
+ mailbox_ = mailbox; |
+ mailbox_changed_ = true; |
+ } |
+ |
+ private: |
+ scoped_ptr<TestWebGraphicsContext3D> context_; |
+ unsigned texture_; |
+ TextureMailbox mailbox_; |
+ bool mailbox_changed_; |
+ DISALLOW_COPY_AND_ASSIGN(FakeTextureLayerClient); |
+}; |
+ |
+class MockMailboxCallback { |
+ public: |
+ MOCK_METHOD3(Release, void(const std::string& mailbox, |
+ unsigned sync_point, |
+ bool lost_resource)); |
+ MOCK_METHOD3(Release2, void(base::SharedMemory* shared_memory, |
+ unsigned sync_point, |
+ bool lost_resource)); |
+}; |
+ |
+struct CommonMailboxObjects { |
+ CommonMailboxObjects() |
+ : mailbox_name1_(64, '1'), |
+ mailbox_name2_(64, '2'), |
+ sync_point1_(1), |
+ sync_point2_(2), |
+ shared_memory_(new base::SharedMemory) { |
+ release_mailbox1_ = base::Bind(&MockMailboxCallback::Release, |
+ base::Unretained(&mock_callback_), |
+ mailbox_name1_); |
+ release_mailbox2_ = base::Bind(&MockMailboxCallback::Release, |
+ base::Unretained(&mock_callback_), |
+ mailbox_name2_); |
+ gpu::Mailbox m1; |
+ m1.SetName(reinterpret_cast<const int8*>(mailbox_name1_.data())); |
+ mailbox1_ = TextureMailbox(m1, release_mailbox1_, sync_point1_); |
+ gpu::Mailbox m2; |
+ m2.SetName(reinterpret_cast<const int8*>(mailbox_name2_.data())); |
+ mailbox2_ = TextureMailbox(m2, release_mailbox2_, sync_point2_); |
+ |
+ gfx::Size size(128, 128); |
+ EXPECT_TRUE(shared_memory_->CreateAndMapAnonymous(4 * size.GetArea())); |
+ release_mailbox3_ = base::Bind(&MockMailboxCallback::Release2, |
+ base::Unretained(&mock_callback_), |
+ shared_memory_.get()); |
+ mailbox3_ = TextureMailbox(shared_memory_.get(), size, release_mailbox3_); |
+ } |
+ |
+ std::string mailbox_name1_; |
+ std::string mailbox_name2_; |
+ MockMailboxCallback mock_callback_; |
+ TextureMailbox::ReleaseCallback release_mailbox1_; |
+ TextureMailbox::ReleaseCallback release_mailbox2_; |
+ TextureMailbox::ReleaseCallback release_mailbox3_; |
+ TextureMailbox mailbox1_; |
+ TextureMailbox mailbox2_; |
+ TextureMailbox mailbox3_; |
+ unsigned sync_point1_; |
+ unsigned sync_point2_; |
+ scoped_ptr<base::SharedMemory> shared_memory_; |
+}; |
+ |
class TextureLayerTest : public testing::Test { |
public: |
TextureLayerTest() |
@@ -52,7 +148,10 @@ class TextureLayerTest : public testing::Test { |
protected: |
virtual void SetUp() { |
layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_)); |
- } |
+ EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber()); |
+ layer_tree_host_->SetViewportSize(gfx::Size(10, 10)); |
+ Mock::VerifyAndClearExpectations(layer_tree_host_.get()); |
+} |
virtual void TearDown() { |
Mock::VerifyAndClearExpectations(layer_tree_host_.get()); |
@@ -69,82 +168,148 @@ class TextureLayerTest : public testing::Test { |
FakeLayerTreeHostImpl host_impl_; |
}; |
-TEST_F(TextureLayerTest, SyncImplWhenChangingTextureId) { |
- scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL); |
+TEST_F(TextureLayerTest, SyncImplWhenClearingTexture) { |
+ FakeTextureLayerClient client; |
+ scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(&client); |
ASSERT_TRUE(test_layer.get()); |
+ test_layer->SetIsDrawable(true); |
+ test_layer->SetBounds(gfx::Size(10, 10)); |
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber()); |
+ EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0); |
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber()); |
layer_tree_host_->SetRootLayer(test_layer); |
Mock::VerifyAndClearExpectations(layer_tree_host_.get()); |
EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get()); |
+ // Clearing the texture before we gave one should not sync. |
+ EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0); |
+ EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber()); |
+ test_layer->ClearTexture(); |
+ Mock::VerifyAndClearExpectations(layer_tree_host_.get()); |
+ |
+ // Give a texture to the layer through the client. |
EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0); |
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); |
- test_layer->SetTextureId(1); |
+ client.set_texture(client.Context3d()->createTexture()); |
+ test_layer->SetNeedsDisplay(); |
+ // Force a commit. |
+ layer_tree_host_->Composite(base::TimeTicks()); |
Mock::VerifyAndClearExpectations(layer_tree_host_.get()); |
+ // Clearing the texture should sync. |
EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1)); |
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); |
- test_layer->SetTextureId(2); |
+ test_layer->ClearTexture(); |
Mock::VerifyAndClearExpectations(layer_tree_host_.get()); |
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1)); |
+ // But only once. |
+ EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0); |
+ EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber()); |
+ test_layer->ClearTexture(); |
+ Mock::VerifyAndClearExpectations(layer_tree_host_.get()); |
+ |
+ // Force a commit to give another texture. |
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); |
- test_layer->SetTextureId(0); |
+ test_layer->SetNeedsDisplay(); |
+ layer_tree_host_->Composite(base::TimeTicks()); |
Mock::VerifyAndClearExpectations(layer_tree_host_.get()); |
-} |
-TEST_F(TextureLayerTest, SyncImplWhenDrawing) { |
- gfx::RectF dirty_rect(0.f, 0.f, 1.f, 1.f); |
+ // Make undrawable and commit. |
+ EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); |
+ test_layer->SetIsDrawable(false); |
+ layer_tree_host_->Composite(base::TimeTicks()); |
+ Mock::VerifyAndClearExpectations(layer_tree_host_.get()); |
- scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL); |
- ASSERT_TRUE(test_layer.get()); |
- scoped_ptr<TextureLayerImpl> impl_layer; |
- impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, false); |
- ASSERT_TRUE(impl_layer); |
+ // Clearing textures should not sync. |
+ EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0); |
+ EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber()); |
+ test_layer->ClearTexture(); |
+ Mock::VerifyAndClearExpectations(layer_tree_host_.get()); |
+} |
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber()); |
+TEST_F(TextureLayerTest, SyncImplWhenClearingMailbox) { |
+ CommonMailboxObjects mailboxes; |
+ FakeTextureLayerClient client; |
+ scoped_refptr<TextureLayer> test_layer = |
+ TextureLayer::CreateForMailbox(&client); |
+ ASSERT_TRUE(test_layer.get()); |
+ test_layer->SetIsDrawable(true); |
+ test_layer->SetBounds(gfx::Size(10, 10)); |
+ EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0); |
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber()); |
layer_tree_host_->SetRootLayer(test_layer); |
- test_layer->SetTextureId(1); |
- test_layer->SetIsDrawable(true); |
Mock::VerifyAndClearExpectations(layer_tree_host_.get()); |
EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get()); |
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(1); |
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0); |
- test_layer->WillModifyTexture(); |
+ // Clearing the mailbox before we gave one should not sync. |
+ EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0); |
+ EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber()); |
+ test_layer->ClearTexture(); |
+ Mock::VerifyAndClearExpectations(layer_tree_host_.get()); |
+ |
+ // Give a mailbox to the layer through the client. |
+ EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0); |
+ EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); |
+ client.set_mailbox(mailboxes.mailbox1_); |
+ test_layer->SetNeedsDisplay(); |
+ // Force a commit. |
+ layer_tree_host_->Composite(base::TimeTicks()); |
+ Mock::VerifyAndClearExpectations(layer_tree_host_.get()); |
+ |
+ // Clearing the mailbox should sync. |
+ EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1)); |
+ EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); |
+ test_layer->ClearTexture(); |
Mock::VerifyAndClearExpectations(layer_tree_host_.get()); |
+ // But only once. |
EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0); |
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1); |
- test_layer->SetNeedsDisplayRect(dirty_rect); |
+ EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber()); |
+ test_layer->ClearTexture(); |
Mock::VerifyAndClearExpectations(layer_tree_host_.get()); |
+ // Force a commit to give another mailbox. |
EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0); |
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1); |
- test_layer->PushPropertiesTo(impl_layer.get()); // fake commit |
- test_layer->SetIsDrawable(false); |
+ EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); |
+ client.set_mailbox(mailboxes.mailbox2_); |
+ test_layer->SetNeedsDisplay(); |
+ // Commit will return mailbox1. |
+ layer_tree_host_->Composite(base::TimeTicks()); |
Mock::VerifyAndClearExpectations(layer_tree_host_.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(*layer_tree_host_, AcquireLayerTextures()).Times(1); |
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0); |
- test_layer->WillModifyTexture(); |
- test_layer->SetNeedsDisplayRect(dirty_rect); |
- test_layer->PushPropertiesTo(impl_layer.get()); // fake commit |
+ // Wait for mailbox callback. |
+ { |
+ base::RunLoop run_loop; |
+ EXPECT_CALL(mailboxes.mock_callback_, |
+ Release(mailboxes.mailbox_name1_, _, false)) |
+ .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit)); |
+ run_loop.Run(); |
+ } |
+ |
+ // Make undrawable and commit. |
+ EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); |
+ test_layer->SetIsDrawable(false); |
+ layer_tree_host_->Composite(base::TimeTicks()); |
Mock::VerifyAndClearExpectations(layer_tree_host_.get()); |
- // Second draw with layer in non-drawable state: no texture |
- // acquisition. |
+ // Clearing textures should not sync. |
EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0); |
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0); |
- test_layer->WillModifyTexture(); |
- test_layer->SetNeedsDisplayRect(dirty_rect); |
+ EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber()); |
+ test_layer->ClearTexture(); |
+ Mock::VerifyAndClearExpectations(layer_tree_host_.get()); |
+ |
+ // Commit will return the mailbox. |
+ layer_tree_host_->Composite(base::TimeTicks()); |
Mock::VerifyAndClearExpectations(layer_tree_host_.get()); |
+ |
+ // Wait for mailbox callback. |
+ { |
+ base::RunLoop run_loop; |
+ EXPECT_CALL(mailboxes.mock_callback_, |
+ Release(mailboxes.mailbox_name2_, _, false)) |
+ .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit)); |
+ run_loop.Run(); |
+ } |
} |
TEST_F(TextureLayerTest, SyncImplWhenRemovingFromTree) { |
@@ -153,9 +318,11 @@ TEST_F(TextureLayerTest, SyncImplWhenRemovingFromTree) { |
scoped_refptr<Layer> child_layer = Layer::Create(); |
ASSERT_TRUE(child_layer.get()); |
root_layer->AddChild(child_layer); |
- scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL); |
+ FakeTextureLayerClient client; |
+ scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(&client); |
+ test_layer->SetIsDrawable(true); |
+ test_layer->SetBounds(gfx::Size(10, 10)); |
ASSERT_TRUE(test_layer.get()); |
- test_layer->SetTextureId(0); |
child_layer->AddChild(test_layer); |
EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber()); |
@@ -173,9 +340,13 @@ TEST_F(TextureLayerTest, SyncImplWhenRemovingFromTree) { |
child_layer->AddChild(test_layer); |
Mock::VerifyAndClearExpectations(layer_tree_host_.get()); |
+ // Give a texture to the layer through the client. |
EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0); |
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); |
- test_layer->SetTextureId(1); |
+ client.set_texture(client.Context3d()->createTexture()); |
+ test_layer->SetNeedsDisplay(); |
+ // Force a commit. |
+ layer_tree_host_->Composite(base::TimeTicks()); |
Mock::VerifyAndClearExpectations(layer_tree_host_.get()); |
EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1)); |
@@ -186,7 +357,7 @@ TEST_F(TextureLayerTest, SyncImplWhenRemovingFromTree) { |
TEST_F(TextureLayerTest, CheckPropertyChangeCausesCorrectBehavior) { |
scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL); |
- layer_tree_host_->SetRootLayer(test_layer); |
+ EXPECT_SET_NEEDS_COMMIT(1, layer_tree_host_->SetRootLayer(test_layer)); |
// Test properties that should call SetNeedsCommit. All properties need to |
// be set to new values in order for SetNeedsCommit to be called. |
@@ -197,35 +368,9 @@ TEST_F(TextureLayerTest, CheckPropertyChangeCausesCorrectBehavior) { |
0.5f, 0.5f, 0.5f, 0.5f)); |
EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPremultipliedAlpha(false)); |
EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBlendBackgroundColor(true)); |
- EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetTextureId(1)); |
- |
- // Calling SetTextureId can call AcquireLayerTextures. |
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber()); |
+ EXPECT_SET_NEEDS_COMMIT(1, test_layer->ClearTexture()); |
} |
-class FakeTextureLayerClient : public TextureLayerClient { |
- public: |
- FakeTextureLayerClient() : context_(TestWebGraphicsContext3D::Create()) {} |
- |
- virtual unsigned PrepareTexture() OVERRIDE { |
- return 0; |
- } |
- |
- virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE { |
- return context_.get(); |
- } |
- |
- virtual bool PrepareTextureMailbox(TextureMailbox* mailbox, |
- bool use_shared_memory) OVERRIDE { |
- *mailbox = TextureMailbox(); |
- return true; |
- } |
- |
- private: |
- scoped_ptr<TestWebGraphicsContext3D> context_; |
- DISALLOW_COPY_AND_ASSIGN(FakeTextureLayerClient); |
-}; |
- |
TEST_F(TextureLayerTest, RateLimiter) { |
FakeTextureLayerClient client; |
scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox( |
@@ -275,58 +420,6 @@ TEST_F(TextureLayerTest, RateLimiter) { |
Mock::VerifyAndClearExpectations(layer_tree_host_.get()); |
} |
-class MockMailboxCallback { |
- public: |
- MOCK_METHOD3(Release, void(const std::string& mailbox, |
- unsigned sync_point, |
- bool lost_resource)); |
- MOCK_METHOD3(Release2, void(base::SharedMemory* shared_memory, |
- unsigned sync_point, |
- bool lost_resource)); |
-}; |
- |
-struct CommonMailboxObjects { |
- CommonMailboxObjects() |
- : mailbox_name1_(64, '1'), |
- mailbox_name2_(64, '2'), |
- sync_point1_(1), |
- sync_point2_(2), |
- shared_memory_(new base::SharedMemory) { |
- release_mailbox1_ = base::Bind(&MockMailboxCallback::Release, |
- base::Unretained(&mock_callback_), |
- mailbox_name1_); |
- release_mailbox2_ = base::Bind(&MockMailboxCallback::Release, |
- base::Unretained(&mock_callback_), |
- mailbox_name2_); |
- gpu::Mailbox m1; |
- m1.SetName(reinterpret_cast<const int8*>(mailbox_name1_.data())); |
- mailbox1_ = TextureMailbox(m1, release_mailbox1_, sync_point1_); |
- gpu::Mailbox m2; |
- m2.SetName(reinterpret_cast<const int8*>(mailbox_name2_.data())); |
- mailbox2_ = TextureMailbox(m2, release_mailbox2_, sync_point2_); |
- |
- gfx::Size size(128, 128); |
- EXPECT_TRUE(shared_memory_->CreateAndMapAnonymous(4 * size.GetArea())); |
- release_mailbox3_ = base::Bind(&MockMailboxCallback::Release2, |
- base::Unretained(&mock_callback_), |
- shared_memory_.get()); |
- mailbox3_ = TextureMailbox(shared_memory_.get(), size, release_mailbox3_); |
- } |
- |
- std::string mailbox_name1_; |
- std::string mailbox_name2_; |
- MockMailboxCallback mock_callback_; |
- TextureMailbox::ReleaseCallback release_mailbox1_; |
- TextureMailbox::ReleaseCallback release_mailbox2_; |
- TextureMailbox::ReleaseCallback release_mailbox3_; |
- TextureMailbox mailbox1_; |
- TextureMailbox mailbox2_; |
- TextureMailbox mailbox3_; |
- unsigned sync_point1_; |
- unsigned sync_point2_; |
- scoped_ptr<base::SharedMemory> shared_memory_; |
-}; |
- |
class TextureLayerWithMailboxTest : public TextureLayerTest { |
protected: |
virtual void TearDown() { |