khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 1 | // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "cc/trees/proxy_main.h" |
| 6 | |
| 7 | #include <algorithm> |
| 8 | #include <string> |
| 9 | |
fdoray | ba12142 | 2016-12-23 19:51:48 | [diff] [blame] | 10 | #include "base/memory/ptr_util.h" |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 11 | #include "base/trace_event/trace_event.h" |
| 12 | #include "base/trace_event/trace_event_argument.h" |
| 13 | #include "base/trace_event/trace_event_synthetic_delay.h" |
khushalsagar | 12020cd4 | 2016-11-21 09:22:48 | [diff] [blame] | 14 | #include "cc/base/completion_event.h" |
chrishtr | 82b5d950 | 2017-03-20 18:25:33 | [diff] [blame] | 15 | #include "cc/base/devtools_instrumentation.h" |
| 16 | #include "cc/benchmarks/benchmark_instrumentation.h" |
danakj | c7afae5 | 2017-06-20 21:12:41 | [diff] [blame^] | 17 | #include "cc/output/layer_tree_frame_sink.h" |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 18 | #include "cc/output/swap_promise.h" |
khushalsagar | 8ec0740 | 2016-09-10 03:13:19 | [diff] [blame] | 19 | #include "cc/resources/ui_resource_manager.h" |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 20 | #include "cc/trees/blocking_task_runner.h" |
khushalsagar | e0e4486e | 2017-01-25 03:15:03 | [diff] [blame] | 21 | #include "cc/trees/layer_tree_host.h" |
loyso | c601b7b8 | 2016-11-10 02:56:44 | [diff] [blame] | 22 | #include "cc/trees/mutator_host.h" |
khushalsagar | 12020cd4 | 2016-11-21 09:22:48 | [diff] [blame] | 23 | #include "cc/trees/proxy_impl.h" |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 24 | #include "cc/trees/scoped_abort_remaining_swap_promises.h" |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 25 | |
| 26 | namespace cc { |
| 27 | |
khushalsagar | e0e4486e | 2017-01-25 03:15:03 | [diff] [blame] | 28 | ProxyMain::ProxyMain(LayerTreeHost* layer_tree_host, |
khushalsagar | 767dd52 | 2015-12-16 05:14:05 | [diff] [blame] | 29 | TaskRunnerProvider* task_runner_provider) |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 30 | : layer_tree_host_(layer_tree_host), |
| 31 | task_runner_provider_(task_runner_provider), |
khushalsagar | cebe494 | 2016-09-07 23:27:01 | [diff] [blame] | 32 | layer_tree_host_id_(layer_tree_host->GetId()), |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 33 | max_requested_pipeline_stage_(NO_PIPELINE_STAGE), |
| 34 | current_pipeline_stage_(NO_PIPELINE_STAGE), |
| 35 | final_pipeline_stage_(NO_PIPELINE_STAGE), |
| 36 | commit_waits_for_activation_(false), |
| 37 | started_(false), |
khushalsagar | 12020cd4 | 2016-11-21 09:22:48 | [diff] [blame] | 38 | defer_commits_(false), |
samans | 44b6dfc | 2017-04-19 16:50:53 | [diff] [blame] | 39 | frame_sink_bound_weak_factory_(this), |
khushalsagar | 12020cd4 | 2016-11-21 09:22:48 | [diff] [blame] | 40 | weak_factory_(this) { |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 41 | TRACE_EVENT0("cc", "ProxyMain::ProxyMain"); |
| 42 | DCHECK(task_runner_provider_); |
| 43 | DCHECK(IsMainThread()); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 44 | } |
| 45 | |
| 46 | ProxyMain::~ProxyMain() { |
| 47 | TRACE_EVENT0("cc", "ProxyMain::~ProxyMain"); |
| 48 | DCHECK(IsMainThread()); |
| 49 | DCHECK(!started_); |
| 50 | } |
| 51 | |
khushalsagar | 12020cd4 | 2016-11-21 09:22:48 | [diff] [blame] | 52 | void ProxyMain::InitializeOnImplThread(CompletionEvent* completion_event) { |
| 53 | DCHECK(task_runner_provider_->IsImplThread()); |
| 54 | DCHECK(!proxy_impl_); |
| 55 | proxy_impl_ = base::MakeUnique<ProxyImpl>( |
| 56 | weak_factory_.GetWeakPtr(), layer_tree_host_, task_runner_provider_); |
| 57 | completion_event->Signal(); |
| 58 | } |
| 59 | |
| 60 | void ProxyMain::DestroyProxyImplOnImplThread( |
| 61 | CompletionEvent* completion_event) { |
| 62 | DCHECK(task_runner_provider_->IsImplThread()); |
| 63 | proxy_impl_.reset(); |
| 64 | completion_event->Signal(); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 65 | } |
| 66 | |
danakj | 9d12442 | 2016-10-14 03:15:08 | [diff] [blame] | 67 | void ProxyMain::DidReceiveCompositorFrameAck() { |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 68 | DCHECK(IsMainThread()); |
danakj | 9d12442 | 2016-10-14 03:15:08 | [diff] [blame] | 69 | layer_tree_host_->DidReceiveCompositorFrameAck(); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 70 | } |
| 71 | |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 72 | void ProxyMain::BeginMainFrameNotExpectedSoon() { |
| 73 | TRACE_EVENT0("cc", "ProxyMain::BeginMainFrameNotExpectedSoon"); |
| 74 | DCHECK(IsMainThread()); |
| 75 | layer_tree_host_->BeginMainFrameNotExpectedSoon(); |
| 76 | } |
| 77 | |
delphick | 9db74aa | 2017-05-05 10:20:49 | [diff] [blame] | 78 | void ProxyMain::BeginMainFrameNotExpectedUntil(base::TimeTicks time) { |
| 79 | TRACE_EVENT0("cc", "ProxyMain::BeginMainFrameNotExpectedUntil"); |
| 80 | DCHECK(IsMainThread()); |
| 81 | layer_tree_host_->BeginMainFrameNotExpectedUntil(time); |
| 82 | } |
| 83 | |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 84 | void ProxyMain::DidCommitAndDrawFrame() { |
| 85 | DCHECK(IsMainThread()); |
| 86 | layer_tree_host_->DidCommitAndDrawFrame(); |
| 87 | } |
| 88 | |
loyso | c601b7b8 | 2016-11-10 02:56:44 | [diff] [blame] | 89 | void ProxyMain::SetAnimationEvents(std::unique_ptr<MutatorEvents> events) { |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 90 | TRACE_EVENT0("cc", "ProxyMain::SetAnimationEvents"); |
| 91 | DCHECK(IsMainThread()); |
| 92 | layer_tree_host_->SetAnimationEvents(std::move(events)); |
| 93 | } |
| 94 | |
danakj | c7afae5 | 2017-06-20 21:12:41 | [diff] [blame^] | 95 | void ProxyMain::DidLoseLayerTreeFrameSink() { |
| 96 | TRACE_EVENT0("cc", "ProxyMain::DidLoseLayerTreeFrameSink"); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 97 | DCHECK(IsMainThread()); |
danakj | c7afae5 | 2017-06-20 21:12:41 | [diff] [blame^] | 98 | layer_tree_host_->DidLoseLayerTreeFrameSink(); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 99 | } |
| 100 | |
danakj | c7afae5 | 2017-06-20 21:12:41 | [diff] [blame^] | 101 | void ProxyMain::RequestNewLayerTreeFrameSink() { |
| 102 | TRACE_EVENT0("cc", "ProxyMain::RequestNewLayerTreeFrameSink"); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 103 | DCHECK(IsMainThread()); |
danakj | c7afae5 | 2017-06-20 21:12:41 | [diff] [blame^] | 104 | layer_tree_host_->RequestNewLayerTreeFrameSink(); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 105 | } |
| 106 | |
danakj | c7afae5 | 2017-06-20 21:12:41 | [diff] [blame^] | 107 | void ProxyMain::DidInitializeLayerTreeFrameSink(bool success) { |
| 108 | TRACE_EVENT0("cc", "ProxyMain::DidInitializeLayerTreeFrameSink"); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 109 | DCHECK(IsMainThread()); |
| 110 | |
danakj | 8c93919 | 2016-08-25 22:09:30 | [diff] [blame] | 111 | if (!success) |
danakj | c7afae5 | 2017-06-20 21:12:41 | [diff] [blame^] | 112 | layer_tree_host_->DidFailToInitializeLayerTreeFrameSink(); |
danakj | 8c93919 | 2016-08-25 22:09:30 | [diff] [blame] | 113 | else |
danakj | c7afae5 | 2017-06-20 21:12:41 | [diff] [blame^] | 114 | layer_tree_host_->DidInitializeLayerTreeFrameSink(); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 115 | } |
| 116 | |
| 117 | void ProxyMain::DidCompletePageScaleAnimation() { |
| 118 | DCHECK(IsMainThread()); |
| 119 | layer_tree_host_->DidCompletePageScaleAnimation(); |
| 120 | } |
| 121 | |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 122 | void ProxyMain::BeginMainFrame( |
danakj | 60bc3bc | 2016-04-09 00:24:48 | [diff] [blame] | 123 | std::unique_ptr<BeginMainFrameAndCommitState> begin_main_frame_state) { |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 124 | benchmark_instrumentation::ScopedBeginFrameTask begin_frame_task( |
| 125 | benchmark_instrumentation::kDoBeginFrame, |
| 126 | begin_main_frame_state->begin_frame_id); |
| 127 | |
| 128 | base::TimeTicks begin_main_frame_start_time = base::TimeTicks::Now(); |
| 129 | |
| 130 | TRACE_EVENT_SYNTHETIC_DELAY_BEGIN("cc.BeginMainFrame"); |
| 131 | DCHECK(IsMainThread()); |
| 132 | DCHECK_EQ(NO_PIPELINE_STAGE, current_pipeline_stage_); |
| 133 | |
vmpstr | f386bcd | 2017-03-08 04:12:07 | [diff] [blame] | 134 | // We need to issue image decode callbacks whether or not we will abort this |
| 135 | // commit, since the callbacks are only stored in |begin_main_frame_state|. |
| 136 | for (auto& callback : |
| 137 | begin_main_frame_state->completed_image_decode_callbacks) { |
| 138 | callback.Run(); |
| 139 | } |
| 140 | |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 141 | if (defer_commits_) { |
| 142 | TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit", |
| 143 | TRACE_EVENT_SCOPE_THREAD); |
sunnyps | ad3235e | 2016-08-09 04:57:52 | [diff] [blame] | 144 | std::vector<std::unique_ptr<SwapPromise>> empty_swap_promises; |
khushalsagar | 12020cd4 | 2016-11-21 09:22:48 | [diff] [blame] | 145 | ImplThreadTaskRunner()->PostTask( |
tzik | 4604bb5 | 2017-04-13 21:50:22 | [diff] [blame] | 146 | FROM_HERE, base::BindOnce(&ProxyImpl::BeginMainFrameAbortedOnImpl, |
| 147 | base::Unretained(proxy_impl_.get()), |
| 148 | CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT, |
| 149 | begin_main_frame_start_time, |
| 150 | base::Passed(&empty_swap_promises))); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 151 | return; |
| 152 | } |
| 153 | |
| 154 | // If the commit finishes, LayerTreeHost will transfer its swap promises to |
| 155 | // LayerTreeImpl. The destructor of ScopedSwapPromiseChecker aborts the |
| 156 | // remaining swap promises. |
khushalsagar | 8297ae99 | 2016-09-14 20:51:23 | [diff] [blame] | 157 | ScopedAbortRemainingSwapPromises swap_promise_checker( |
| 158 | layer_tree_host_->GetSwapPromiseManager()); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 159 | |
| 160 | final_pipeline_stage_ = max_requested_pipeline_stage_; |
| 161 | max_requested_pipeline_stage_ = NO_PIPELINE_STAGE; |
| 162 | |
khushalsagar | cebe494 | 2016-09-07 23:27:01 | [diff] [blame] | 163 | if (!layer_tree_host_->IsVisible()) { |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 164 | TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD); |
sunnyps | ad3235e | 2016-08-09 04:57:52 | [diff] [blame] | 165 | std::vector<std::unique_ptr<SwapPromise>> empty_swap_promises; |
khushalsagar | 12020cd4 | 2016-11-21 09:22:48 | [diff] [blame] | 166 | ImplThreadTaskRunner()->PostTask( |
tzik | 4604bb5 | 2017-04-13 21:50:22 | [diff] [blame] | 167 | FROM_HERE, base::BindOnce(&ProxyImpl::BeginMainFrameAbortedOnImpl, |
| 168 | base::Unretained(proxy_impl_.get()), |
| 169 | CommitEarlyOutReason::ABORTED_NOT_VISIBLE, |
| 170 | begin_main_frame_start_time, |
| 171 | base::Passed(&empty_swap_promises))); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 172 | return; |
| 173 | } |
| 174 | |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 175 | current_pipeline_stage_ = ANIMATE_PIPELINE_STAGE; |
| 176 | |
| 177 | layer_tree_host_->ApplyScrollAndScale( |
| 178 | begin_main_frame_state->scroll_info.get()); |
| 179 | |
majidvp | 96452d0 | 2016-04-11 20:36:04 | [diff] [blame] | 180 | if (begin_main_frame_state->begin_frame_callbacks) { |
| 181 | for (auto& callback : *begin_main_frame_state->begin_frame_callbacks) |
| 182 | callback.Run(); |
| 183 | } |
| 184 | |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 185 | layer_tree_host_->WillBeginMainFrame(); |
| 186 | |
| 187 | layer_tree_host_->BeginMainFrame(begin_main_frame_state->begin_frame_args); |
| 188 | layer_tree_host_->AnimateLayers( |
| 189 | begin_main_frame_state->begin_frame_args.frame_time); |
| 190 | |
| 191 | // Recreate all UI resources if there were evicted UI resources when the impl |
| 192 | // thread initiated the commit. |
| 193 | if (begin_main_frame_state->evicted_ui_resources) |
khushalsagar | 8ec0740 | 2016-09-10 03:13:19 | [diff] [blame] | 194 | layer_tree_host_->GetUIResourceManager()->RecreateUIResources(); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 195 | |
| 196 | layer_tree_host_->RequestMainFrameUpdate(); |
danakj | 97660d9 | 2017-03-27 14:11:49 | [diff] [blame] | 197 | |
| 198 | // At this point the main frame may have deferred commits to avoid committing |
| 199 | // right now. |
| 200 | if (defer_commits_) { |
| 201 | TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit_InsideBeginMainFrame", |
| 202 | TRACE_EVENT_SCOPE_THREAD); |
| 203 | std::vector<std::unique_ptr<SwapPromise>> empty_swap_promises; |
| 204 | ImplThreadTaskRunner()->PostTask( |
tzik | 4604bb5 | 2017-04-13 21:50:22 | [diff] [blame] | 205 | FROM_HERE, base::BindOnce(&ProxyImpl::BeginMainFrameAbortedOnImpl, |
| 206 | base::Unretained(proxy_impl_.get()), |
| 207 | CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT, |
| 208 | begin_main_frame_start_time, |
| 209 | base::Passed(&empty_swap_promises))); |
danakj | 97660d9 | 2017-03-27 14:11:49 | [diff] [blame] | 210 | current_pipeline_stage_ = NO_PIPELINE_STAGE; |
| 211 | // We intentionally don't report CommitComplete() here since it was aborted |
| 212 | // prematurely and we're waiting to do another commit in the future. |
| 213 | layer_tree_host_->DidBeginMainFrame(); |
| 214 | return; |
| 215 | } |
| 216 | |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 217 | TRACE_EVENT_SYNTHETIC_DELAY_END("cc.BeginMainFrame"); |
| 218 | |
| 219 | bool can_cancel_this_commit = final_pipeline_stage_ < COMMIT_PIPELINE_STAGE && |
| 220 | !begin_main_frame_state->evicted_ui_resources; |
| 221 | |
| 222 | current_pipeline_stage_ = UPDATE_LAYERS_PIPELINE_STAGE; |
| 223 | bool should_update_layers = |
| 224 | final_pipeline_stage_ >= UPDATE_LAYERS_PIPELINE_STAGE; |
| 225 | bool updated = should_update_layers && layer_tree_host_->UpdateLayers(); |
| 226 | |
| 227 | layer_tree_host_->WillCommit(); |
| 228 | devtools_instrumentation::ScopedCommitTrace commit_task( |
khushalsagar | cebe494 | 2016-09-07 23:27:01 | [diff] [blame] | 229 | layer_tree_host_->GetId()); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 230 | |
| 231 | current_pipeline_stage_ = COMMIT_PIPELINE_STAGE; |
| 232 | if (!updated && can_cancel_this_commit) { |
| 233 | TRACE_EVENT_INSTANT0("cc", "EarlyOut_NoUpdates", TRACE_EVENT_SCOPE_THREAD); |
khushalsagar | 12020cd4 | 2016-11-21 09:22:48 | [diff] [blame] | 234 | std::vector<std::unique_ptr<SwapPromise>> swap_promises = |
| 235 | layer_tree_host_->GetSwapPromiseManager()->TakeSwapPromises(); |
| 236 | ImplThreadTaskRunner()->PostTask( |
tzik | 4604bb5 | 2017-04-13 21:50:22 | [diff] [blame] | 237 | FROM_HERE, base::BindOnce(&ProxyImpl::BeginMainFrameAbortedOnImpl, |
| 238 | base::Unretained(proxy_impl_.get()), |
| 239 | CommitEarlyOutReason::FINISHED_NO_UPDATES, |
| 240 | begin_main_frame_start_time, |
| 241 | base::Passed(&swap_promises))); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 242 | |
| 243 | // Although the commit is internally aborted, this is because it has been |
| 244 | // detected to be a no-op. From the perspective of an embedder, this commit |
| 245 | // went through, and input should no longer be throttled, etc. |
| 246 | current_pipeline_stage_ = NO_PIPELINE_STAGE; |
| 247 | layer_tree_host_->CommitComplete(); |
| 248 | layer_tree_host_->DidBeginMainFrame(); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 249 | return; |
| 250 | } |
| 251 | |
| 252 | // Notify the impl thread that the main thread is ready to commit. This will |
| 253 | // begin the commit process, which is blocking from the main thread's |
| 254 | // point of view, but asynchronously performed on the impl thread, |
| 255 | // coordinated by the Scheduler. |
| 256 | { |
| 257 | TRACE_EVENT0("cc", "ProxyMain::BeginMainFrame::commit"); |
| 258 | |
| 259 | DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_); |
| 260 | |
| 261 | // This CapturePostTasks should be destroyed before CommitComplete() is |
| 262 | // called since that goes out to the embedder, and we want the embedder |
| 263 | // to receive its callbacks before that. |
| 264 | BlockingTaskRunner::CapturePostTasks blocked( |
| 265 | task_runner_provider_->blocking_main_thread_task_runner()); |
| 266 | |
| 267 | bool hold_commit_for_activation = commit_waits_for_activation_; |
| 268 | commit_waits_for_activation_ = false; |
| 269 | CompletionEvent completion; |
khushalsagar | 12020cd4 | 2016-11-21 09:22:48 | [diff] [blame] | 270 | ImplThreadTaskRunner()->PostTask( |
tzik | 4604bb5 | 2017-04-13 21:50:22 | [diff] [blame] | 271 | FROM_HERE, |
| 272 | base::BindOnce(&ProxyImpl::NotifyReadyToCommitOnImpl, |
| 273 | base::Unretained(proxy_impl_.get()), &completion, |
| 274 | layer_tree_host_, begin_main_frame_start_time, |
| 275 | hold_commit_for_activation)); |
Sunny Sachanandani | 40f1892 | 2017-04-21 20:02:57 | [diff] [blame] | 276 | completion.Wait(); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 277 | } |
| 278 | |
| 279 | current_pipeline_stage_ = NO_PIPELINE_STAGE; |
| 280 | layer_tree_host_->CommitComplete(); |
| 281 | layer_tree_host_->DidBeginMainFrame(); |
| 282 | } |
| 283 | |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 284 | bool ProxyMain::IsStarted() const { |
| 285 | DCHECK(IsMainThread()); |
| 286 | return started_; |
| 287 | } |
| 288 | |
| 289 | bool ProxyMain::CommitToActiveTree() const { |
| 290 | // With ProxyMain, we use a pending tree and activate it once it's ready to |
| 291 | // draw to allow input to modify the active tree and draw during raster. |
| 292 | return false; |
| 293 | } |
| 294 | |
danakj | c7afae5 | 2017-06-20 21:12:41 | [diff] [blame^] | 295 | void ProxyMain::SetLayerTreeFrameSink( |
| 296 | LayerTreeFrameSink* layer_tree_frame_sink) { |
khushalsagar | 12020cd4 | 2016-11-21 09:22:48 | [diff] [blame] | 297 | ImplThreadTaskRunner()->PostTask( |
samans | 44b6dfc | 2017-04-19 16:50:53 | [diff] [blame] | 298 | FROM_HERE, |
danakj | c7afae5 | 2017-06-20 21:12:41 | [diff] [blame^] | 299 | base::BindOnce(&ProxyImpl::InitializeLayerTreeFrameSinkOnImpl, |
| 300 | base::Unretained(proxy_impl_.get()), layer_tree_frame_sink, |
samans | 44b6dfc | 2017-04-19 16:50:53 | [diff] [blame] | 301 | frame_sink_bound_weak_factory_.GetWeakPtr())); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 302 | } |
| 303 | |
| 304 | void ProxyMain::SetVisible(bool visible) { |
| 305 | TRACE_EVENT1("cc", "ProxyMain::SetVisible", "visible", visible); |
khushalsagar | 12020cd4 | 2016-11-21 09:22:48 | [diff] [blame] | 306 | ImplThreadTaskRunner()->PostTask( |
tzik | 4604bb5 | 2017-04-13 21:50:22 | [diff] [blame] | 307 | FROM_HERE, base::BindOnce(&ProxyImpl::SetVisibleOnImpl, |
| 308 | base::Unretained(proxy_impl_.get()), visible)); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 309 | } |
| 310 | |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 311 | void ProxyMain::SetNeedsAnimate() { |
| 312 | DCHECK(IsMainThread()); |
| 313 | if (SendCommitRequestToImplThreadIfNeeded(ANIMATE_PIPELINE_STAGE)) { |
| 314 | TRACE_EVENT_INSTANT0("cc", "ProxyMain::SetNeedsAnimate", |
| 315 | TRACE_EVENT_SCOPE_THREAD); |
| 316 | } |
| 317 | } |
| 318 | |
| 319 | void ProxyMain::SetNeedsUpdateLayers() { |
| 320 | DCHECK(IsMainThread()); |
| 321 | // If we are currently animating, make sure we also update the layers. |
| 322 | if (current_pipeline_stage_ == ANIMATE_PIPELINE_STAGE) { |
| 323 | final_pipeline_stage_ = |
| 324 | std::max(final_pipeline_stage_, UPDATE_LAYERS_PIPELINE_STAGE); |
| 325 | return; |
| 326 | } |
| 327 | if (SendCommitRequestToImplThreadIfNeeded(UPDATE_LAYERS_PIPELINE_STAGE)) { |
| 328 | TRACE_EVENT_INSTANT0("cc", "ProxyMain::SetNeedsUpdateLayers", |
| 329 | TRACE_EVENT_SCOPE_THREAD); |
| 330 | } |
| 331 | } |
| 332 | |
| 333 | void ProxyMain::SetNeedsCommit() { |
| 334 | DCHECK(IsMainThread()); |
| 335 | // If we are currently animating, make sure we don't skip the commit. Note |
| 336 | // that requesting a commit during the layer update stage means we need to |
| 337 | // schedule another full commit. |
| 338 | if (current_pipeline_stage_ == ANIMATE_PIPELINE_STAGE) { |
| 339 | final_pipeline_stage_ = |
| 340 | std::max(final_pipeline_stage_, COMMIT_PIPELINE_STAGE); |
| 341 | return; |
| 342 | } |
| 343 | if (SendCommitRequestToImplThreadIfNeeded(COMMIT_PIPELINE_STAGE)) { |
| 344 | TRACE_EVENT_INSTANT0("cc", "ProxyMain::SetNeedsCommit", |
| 345 | TRACE_EVENT_SCOPE_THREAD); |
| 346 | } |
| 347 | } |
| 348 | |
| 349 | void ProxyMain::SetNeedsRedraw(const gfx::Rect& damage_rect) { |
| 350 | TRACE_EVENT0("cc", "ProxyMain::SetNeedsRedraw"); |
| 351 | DCHECK(IsMainThread()); |
khushalsagar | 12020cd4 | 2016-11-21 09:22:48 | [diff] [blame] | 352 | ImplThreadTaskRunner()->PostTask( |
tzik | 4604bb5 | 2017-04-13 21:50:22 | [diff] [blame] | 353 | FROM_HERE, |
| 354 | base::BindOnce(&ProxyImpl::SetNeedsRedrawOnImpl, |
| 355 | base::Unretained(proxy_impl_.get()), damage_rect)); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 356 | } |
| 357 | |
| 358 | void ProxyMain::SetNextCommitWaitsForActivation() { |
| 359 | DCHECK(IsMainThread()); |
| 360 | commit_waits_for_activation_ = true; |
| 361 | } |
| 362 | |
| 363 | void ProxyMain::NotifyInputThrottledUntilCommit() { |
| 364 | DCHECK(IsMainThread()); |
khushalsagar | 12020cd4 | 2016-11-21 09:22:48 | [diff] [blame] | 365 | ImplThreadTaskRunner()->PostTask( |
tzik | 4604bb5 | 2017-04-13 21:50:22 | [diff] [blame] | 366 | FROM_HERE, base::BindOnce(&ProxyImpl::SetInputThrottledUntilCommitOnImpl, |
| 367 | base::Unretained(proxy_impl_.get()), true)); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 368 | } |
| 369 | |
| 370 | void ProxyMain::SetDeferCommits(bool defer_commits) { |
| 371 | DCHECK(IsMainThread()); |
| 372 | if (defer_commits_ == defer_commits) |
| 373 | return; |
| 374 | |
| 375 | defer_commits_ = defer_commits; |
| 376 | if (defer_commits_) |
| 377 | TRACE_EVENT_ASYNC_BEGIN0("cc", "ProxyMain::SetDeferCommits", this); |
| 378 | else |
| 379 | TRACE_EVENT_ASYNC_END0("cc", "ProxyMain::SetDeferCommits", this); |
| 380 | |
khushalsagar | 12020cd4 | 2016-11-21 09:22:48 | [diff] [blame] | 381 | ImplThreadTaskRunner()->PostTask( |
| 382 | FROM_HERE, |
tzik | 4604bb5 | 2017-04-13 21:50:22 | [diff] [blame] | 383 | base::BindOnce(&ProxyImpl::SetDeferCommitsOnImpl, |
| 384 | base::Unretained(proxy_impl_.get()), defer_commits)); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 385 | } |
| 386 | |
| 387 | bool ProxyMain::CommitRequested() const { |
| 388 | DCHECK(IsMainThread()); |
| 389 | // TODO(skyostil): Split this into something like CommitRequested() and |
| 390 | // CommitInProgress(). |
| 391 | return current_pipeline_stage_ != NO_PIPELINE_STAGE || |
| 392 | max_requested_pipeline_stage_ >= COMMIT_PIPELINE_STAGE; |
| 393 | } |
| 394 | |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 395 | void ProxyMain::MainThreadHasStoppedFlinging() { |
| 396 | DCHECK(IsMainThread()); |
khushalsagar | 12020cd4 | 2016-11-21 09:22:48 | [diff] [blame] | 397 | ImplThreadTaskRunner()->PostTask( |
tzik | 4604bb5 | 2017-04-13 21:50:22 | [diff] [blame] | 398 | FROM_HERE, base::BindOnce(&ProxyImpl::MainThreadHasStoppedFlingingOnImpl, |
| 399 | base::Unretained(proxy_impl_.get()))); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 400 | } |
| 401 | |
enne | 2b0ad68 | 2016-09-21 01:44:47 | [diff] [blame] | 402 | void ProxyMain::Start() { |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 403 | DCHECK(IsMainThread()); |
khushalsagar | c7eae9d | 2016-11-12 04:43:42 | [diff] [blame] | 404 | DCHECK(layer_tree_host_->IsThreaded()); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 405 | |
khushalsagar | 12020cd4 | 2016-11-21 09:22:48 | [diff] [blame] | 406 | { |
| 407 | DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_); |
| 408 | CompletionEvent completion; |
| 409 | ImplThreadTaskRunner()->PostTask( |
tzik | 4604bb5 | 2017-04-13 21:50:22 | [diff] [blame] | 410 | FROM_HERE, base::BindOnce(&ProxyMain::InitializeOnImplThread, |
| 411 | base::Unretained(this), &completion)); |
khushalsagar | 12020cd4 | 2016-11-21 09:22:48 | [diff] [blame] | 412 | completion.Wait(); |
| 413 | } |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 414 | |
| 415 | started_ = true; |
| 416 | } |
| 417 | |
| 418 | void ProxyMain::Stop() { |
| 419 | TRACE_EVENT0("cc", "ProxyMain::Stop"); |
| 420 | DCHECK(IsMainThread()); |
| 421 | DCHECK(started_); |
| 422 | |
khushalsagar | 12020cd4 | 2016-11-21 09:22:48 | [diff] [blame] | 423 | // Synchronously finishes pending GL operations and deletes the impl. |
| 424 | // The two steps are done as separate post tasks, so that tasks posted |
| 425 | // by the GL implementation due to the Finish can be executed by the |
| 426 | // renderer before shutting it down. |
| 427 | { |
| 428 | DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_); |
| 429 | CompletionEvent completion; |
| 430 | ImplThreadTaskRunner()->PostTask( |
| 431 | FROM_HERE, |
tzik | 4604bb5 | 2017-04-13 21:50:22 | [diff] [blame] | 432 | base::BindOnce(&ProxyImpl::FinishGLOnImpl, |
| 433 | base::Unretained(proxy_impl_.get()), &completion)); |
khushalsagar | 12020cd4 | 2016-11-21 09:22:48 | [diff] [blame] | 434 | completion.Wait(); |
| 435 | } |
| 436 | { |
| 437 | DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_); |
| 438 | CompletionEvent completion; |
| 439 | ImplThreadTaskRunner()->PostTask( |
tzik | 4604bb5 | 2017-04-13 21:50:22 | [diff] [blame] | 440 | FROM_HERE, base::BindOnce(&ProxyMain::DestroyProxyImplOnImplThread, |
| 441 | base::Unretained(this), &completion)); |
khushalsagar | 12020cd4 | 2016-11-21 09:22:48 | [diff] [blame] | 442 | completion.Wait(); |
| 443 | } |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 444 | |
khushalsagar | 12020cd4 | 2016-11-21 09:22:48 | [diff] [blame] | 445 | weak_factory_.InvalidateWeakPtrs(); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 446 | layer_tree_host_ = nullptr; |
| 447 | started_ = false; |
| 448 | } |
| 449 | |
flackr | f54e9b4 | 2016-05-31 15:20:10 | [diff] [blame] | 450 | void ProxyMain::SetMutator(std::unique_ptr<LayerTreeMutator> mutator) { |
| 451 | TRACE_EVENT0("compositor-worker", "ThreadProxy::SetMutator"); |
khushalsagar | 12020cd4 | 2016-11-21 09:22:48 | [diff] [blame] | 452 | ImplThreadTaskRunner()->PostTask( |
tzik | 4604bb5 | 2017-04-13 21:50:22 | [diff] [blame] | 453 | FROM_HERE, base::BindOnce(&ProxyImpl::InitializeMutatorOnImpl, |
| 454 | base::Unretained(proxy_impl_.get()), |
| 455 | base::Passed(std::move(mutator)))); |
flackr | f54e9b4 | 2016-05-31 15:20:10 | [diff] [blame] | 456 | } |
| 457 | |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 458 | bool ProxyMain::SupportsImplScrolling() const { |
| 459 | return true; |
| 460 | } |
| 461 | |
| 462 | bool ProxyMain::MainFrameWillHappenForTesting() { |
| 463 | DCHECK(IsMainThread()); |
| 464 | bool main_frame_will_happen = false; |
| 465 | { |
| 466 | DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_); |
| 467 | CompletionEvent completion; |
khushalsagar | 12020cd4 | 2016-11-21 09:22:48 | [diff] [blame] | 468 | ImplThreadTaskRunner()->PostTask( |
tzik | 4604bb5 | 2017-04-13 21:50:22 | [diff] [blame] | 469 | FROM_HERE, |
| 470 | base::BindOnce(&ProxyImpl::MainFrameWillHappenOnImplForTesting, |
| 471 | base::Unretained(proxy_impl_.get()), &completion, |
| 472 | &main_frame_will_happen)); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 473 | completion.Wait(); |
| 474 | } |
| 475 | return main_frame_will_happen; |
| 476 | } |
| 477 | |
danakj | c7afae5 | 2017-06-20 21:12:41 | [diff] [blame^] | 478 | void ProxyMain::ReleaseLayerTreeFrameSink() { |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 479 | DCHECK(IsMainThread()); |
samans | 44b6dfc | 2017-04-19 16:50:53 | [diff] [blame] | 480 | frame_sink_bound_weak_factory_.InvalidateWeakPtrs(); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 481 | DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_); |
| 482 | CompletionEvent completion; |
khushalsagar | 12020cd4 | 2016-11-21 09:22:48 | [diff] [blame] | 483 | ImplThreadTaskRunner()->PostTask( |
tzik | 4604bb5 | 2017-04-13 21:50:22 | [diff] [blame] | 484 | FROM_HERE, |
danakj | c7afae5 | 2017-06-20 21:12:41 | [diff] [blame^] | 485 | base::BindOnce(&ProxyImpl::ReleaseLayerTreeFrameSinkOnImpl, |
tzik | 4604bb5 | 2017-04-13 21:50:22 | [diff] [blame] | 486 | base::Unretained(proxy_impl_.get()), &completion)); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 487 | completion.Wait(); |
| 488 | } |
| 489 | |
mdjones | 2ee41afd | 2016-10-27 16:50:20 | [diff] [blame] | 490 | void ProxyMain::UpdateBrowserControlsState(BrowserControlsState constraints, |
| 491 | BrowserControlsState current, |
| 492 | bool animate) { |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 493 | DCHECK(IsMainThread()); |
khushalsagar | 12020cd4 | 2016-11-21 09:22:48 | [diff] [blame] | 494 | ImplThreadTaskRunner()->PostTask( |
tzik | 4604bb5 | 2017-04-13 21:50:22 | [diff] [blame] | 495 | FROM_HERE, base::BindOnce(&ProxyImpl::UpdateBrowserControlsStateOnImpl, |
| 496 | base::Unretained(proxy_impl_.get()), |
| 497 | constraints, current, animate)); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 498 | } |
| 499 | |
Dan Elphick | 95929fd5 | 2017-06-13 09:15:07 | [diff] [blame] | 500 | void ProxyMain::RequestBeginMainFrameNotExpected(bool new_state) { |
| 501 | DCHECK(IsMainThread()); |
| 502 | ImplThreadTaskRunner()->PostTask( |
| 503 | FROM_HERE, |
| 504 | base::BindOnce(&ProxyImpl::RequestBeginMainFrameNotExpected, |
| 505 | base::Unretained(proxy_impl_.get()), new_state)); |
| 506 | } |
| 507 | |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 508 | bool ProxyMain::SendCommitRequestToImplThreadIfNeeded( |
| 509 | CommitPipelineStage required_stage) { |
| 510 | DCHECK(IsMainThread()); |
| 511 | DCHECK_NE(NO_PIPELINE_STAGE, required_stage); |
| 512 | bool already_posted = max_requested_pipeline_stage_ != NO_PIPELINE_STAGE; |
| 513 | max_requested_pipeline_stage_ = |
| 514 | std::max(max_requested_pipeline_stage_, required_stage); |
| 515 | if (already_posted) |
| 516 | return false; |
khushalsagar | 12020cd4 | 2016-11-21 09:22:48 | [diff] [blame] | 517 | ImplThreadTaskRunner()->PostTask( |
tzik | 4604bb5 | 2017-04-13 21:50:22 | [diff] [blame] | 518 | FROM_HERE, base::BindOnce(&ProxyImpl::SetNeedsCommitOnImpl, |
| 519 | base::Unretained(proxy_impl_.get()))); |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 520 | return true; |
| 521 | } |
| 522 | |
| 523 | bool ProxyMain::IsMainThread() const { |
| 524 | return task_runner_provider_->IsMainThread(); |
| 525 | } |
| 526 | |
khushalsagar | 12020cd4 | 2016-11-21 09:22:48 | [diff] [blame] | 527 | bool ProxyMain::IsImplThread() const { |
| 528 | return task_runner_provider_->IsImplThread(); |
| 529 | } |
| 530 | |
| 531 | base::SingleThreadTaskRunner* ProxyMain::ImplThreadTaskRunner() { |
| 532 | return task_runner_provider_->ImplThreadTaskRunner(); |
| 533 | } |
| 534 | |
khushalsagar | 0a226af | 2015-12-09 10:30:20 | [diff] [blame] | 535 | } // namespace cc |