| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "blimp/client/core/compositor/blimp_compositor.h" | 5 #include "blimp/client/core/compositor/blimp_compositor.h" |
| 6 | 6 |
| 7 #include "base/bind_helpers.h" | 7 #include "base/bind_helpers.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
| 10 #include "base/metrics/histogram_macros.h" | 10 #include "base/metrics/histogram_macros.h" |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 cc::Surface* surface = manager->GetSurfaceForId(id); | 53 cc::Surface* surface = manager->GetSurfaceForId(id); |
| 54 if (!surface) { | 54 if (!surface) { |
| 55 LOG(ERROR) << "Attempting to require callback on nonexistent surface"; | 55 LOG(ERROR) << "Attempting to require callback on nonexistent surface"; |
| 56 return; | 56 return; |
| 57 } | 57 } |
| 58 surface->AddDestructionDependency(sequence); | 58 surface->AddDestructionDependency(sequence); |
| 59 } | 59 } |
| 60 | 60 |
| 61 } // namespace | 61 } // namespace |
| 62 | 62 |
| 63 // static |
| 64 std::unique_ptr<BlimpCompositor> BlimpCompositor::Create( |
| 65 BlimpCompositorDependencies* compositor_dependencies, |
| 66 BlimpCompositorClient* client, |
| 67 bool use_threaded_layer_tree_host) { |
| 68 std::unique_ptr<BlimpCompositor> compositor = |
| 69 base::WrapUnique(new BlimpCompositor(compositor_dependencies, client, |
| 70 use_threaded_layer_tree_host)); |
| 71 compositor->Initialize(); |
| 72 return compositor; |
| 73 } |
| 74 |
| 63 BlimpCompositor::BlimpCompositor( | 75 BlimpCompositor::BlimpCompositor( |
| 64 BlimpCompositorDependencies* compositor_dependencies, | 76 BlimpCompositorDependencies* compositor_dependencies, |
| 65 BlimpCompositorClient* client, | 77 BlimpCompositorClient* client, |
| 66 bool use_threaded_layer_tree_host) | 78 bool use_threaded_layer_tree_host) |
| 67 : use_threaded_layer_tree_host_(use_threaded_layer_tree_host), | 79 : use_threaded_layer_tree_host_(use_threaded_layer_tree_host), |
| 68 client_(client), | 80 client_(client), |
| 69 compositor_dependencies_(compositor_dependencies), | 81 compositor_dependencies_(compositor_dependencies), |
| 70 frame_sink_id_(compositor_dependencies_->GetEmbedderDependencies() | 82 frame_sink_id_(compositor_dependencies_->GetEmbedderDependencies() |
| 71 ->AllocateFrameSinkId()), | 83 ->AllocateFrameSinkId()), |
| 72 proxy_client_(nullptr), | 84 proxy_client_(nullptr), |
| 73 compositor_frame_sink_request_pending_(false), | 85 compositor_frame_sink_request_pending_(false), |
| 74 layer_(cc::Layer::Create()), | 86 layer_(cc::Layer::Create()), |
| 75 remote_proto_channel_receiver_(nullptr), | 87 remote_proto_channel_receiver_(nullptr), |
| 76 outstanding_commits_(0U), | 88 outstanding_commits_(0U), |
| 77 weak_ptr_factory_(this) { | 89 weak_ptr_factory_(this) { |
| 78 DCHECK(thread_checker_.CalledOnValidThread()); | 90 DCHECK(thread_checker_.CalledOnValidThread()); |
| 91 } |
| 79 | 92 |
| 93 void BlimpCompositor::Initialize() { |
| 80 surface_id_allocator_ = base::MakeUnique<cc::SurfaceIdAllocator>(); | 94 surface_id_allocator_ = base::MakeUnique<cc::SurfaceIdAllocator>(); |
| 81 GetEmbedderDeps()->GetSurfaceManager()->RegisterFrameSinkId(frame_sink_id_); | 95 GetEmbedderDeps()->GetSurfaceManager()->RegisterFrameSinkId(frame_sink_id_); |
| 82 CreateLayerTreeHost(); | 96 host_ = CreateLayerTreeHost(); |
| 83 | 97 |
| 84 if (use_threaded_layer_tree_host_) { | 98 if (use_threaded_layer_tree_host_) { |
| 85 std::unique_ptr<cc::ClientPictureCache> client_picture_cache = | 99 std::unique_ptr<cc::ClientPictureCache> client_picture_cache = |
| 86 compositor_dependencies_->GetImageSerializationProcessor() | 100 compositor_dependencies_->GetImageSerializationProcessor() |
| 87 ->CreateClientPictureCache(); | 101 ->CreateClientPictureCache(); |
| 88 compositor_state_deserializer_ = | 102 compositor_state_deserializer_ = |
| 89 base::MakeUnique<cc::CompositorStateDeserializer>( | 103 base::MakeUnique<cc::CompositorStateDeserializer>( |
| 90 host_.get(), std::move(client_picture_cache), | 104 host_.get(), std::move(client_picture_cache), this); |
| 91 base::Bind(&BlimpCompositor::LayerScrolled, | |
| 92 weak_ptr_factory_.GetWeakPtr()), | |
| 93 this); | |
| 94 } | 105 } |
| 95 } | 106 } |
| 96 | 107 |
| 97 BlimpCompositor::~BlimpCompositor() { | 108 BlimpCompositor::~BlimpCompositor() { |
| 98 DCHECK(thread_checker_.CalledOnValidThread()); | 109 DCHECK(thread_checker_.CalledOnValidThread()); |
| 99 | 110 |
| 100 DestroyLayerTreeHost(); | 111 DestroyLayerTreeHost(); |
| 101 GetEmbedderDeps()->GetSurfaceManager()->InvalidateFrameSinkId(frame_sink_id_); | 112 GetEmbedderDeps()->GetSurfaceManager()->InvalidateFrameSinkId(frame_sink_id_); |
| 102 | 113 |
| 103 CheckPendingCommitCounts(true /* flush */); | 114 CheckPendingCommitCounts(true /* flush */); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 114 if (outstanding_commits_ == 0) { | 125 if (outstanding_commits_ == 0) { |
| 115 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); | 126 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); |
| 116 return; | 127 return; |
| 117 } | 128 } |
| 118 | 129 |
| 119 pending_commit_trackers_.push_back( | 130 pending_commit_trackers_.push_back( |
| 120 std::make_pair(outstanding_commits_, callback)); | 131 std::make_pair(outstanding_commits_, callback)); |
| 121 } | 132 } |
| 122 | 133 |
| 123 void BlimpCompositor::UpdateLayerTreeHost() { | 134 void BlimpCompositor::UpdateLayerTreeHost() { |
| 135 DCHECK(use_threaded_layer_tree_host_); |
| 136 |
| 137 // UpdateLayerTreeHost marks the end of reporting of any deltas from the impl |
| 138 // thread. So send a client state update if the local state was modified now. |
| 139 FlushClientState(); |
| 140 |
| 124 if (pending_frame_update_) { | 141 if (pending_frame_update_) { |
| 125 DCHECK(use_threaded_layer_tree_host_); | 142 DCHECK(use_threaded_layer_tree_host_); |
| 126 compositor_state_deserializer_->DeserializeCompositorUpdate( | 143 compositor_state_deserializer_->DeserializeCompositorUpdate( |
| 127 pending_frame_update_->layer_tree_host()); | 144 pending_frame_update_->layer_tree_host()); |
| 128 pending_frame_update_ = nullptr; | 145 pending_frame_update_ = nullptr; |
| 129 cc::proto::CompositorMessage frame_ack; | 146 cc::proto::CompositorMessage frame_ack; |
| 130 frame_ack.set_frame_ack(true); | 147 frame_ack.set_frame_ack(true); |
| 131 client_->SendCompositorMessage(frame_ack); | 148 client_->SendCompositorMessage(frame_ack); |
| 132 } | 149 } |
| 150 |
| 151 // Send back any deltas that have not yet been resolved on the main thread |
| 152 // back to the impl thread. |
| 153 compositor_state_deserializer_->SendUnappliedDeltasToLayerTreeHost(); |
| 154 } |
| 155 |
| 156 void BlimpCompositor::ApplyViewportDeltas( |
| 157 const gfx::Vector2dF& inner_delta, |
| 158 const gfx::Vector2dF& outer_delta, |
| 159 const gfx::Vector2dF& elastic_overscroll_delta, |
| 160 float page_scale, |
| 161 float top_controls_delta) { |
| 162 DCHECK(use_threaded_layer_tree_host_); |
| 163 compositor_state_deserializer_->ApplyViewportDeltas( |
| 164 inner_delta, outer_delta, elastic_overscroll_delta, page_scale, |
| 165 top_controls_delta); |
| 133 } | 166 } |
| 134 | 167 |
| 135 void BlimpCompositor::RequestNewCompositorFrameSink() { | 168 void BlimpCompositor::RequestNewCompositorFrameSink() { |
| 136 DCHECK(!surface_factory_); | 169 DCHECK(!surface_factory_); |
| 137 DCHECK(!compositor_frame_sink_request_pending_); | 170 DCHECK(!compositor_frame_sink_request_pending_); |
| 138 | 171 |
| 139 compositor_frame_sink_request_pending_ = true; | 172 compositor_frame_sink_request_pending_ = true; |
| 140 GetEmbedderDeps()->GetContextProviders( | 173 GetEmbedderDeps()->GetContextProviders( |
| 141 base::Bind(&BlimpCompositor::OnContextProvidersCreated, | 174 base::Bind(&BlimpCompositor::OnContextProvidersCreated, |
| 142 weak_ptr_factory_.GetWeakPtr())); | 175 weak_ptr_factory_.GetWeakPtr())); |
| 143 } | 176 } |
| 144 | 177 |
| 145 void BlimpCompositor::DidInitializeCompositorFrameSink() { | 178 void BlimpCompositor::DidInitializeCompositorFrameSink() { |
| 146 compositor_frame_sink_request_pending_ = false; | 179 compositor_frame_sink_request_pending_ = false; |
| 147 } | 180 } |
| 148 | 181 |
| 149 void BlimpCompositor::DidCommitAndDrawFrame() { | 182 void BlimpCompositor::DidCommitAndDrawFrame() { |
| 150 BlimpStats::GetInstance()->Add(BlimpStats::COMMIT, 1); | 183 BlimpStats::GetInstance()->Add(BlimpStats::COMMIT, 1); |
| 151 | 184 |
| 185 // TODO(khushalsagar): Fix before landing, the code here assumes that every |
| 186 // commit came from the engine. :X. |
| 187 return; |
| 188 |
| 152 DCHECK_GT(outstanding_commits_, 0U); | 189 DCHECK_GT(outstanding_commits_, 0U); |
| 153 outstanding_commits_--; | 190 outstanding_commits_--; |
| 154 | 191 |
| 155 CheckPendingCommitCounts(false /* flush */); | 192 CheckPendingCommitCounts(false /* flush */); |
| 156 } | 193 } |
| 157 | 194 |
| 158 void BlimpCompositor::SetProtoReceiver(ProtoReceiver* receiver) { | 195 void BlimpCompositor::SetProtoReceiver(ProtoReceiver* receiver) { |
| 159 DCHECK(!use_threaded_layer_tree_host_); | 196 DCHECK(!use_threaded_layer_tree_host_); |
| 160 remote_proto_channel_receiver_ = receiver; | 197 remote_proto_channel_receiver_ = receiver; |
| 161 } | 198 } |
| 162 | 199 |
| 163 void BlimpCompositor::SendCompositorProto( | 200 void BlimpCompositor::SendCompositorProto( |
| 164 const cc::proto::CompositorMessage& proto) { | 201 const cc::proto::CompositorMessage& proto) { |
| 165 DCHECK(!use_threaded_layer_tree_host_); | 202 DCHECK(!use_threaded_layer_tree_host_); |
| 166 client_->SendCompositorMessage(proto); | 203 client_->SendCompositorMessage(proto); |
| 167 } | 204 } |
| 168 | 205 |
| 169 void BlimpCompositor::OnCompositorMessageReceived( | 206 void BlimpCompositor::OnCompositorMessageReceived( |
| 170 std::unique_ptr<cc::proto::CompositorMessage> message) { | 207 std::unique_ptr<cc::proto::CompositorMessage> message) { |
| 171 if (message->has_to_impl()) { | 208 if (message->has_to_impl()) { |
| 172 HandleCompositorMessageToImpl(std::move(message)); | 209 HandleCompositorMessageToImpl(std::move(message)); |
| 173 return; | 210 return; |
| 174 } | 211 } |
| 175 | 212 |
| 176 DCHECK(use_threaded_layer_tree_host_); | 213 DCHECK(use_threaded_layer_tree_host_); |
| 177 DCHECK(message->has_layer_tree_host()) | 214 cc::proto::CompositorMessage* message_received = message.get(); |
| 178 << "The engine only sends frame updates"; | |
| 179 DCHECK(!pending_frame_update_) | |
| 180 << "We should have only a single frame in flight"; | |
| 181 | 215 |
| 182 UMA_HISTOGRAM_MEMORY_KB("Blimp.Compositor.CommitSizeKb", | 216 if (message_received->has_layer_tree_host()) { |
| 183 (float)message->ByteSize() / 1024); | 217 DCHECK(!pending_frame_update_) |
| 184 pending_frame_update_ = std::move(message); | 218 << "We should have only a single frame in flight"; |
| 185 outstanding_commits_++; | 219 |
| 186 host_->SetNeedsAnimate(); | 220 UMA_HISTOGRAM_MEMORY_KB("Blimp.Compositor.CommitSizeKb", |
| 221 (float)message->ByteSize() / 1024); |
| 222 pending_frame_update_ = std::move(message); |
| 223 outstanding_commits_++; |
| 224 host_->SetNeedsAnimate(); |
| 225 } |
| 226 |
| 227 if (message_received->client_state_update_ack()) { |
| 228 DCHECK(client_state_update_ack_pending_); |
| 229 |
| 230 client_state_update_ack_pending_ = false; |
| 231 compositor_state_deserializer_->DidApplyStateUpdatesOnEngine(); |
| 232 |
| 233 // If there are any updates that we have queued because we were waiting for |
| 234 // an ack, send them now. |
| 235 FlushClientState(); |
| 236 } |
| 187 } | 237 } |
| 188 | 238 |
| 189 void BlimpCompositor::HandleCompositorMessageToImpl( | 239 void BlimpCompositor::HandleCompositorMessageToImpl( |
| 190 std::unique_ptr<cc::proto::CompositorMessage> message) { | 240 std::unique_ptr<cc::proto::CompositorMessage> message) { |
| 191 DCHECK(!use_threaded_layer_tree_host_); | 241 DCHECK(!use_threaded_layer_tree_host_); |
| 192 DCHECK(message->has_to_impl()); | 242 DCHECK(message->has_to_impl()); |
| 193 | 243 |
| 194 const cc::proto::CompositorMessageToImpl to_impl_proto = message->to_impl(); | 244 const cc::proto::CompositorMessageToImpl to_impl_proto = message->to_impl(); |
| 195 DCHECK(to_impl_proto.has_message_type()); | 245 DCHECK(to_impl_proto.has_message_type()); |
| 196 | 246 |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 void BlimpCompositor::ReturnResources( | 365 void BlimpCompositor::ReturnResources( |
| 316 const cc::ReturnedResourceArray& resources) { | 366 const cc::ReturnedResourceArray& resources) { |
| 317 DCHECK(surface_factory_); | 367 DCHECK(surface_factory_); |
| 318 compositor_dependencies_->GetCompositorTaskRunner()->PostTask( | 368 compositor_dependencies_->GetCompositorTaskRunner()->PostTask( |
| 319 FROM_HERE, | 369 FROM_HERE, |
| 320 base::Bind( | 370 base::Bind( |
| 321 &BlimpCompositorFrameSinkProxyClient::ReclaimCompositorResources, | 371 &BlimpCompositorFrameSinkProxyClient::ReclaimCompositorResources, |
| 322 proxy_client_, resources)); | 372 proxy_client_, resources)); |
| 323 } | 373 } |
| 324 | 374 |
| 325 bool BlimpCompositor::ShouldRetainClientScroll( | 375 void BlimpCompositor::DidUpdateLocalState() { |
| 326 int engine_layer_id, | 376 client_state_dirty_ = true; |
| 327 const gfx::ScrollOffset& new_offset) { | |
| 328 // TODO(khushalsagar): Update when adding scroll/scale sync. See | |
| 329 // crbug.com/648442. | |
| 330 return true; | |
| 331 } | 377 } |
| 332 | 378 |
| 333 bool BlimpCompositor::ShouldRetainClientPageScale(float new_page_scale) { | 379 void BlimpCompositor::FlushClientState() { |
| 334 // TODO(khushalsagar): Update when adding scroll/scale sync. See | 380 // If the client state has not been modified, we don't need to send an update. |
| 335 // crbug.com/648442. | 381 if (!client_state_dirty_) |
| 336 return true; | 382 return; |
| 337 } | |
| 338 | 383 |
| 339 void BlimpCompositor::LayerScrolled(int engine_layer_id) { | 384 // If we had sent an update and an ack for it is still pending, we can't send |
| 340 DCHECK(use_threaded_layer_tree_host_); | 385 // another update till the ack is received. |
| 386 if (client_state_update_ack_pending_) |
| 387 return; |
| 388 |
| 389 cc::proto::CompositorMessage message; |
| 390 message.set_frame_ack(false); |
| 391 compositor_state_deserializer_->PullClientStateUpdate( |
| 392 message.mutable_client_state_update()); |
| 393 |
| 394 client_state_dirty_ = false; |
| 395 client_state_update_ack_pending_ = true; |
| 396 client_->SendCompositorMessage(message); |
| 341 } | 397 } |
| 342 | 398 |
| 343 CompositorDependencies* BlimpCompositor::GetEmbedderDeps() { | 399 CompositorDependencies* BlimpCompositor::GetEmbedderDeps() { |
| 344 return compositor_dependencies_->GetEmbedderDependencies(); | 400 return compositor_dependencies_->GetEmbedderDependencies(); |
| 345 } | 401 } |
| 346 | 402 |
| 347 void BlimpCompositor::DestroyDelegatedContent() { | 403 void BlimpCompositor::DestroyDelegatedContent() { |
| 348 if (local_frame_id_.is_null()) | 404 if (local_frame_id_.is_null()) |
| 349 return; | 405 return; |
| 350 | 406 |
| 351 // Remove any references for the surface layer that uses this | 407 // Remove any references for the surface layer that uses this |
| 352 // |local_frame_id_|. | 408 // |local_frame_id_|. |
| 353 layer_->RemoveAllChildren(); | 409 layer_->RemoveAllChildren(); |
| 354 surface_factory_->Destroy(local_frame_id_); | 410 surface_factory_->Destroy(local_frame_id_); |
| 355 local_frame_id_ = cc::LocalFrameId(); | 411 local_frame_id_ = cc::LocalFrameId(); |
| 356 } | 412 } |
| 357 | 413 |
| 358 void BlimpCompositor::CreateLayerTreeHost() { | 414 std::unique_ptr<cc::LayerTreeHostInProcess> |
| 359 DCHECK(!host_); | 415 BlimpCompositor::CreateLayerTreeHost() { |
| 360 VLOG(1) << "Creating LayerTreeHost."; | 416 std::unique_ptr<cc::LayerTreeHostInProcess> host; |
| 361 | 417 |
| 362 // Create the LayerTreeHost | |
| 363 cc::LayerTreeHostInProcess::InitParams params; | 418 cc::LayerTreeHostInProcess::InitParams params; |
| 364 params.client = this; | 419 params.client = this; |
| 365 params.task_graph_runner = compositor_dependencies_->GetTaskGraphRunner(); | 420 params.task_graph_runner = compositor_dependencies_->GetTaskGraphRunner(); |
| 366 params.gpu_memory_buffer_manager = | 421 params.gpu_memory_buffer_manager = |
| 367 GetEmbedderDeps()->GetGpuMemoryBufferManager(); | 422 GetEmbedderDeps()->GetGpuMemoryBufferManager(); |
| 368 params.main_task_runner = base::ThreadTaskRunnerHandle::Get(); | 423 params.main_task_runner = base::ThreadTaskRunnerHandle::Get(); |
| 369 if (!use_threaded_layer_tree_host_) { | 424 if (!use_threaded_layer_tree_host_) { |
| 370 params.image_serialization_processor = | 425 params.image_serialization_processor = |
| 371 compositor_dependencies_->GetImageSerializationProcessor(); | 426 compositor_dependencies_->GetImageSerializationProcessor(); |
| 372 } | 427 } |
| 373 | 428 |
| 374 cc::LayerTreeSettings* settings = | 429 cc::LayerTreeSettings* settings = |
| 375 compositor_dependencies_->GetLayerTreeSettings(); | 430 compositor_dependencies_->GetLayerTreeSettings(); |
| 376 params.settings = settings; | 431 params.settings = settings; |
| 377 | 432 |
| 378 params.animation_host = cc::AnimationHost::CreateMainInstance(); | 433 params.animation_host = cc::AnimationHost::CreateMainInstance(); |
| 379 | 434 |
| 380 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner = | 435 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner = |
| 381 compositor_dependencies_->GetCompositorTaskRunner(); | 436 compositor_dependencies_->GetCompositorTaskRunner(); |
| 382 | 437 |
| 383 if (use_threaded_layer_tree_host_) { | 438 if (use_threaded_layer_tree_host_) { |
| 384 host_ = cc::LayerTreeHostInProcess::CreateThreaded(compositor_task_runner, | 439 host = cc::LayerTreeHostInProcess::CreateThreaded(compositor_task_runner, |
| 385 ¶ms); | 440 ¶ms); |
| 386 } else { | 441 } else { |
| 387 host_ = cc::LayerTreeHostInProcess::CreateRemoteClient( | 442 host = cc::LayerTreeHostInProcess::CreateRemoteClient( |
| 388 this /* remote_proto_channel */, compositor_task_runner, ¶ms); | 443 this /* remote_proto_channel */, compositor_task_runner, ¶ms); |
| 389 } | 444 } |
| 445 |
| 446 return host; |
| 390 } | 447 } |
| 391 | 448 |
| 392 void BlimpCompositor::DestroyLayerTreeHost() { | 449 void BlimpCompositor::DestroyLayerTreeHost() { |
| 393 DCHECK(host_); | 450 DCHECK(host_); |
| 394 VLOG(1) << "Destroying LayerTreeHost."; | |
| 395 | 451 |
| 396 // Tear down the output surface connection with the old LayerTreeHost | 452 // Tear down the output surface connection with the old LayerTreeHost |
| 397 // instance. | 453 // instance. |
| 398 DestroyDelegatedContent(); | 454 DestroyDelegatedContent(); |
| 399 surface_factory_.reset(); | 455 surface_factory_.reset(); |
| 400 | 456 |
| 401 // Destroy the old LayerTreeHost state. | 457 // Destroy the old LayerTreeHost state. |
| 402 host_.reset(); | 458 host_.reset(); |
| 403 | 459 |
| 404 // Cancel any outstanding CompositorFrameSink requests. That way if we get an | 460 // Cancel any outstanding CompositorFrameSink requests. That way if we get an |
| (...skipping 11 matching lines...) Expand all Loading... |
| 416 it->second.Run(); | 472 it->second.Run(); |
| 417 it = pending_commit_trackers_.erase(it); | 473 it = pending_commit_trackers_.erase(it); |
| 418 } else { | 474 } else { |
| 419 ++it; | 475 ++it; |
| 420 } | 476 } |
| 421 } | 477 } |
| 422 } | 478 } |
| 423 | 479 |
| 424 } // namespace client | 480 } // namespace client |
| 425 } // namespace blimp | 481 } // namespace blimp |
| OLD | NEW |