Chromium Code Reviews| 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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 109 return DidNotSwapAction::BREAK_PROMISE; | 109 return DidNotSwapAction::BREAK_PROMISE; |
| 110 } | 110 } |
| 111 int64_t TraceId() const override { return 0; } | 111 int64_t TraceId() const override { return 0; } |
| 112 | 112 |
| 113 private: | 113 private: |
| 114 std::unique_ptr<cc::CopyOutputRequest> copy_request_; | 114 std::unique_ptr<cc::CopyOutputRequest> copy_request_; |
| 115 base::WeakPtr<BlimpCompositor> compositor_weak_ptr_; | 115 base::WeakPtr<BlimpCompositor> compositor_weak_ptr_; |
| 116 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; | 116 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; |
| 117 }; | 117 }; |
| 118 | 118 |
| 119 // static | |
| 120 std::unique_ptr<BlimpCompositor> BlimpCompositor::Create( | |
| 121 BlimpCompositorDependencies* compositor_dependencies, | |
| 122 BlimpCompositorClient* client, | |
| 123 bool use_threaded_layer_tree_host) { | |
| 124 std::unique_ptr<BlimpCompositor> compositor = | |
| 125 base::WrapUnique(new BlimpCompositor(compositor_dependencies, client, | |
| 126 use_threaded_layer_tree_host)); | |
| 127 compositor->Initialize(); | |
| 128 return compositor; | |
| 129 } | |
| 130 | |
| 119 BlimpCompositor::BlimpCompositor( | 131 BlimpCompositor::BlimpCompositor( |
| 120 BlimpCompositorDependencies* compositor_dependencies, | 132 BlimpCompositorDependencies* compositor_dependencies, |
| 121 BlimpCompositorClient* client, | 133 BlimpCompositorClient* client, |
| 122 bool use_threaded_layer_tree_host) | 134 bool use_threaded_layer_tree_host) |
| 123 : use_threaded_layer_tree_host_(use_threaded_layer_tree_host), | 135 : use_threaded_layer_tree_host_(use_threaded_layer_tree_host), |
| 124 client_(client), | 136 client_(client), |
| 125 compositor_dependencies_(compositor_dependencies), | 137 compositor_dependencies_(compositor_dependencies), |
| 126 frame_sink_id_(compositor_dependencies_->GetEmbedderDependencies() | 138 frame_sink_id_(compositor_dependencies_->GetEmbedderDependencies() |
| 127 ->AllocateFrameSinkId()), | 139 ->AllocateFrameSinkId()), |
| 128 proxy_client_(nullptr), | 140 proxy_client_(nullptr), |
| 129 compositor_frame_sink_request_pending_(false), | 141 compositor_frame_sink_request_pending_(false), |
| 130 layer_(cc::Layer::Create()), | 142 layer_(cc::Layer::Create()), |
| 131 remote_proto_channel_receiver_(nullptr), | 143 remote_proto_channel_receiver_(nullptr), |
| 132 outstanding_commits_(0U), | 144 outstanding_commits_(0U), |
| 133 weak_ptr_factory_(this) { | 145 weak_ptr_factory_(this) { |
| 134 DCHECK(thread_checker_.CalledOnValidThread()); | 146 DCHECK(thread_checker_.CalledOnValidThread()); |
| 147 } | |
| 135 | 148 |
| 149 void BlimpCompositor::Initialize() { | |
| 136 surface_id_allocator_ = base::MakeUnique<cc::SurfaceIdAllocator>(); | 150 surface_id_allocator_ = base::MakeUnique<cc::SurfaceIdAllocator>(); |
| 137 GetEmbedderDeps()->GetSurfaceManager()->RegisterFrameSinkId(frame_sink_id_); | 151 GetEmbedderDeps()->GetSurfaceManager()->RegisterFrameSinkId(frame_sink_id_); |
| 138 CreateLayerTreeHost(); | 152 host_ = CreateLayerTreeHost(); |
| 139 | 153 |
| 140 if (use_threaded_layer_tree_host_) { | 154 if (use_threaded_layer_tree_host_) { |
| 141 std::unique_ptr<cc::ClientPictureCache> client_picture_cache = | 155 std::unique_ptr<cc::ClientPictureCache> client_picture_cache = |
| 142 compositor_dependencies_->GetImageSerializationProcessor() | 156 compositor_dependencies_->GetImageSerializationProcessor() |
| 143 ->CreateClientPictureCache(); | 157 ->CreateClientPictureCache(); |
| 144 compositor_state_deserializer_ = | 158 compositor_state_deserializer_ = |
| 145 base::MakeUnique<cc::CompositorStateDeserializer>( | 159 base::MakeUnique<cc::CompositorStateDeserializer>( |
| 146 host_.get(), std::move(client_picture_cache), | 160 host_.get(), std::move(client_picture_cache), this); |
| 147 base::Bind(&BlimpCompositor::LayerScrolled, | |
| 148 weak_ptr_factory_.GetWeakPtr()), | |
| 149 this); | |
| 150 } | 161 } |
| 151 } | 162 } |
| 152 | 163 |
| 153 BlimpCompositor::~BlimpCompositor() { | 164 BlimpCompositor::~BlimpCompositor() { |
| 154 DCHECK(thread_checker_.CalledOnValidThread()); | 165 DCHECK(thread_checker_.CalledOnValidThread()); |
| 155 | 166 |
| 156 DestroyLayerTreeHost(); | 167 DestroyLayerTreeHost(); |
| 157 GetEmbedderDeps()->GetSurfaceManager()->InvalidateFrameSinkId(frame_sink_id_); | 168 GetEmbedderDeps()->GetSurfaceManager()->InvalidateFrameSinkId(frame_sink_id_); |
| 158 } | 169 } |
| 159 | 170 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 195 surface_factory_->RequestCopyOfSurface(local_frame_id_, | 206 surface_factory_->RequestCopyOfSurface(local_frame_id_, |
| 196 std::move(copy_request)); | 207 std::move(copy_request)); |
| 197 return; | 208 return; |
| 198 } | 209 } |
| 199 | 210 |
| 200 pending_commit_trackers_.push_back( | 211 pending_commit_trackers_.push_back( |
| 201 std::make_pair(outstanding_commits_, std::move(copy_request))); | 212 std::make_pair(outstanding_commits_, std::move(copy_request))); |
| 202 } | 213 } |
| 203 | 214 |
| 204 void BlimpCompositor::UpdateLayerTreeHost() { | 215 void BlimpCompositor::UpdateLayerTreeHost() { |
| 216 DCHECK(use_threaded_layer_tree_host_); | |
| 217 | |
| 218 // UpdateLayerTreeHost marks the end of reporting of any deltas from the impl | |
| 219 // thread. So send a client state update if the local state was modified now. | |
| 220 FlushClientState(); | |
| 221 | |
| 205 if (pending_frame_update_) { | 222 if (pending_frame_update_) { |
| 206 DCHECK(use_threaded_layer_tree_host_); | 223 DCHECK(use_threaded_layer_tree_host_); |
| 207 compositor_state_deserializer_->DeserializeCompositorUpdate( | 224 compositor_state_deserializer_->DeserializeCompositorUpdate( |
| 208 pending_frame_update_->layer_tree_host()); | 225 pending_frame_update_->layer_tree_host()); |
| 209 pending_frame_update_ = nullptr; | 226 pending_frame_update_ = nullptr; |
| 210 cc::proto::CompositorMessage frame_ack; | 227 cc::proto::CompositorMessage frame_ack; |
| 211 frame_ack.set_frame_ack(true); | 228 frame_ack.set_frame_ack(true); |
| 212 client_->SendCompositorMessage(frame_ack); | 229 client_->SendCompositorMessage(frame_ack); |
| 213 } | 230 } |
| 231 | |
| 232 // Send back any deltas that have not yet been resolved on the main thread | |
| 233 // back to the impl thread. | |
| 234 compositor_state_deserializer_->SendUnappliedDeltasToLayerTreeHost(); | |
| 235 } | |
| 236 | |
| 237 void BlimpCompositor::ApplyViewportDeltas( | |
| 238 const gfx::Vector2dF& inner_delta, | |
| 239 const gfx::Vector2dF& outer_delta, | |
| 240 const gfx::Vector2dF& elastic_overscroll_delta, | |
| 241 float page_scale, | |
| 242 float top_controls_delta) { | |
| 243 DCHECK(use_threaded_layer_tree_host_); | |
| 244 compositor_state_deserializer_->ApplyViewportDeltas( | |
| 245 inner_delta, outer_delta, elastic_overscroll_delta, page_scale, | |
| 246 top_controls_delta); | |
| 214 } | 247 } |
| 215 | 248 |
| 216 void BlimpCompositor::RequestNewCompositorFrameSink() { | 249 void BlimpCompositor::RequestNewCompositorFrameSink() { |
| 217 DCHECK(!surface_factory_); | 250 DCHECK(!surface_factory_); |
| 218 DCHECK(!compositor_frame_sink_request_pending_); | 251 DCHECK(!compositor_frame_sink_request_pending_); |
| 219 | 252 |
| 220 compositor_frame_sink_request_pending_ = true; | 253 compositor_frame_sink_request_pending_ = true; |
| 221 GetEmbedderDeps()->GetContextProviders( | 254 GetEmbedderDeps()->GetContextProviders( |
| 222 base::Bind(&BlimpCompositor::OnContextProvidersCreated, | 255 base::Bind(&BlimpCompositor::OnContextProvidersCreated, |
| 223 weak_ptr_factory_.GetWeakPtr())); | 256 weak_ptr_factory_.GetWeakPtr())); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 259 } | 292 } |
| 260 | 293 |
| 261 void BlimpCompositor::OnCompositorMessageReceived( | 294 void BlimpCompositor::OnCompositorMessageReceived( |
| 262 std::unique_ptr<cc::proto::CompositorMessage> message) { | 295 std::unique_ptr<cc::proto::CompositorMessage> message) { |
| 263 if (message->has_to_impl()) { | 296 if (message->has_to_impl()) { |
| 264 HandleCompositorMessageToImpl(std::move(message)); | 297 HandleCompositorMessageToImpl(std::move(message)); |
| 265 return; | 298 return; |
| 266 } | 299 } |
| 267 | 300 |
| 268 DCHECK(use_threaded_layer_tree_host_); | 301 DCHECK(use_threaded_layer_tree_host_); |
| 269 DCHECK(message->has_layer_tree_host()) | 302 cc::proto::CompositorMessage* message_received = message.get(); |
| 270 << "The engine only sends frame updates"; | |
| 271 DCHECK(!pending_frame_update_) | |
| 272 << "We should have only a single frame in flight"; | |
| 273 | 303 |
| 274 UMA_HISTOGRAM_MEMORY_KB("Blimp.Compositor.CommitSizeKb", | 304 if (message_received->has_layer_tree_host()) { |
| 275 (float)message->ByteSize() / 1024); | 305 DCHECK(!pending_frame_update_) |
| 276 BlimpStats::GetInstance()->Add(BlimpStats::COMMIT, 1); | 306 << "We should have only a single frame in flight"; |
| 277 pending_frame_update_ = std::move(message); | 307 |
| 278 host_->SetNeedsAnimate(); | 308 UMA_HISTOGRAM_MEMORY_KB("Blimp.Compositor.CommitSizeKb", |
| 309 (float)message->ByteSize() / 1024); | |
| 310 BlimpStats::GetInstance()->Add(BlimpStats::COMMIT, 1); | |
| 311 | |
| 312 pending_frame_update_ = std::move(message); | |
| 313 outstanding_commits_++; | |
| 314 host_->SetNeedsAnimate(); | |
| 315 } | |
| 316 | |
| 317 if (message_received->client_state_update_ack()) { | |
| 318 DCHECK(client_state_update_ack_pending_); | |
| 319 | |
| 320 client_state_update_ack_pending_ = false; | |
| 321 compositor_state_deserializer_->DidApplyStateUpdatesOnEngine(); | |
| 322 | |
| 323 // If there are any updates that we have queued because we were waiting for | |
| 324 // an ack, send them now. | |
| 325 FlushClientState(); | |
| 326 } | |
| 279 } | 327 } |
| 280 | 328 |
| 281 void BlimpCompositor::HandleCompositorMessageToImpl( | 329 void BlimpCompositor::HandleCompositorMessageToImpl( |
| 282 std::unique_ptr<cc::proto::CompositorMessage> message) { | 330 std::unique_ptr<cc::proto::CompositorMessage> message) { |
| 283 DCHECK(!use_threaded_layer_tree_host_); | 331 DCHECK(!use_threaded_layer_tree_host_); |
| 284 DCHECK(message->has_to_impl()); | 332 DCHECK(message->has_to_impl()); |
| 285 | 333 |
| 286 const cc::proto::CompositorMessageToImpl to_impl_proto = message->to_impl(); | 334 const cc::proto::CompositorMessageToImpl to_impl_proto = message->to_impl(); |
| 287 DCHECK(to_impl_proto.has_message_type()); | 335 DCHECK(to_impl_proto.has_message_type()); |
| 288 | 336 |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 419 void BlimpCompositor::ReturnResources( | 467 void BlimpCompositor::ReturnResources( |
| 420 const cc::ReturnedResourceArray& resources) { | 468 const cc::ReturnedResourceArray& resources) { |
| 421 DCHECK(surface_factory_); | 469 DCHECK(surface_factory_); |
| 422 compositor_dependencies_->GetCompositorTaskRunner()->PostTask( | 470 compositor_dependencies_->GetCompositorTaskRunner()->PostTask( |
| 423 FROM_HERE, | 471 FROM_HERE, |
| 424 base::Bind( | 472 base::Bind( |
| 425 &BlimpCompositorFrameSinkProxyClient::ReclaimCompositorResources, | 473 &BlimpCompositorFrameSinkProxyClient::ReclaimCompositorResources, |
| 426 proxy_client_, resources)); | 474 proxy_client_, resources)); |
| 427 } | 475 } |
| 428 | 476 |
| 429 bool BlimpCompositor::ShouldRetainClientScroll( | 477 void BlimpCompositor::DidUpdateLocalState() { |
| 430 int engine_layer_id, | 478 client_state_dirty_ = true; |
| 431 const gfx::ScrollOffset& new_offset) { | |
| 432 // TODO(khushalsagar): Update when adding scroll/scale sync. See | |
| 433 // crbug.com/648442. | |
| 434 return true; | |
| 435 } | 479 } |
| 436 | 480 |
| 437 bool BlimpCompositor::ShouldRetainClientPageScale(float new_page_scale) { | 481 void BlimpCompositor::FlushClientState() { |
| 438 // TODO(khushalsagar): Update when adding scroll/scale sync. See | 482 // If the client state has not been modified, we don't need to send an update. |
| 439 // crbug.com/648442. | 483 if (!client_state_dirty_) |
| 440 return true; | 484 return; |
| 441 } | |
| 442 | 485 |
| 443 void BlimpCompositor::LayerScrolled(int engine_layer_id) { | 486 // If we had sent an update and an ack for it is still pending, we can't send |
| 444 DCHECK(use_threaded_layer_tree_host_); | 487 // another update till the ack is received. |
| 488 if (client_state_update_ack_pending_) | |
| 489 return; | |
| 490 | |
| 491 cc::proto::CompositorMessage message; | |
| 492 message.set_frame_ack(false); | |
|
David Trainor- moved to gerrit
2016/11/03 05:34:59
Should we just not set this if we're not ack'ing t
Khushal
2016/11/03 06:17:28
I guess we could just do a has_frame_ack instead.
| |
| 493 compositor_state_deserializer_->PullClientStateUpdate( | |
| 494 message.mutable_client_state_update()); | |
| 495 | |
| 496 client_state_dirty_ = false; | |
| 497 client_state_update_ack_pending_ = true; | |
| 498 client_->SendCompositorMessage(message); | |
| 445 } | 499 } |
| 446 | 500 |
| 447 CompositorDependencies* BlimpCompositor::GetEmbedderDeps() { | 501 CompositorDependencies* BlimpCompositor::GetEmbedderDeps() { |
| 448 return compositor_dependencies_->GetEmbedderDependencies(); | 502 return compositor_dependencies_->GetEmbedderDependencies(); |
| 449 } | 503 } |
| 450 | 504 |
| 451 void BlimpCompositor::DestroyDelegatedContent() { | 505 void BlimpCompositor::DestroyDelegatedContent() { |
| 452 if (local_frame_id_.is_null()) | 506 if (local_frame_id_.is_null()) |
| 453 return; | 507 return; |
| 454 | 508 |
| 455 // Remove any references for the surface layer that uses this | 509 // Remove any references for the surface layer that uses this |
| 456 // |local_frame_id_|. | 510 // |local_frame_id_|. |
| 457 layer_->RemoveAllChildren(); | 511 layer_->RemoveAllChildren(); |
| 458 surface_factory_->Destroy(local_frame_id_); | 512 surface_factory_->Destroy(local_frame_id_); |
| 459 local_frame_id_ = cc::LocalFrameId(); | 513 local_frame_id_ = cc::LocalFrameId(); |
| 460 } | 514 } |
| 461 | 515 |
| 462 void BlimpCompositor::CreateLayerTreeHost() { | 516 std::unique_ptr<cc::LayerTreeHostInProcess> |
| 463 DCHECK(!host_); | 517 BlimpCompositor::CreateLayerTreeHost() { |
| 518 std::unique_ptr<cc::LayerTreeHostInProcess> host; | |
| 464 | 519 |
| 465 // Create the LayerTreeHost | |
| 466 cc::LayerTreeHostInProcess::InitParams params; | 520 cc::LayerTreeHostInProcess::InitParams params; |
| 467 params.client = this; | 521 params.client = this; |
| 468 params.task_graph_runner = compositor_dependencies_->GetTaskGraphRunner(); | 522 params.task_graph_runner = compositor_dependencies_->GetTaskGraphRunner(); |
| 469 params.gpu_memory_buffer_manager = | 523 params.gpu_memory_buffer_manager = |
| 470 GetEmbedderDeps()->GetGpuMemoryBufferManager(); | 524 GetEmbedderDeps()->GetGpuMemoryBufferManager(); |
| 471 params.main_task_runner = base::ThreadTaskRunnerHandle::Get(); | 525 params.main_task_runner = base::ThreadTaskRunnerHandle::Get(); |
| 472 if (!use_threaded_layer_tree_host_) { | 526 if (!use_threaded_layer_tree_host_) { |
| 473 params.image_serialization_processor = | 527 params.image_serialization_processor = |
| 474 compositor_dependencies_->GetImageSerializationProcessor(); | 528 compositor_dependencies_->GetImageSerializationProcessor(); |
| 475 } | 529 } |
| 476 | 530 |
| 477 cc::LayerTreeSettings* settings = | 531 cc::LayerTreeSettings* settings = |
| 478 compositor_dependencies_->GetLayerTreeSettings(); | 532 compositor_dependencies_->GetLayerTreeSettings(); |
| 479 params.settings = settings; | 533 params.settings = settings; |
| 480 | 534 |
| 481 params.animation_host = cc::AnimationHost::CreateMainInstance(); | 535 params.animation_host = cc::AnimationHost::CreateMainInstance(); |
| 482 | 536 |
| 483 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner = | 537 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner = |
| 484 compositor_dependencies_->GetCompositorTaskRunner(); | 538 compositor_dependencies_->GetCompositorTaskRunner(); |
| 485 | 539 |
| 486 if (use_threaded_layer_tree_host_) { | 540 if (use_threaded_layer_tree_host_) { |
| 487 host_ = cc::LayerTreeHostInProcess::CreateThreaded(compositor_task_runner, | 541 host = cc::LayerTreeHostInProcess::CreateThreaded(compositor_task_runner, |
| 488 ¶ms); | 542 ¶ms); |
| 489 } else { | 543 } else { |
| 490 host_ = cc::LayerTreeHostInProcess::CreateRemoteClient( | 544 host = cc::LayerTreeHostInProcess::CreateRemoteClient( |
| 491 this /* remote_proto_channel */, compositor_task_runner, ¶ms); | 545 this /* remote_proto_channel */, compositor_task_runner, ¶ms); |
| 492 } | 546 } |
| 547 | |
| 548 return host; | |
| 493 } | 549 } |
| 494 | 550 |
| 495 void BlimpCompositor::DestroyLayerTreeHost() { | 551 void BlimpCompositor::DestroyLayerTreeHost() { |
| 496 DCHECK(host_); | 552 DCHECK(host_); |
| 497 | 553 |
| 498 // Tear down the output surface connection with the old LayerTreeHost | 554 // Tear down the output surface connection with the old LayerTreeHost |
| 499 // instance. | 555 // instance. |
| 500 DestroyDelegatedContent(); | 556 DestroyDelegatedContent(); |
| 501 surface_factory_.reset(); | 557 surface_factory_.reset(); |
| 502 | 558 |
| 503 // Destroy the old LayerTreeHost state. | 559 // Destroy the old LayerTreeHost state. |
| 504 host_.reset(); | 560 host_.reset(); |
| 505 | 561 |
| 506 // Cancel any outstanding CompositorFrameSink requests. That way if we get an | 562 // Cancel any outstanding CompositorFrameSink requests. That way if we get an |
| 507 // async callback related to the old request we know to drop it. | 563 // async callback related to the old request we know to drop it. |
| 508 compositor_frame_sink_request_pending_ = false; | 564 compositor_frame_sink_request_pending_ = false; |
| 509 | 565 |
| 510 // Make sure we don't have a receiver at this point. | 566 // Make sure we don't have a receiver at this point. |
| 511 DCHECK(!remote_proto_channel_receiver_); | 567 DCHECK(!remote_proto_channel_receiver_); |
| 512 } | 568 } |
| 513 | 569 |
| 514 } // namespace client | 570 } // namespace client |
| 515 } // namespace blimp | 571 } // namespace blimp |
| OLD | NEW |