Index: cc/layers/texture_layer_unittest.cc |
diff --git a/cc/layers/texture_layer_unittest.cc b/cc/layers/texture_layer_unittest.cc |
index 729f4a1d6da47de120febf650e603b61779c92c4..a3c568f49fc57dcacfbb8e702832708586cd46b7 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,245 @@ 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(); |
+ |
+ base::AutoLock lock(activate_lock_); |
+ ++activate_count_; |
+ } |
+ |
+ virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { |
+ // The main thread is awake now, and will run DidCommit() immediately. |
+ // Run DidActivate() afterwards by posting it now. |
+ 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()); |
+ break; |
+ case 3: |
+ EndTest(); |
+ break; |
+ } |
+ } |
+ |
+ 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_); |
+ 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(); |
+ |
+ base::AutoLock lock(activate_lock_); |
+ ++activate_count_; |
+ } |
+ |
+ virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { |
+ // The main thread is awake now, and will run DidCommit() immediately. |
+ // Run DidActivate() afterwards by posting it now. |
+ 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()); |
+ break; |
+ case 3: |
+ EndTest(); |
+ break; |
+ } |
+ } |
+ |
+ 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_); |
+ 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() |