| OLD | NEW |
| (Empty) |
| 1 // Copyright 2016 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/remote_channel_main.h" | |
| 6 | |
| 7 #include <memory> | |
| 8 | |
| 9 #include "base/memory/ptr_util.h" | |
| 10 #include "cc/proto/base_conversions.h" | |
| 11 #include "cc/proto/compositor_message.pb.h" | |
| 12 #include "cc/proto/compositor_message_to_impl.pb.h" | |
| 13 #include "cc/proto/compositor_message_to_main.pb.h" | |
| 14 #include "cc/proto/gfx_conversions.h" | |
| 15 #include "cc/trees/layer_tree_host_in_process.h" | |
| 16 #include "cc/trees/proxy_main.h" | |
| 17 | |
| 18 namespace cc { | |
| 19 | |
| 20 std::unique_ptr<RemoteChannelMain> RemoteChannelMain::Create( | |
| 21 RemoteProtoChannel* remote_proto_channel, | |
| 22 ProxyMain* proxy_main, | |
| 23 TaskRunnerProvider* task_runner_provider) { | |
| 24 return base::WrapUnique(new RemoteChannelMain( | |
| 25 remote_proto_channel, proxy_main, task_runner_provider)); | |
| 26 } | |
| 27 | |
| 28 RemoteChannelMain::RemoteChannelMain(RemoteProtoChannel* remote_proto_channel, | |
| 29 ProxyMain* proxy_main, | |
| 30 TaskRunnerProvider* task_runner_provider) | |
| 31 : remote_proto_channel_(remote_proto_channel), | |
| 32 proxy_main_(proxy_main), | |
| 33 task_runner_provider_(task_runner_provider), | |
| 34 initialized_(false), | |
| 35 weak_factory_(this) { | |
| 36 TRACE_EVENT0("cc.remote", "RemoteChannelMain::RemoteChannelMain"); | |
| 37 DCHECK(remote_proto_channel_); | |
| 38 DCHECK(proxy_main_); | |
| 39 DCHECK(task_runner_provider_); | |
| 40 DCHECK(task_runner_provider_->IsMainThread()); | |
| 41 remote_proto_channel_->SetProtoReceiver(this); | |
| 42 } | |
| 43 | |
| 44 RemoteChannelMain::~RemoteChannelMain() { | |
| 45 TRACE_EVENT0("cc.remote", "~RemoteChannelMain::RemoteChannelMain"); | |
| 46 DCHECK(task_runner_provider_->IsMainThread()); | |
| 47 DCHECK(!initialized_); | |
| 48 | |
| 49 remote_proto_channel_->SetProtoReceiver(nullptr); | |
| 50 } | |
| 51 | |
| 52 void RemoteChannelMain::OnProtoReceived( | |
| 53 std::unique_ptr<proto::CompositorMessage> proto) { | |
| 54 TRACE_EVENT0("cc.remote", "RemoteChannelMain::OnProtoReceived"); | |
| 55 DCHECK(task_runner_provider_->IsMainThread()); | |
| 56 DCHECK(proto->has_to_main()); | |
| 57 | |
| 58 HandleProto(proto->to_main()); | |
| 59 } | |
| 60 | |
| 61 void RemoteChannelMain::UpdateBrowserControlsStateOnImpl( | |
| 62 BrowserControlsState constraints, | |
| 63 BrowserControlsState current, | |
| 64 bool animate) {} | |
| 65 | |
| 66 void RemoteChannelMain::InitializeCompositorFrameSinkOnImpl( | |
| 67 CompositorFrameSink*) { | |
| 68 NOTREACHED() << "Should not be called on the server LayerTreeHost"; | |
| 69 } | |
| 70 | |
| 71 void RemoteChannelMain::InitializeMutatorOnImpl( | |
| 72 std::unique_ptr<LayerTreeMutator> mutator) { | |
| 73 // TODO(vollick): add support for CompositorWorker. | |
| 74 NOTIMPLEMENTED(); | |
| 75 } | |
| 76 | |
| 77 void RemoteChannelMain::MainThreadHasStoppedFlingingOnImpl() { | |
| 78 NOTIMPLEMENTED(); | |
| 79 } | |
| 80 | |
| 81 void RemoteChannelMain::SetInputThrottledUntilCommitOnImpl(bool is_throttled) {} | |
| 82 | |
| 83 void RemoteChannelMain::SetDeferCommitsOnImpl(bool defer_commits) { | |
| 84 TRACE_EVENT1("cc.remote", "RemoteChannelMain::SetDeferCommitsOnImpl", | |
| 85 "defer_commits", defer_commits); | |
| 86 proto::CompositorMessage proto; | |
| 87 proto::CompositorMessageToImpl* to_impl_proto = proto.mutable_to_impl(); | |
| 88 to_impl_proto->set_message_type( | |
| 89 proto::CompositorMessageToImpl::SET_DEFER_COMMITS); | |
| 90 proto::SetDeferCommits* defer_commits_message = | |
| 91 to_impl_proto->mutable_defer_commits_message(); | |
| 92 defer_commits_message->set_defer_commits(defer_commits); | |
| 93 | |
| 94 VLOG(1) << "Sending defer commits: " << defer_commits << " to client."; | |
| 95 SendMessageProto(proto); | |
| 96 } | |
| 97 | |
| 98 void RemoteChannelMain::SetVisibleOnImpl(bool visible) { | |
| 99 NOTIMPLEMENTED() << "Visibility is not controlled by the server"; | |
| 100 } | |
| 101 | |
| 102 void RemoteChannelMain::ReleaseCompositorFrameSinkOnImpl( | |
| 103 CompletionEvent* completion) { | |
| 104 NOTREACHED() << "Should not be called on the server LayerTreeHost"; | |
| 105 completion->Signal(); | |
| 106 } | |
| 107 | |
| 108 void RemoteChannelMain::MainFrameWillHappenOnImplForTesting( | |
| 109 CompletionEvent* completion, | |
| 110 bool* main_frame_will_happen) { | |
| 111 // For the LayerTreeTests in remote mode, LayerTreeTest directly calls | |
| 112 // RemoteChannelImpl::MainFrameWillHappenForTesting and avoids adding a | |
| 113 // message type for tests to the compositor protocol. | |
| 114 NOTREACHED(); | |
| 115 } | |
| 116 | |
| 117 void RemoteChannelMain::SetNeedsRedrawOnImpl(const gfx::Rect& damage_rect) { | |
| 118 TRACE_EVENT0("cc.remote", "RemoteChannelMain::SetNeedsRedrawOnImpl"); | |
| 119 proto::CompositorMessage proto; | |
| 120 proto::CompositorMessageToImpl* to_impl_proto = proto.mutable_to_impl(); | |
| 121 to_impl_proto->set_message_type( | |
| 122 proto::CompositorMessageToImpl::SET_NEEDS_REDRAW); | |
| 123 proto::SetNeedsRedraw* set_needs_redraw_message = | |
| 124 to_impl_proto->mutable_set_needs_redraw_message(); | |
| 125 RectToProto(damage_rect, set_needs_redraw_message->mutable_damaged_rect()); | |
| 126 | |
| 127 VLOG(1) << "Sending redraw request to client."; | |
| 128 SendMessageProto(proto); | |
| 129 | |
| 130 // The client will not inform us when the frame buffers are swapped. | |
| 131 MainThreadTaskRunner()->PostTask( | |
| 132 FROM_HERE, base::Bind(&RemoteChannelMain::DidReceiveCompositorFrameAck, | |
| 133 weak_factory_.GetWeakPtr())); | |
| 134 } | |
| 135 | |
| 136 void RemoteChannelMain::SetNeedsCommitOnImpl() { | |
| 137 TRACE_EVENT0("cc.remote", "RemoteChannelMain::SetNeedsCommitOnImpl"); | |
| 138 proto::CompositorMessage proto; | |
| 139 proto::CompositorMessageToImpl* to_impl_proto = proto.mutable_to_impl(); | |
| 140 to_impl_proto->set_message_type( | |
| 141 proto::CompositorMessageToImpl::SET_NEEDS_COMMIT); | |
| 142 | |
| 143 VLOG(1) << "Sending commit request to client."; | |
| 144 SendMessageProto(proto); | |
| 145 } | |
| 146 | |
| 147 void RemoteChannelMain::BeginMainFrameAbortedOnImpl( | |
| 148 CommitEarlyOutReason reason, | |
| 149 base::TimeTicks main_thread_start_time, | |
| 150 std::vector<std::unique_ptr<SwapPromise>> swap_promises) { | |
| 151 TRACE_EVENT1("cc.remote", "RemoteChannelMain::BeginMainFrameAbortedOnImpl", | |
| 152 "reason", CommitEarlyOutReasonToString(reason)); | |
| 153 proto::CompositorMessage proto; | |
| 154 proto::CompositorMessageToImpl* to_impl_proto = proto.mutable_to_impl(); | |
| 155 to_impl_proto->set_message_type( | |
| 156 proto::CompositorMessageToImpl::BEGIN_MAIN_FRAME_ABORTED); | |
| 157 proto::BeginMainFrameAborted* begin_main_frame_aborted_message = | |
| 158 to_impl_proto->mutable_begin_main_frame_aborted_message(); | |
| 159 CommitEarlyOutReasonToProtobuf( | |
| 160 reason, begin_main_frame_aborted_message->mutable_reason()); | |
| 161 | |
| 162 VLOG(1) << "Sending BeginMainFrameAborted message to client with reason: " | |
| 163 << CommitEarlyOutReasonToString(reason); | |
| 164 SendMessageProto(proto); | |
| 165 | |
| 166 // Notify swap promises that commit had no updates. In the local compositor | |
| 167 // case this goes to the impl thread to be queued up in case we have an | |
| 168 // activation pending but that never happens for remote compositor. | |
| 169 for (const auto& swap_promise : swap_promises) | |
| 170 swap_promise->DidNotSwap(SwapPromise::COMMIT_NO_UPDATE); | |
| 171 } | |
| 172 | |
| 173 void RemoteChannelMain::NotifyReadyToCommitOnImpl( | |
| 174 CompletionEvent* completion, | |
| 175 LayerTreeHostInProcess* layer_tree_host, | |
| 176 base::TimeTicks main_thread_start_time, | |
| 177 bool hold_commit_for_activation) { | |
| 178 TRACE_EVENT0("cc.remote", "RemoteChannelMain::NotifyReadyToCommitOnImpl"); | |
| 179 proto::CompositorMessage proto; | |
| 180 proto::CompositorMessageToImpl* to_impl_proto = proto.mutable_to_impl(); | |
| 181 to_impl_proto->set_message_type(proto::CompositorMessageToImpl::START_COMMIT); | |
| 182 proto::StartCommit* start_commit_message = | |
| 183 to_impl_proto->mutable_start_commit_message(); | |
| 184 std::vector<std::unique_ptr<SwapPromise>> swap_promises; | |
| 185 layer_tree_host->ToProtobufForCommit( | |
| 186 start_commit_message->mutable_layer_tree_host(), &swap_promises); | |
| 187 | |
| 188 VLOG(1) << "Sending commit message to client. Commit bytes size: " | |
| 189 << proto.ByteSize(); | |
| 190 SendMessageProto(proto); | |
| 191 | |
| 192 // Activate the swap promises after the commit is queued. | |
| 193 // In the threaded compositor, activation implies that the pending tree on the | |
| 194 // impl thread has been activated. While the impl thread for the remote | |
| 195 // compositor is on the client, the embedder still expects to receive these | |
| 196 // events in order to drive decisions that depend on impl frame production. | |
| 197 // So we dispatch these events after a commit message is sent to the client. | |
| 198 // Sending the commit message implies that a visual update has been queued for | |
| 199 // the client, which is the closest we can come to offering an indicator akin | |
| 200 // to an impl frame queued for display. | |
| 201 for (const auto& swap_promise : swap_promises) | |
| 202 swap_promise->DidActivate(); | |
| 203 | |
| 204 // In order to avoid incurring the overhead for the client to send us a | |
| 205 // message for when a frame to be committed is drawn we inform the embedder | |
| 206 // that the draw was successful immediately after sending the commit message. | |
| 207 // Since the compositing state may be used by the embedder to throttle | |
| 208 // commit/draw requests, it is better to allow them to propagate rather than | |
| 209 // incurring a round-trip to get Acks for draw from the client for each frame. | |
| 210 | |
| 211 // This is done as a separate PostTask to ensure that these calls run after | |
| 212 // LayerTreeHostClient::DidCommit and stay consistent with the | |
| 213 // behaviour in the threaded compositor. | |
| 214 MainThreadTaskRunner()->PostTask( | |
| 215 FROM_HERE, base::Bind(&RemoteChannelMain::DidCommitAndDrawFrame, | |
| 216 weak_factory_.GetWeakPtr())); | |
| 217 | |
| 218 completion->Signal(); | |
| 219 } | |
| 220 | |
| 221 void RemoteChannelMain::SynchronouslyInitializeImpl( | |
| 222 LayerTreeHostInProcess* layer_tree_host) { | |
| 223 TRACE_EVENT0("cc.remote", "RemoteChannelMain::SynchronouslyInitializeImpl"); | |
| 224 DCHECK(!initialized_); | |
| 225 | |
| 226 initialized_ = true; | |
| 227 } | |
| 228 | |
| 229 void RemoteChannelMain::SynchronouslyCloseImpl() { | |
| 230 TRACE_EVENT0("cc.remote", "RemoteChannelMain::SynchronouslyCloseImpl"); | |
| 231 DCHECK(initialized_); | |
| 232 | |
| 233 initialized_ = false; | |
| 234 } | |
| 235 | |
| 236 void RemoteChannelMain::SendMessageProto( | |
| 237 const proto::CompositorMessage& proto) { | |
| 238 TRACE_EVENT0("cc.remote", "RemoteChannelMain::SendMessageProto"); | |
| 239 remote_proto_channel_->SendCompositorProto(proto); | |
| 240 } | |
| 241 | |
| 242 void RemoteChannelMain::HandleProto( | |
| 243 const proto::CompositorMessageToMain& proto) { | |
| 244 TRACE_EVENT0("cc.remote", "RemoteChannelMain::HandleProto"); | |
| 245 DCHECK(proto.has_message_type()); | |
| 246 | |
| 247 switch (proto.message_type()) { | |
| 248 case proto::CompositorMessageToMain::UNKNOWN: | |
| 249 NOTIMPLEMENTED() << "Ignoring message proto of unknown type"; | |
| 250 break; | |
| 251 case proto::CompositorMessageToMain::BEGIN_MAIN_FRAME: { | |
| 252 TRACE_EVENT0("cc.remote", "RemoteChannelMain::BeginMainFrame"); | |
| 253 VLOG(1) << "Received BeginMainFrame request from client."; | |
| 254 const proto::BeginMainFrame& begin_main_frame_message = | |
| 255 proto.begin_main_frame_message(); | |
| 256 std::unique_ptr<BeginMainFrameAndCommitState> begin_main_frame_state; | |
| 257 begin_main_frame_state.reset(new BeginMainFrameAndCommitState); | |
| 258 begin_main_frame_state->FromProtobuf( | |
| 259 begin_main_frame_message.begin_main_frame_state()); | |
| 260 proxy_main_->BeginMainFrame(std::move(begin_main_frame_state)); | |
| 261 } break; | |
| 262 } | |
| 263 } | |
| 264 | |
| 265 void RemoteChannelMain::DidCommitAndDrawFrame() { | |
| 266 proxy_main_->DidCommitAndDrawFrame(); | |
| 267 DidReceiveCompositorFrameAck(); | |
| 268 } | |
| 269 | |
| 270 void RemoteChannelMain::DidReceiveCompositorFrameAck() { | |
| 271 proxy_main_->DidReceiveCompositorFrameAck(); | |
| 272 } | |
| 273 | |
| 274 base::SingleThreadTaskRunner* RemoteChannelMain::MainThreadTaskRunner() const { | |
| 275 return task_runner_provider_->MainThreadTaskRunner(); | |
| 276 } | |
| 277 | |
| 278 } // namespace cc | |
| OLD | NEW |