Index: cc/trees/layer_tree_host_unittest_proxy.cc |
diff --git a/cc/trees/layer_tree_host_unittest_proxy.cc b/cc/trees/layer_tree_host_unittest_proxy.cc |
index 46a2d36e7d7ffb57ea410d30fc68065e010e4ef9..d19ec46b6094c8b1aeed8c51f50aa76ff52b69ff 100644 |
--- a/cc/trees/layer_tree_host_unittest_proxy.cc |
+++ b/cc/trees/layer_tree_host_unittest_proxy.cc |
@@ -2,6 +2,7 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
+#include "base/atomic_ref_count.h" |
#include "base/compiler_specific.h" |
#include "base/macros.h" |
#include "cc/test/fake_content_layer_client.h" |
@@ -280,64 +281,152 @@ PROXY_MAIN_THREADED_TEST_F(ProxyMainThreadedSetNeedsCommitWhileAnimating); |
class ProxyMainThreadedCommitWaitsForActivation : public ProxyMainThreaded { |
protected: |
- ProxyMainThreadedCommitWaitsForActivation() : commits_completed_(0) {} |
+ ProxyMainThreadedCommitWaitsForActivation() |
+ : num_commits_(0), commit_blocked_on_activation_(0) {} |
~ProxyMainThreadedCommitWaitsForActivation() override {} |
void BeginTest() override { proxy()->SetNeedsCommit(); } |
+ void DidBeginMainFrame() override { |
+ // Check that commit is not blocked on activation after it finishes on the |
+ // impl thread. |
+ bool commit_blocked_on_activation = |
+ !base::AtomicRefCountIsZero(&commit_blocked_on_activation_); |
+ EXPECT_FALSE(commit_blocked_on_activation); |
+ } |
+ |
void ScheduledActionCommit() override { |
- switch (commits_completed_) { |
+ switch (num_commits_) { |
case 0: |
- // The first commit does not wait for activation. Verify that the |
- // completion event is cleared. |
- EXPECT_FALSE(GetProxyImplForTest()->HasCommitCompletionEvent()); |
- EXPECT_FALSE(GetProxyImplForTest()->GetNextCommitWaitsForActivation()); |
- |
+ // The next commit is marked as blocked on activation. |
+ EXPECT_TRUE(base::AtomicRefCountIsZero(&commit_blocked_on_activation_)); |
+ base::AtomicRefCountInc(&commit_blocked_on_activation_); |
// Set next commit waits for activation and start another commit. |
- commits_completed_++; |
PostNextCommitWaitsForActivationToMainThread(); |
+ // Fallthrough. |
+ case 1: |
PostSetNeedsCommitToMainThread(); |
break; |
+ } |
+ num_commits_++; |
+ } |
+ |
+ void DidActivateSyncTree() override { |
+ switch (num_commits_) { |
+ case 2: |
+ // Mark commit as unblocked since activation is done. |
+ EXPECT_TRUE(base::AtomicRefCountIsOne(&commit_blocked_on_activation_)); |
+ base::AtomicRefCountDec(&commit_blocked_on_activation_); |
+ break; |
+ case 3: |
+ EndTest(); |
+ break; |
+ } |
+ } |
+ |
+ void AfterTest() override { |
+ // It is safe to read num_commits_ on the main thread now since AfterTest() |
+ // runs after the LayerTreeHost is destroyed and the impl thread tear down |
+ // is finished. |
+ EXPECT_EQ(3, num_commits_); |
+ } |
+ |
+ private: |
+ int num_commits_; |
+ base::AtomicRefCount commit_blocked_on_activation_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ProxyMainThreadedCommitWaitsForActivation); |
+}; |
+ |
+PROXY_MAIN_THREADED_TEST_F(ProxyMainThreadedCommitWaitsForActivation); |
+ |
+// Test for a corner case of main frame before activation (MFBA) and commit |
+// waits for activation. If a commit (with wait for activation flag set) |
+// is ready before the activation for a previous commit then the activation |
+// should not signal the completion event of the second commit. |
+class ProxyMainThreadedCommitWaitsForActivationMFBA : public ProxyMainThreaded { |
+ protected: |
+ ProxyMainThreadedCommitWaitsForActivationMFBA() |
+ : num_commits_(0), commit_blocked_on_activation_(0) {} |
+ ~ProxyMainThreadedCommitWaitsForActivationMFBA() override {} |
+ |
+ void InitializeSettings(LayerTreeSettings* settings) override { |
+ settings->main_frame_before_activation_enabled = true; |
+ ProxyMainThreaded::InitializeSettings(settings); |
+ } |
+ |
+ void BeginTest() override { proxy()->SetNeedsCommit(); } |
+ |
+ void DidBeginMainFrame() override { |
+ // Check that commit is not blocked on activation after it finishes on the |
+ // impl thread. |
+ bool commit_blocked_on_activation = |
+ !base::AtomicRefCountIsZero(&commit_blocked_on_activation_); |
+ EXPECT_FALSE(commit_blocked_on_activation); |
+ } |
+ |
+ void StartCommitOnImpl() override { |
+ switch (num_commits_) { |
+ case 0: |
+ // Block activation until next commit is ready. |
+ GetProxyImplForTest()->BlockNotifyReadyToActivateForTesting(true); |
+ break; |
case 1: |
- // The second commit should be held until activation. |
- EXPECT_TRUE(GetProxyImplForTest()->HasCommitCompletionEvent()); |
- EXPECT_TRUE(GetProxyImplForTest()->GetNextCommitWaitsForActivation()); |
+ // After the second commit is ready unblock activation. |
+ if (num_commits_ == 1) { |
+ ImplThreadTaskRunner()->PostTask( |
+ FROM_HERE, |
+ base::Bind( |
+ &ProxyImplForTest::BlockNotifyReadyToActivateForTesting, |
+ base::Unretained(GetProxyImplForTest()), false)); |
+ } |
+ break; |
+ } |
+ } |
- // Start another commit to verify that this is not held until |
- // activation. |
- commits_completed_++; |
+ void ScheduledActionCommit() override { |
+ switch (num_commits_) { |
+ case 0: |
+ // The next commit is marked as blocked on activation. |
+ EXPECT_TRUE(base::AtomicRefCountIsZero(&commit_blocked_on_activation_)); |
+ base::AtomicRefCountInc(&commit_blocked_on_activation_); |
+ // Set next commit waits for activation and start another commit. |
+ PostNextCommitWaitsForActivationToMainThread(); |
+ // Fallthrough. |
+ case 1: |
PostSetNeedsCommitToMainThread(); |
break; |
- case 2: |
- // The third commit should not wait for activation. |
- EXPECT_FALSE(GetProxyImplForTest()->HasCommitCompletionEvent()); |
- EXPECT_FALSE(GetProxyImplForTest()->GetNextCommitWaitsForActivation()); |
- |
- commits_completed_++; |
} |
+ num_commits_++; |
} |
void DidActivateSyncTree() override { |
- // The next_commit_waits_for_activation should have been cleared after the |
- // sync tree is activated. |
- EXPECT_FALSE(GetProxyImplForTest()->GetNextCommitWaitsForActivation()); |
- if (commits_completed_ == 3) |
- EndTest(); |
+ switch (num_commits_) { |
+ case 2: |
+ // Mark commit as unblocked since activation is done. |
+ EXPECT_TRUE(base::AtomicRefCountIsOne(&commit_blocked_on_activation_)); |
+ base::AtomicRefCountDec(&commit_blocked_on_activation_); |
+ break; |
+ case 3: |
+ EndTest(); |
+ break; |
+ } |
} |
void AfterTest() override { |
- // It is safe to read commits_completed_ on the main thread now since |
- // AfterTest() runs after the LayerTreeHost is destroyed and the impl thread |
- // tear down is finished. |
- EXPECT_EQ(3, commits_completed_); |
+ // It is safe to read num_commits_ on the main thread now since AfterTest() |
+ // runs after the LayerTreeHost is destroyed and the impl thread tear down |
+ // is finished. |
+ EXPECT_EQ(3, num_commits_); |
} |
private: |
- int commits_completed_; |
+ int num_commits_; |
+ base::AtomicRefCount commit_blocked_on_activation_; |
- DISALLOW_COPY_AND_ASSIGN(ProxyMainThreadedCommitWaitsForActivation); |
+ DISALLOW_COPY_AND_ASSIGN(ProxyMainThreadedCommitWaitsForActivationMFBA); |
}; |
-PROXY_MAIN_THREADED_TEST_F(ProxyMainThreadedCommitWaitsForActivation); |
+PROXY_MAIN_THREADED_TEST_F(ProxyMainThreadedCommitWaitsForActivationMFBA); |
} // namespace cc |