| Index: cc/trees/thread_proxy.cc
|
| diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc
|
| index 21a69ae2fa55c0eb2e2161a866358876c63a4dab..dddf3e39ecfd1e37a7eaa7f2b75d4093a955dda2 100644
|
| --- a/cc/trees/thread_proxy.cc
|
| +++ b/cc/trees/thread_proxy.cc
|
| @@ -62,8 +62,7 @@ ThreadProxy::ThreadProxy(
|
| scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner,
|
| scoped_ptr<BeginFrameSource> external_begin_frame_source)
|
| : Proxy(main_task_runner, impl_task_runner),
|
| - main_thread_only_vars_unsafe_(this, layer_tree_host->id()),
|
| - main_thread_or_blocked_vars_unsafe_(layer_tree_host),
|
| + main_thread_only_vars_unsafe_(this, layer_tree_host),
|
| compositor_thread_vars_unsafe_(
|
| this,
|
| layer_tree_host->id(),
|
| @@ -79,11 +78,13 @@ ThreadProxy::ThreadProxy(
|
| }
|
|
|
| ThreadProxy::MainThreadOnly::MainThreadOnly(ThreadProxy* proxy,
|
| - int layer_tree_host_id)
|
| - : layer_tree_host_id(layer_tree_host_id),
|
| + LayerTreeHost* layer_tree_host)
|
| + : layer_tree_host_id(layer_tree_host->id()),
|
| + layer_tree_host(layer_tree_host),
|
| max_requested_pipeline_stage(NO_PIPELINE_STAGE),
|
| current_pipeline_stage(NO_PIPELINE_STAGE),
|
| final_pipeline_stage(NO_PIPELINE_STAGE),
|
| + commit_waits_for_activation(false),
|
| started(false),
|
| prepare_tiles_pending(false),
|
| defer_commits(false),
|
| @@ -91,13 +92,10 @@ ThreadProxy::MainThreadOnly::MainThreadOnly(ThreadProxy* proxy,
|
|
|
| ThreadProxy::MainThreadOnly::~MainThreadOnly() {}
|
|
|
| -ThreadProxy::MainThreadOrBlockedMainThread::MainThreadOrBlockedMainThread(
|
| - LayerTreeHost* host)
|
| - : layer_tree_host(host),
|
| - commit_waits_for_activation(false),
|
| - main_thread_inside_commit(false) {}
|
| +ThreadProxy::BlockedMainCommitOnly::BlockedMainCommitOnly()
|
| + : layer_tree_host(nullptr) {}
|
|
|
| -ThreadProxy::MainThreadOrBlockedMainThread::~MainThreadOrBlockedMainThread() {}
|
| +ThreadProxy::BlockedMainCommitOnly::~BlockedMainCommitOnly() {}
|
|
|
| ThreadProxy::CompositorThreadOnly::CompositorThreadOnly(
|
| ThreadProxy* proxy,
|
| @@ -105,8 +103,8 @@ ThreadProxy::CompositorThreadOnly::CompositorThreadOnly(
|
| RenderingStatsInstrumentation* rendering_stats_instrumentation,
|
| scoped_ptr<BeginFrameSource> external_begin_frame_source)
|
| : layer_tree_host_id(layer_tree_host_id),
|
| + next_commit_waits_for_activation(false),
|
| commit_completion_event(nullptr),
|
| - completion_event_for_commit_held_on_tree_activation(nullptr),
|
| next_frame_is_newly_committed_frame(false),
|
| inside_draw(false),
|
| input_throttled_until_commit(false),
|
| @@ -402,8 +400,7 @@ void ThreadProxy::SetNeedsRedrawOnImpl(const gfx::Rect& damage_rect) {
|
|
|
| void ThreadProxy::SetNextCommitWaitsForActivation() {
|
| DCHECK(IsMainThread());
|
| - DCHECK(!blocked_main().main_thread_inside_commit);
|
| - blocked_main().commit_waits_for_activation = true;
|
| + main().commit_waits_for_activation = true;
|
| }
|
|
|
| void ThreadProxy::SetDeferCommits(bool defer_commits) {
|
| @@ -485,11 +482,11 @@ void ThreadProxy::SetInputThrottledUntilCommitOnImpl(bool is_throttled) {
|
| }
|
|
|
| LayerTreeHost* ThreadProxy::layer_tree_host() {
|
| - return blocked_main().layer_tree_host;
|
| + return main().layer_tree_host;
|
| }
|
|
|
| const LayerTreeHost* ThreadProxy::layer_tree_host() const {
|
| - return blocked_main().layer_tree_host;
|
| + return main().layer_tree_host;
|
| }
|
|
|
| ThreadProxy::MainThreadOnly& ThreadProxy::main() {
|
| @@ -501,15 +498,9 @@ const ThreadProxy::MainThreadOnly& ThreadProxy::main() const {
|
| return main_thread_only_vars_unsafe_;
|
| }
|
|
|
| -ThreadProxy::MainThreadOrBlockedMainThread& ThreadProxy::blocked_main() {
|
| - DCHECK(IsMainThread() || IsMainThreadBlocked());
|
| - return main_thread_or_blocked_vars_unsafe_;
|
| -}
|
| -
|
| -const ThreadProxy::MainThreadOrBlockedMainThread& ThreadProxy::blocked_main()
|
| - const {
|
| - DCHECK(IsMainThread() || IsMainThreadBlocked());
|
| - return main_thread_or_blocked_vars_unsafe_;
|
| +ThreadProxy::BlockedMainCommitOnly& ThreadProxy::blocked_main_commit() {
|
| + DCHECK(IsMainThreadBlocked() && impl().commit_completion_event);
|
| + return main_thread_blocked_commit_vars_unsafe_;
|
| }
|
|
|
| ThreadProxy::CompositorThreadOnly& ThreadProxy::impl() {
|
| @@ -529,11 +520,7 @@ void ThreadProxy::Start() {
|
| // Create LayerTreeHostImpl.
|
| DebugScopedSetMainThreadBlocked main_thread_blocked(this);
|
| CompletionEvent completion;
|
| - Proxy::ImplThreadTaskRunner()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&ThreadProxy::InitializeImplOnImplThread,
|
| - base::Unretained(this),
|
| - &completion));
|
| + main().channel_main->InitializeImplOnImpl(&completion, layer_tree_host());
|
| completion.Wait();
|
|
|
| main_thread_weak_ptr_ = main().weak_factory.GetWeakPtr();
|
| @@ -560,16 +547,12 @@ void ThreadProxy::Stop() {
|
| DebugScopedSetMainThreadBlocked main_thread_blocked(this);
|
|
|
| CompletionEvent completion;
|
| - Proxy::ImplThreadTaskRunner()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&ThreadProxy::LayerTreeHostClosedOnImplThread,
|
| - impl_thread_weak_ptr_,
|
| - &completion));
|
| + main().channel_main->LayerTreeHostClosedOnImpl(&completion);
|
| completion.Wait();
|
| }
|
|
|
| main().weak_factory.InvalidateWeakPtrs();
|
| - blocked_main().layer_tree_host = NULL;
|
| + main().layer_tree_host = nullptr;
|
| main().started = false;
|
| }
|
|
|
| @@ -715,8 +698,11 @@ void ThreadProxy::BeginMainFrame(
|
| BlockingTaskRunner::CapturePostTasks blocked(
|
| blocking_main_thread_task_runner());
|
|
|
| + bool hold_commit_for_activation = main().commit_waits_for_activation;
|
| + main().commit_waits_for_activation = false;
|
| CompletionEvent completion;
|
| - main().channel_main->StartCommitOnImpl(&completion);
|
| + main().channel_main->StartCommitOnImpl(&completion, layer_tree_host(),
|
| + hold_commit_for_activation);
|
| completion.Wait();
|
| }
|
|
|
| @@ -731,13 +717,22 @@ void ThreadProxy::BeginMainFrameNotExpectedSoon() {
|
| layer_tree_host()->BeginMainFrameNotExpectedSoon();
|
| }
|
|
|
| -void ThreadProxy::StartCommitOnImpl(CompletionEvent* completion) {
|
| +void ThreadProxy::StartCommitOnImpl(CompletionEvent* completion,
|
| + LayerTreeHost* layer_tree_host,
|
| + bool hold_commit_for_activation) {
|
| TRACE_EVENT0("cc", "ThreadProxy::StartCommitOnImplThread");
|
| DCHECK(!impl().commit_completion_event);
|
| DCHECK(IsImplThread() && IsMainThreadBlocked());
|
| DCHECK(impl().scheduler);
|
| DCHECK(impl().scheduler->CommitPending());
|
|
|
| + if (hold_commit_for_activation) {
|
| + // This commit may be aborted. Store the value for
|
| + // hold_commit_for_activation so that whenever the next commit is started,
|
| + // the main thread will be unblocked only after pending tree activation.
|
| + impl().next_commit_waits_for_activation = hold_commit_for_activation;
|
| + }
|
| +
|
| if (!impl().layer_tree_host_impl) {
|
| TRACE_EVENT_INSTANT0(
|
| "cc", "EarlyOut_NoLayerTree", TRACE_EVENT_SCOPE_THREAD);
|
| @@ -749,6 +744,8 @@ void ThreadProxy::StartCommitOnImpl(CompletionEvent* completion) {
|
| // But, we can avoid a PostTask in here.
|
| impl().scheduler->NotifyBeginMainFrameStarted();
|
| impl().commit_completion_event = completion;
|
| + DCHECK(!blocked_main_commit().layer_tree_host);
|
| + blocked_main_commit().layer_tree_host = layer_tree_host;
|
| impl().scheduler->NotifyReadyToCommit();
|
| }
|
|
|
| @@ -781,24 +778,20 @@ void ThreadProxy::ScheduledActionCommit() {
|
| DCHECK(IsImplThread());
|
| DCHECK(IsMainThreadBlocked());
|
| DCHECK(impl().commit_completion_event);
|
| + DCHECK(blocked_main_commit().layer_tree_host);
|
|
|
| - blocked_main().main_thread_inside_commit = true;
|
| impl().layer_tree_host_impl->BeginCommit();
|
| - layer_tree_host()->FinishCommitOnImplThread(
|
| + blocked_main_commit().layer_tree_host->FinishCommitOnImplThread(
|
| impl().layer_tree_host_impl.get());
|
| - blocked_main().main_thread_inside_commit = false;
|
|
|
| - bool hold_commit = blocked_main().commit_waits_for_activation;
|
| - blocked_main().commit_waits_for_activation = false;
|
| + // Remove the LayerTreeHost reference before the completion event is signaled.
|
| + blocked_main_commit().layer_tree_host = nullptr;
|
|
|
| - if (hold_commit) {
|
| + if (impl().next_commit_waits_for_activation) {
|
| // For some layer types in impl-side painting, the commit is held until
|
| // the sync tree is activated. It's also possible that the
|
| // sync tree has already activated if there was no work to be done.
|
| TRACE_EVENT_INSTANT0("cc", "HoldCommit", TRACE_EVENT_SCOPE_THREAD);
|
| - impl().completion_event_for_commit_held_on_tree_activation =
|
| - impl().commit_completion_event;
|
| - impl().commit_completion_event = nullptr;
|
| } else {
|
| impl().commit_completion_event->Signal();
|
| impl().commit_completion_event = nullptr;
|
| @@ -945,19 +938,21 @@ void ThreadProxy::SetAnimationEvents(scoped_ptr<AnimationEventsVector> events) {
|
| layer_tree_host()->SetAnimationEvents(events.Pass());
|
| }
|
|
|
| -void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) {
|
| +void ThreadProxy::InitializeImplOnImpl(CompletionEvent* completion,
|
| + LayerTreeHost* layer_tree_host) {
|
| TRACE_EVENT0("cc", "ThreadProxy::InitializeImplOnImplThread");
|
| DCHECK(IsImplThread());
|
| + DCHECK(IsMainThreadBlocked());
|
| + DCHECK(layer_tree_host);
|
|
|
| // TODO(khushalsagar): ThreadedChannel will create ProxyImpl here and pass a
|
| // reference to itself.
|
| impl().channel_impl = threaded_channel_.get();
|
|
|
| - impl().layer_tree_host_impl =
|
| - layer_tree_host()->CreateLayerTreeHostImpl(this);
|
| + impl().layer_tree_host_impl = layer_tree_host->CreateLayerTreeHostImpl(this);
|
|
|
| SchedulerSettings scheduler_settings(
|
| - layer_tree_host()->settings().ToSchedulerSettings());
|
| + layer_tree_host->settings().ToSchedulerSettings());
|
|
|
| scoped_ptr<CompositorTimingHistory> compositor_timing_history(
|
| new CompositorTimingHistory(CompositorTimingHistory::RENDERER_UMA,
|
| @@ -1014,7 +1009,7 @@ void ThreadProxy::FinishGLOnImpl(CompletionEvent* completion) {
|
| completion->Signal();
|
| }
|
|
|
| -void ThreadProxy::LayerTreeHostClosedOnImplThread(CompletionEvent* completion) {
|
| +void ThreadProxy::LayerTreeHostClosedOnImpl(CompletionEvent* completion) {
|
| TRACE_EVENT0("cc", "ThreadProxy::LayerTreeHostClosedOnImplThread");
|
| DCHECK(IsImplThread());
|
| DCHECK(IsMainThreadBlocked());
|
| @@ -1118,11 +1113,13 @@ void ThreadProxy::DidActivateSyncTree() {
|
| TRACE_EVENT0("cc", "ThreadProxy::DidActivateSyncTreeOnImplThread");
|
| DCHECK(IsImplThread());
|
|
|
| - if (impl().completion_event_for_commit_held_on_tree_activation) {
|
| + if (impl().next_commit_waits_for_activation) {
|
| TRACE_EVENT_INSTANT0(
|
| "cc", "ReleaseCommitbyActivation", TRACE_EVENT_SCOPE_THREAD);
|
| - impl().completion_event_for_commit_held_on_tree_activation->Signal();
|
| - impl().completion_event_for_commit_held_on_tree_activation = nullptr;
|
| + DCHECK(impl().commit_completion_event);
|
| + impl().commit_completion_event->Signal();
|
| + impl().commit_completion_event = nullptr;
|
| + impl().next_commit_waits_for_activation = false;
|
| }
|
|
|
| impl().last_processed_begin_main_frame_args =
|
|
|