| 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 |
| 160 void BlimpCompositor::SetVisible(bool visible) { | 171 void BlimpCompositor::SetVisible(bool visible) { |
| 161 host_->SetVisible(visible); | 172 host_->SetVisible(visible); |
| 162 } | 173 } |
| 163 | 174 |
| 175 bool BlimpCompositor::IsVisible() const { |
| 176 return host_->IsVisible(); |
| 177 } |
| 178 |
| 179 bool BlimpCompositor::HasPendingFrameUpdateFromEngine() const { |
| 180 return pending_frame_update_.get() != nullptr; |
| 181 } |
| 182 |
| 164 void BlimpCompositor::RequestCopyOfOutput( | 183 void BlimpCompositor::RequestCopyOfOutput( |
| 165 std::unique_ptr<cc::CopyOutputRequest> copy_request, | 184 std::unique_ptr<cc::CopyOutputRequest> copy_request, |
| 166 bool flush_pending_update) { | 185 bool flush_pending_update) { |
| 167 // If we don't have a FrameSink, fail right away. | 186 // If we don't have a FrameSink, fail right away. |
| 168 if (!surface_factory_) | 187 if (!surface_factory_) |
| 169 return; | 188 return; |
| 170 | 189 |
| 171 if (!use_threaded_layer_tree_host_) { | 190 if (!use_threaded_layer_tree_host_) { |
| 172 RequestCopyOfOutputDeprecated(std::move(copy_request)); | 191 RequestCopyOfOutputDeprecated(std::move(copy_request)); |
| 173 return; | 192 return; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 195 surface_factory_->RequestCopyOfSurface(local_frame_id_, | 214 surface_factory_->RequestCopyOfSurface(local_frame_id_, |
| 196 std::move(copy_request)); | 215 std::move(copy_request)); |
| 197 return; | 216 return; |
| 198 } | 217 } |
| 199 | 218 |
| 200 pending_commit_trackers_.push_back( | 219 pending_commit_trackers_.push_back( |
| 201 std::make_pair(outstanding_commits_, std::move(copy_request))); | 220 std::make_pair(outstanding_commits_, std::move(copy_request))); |
| 202 } | 221 } |
| 203 | 222 |
| 204 void BlimpCompositor::UpdateLayerTreeHost() { | 223 void BlimpCompositor::UpdateLayerTreeHost() { |
| 224 DCHECK(use_threaded_layer_tree_host_); |
| 225 |
| 226 // UpdateLayerTreeHost marks the end of reporting of any deltas from the impl |
| 227 // thread. So send a client state update if the local state was modified now. |
| 228 FlushClientState(); |
| 229 |
| 205 if (pending_frame_update_) { | 230 if (pending_frame_update_) { |
| 206 DCHECK(use_threaded_layer_tree_host_); | 231 DCHECK(use_threaded_layer_tree_host_); |
| 207 compositor_state_deserializer_->DeserializeCompositorUpdate( | 232 compositor_state_deserializer_->DeserializeCompositorUpdate( |
| 208 pending_frame_update_->layer_tree_host()); | 233 pending_frame_update_->layer_tree_host()); |
| 209 pending_frame_update_ = nullptr; | 234 pending_frame_update_ = nullptr; |
| 210 cc::proto::CompositorMessage frame_ack; | 235 cc::proto::CompositorMessage frame_ack; |
| 211 frame_ack.set_frame_ack(true); | 236 frame_ack.set_frame_ack(true); |
| 212 client_->SendCompositorMessage(frame_ack); | 237 client_->SendCompositorMessage(frame_ack); |
| 213 } | 238 } |
| 239 |
| 240 // Send back any deltas that have not yet been resolved on the main thread |
| 241 // back to the impl thread. |
| 242 compositor_state_deserializer_->SendUnappliedDeltasToLayerTreeHost(); |
| 243 } |
| 244 |
| 245 void BlimpCompositor::ApplyViewportDeltas( |
| 246 const gfx::Vector2dF& inner_delta, |
| 247 const gfx::Vector2dF& outer_delta, |
| 248 const gfx::Vector2dF& elastic_overscroll_delta, |
| 249 float page_scale, |
| 250 float top_controls_delta) { |
| 251 DCHECK(use_threaded_layer_tree_host_); |
| 252 compositor_state_deserializer_->ApplyViewportDeltas( |
| 253 inner_delta, outer_delta, elastic_overscroll_delta, page_scale, |
| 254 top_controls_delta); |
| 214 } | 255 } |
| 215 | 256 |
| 216 void BlimpCompositor::RequestNewCompositorFrameSink() { | 257 void BlimpCompositor::RequestNewCompositorFrameSink() { |
| 217 DCHECK(!surface_factory_); | 258 DCHECK(!surface_factory_); |
| 218 DCHECK(!compositor_frame_sink_request_pending_); | 259 DCHECK(!compositor_frame_sink_request_pending_); |
| 219 | 260 |
| 220 compositor_frame_sink_request_pending_ = true; | 261 compositor_frame_sink_request_pending_ = true; |
| 221 GetEmbedderDeps()->GetContextProviders( | 262 GetEmbedderDeps()->GetContextProviders( |
| 222 base::Bind(&BlimpCompositor::OnContextProvidersCreated, | 263 base::Bind(&BlimpCompositor::OnContextProvidersCreated, |
| 223 weak_ptr_factory_.GetWeakPtr())); | 264 weak_ptr_factory_.GetWeakPtr())); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 } | 300 } |
| 260 | 301 |
| 261 void BlimpCompositor::OnCompositorMessageReceived( | 302 void BlimpCompositor::OnCompositorMessageReceived( |
| 262 std::unique_ptr<cc::proto::CompositorMessage> message) { | 303 std::unique_ptr<cc::proto::CompositorMessage> message) { |
| 263 if (message->has_to_impl()) { | 304 if (message->has_to_impl()) { |
| 264 HandleCompositorMessageToImpl(std::move(message)); | 305 HandleCompositorMessageToImpl(std::move(message)); |
| 265 return; | 306 return; |
| 266 } | 307 } |
| 267 | 308 |
| 268 DCHECK(use_threaded_layer_tree_host_); | 309 DCHECK(use_threaded_layer_tree_host_); |
| 269 DCHECK(message->has_layer_tree_host()) | 310 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 | 311 |
| 274 UMA_HISTOGRAM_MEMORY_KB("Blimp.Compositor.CommitSizeKb", | 312 if (message_received->has_layer_tree_host()) { |
| 275 (float)message->ByteSize() / 1024); | 313 DCHECK(!pending_frame_update_) |
| 276 BlimpStats::GetInstance()->Add(BlimpStats::COMMIT, 1); | 314 << "We should have only a single frame in flight"; |
| 277 pending_frame_update_ = std::move(message); | 315 |
| 278 host_->SetNeedsAnimate(); | 316 UMA_HISTOGRAM_MEMORY_KB("Blimp.Compositor.CommitSizeKb", |
| 317 (float)message->ByteSize() / 1024); |
| 318 BlimpStats::GetInstance()->Add(BlimpStats::COMMIT, 1); |
| 319 |
| 320 pending_frame_update_ = std::move(message); |
| 321 outstanding_commits_++; |
| 322 host_->SetNeedsAnimate(); |
| 323 } |
| 324 |
| 325 if (message_received->client_state_update_ack()) { |
| 326 DCHECK(client_state_update_ack_pending_); |
| 327 |
| 328 client_state_update_ack_pending_ = false; |
| 329 compositor_state_deserializer_->DidApplyStateUpdatesOnEngine(); |
| 330 |
| 331 // If there are any updates that we have queued because we were waiting for |
| 332 // an ack, send them now. |
| 333 FlushClientState(); |
| 334 } |
| 279 } | 335 } |
| 280 | 336 |
| 281 void BlimpCompositor::HandleCompositorMessageToImpl( | 337 void BlimpCompositor::HandleCompositorMessageToImpl( |
| 282 std::unique_ptr<cc::proto::CompositorMessage> message) { | 338 std::unique_ptr<cc::proto::CompositorMessage> message) { |
| 283 DCHECK(!use_threaded_layer_tree_host_); | 339 DCHECK(!use_threaded_layer_tree_host_); |
| 284 DCHECK(message->has_to_impl()); | 340 DCHECK(message->has_to_impl()); |
| 285 | 341 |
| 286 const cc::proto::CompositorMessageToImpl to_impl_proto = message->to_impl(); | 342 const cc::proto::CompositorMessageToImpl to_impl_proto = message->to_impl(); |
| 287 DCHECK(to_impl_proto.has_message_type()); | 343 DCHECK(to_impl_proto.has_message_type()); |
| 288 | 344 |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 void BlimpCompositor::ReturnResources( | 475 void BlimpCompositor::ReturnResources( |
| 420 const cc::ReturnedResourceArray& resources) { | 476 const cc::ReturnedResourceArray& resources) { |
| 421 DCHECK(surface_factory_); | 477 DCHECK(surface_factory_); |
| 422 compositor_dependencies_->GetCompositorTaskRunner()->PostTask( | 478 compositor_dependencies_->GetCompositorTaskRunner()->PostTask( |
| 423 FROM_HERE, | 479 FROM_HERE, |
| 424 base::Bind( | 480 base::Bind( |
| 425 &BlimpCompositorFrameSinkProxyClient::ReclaimCompositorResources, | 481 &BlimpCompositorFrameSinkProxyClient::ReclaimCompositorResources, |
| 426 proxy_client_, resources)); | 482 proxy_client_, resources)); |
| 427 } | 483 } |
| 428 | 484 |
| 429 bool BlimpCompositor::ShouldRetainClientScroll( | 485 void BlimpCompositor::DidUpdateLocalState() { |
| 430 int engine_layer_id, | 486 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 } | 487 } |
| 436 | 488 |
| 437 bool BlimpCompositor::ShouldRetainClientPageScale(float new_page_scale) { | 489 void BlimpCompositor::FlushClientState() { |
| 438 // TODO(khushalsagar): Update when adding scroll/scale sync. See | 490 // If the client state has not been modified, we don't need to send an update. |
| 439 // crbug.com/648442. | 491 if (!client_state_dirty_) |
| 440 return true; | 492 return; |
| 441 } | |
| 442 | 493 |
| 443 void BlimpCompositor::LayerScrolled(int engine_layer_id) { | 494 // 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_); | 495 // another update till the ack is received. |
| 496 if (client_state_update_ack_pending_) |
| 497 return; |
| 498 |
| 499 cc::proto::CompositorMessage message; |
| 500 message.set_frame_ack(false); |
| 501 compositor_state_deserializer_->PullClientStateUpdate( |
| 502 message.mutable_client_state_update()); |
| 503 |
| 504 client_state_dirty_ = false; |
| 505 client_state_update_ack_pending_ = true; |
| 506 client_->SendCompositorMessage(message); |
| 445 } | 507 } |
| 446 | 508 |
| 447 CompositorDependencies* BlimpCompositor::GetEmbedderDeps() { | 509 CompositorDependencies* BlimpCompositor::GetEmbedderDeps() { |
| 448 return compositor_dependencies_->GetEmbedderDependencies(); | 510 return compositor_dependencies_->GetEmbedderDependencies(); |
| 449 } | 511 } |
| 450 | 512 |
| 451 void BlimpCompositor::DestroyDelegatedContent() { | 513 void BlimpCompositor::DestroyDelegatedContent() { |
| 452 if (local_frame_id_.is_null()) | 514 if (local_frame_id_.is_null()) |
| 453 return; | 515 return; |
| 454 | 516 |
| 455 // Remove any references for the surface layer that uses this | 517 // Remove any references for the surface layer that uses this |
| 456 // |local_frame_id_|. | 518 // |local_frame_id_|. |
| 457 layer_->RemoveAllChildren(); | 519 layer_->RemoveAllChildren(); |
| 458 surface_factory_->Destroy(local_frame_id_); | 520 surface_factory_->Destroy(local_frame_id_); |
| 459 local_frame_id_ = cc::LocalFrameId(); | 521 local_frame_id_ = cc::LocalFrameId(); |
| 460 } | 522 } |
| 461 | 523 |
| 462 void BlimpCompositor::CreateLayerTreeHost() { | 524 std::unique_ptr<cc::LayerTreeHostInProcess> |
| 463 DCHECK(!host_); | 525 BlimpCompositor::CreateLayerTreeHost() { |
| 526 std::unique_ptr<cc::LayerTreeHostInProcess> host; |
| 464 | 527 |
| 465 // Create the LayerTreeHost | |
| 466 cc::LayerTreeHostInProcess::InitParams params; | 528 cc::LayerTreeHostInProcess::InitParams params; |
| 467 params.client = this; | 529 params.client = this; |
| 468 params.task_graph_runner = compositor_dependencies_->GetTaskGraphRunner(); | 530 params.task_graph_runner = compositor_dependencies_->GetTaskGraphRunner(); |
| 469 params.main_task_runner = base::ThreadTaskRunnerHandle::Get(); | 531 params.main_task_runner = base::ThreadTaskRunnerHandle::Get(); |
| 470 if (!use_threaded_layer_tree_host_) { | 532 if (!use_threaded_layer_tree_host_) { |
| 471 params.image_serialization_processor = | 533 params.image_serialization_processor = |
| 472 compositor_dependencies_->GetImageSerializationProcessor(); | 534 compositor_dependencies_->GetImageSerializationProcessor(); |
| 473 } | 535 } |
| 474 | 536 |
| 475 cc::LayerTreeSettings* settings = | 537 cc::LayerTreeSettings* settings = |
| 476 compositor_dependencies_->GetLayerTreeSettings(); | 538 compositor_dependencies_->GetLayerTreeSettings(); |
| 477 params.settings = settings; | 539 params.settings = settings; |
| 478 | 540 |
| 479 params.animation_host = cc::AnimationHost::CreateMainInstance(); | 541 params.animation_host = cc::AnimationHost::CreateMainInstance(); |
| 480 | 542 |
| 481 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner = | 543 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner = |
| 482 compositor_dependencies_->GetCompositorTaskRunner(); | 544 compositor_dependencies_->GetCompositorTaskRunner(); |
| 483 | 545 |
| 484 if (use_threaded_layer_tree_host_) { | 546 if (use_threaded_layer_tree_host_) { |
| 485 host_ = cc::LayerTreeHostInProcess::CreateThreaded(compositor_task_runner, | 547 host = cc::LayerTreeHostInProcess::CreateThreaded(compositor_task_runner, |
| 486 ¶ms); | 548 ¶ms); |
| 487 } else { | 549 } else { |
| 488 host_ = cc::LayerTreeHostInProcess::CreateRemoteClient( | 550 host = cc::LayerTreeHostInProcess::CreateRemoteClient( |
| 489 this /* remote_proto_channel */, compositor_task_runner, ¶ms); | 551 this /* remote_proto_channel */, compositor_task_runner, ¶ms); |
| 490 } | 552 } |
| 553 |
| 554 return host; |
| 491 } | 555 } |
| 492 | 556 |
| 493 void BlimpCompositor::DestroyLayerTreeHost() { | 557 void BlimpCompositor::DestroyLayerTreeHost() { |
| 494 DCHECK(host_); | 558 DCHECK(host_); |
| 495 | 559 |
| 496 // Tear down the output surface connection with the old LayerTreeHost | 560 // Tear down the output surface connection with the old LayerTreeHost |
| 497 // instance. | 561 // instance. |
| 498 DestroyDelegatedContent(); | 562 DestroyDelegatedContent(); |
| 499 surface_factory_.reset(); | 563 surface_factory_.reset(); |
| 500 | 564 |
| 501 // Destroy the old LayerTreeHost state. | 565 // Destroy the old LayerTreeHost state. |
| 502 host_.reset(); | 566 host_.reset(); |
| 503 | 567 |
| 504 // Cancel any outstanding CompositorFrameSink requests. That way if we get an | 568 // Cancel any outstanding CompositorFrameSink requests. That way if we get an |
| 505 // async callback related to the old request we know to drop it. | 569 // async callback related to the old request we know to drop it. |
| 506 compositor_frame_sink_request_pending_ = false; | 570 compositor_frame_sink_request_pending_ = false; |
| 507 | 571 |
| 508 // Make sure we don't have a receiver at this point. | 572 // Make sure we don't have a receiver at this point. |
| 509 DCHECK(!remote_proto_channel_receiver_); | 573 DCHECK(!remote_proto_channel_receiver_); |
| 510 } | 574 } |
| 511 | 575 |
| 512 } // namespace client | 576 } // namespace client |
| 513 } // namespace blimp | 577 } // namespace blimp |
| OLD | NEW |