diff options
Diffstat (limited to 'cc/layers/texture_layer_unittest.cc')
-rw-r--r-- | cc/layers/texture_layer_unittest.cc | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/cc/layers/texture_layer_unittest.cc b/cc/layers/texture_layer_unittest.cc index 729f4a1..064bb2b 100644 --- a/cc/layers/texture_layer_unittest.cc +++ b/cc/layers/texture_layer_unittest.cc @@ -8,6 +8,8 @@ #include "base/callback.h" #include "base/synchronization/waitable_event.h" +#include "base/threading/thread.h" +#include "base/time/time.h" #include "cc/debug/test_web_graphics_context_3d.h" #include "cc/layers/texture_layer_client.h" #include "cc/layers/texture_layer_impl.h" @@ -861,6 +863,241 @@ class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest { SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( TextureLayerImplWithMailboxThreadedCallback); + +class TextureLayerNoMailboxIsActivatedDuringCommit : public LayerTreeTest, + public TextureLayerClient { + protected: + TextureLayerNoMailboxIsActivatedDuringCommit() + : wait_thread_("WAIT"), + wait_event_(false, false) { + wait_thread_.Start(); + } + + virtual void BeginTest() OVERRIDE { + activate_count_ = 0; + + gfx::Size bounds(100, 100); + root_ = Layer::Create(); + root_->SetAnchorPoint(gfx::PointF()); + root_->SetBounds(bounds); + + layer_ = TextureLayer::Create(this); + layer_->SetIsDrawable(true); + layer_->SetAnchorPoint(gfx::PointF()); + layer_->SetBounds(bounds); + + root_->AddChild(layer_); + layer_tree_host()->SetRootLayer(root_); + layer_tree_host()->SetViewportSize(bounds); + + PostSetNeedsCommitToMainThread(); + } + + // TextureLayerClient implementation. + virtual unsigned PrepareTexture() OVERRIDE { + return OffscreenContextProviderForMainThread() + ->Context3d()->createTexture(); + } + virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE { + return OffscreenContextProviderForMainThread()->Context3d(); + } + virtual bool PrepareTextureMailbox(TextureMailbox* mailbox, + bool use_shared_memory) OVERRIDE { + return false; + } + + virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { + // Slow down activation so the main thread DidCommit() will run if + // not blocked. + wait_thread_.message_loop()->PostDelayedTask( + FROM_HERE, + base::Bind(&base::WaitableEvent::Signal, + base::Unretained(&wait_event_)), + base::TimeDelta::FromMilliseconds(10)); + wait_event_.Wait(); + } + + virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { + { + base::AutoLock lock(activate_lock_); + ++activate_count_; + } + + proxy()->MainThreadTaskRunner()->PostTask( + FROM_HERE, + base::Bind(&TextureLayerNoMailboxIsActivatedDuringCommit::DidActivate, + base::Unretained(this))); + } + + void DidActivate() { + base::AutoLock lock(activate_lock_); + switch (activate_count_) { + case 1: + // The first texture has been activated. Invalidate the layer so it + // grabs a new texture id from the client. + layer_->SetNeedsDisplay(); + // So this commit number should complete after the second activate. + EXPECT_EQ(1, layer_tree_host()->source_frame_number()); + break; + case 2: + // The second mailbox has been activated. Remove the layer from + // the tree to cause another commit/activation. The commit should + // finish *after* the layer is removed from the active tree. + layer_->RemoveFromParent(); + // So this commit number should complete after the third activate. + EXPECT_EQ(2, layer_tree_host()->source_frame_number()); + } + } + + virtual void DidCommit() OVERRIDE { + switch (layer_tree_host()->source_frame_number()) { + case 2: { + // The activate for the 2nd texture should have happened before now. + base::AutoLock lock(activate_lock_); + EXPECT_EQ(2, activate_count_); + break; + } + case 3: { + // The activate to remove the layer should have happened before now. + base::AutoLock lock(activate_lock_); + EXPECT_EQ(3, activate_count_); + + EndTest(); + break; + } + } + } + + + virtual void AfterTest() OVERRIDE {} + + base::Thread wait_thread_; + base::WaitableEvent wait_event_; + base::Lock activate_lock_; + int activate_count_; + int activate_commit_; + scoped_refptr<Layer> root_; + scoped_refptr<TextureLayer> layer_; +}; + +SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( + TextureLayerNoMailboxIsActivatedDuringCommit); + +class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest { + protected: + TextureLayerMailboxIsActivatedDuringCommit() + : wait_thread_("WAIT"), + wait_event_(false, false) { + wait_thread_.Start(); + } + + static void ReleaseCallback(unsigned sync_point, bool lost_resource) {} + + void SetMailbox(char mailbox_char) { + TextureMailbox mailbox( + std::string(64, mailbox_char), + base::Bind( + &TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback)); + layer_->SetTextureMailbox(mailbox); + } + + virtual void BeginTest() OVERRIDE { + activate_count_ = 0; + + gfx::Size bounds(100, 100); + root_ = Layer::Create(); + root_->SetAnchorPoint(gfx::PointF()); + root_->SetBounds(bounds); + + layer_ = TextureLayer::CreateForMailbox(NULL); + layer_->SetIsDrawable(true); + layer_->SetAnchorPoint(gfx::PointF()); + layer_->SetBounds(bounds); + + root_->AddChild(layer_); + layer_tree_host()->SetRootLayer(root_); + layer_tree_host()->SetViewportSize(bounds); + SetMailbox('1'); + + PostSetNeedsCommitToMainThread(); + } + + virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { + // Slow down activation so the main thread DidCommit() will run if + // not blocked. + wait_thread_.message_loop()->PostDelayedTask( + FROM_HERE, + base::Bind(&base::WaitableEvent::Signal, + base::Unretained(&wait_event_)), + base::TimeDelta::FromMilliseconds(10)); + wait_event_.Wait(); + } + + virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { + { + base::AutoLock lock(activate_lock_); + ++activate_count_; + } + + proxy()->MainThreadTaskRunner()->PostTask( + FROM_HERE, + base::Bind(&TextureLayerMailboxIsActivatedDuringCommit::DidActivate, + base::Unretained(this))); + } + + void DidActivate() { + base::AutoLock lock(activate_lock_); + switch (activate_count_) { + case 1: + // The first mailbox has been activated. Set a new mailbox, and + // expect the next commit to finish *after* it is activated. + SetMailbox('2'); + // So this commit number should complete after the second activate. + EXPECT_EQ(1, layer_tree_host()->source_frame_number()); + break; + case 2: + // The second mailbox has been activated. Remove the layer from + // the tree to cause another commit/activation. The commit should + // finish *after* the layer is removed from the active tree. + layer_->RemoveFromParent(); + // So this commit number should complete after the third activate. + EXPECT_EQ(2, layer_tree_host()->source_frame_number()); + } + } + + virtual void DidCommit() OVERRIDE { + switch (layer_tree_host()->source_frame_number()) { + case 2: { + // The activate for the 2nd mailbox should have happened before now. + base::AutoLock lock(activate_lock_); + EXPECT_EQ(2, activate_count_); + break; + } + case 3: { + // The activate to remove the layer should have happened before now. + base::AutoLock lock(activate_lock_); + EXPECT_EQ(3, activate_count_); + + EndTest(); + break; + } + } + } + + + virtual void AfterTest() OVERRIDE {} + + base::Thread wait_thread_; + base::WaitableEvent wait_event_; + base::Lock activate_lock_; + int activate_count_; + scoped_refptr<Layer> root_; + scoped_refptr<TextureLayer> layer_; +}; + +SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( + TextureLayerMailboxIsActivatedDuringCommit); + class TextureLayerImplWithMailboxTest : public TextureLayerTest { protected: TextureLayerImplWithMailboxTest() |