Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(912)

Side by Side Diff: blimp/client/core/compositor/blimp_compositor.cc

Issue 2459823003: blimp: Use SwapPromises for readback API. (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 class BlimpCompositor::FrameTrackingSwapPromise : public cc::SwapPromise {
64 public:
65 FrameTrackingSwapPromise(
66 std::unique_ptr<cc::CopyOutputRequest> copy_request,
67 base::WeakPtr<BlimpCompositor> compositor,
68 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner)
69 : copy_request_(std::move(copy_request)),
70 compositor_weak_ptr_(compositor),
71 main_task_runner_(std::move(main_task_runner)) {}
72 ~FrameTrackingSwapPromise() override = default;
73
74 // cc::SwapPromise implementation.
75 void DidActivate() override {}
76 void DidSwap(cc::CompositorFrameMetadata* metadata) override {
77 // DidSwap is called right before the CompositorFrame is submitted to the
78 // CompositorFrameSink, so we make sure to delay the copy request till that
79 // frame is submitted.
80 main_task_runner_->PostTask(
81 FROM_HERE,
82 base::Bind(&BlimpCompositor::MakeCopyRequestOnNextSwap,
83 compositor_weak_ptr_, base::Passed(&copy_request_)));
84 }
85 DidNotSwapAction DidNotSwap(DidNotSwapReason reason) override {
86 switch (reason) {
87 case DidNotSwapReason::SWAP_FAILS:
88 // The swap will fail if there is no frame damage, we can queue the
89 // request right away.
90 main_task_runner_->PostTask(
91 FROM_HERE, base::Bind(&BlimpCompositor::RequestCopyOfOutput,
92 compositor_weak_ptr_,
93 base::Passed(&copy_request_), false));
94 break;
95 case DidNotSwapReason::COMMIT_FAILS:
96 // The commit fails when the host is going away.
97 break;
98 case DidNotSwapReason::COMMIT_NO_UPDATE:
99 main_task_runner_->PostTask(
100 FROM_HERE, base::Bind(&BlimpCompositor::RequestCopyOfOutput,
101 compositor_weak_ptr_,
102 base::Passed(&copy_request_), false));
103 break;
104 case DidNotSwapReason::ACTIVATION_FAILS:
105 // Failure to activate the pending tree implies either the host in going
106 // away or the FrameSink was lost.
107 break;
108 }
109 return DidNotSwapAction::BREAK_PROMISE;
110 }
111 int64_t TraceId() const override { return 0; }
112
113 private:
114 std::unique_ptr<cc::CopyOutputRequest> copy_request_;
115 base::WeakPtr<BlimpCompositor> compositor_weak_ptr_;
116 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
117 };
118
63 BlimpCompositor::BlimpCompositor( 119 BlimpCompositor::BlimpCompositor(
64 BlimpCompositorDependencies* compositor_dependencies, 120 BlimpCompositorDependencies* compositor_dependencies,
65 BlimpCompositorClient* client, 121 BlimpCompositorClient* client,
66 bool use_threaded_layer_tree_host) 122 bool use_threaded_layer_tree_host)
67 : use_threaded_layer_tree_host_(use_threaded_layer_tree_host), 123 : use_threaded_layer_tree_host_(use_threaded_layer_tree_host),
68 client_(client), 124 client_(client),
69 compositor_dependencies_(compositor_dependencies), 125 compositor_dependencies_(compositor_dependencies),
70 frame_sink_id_(compositor_dependencies_->GetEmbedderDependencies() 126 frame_sink_id_(compositor_dependencies_->GetEmbedderDependencies()
71 ->AllocateFrameSinkId()), 127 ->AllocateFrameSinkId()),
72 proxy_client_(nullptr), 128 proxy_client_(nullptr),
(...skipping 19 matching lines...) Expand all
92 weak_ptr_factory_.GetWeakPtr()), 148 weak_ptr_factory_.GetWeakPtr()),
93 this); 149 this);
94 } 150 }
95 } 151 }
96 152
97 BlimpCompositor::~BlimpCompositor() { 153 BlimpCompositor::~BlimpCompositor() {
98 DCHECK(thread_checker_.CalledOnValidThread()); 154 DCHECK(thread_checker_.CalledOnValidThread());
99 155
100 DestroyLayerTreeHost(); 156 DestroyLayerTreeHost();
101 GetEmbedderDeps()->GetSurfaceManager()->InvalidateFrameSinkId(frame_sink_id_); 157 GetEmbedderDeps()->GetSurfaceManager()->InvalidateFrameSinkId(frame_sink_id_);
102
103 CheckPendingCommitCounts(true /* flush */);
104 } 158 }
105 159
106 void BlimpCompositor::SetVisible(bool visible) { 160 void BlimpCompositor::SetVisible(bool visible) {
107 host_->SetVisible(visible); 161 host_->SetVisible(visible);
108
109 if (!visible)
110 CheckPendingCommitCounts(true /* flush */);
111 } 162 }
112 163
113 void BlimpCompositor::NotifyWhenDonePendingCommits(base::Closure callback) { 164 void BlimpCompositor::RequestCopyOfOutput(
165 std::unique_ptr<cc::CopyOutputRequest> copy_request,
166 bool flush_pending_update) {
167 // If we don't have a FrameSink, fail right away.
168 if (!surface_factory_)
169 return;
170
171 if (!use_threaded_layer_tree_host_) {
172 RequestCopyOfOutputDeprecated(std::move(copy_request));
173 return;
174 }
175
176 if (flush_pending_update) {
177 // Always request a commit when queuing the promise to make sure that any
178 // frames pending draws are cleared from the pipeline.
179 host_->QueueSwapPromise(base::MakeUnique<FrameTrackingSwapPromise>(
180 std::move(copy_request), weak_ptr_factory_.GetWeakPtr(),
181 base::ThreadTaskRunnerHandle::Get()));
182 host_->SetNeedsCommit();
183 } else if (!local_frame_id_.is_null()) {
184 // Make a copy request for the surface directly.
185 surface_factory_->RequestCopyOfSurface(local_frame_id_,
186 std::move(copy_request));
187 }
188 }
189
190 void BlimpCompositor::RequestCopyOfOutputDeprecated(
191 std::unique_ptr<cc::CopyOutputRequest> copy_request) {
192 DCHECK(!use_threaded_layer_tree_host_);
193
114 if (outstanding_commits_ == 0) { 194 if (outstanding_commits_ == 0) {
115 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); 195 surface_factory_->RequestCopyOfSurface(local_frame_id_,
196 std::move(copy_request));
116 return; 197 return;
117 } 198 }
118 199
119 pending_commit_trackers_.push_back( 200 pending_commit_trackers_.push_back(
120 std::make_pair(outstanding_commits_, callback)); 201 std::make_pair(outstanding_commits_, std::move(copy_request)));
121 } 202 }
122 203
123 void BlimpCompositor::UpdateLayerTreeHost() { 204 void BlimpCompositor::UpdateLayerTreeHost() {
124 if (pending_frame_update_) { 205 if (pending_frame_update_) {
125 DCHECK(use_threaded_layer_tree_host_); 206 DCHECK(use_threaded_layer_tree_host_);
126 compositor_state_deserializer_->DeserializeCompositorUpdate( 207 compositor_state_deserializer_->DeserializeCompositorUpdate(
127 pending_frame_update_->layer_tree_host()); 208 pending_frame_update_->layer_tree_host());
128 pending_frame_update_ = nullptr; 209 pending_frame_update_ = nullptr;
129 cc::proto::CompositorMessage frame_ack; 210 cc::proto::CompositorMessage frame_ack;
130 frame_ack.set_frame_ack(true); 211 frame_ack.set_frame_ack(true);
131 client_->SendCompositorMessage(frame_ack); 212 client_->SendCompositorMessage(frame_ack);
132 } 213 }
133 } 214 }
134 215
135 void BlimpCompositor::RequestNewCompositorFrameSink() { 216 void BlimpCompositor::RequestNewCompositorFrameSink() {
136 DCHECK(!surface_factory_); 217 DCHECK(!surface_factory_);
137 DCHECK(!compositor_frame_sink_request_pending_); 218 DCHECK(!compositor_frame_sink_request_pending_);
138 219
139 compositor_frame_sink_request_pending_ = true; 220 compositor_frame_sink_request_pending_ = true;
140 GetEmbedderDeps()->GetContextProviders( 221 GetEmbedderDeps()->GetContextProviders(
141 base::Bind(&BlimpCompositor::OnContextProvidersCreated, 222 base::Bind(&BlimpCompositor::OnContextProvidersCreated,
142 weak_ptr_factory_.GetWeakPtr())); 223 weak_ptr_factory_.GetWeakPtr()));
143 } 224 }
144 225
145 void BlimpCompositor::DidInitializeCompositorFrameSink() { 226 void BlimpCompositor::DidInitializeCompositorFrameSink() {
146 compositor_frame_sink_request_pending_ = false; 227 compositor_frame_sink_request_pending_ = false;
147 } 228 }
148 229
149 void BlimpCompositor::DidCommitAndDrawFrame() { 230 void BlimpCompositor::DidCommitAndDrawFrame() {
150 BlimpStats::GetInstance()->Add(BlimpStats::COMMIT, 1); 231 if (use_threaded_layer_tree_host_)
aelias_OOO_until_Jul13 2016/11/02 07:02:10 For my edification, what is !use_threaded_layer_tr
Khushal 2016/11/02 07:24:21 Right now our split point in the pipeline is right
232 return;
151 233
152 DCHECK_GT(outstanding_commits_, 0U); 234 DCHECK_GT(outstanding_commits_, 0U);
153 outstanding_commits_--; 235 outstanding_commits_--;
154 236
155 CheckPendingCommitCounts(false /* flush */); 237 for (auto it = pending_commit_trackers_.begin();
238 it != pending_commit_trackers_.end();) {
239 if (--it->first == 0) {
240 if (surface_factory_)
241 surface_factory_->RequestCopyOfSurface(local_frame_id_,
242 std::move(it->second));
243 it = pending_commit_trackers_.erase(it);
244 } else {
245 ++it;
246 }
247 }
156 } 248 }
157 249
158 void BlimpCompositor::SetProtoReceiver(ProtoReceiver* receiver) { 250 void BlimpCompositor::SetProtoReceiver(ProtoReceiver* receiver) {
159 DCHECK(!use_threaded_layer_tree_host_); 251 DCHECK(!use_threaded_layer_tree_host_);
160 remote_proto_channel_receiver_ = receiver; 252 remote_proto_channel_receiver_ = receiver;
161 } 253 }
162 254
163 void BlimpCompositor::SendCompositorProto( 255 void BlimpCompositor::SendCompositorProto(
164 const cc::proto::CompositorMessage& proto) { 256 const cc::proto::CompositorMessage& proto) {
165 DCHECK(!use_threaded_layer_tree_host_); 257 DCHECK(!use_threaded_layer_tree_host_);
166 client_->SendCompositorMessage(proto); 258 client_->SendCompositorMessage(proto);
167 } 259 }
168 260
169 void BlimpCompositor::OnCompositorMessageReceived( 261 void BlimpCompositor::OnCompositorMessageReceived(
170 std::unique_ptr<cc::proto::CompositorMessage> message) { 262 std::unique_ptr<cc::proto::CompositorMessage> message) {
171 if (message->has_to_impl()) { 263 if (message->has_to_impl()) {
172 HandleCompositorMessageToImpl(std::move(message)); 264 HandleCompositorMessageToImpl(std::move(message));
173 return; 265 return;
174 } 266 }
175 267
176 DCHECK(use_threaded_layer_tree_host_); 268 DCHECK(use_threaded_layer_tree_host_);
177 DCHECK(message->has_layer_tree_host()) 269 DCHECK(message->has_layer_tree_host())
178 << "The engine only sends frame updates"; 270 << "The engine only sends frame updates";
179 DCHECK(!pending_frame_update_) 271 DCHECK(!pending_frame_update_)
180 << "We should have only a single frame in flight"; 272 << "We should have only a single frame in flight";
181 273
182 UMA_HISTOGRAM_MEMORY_KB("Blimp.Compositor.CommitSizeKb", 274 UMA_HISTOGRAM_MEMORY_KB("Blimp.Compositor.CommitSizeKb",
183 (float)message->ByteSize() / 1024); 275 (float)message->ByteSize() / 1024);
276 BlimpStats::GetInstance()->Add(BlimpStats::COMMIT, 1);
184 pending_frame_update_ = std::move(message); 277 pending_frame_update_ = std::move(message);
185 outstanding_commits_++;
186 host_->SetNeedsAnimate(); 278 host_->SetNeedsAnimate();
187 } 279 }
188 280
189 void BlimpCompositor::HandleCompositorMessageToImpl( 281 void BlimpCompositor::HandleCompositorMessageToImpl(
190 std::unique_ptr<cc::proto::CompositorMessage> message) { 282 std::unique_ptr<cc::proto::CompositorMessage> message) {
191 DCHECK(!use_threaded_layer_tree_host_); 283 DCHECK(!use_threaded_layer_tree_host_);
192 DCHECK(message->has_to_impl()); 284 DCHECK(message->has_to_impl());
193 285
194 const cc::proto::CompositorMessageToImpl to_impl_proto = message->to_impl(); 286 const cc::proto::CompositorMessageToImpl to_impl_proto = message->to_impl();
195 DCHECK(to_impl_proto.has_message_type()); 287 DCHECK(to_impl_proto.has_message_type());
196 288
197 if (to_impl_proto.message_type() == 289 if (to_impl_proto.message_type() ==
198 cc::proto::CompositorMessageToImpl::START_COMMIT) { 290 cc::proto::CompositorMessageToImpl::START_COMMIT) {
291 BlimpStats::GetInstance()->Add(BlimpStats::COMMIT, 1);
199 outstanding_commits_++; 292 outstanding_commits_++;
200 } 293 }
201 294
202 switch (to_impl_proto.message_type()) { 295 switch (to_impl_proto.message_type()) {
203 case cc::proto::CompositorMessageToImpl::UNKNOWN: 296 case cc::proto::CompositorMessageToImpl::UNKNOWN:
204 NOTIMPLEMENTED() << "Ignoring message of UNKNOWN type"; 297 NOTIMPLEMENTED() << "Ignoring message of UNKNOWN type";
205 break; 298 break;
206 case cc::proto::CompositorMessageToImpl::START_COMMIT: 299 case cc::proto::CompositorMessageToImpl::START_COMMIT:
207 UMA_HISTOGRAM_MEMORY_KB("Blimp.Compositor.CommitSizeKb", 300 UMA_HISTOGRAM_MEMORY_KB("Blimp.Compositor.CommitSizeKb",
208 (float)message->ByteSize() / 1024); 301 (float)message->ByteSize() / 1024);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 content_layer->SetIsDrawable(true); 379 content_layer->SetIsDrawable(true);
287 content_layer->SetContentsOpaque(true); 380 content_layer->SetContentsOpaque(true);
288 381
289 layer_->AddChild(content_layer); 382 layer_->AddChild(content_layer);
290 } 383 }
291 384
292 surface_factory_->SubmitCompositorFrame( 385 surface_factory_->SubmitCompositorFrame(
293 local_frame_id_, std::move(frame), 386 local_frame_id_, std::move(frame),
294 base::Bind(&BlimpCompositor::SubmitCompositorFrameAck, 387 base::Bind(&BlimpCompositor::SubmitCompositorFrameAck,
295 weak_ptr_factory_.GetWeakPtr())); 388 weak_ptr_factory_.GetWeakPtr()));
389
390 for (auto& copy_request : copy_requests_for_next_swap_) {
391 surface_factory_->RequestCopyOfSurface(local_frame_id_,
392 std::move(copy_request));
393 }
394 copy_requests_for_next_swap_.clear();
296 } 395 }
297 396
298 void BlimpCompositor::SubmitCompositorFrameAck() { 397 void BlimpCompositor::SubmitCompositorFrameAck() {
299 DCHECK(surface_factory_); 398 DCHECK(surface_factory_);
300 compositor_dependencies_->GetCompositorTaskRunner()->PostTask( 399 compositor_dependencies_->GetCompositorTaskRunner()->PostTask(
301 FROM_HERE, 400 FROM_HERE,
302 base::Bind(&BlimpCompositorFrameSinkProxyClient::SubmitCompositorFrameAck, 401 base::Bind(&BlimpCompositorFrameSinkProxyClient::SubmitCompositorFrameAck,
303 proxy_client_)); 402 proxy_client_));
304 } 403 }
305 404
405 void BlimpCompositor::MakeCopyRequestOnNextSwap(
406 std::unique_ptr<cc::CopyOutputRequest> copy_request) {
407 copy_requests_for_next_swap_.push_back(std::move(copy_request));
408 }
409
306 void BlimpCompositor::UnbindProxyClient() { 410 void BlimpCompositor::UnbindProxyClient() {
307 DCHECK(thread_checker_.CalledOnValidThread()); 411 DCHECK(thread_checker_.CalledOnValidThread());
308 DCHECK(surface_factory_); 412 DCHECK(surface_factory_);
309 413
310 DestroyDelegatedContent(); 414 DestroyDelegatedContent();
311 surface_factory_.reset(); 415 surface_factory_.reset();
312 proxy_client_ = nullptr; 416 proxy_client_ = nullptr;
313 } 417 }
314 418
315 void BlimpCompositor::ReturnResources( 419 void BlimpCompositor::ReturnResources(
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 454
351 // Remove any references for the surface layer that uses this 455 // Remove any references for the surface layer that uses this
352 // |local_frame_id_|. 456 // |local_frame_id_|.
353 layer_->RemoveAllChildren(); 457 layer_->RemoveAllChildren();
354 surface_factory_->Destroy(local_frame_id_); 458 surface_factory_->Destroy(local_frame_id_);
355 local_frame_id_ = cc::LocalFrameId(); 459 local_frame_id_ = cc::LocalFrameId();
356 } 460 }
357 461
358 void BlimpCompositor::CreateLayerTreeHost() { 462 void BlimpCompositor::CreateLayerTreeHost() {
359 DCHECK(!host_); 463 DCHECK(!host_);
360 VLOG(1) << "Creating LayerTreeHost.";
361 464
362 // Create the LayerTreeHost 465 // Create the LayerTreeHost
363 cc::LayerTreeHostInProcess::InitParams params; 466 cc::LayerTreeHostInProcess::InitParams params;
364 params.client = this; 467 params.client = this;
365 params.task_graph_runner = compositor_dependencies_->GetTaskGraphRunner(); 468 params.task_graph_runner = compositor_dependencies_->GetTaskGraphRunner();
366 params.gpu_memory_buffer_manager = 469 params.gpu_memory_buffer_manager =
367 GetEmbedderDeps()->GetGpuMemoryBufferManager(); 470 GetEmbedderDeps()->GetGpuMemoryBufferManager();
368 params.main_task_runner = base::ThreadTaskRunnerHandle::Get(); 471 params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
369 if (!use_threaded_layer_tree_host_) { 472 if (!use_threaded_layer_tree_host_) {
370 params.image_serialization_processor = 473 params.image_serialization_processor =
(...skipping 13 matching lines...) Expand all
384 host_ = cc::LayerTreeHostInProcess::CreateThreaded(compositor_task_runner, 487 host_ = cc::LayerTreeHostInProcess::CreateThreaded(compositor_task_runner,
385 &params); 488 &params);
386 } else { 489 } else {
387 host_ = cc::LayerTreeHostInProcess::CreateRemoteClient( 490 host_ = cc::LayerTreeHostInProcess::CreateRemoteClient(
388 this /* remote_proto_channel */, compositor_task_runner, &params); 491 this /* remote_proto_channel */, compositor_task_runner, &params);
389 } 492 }
390 } 493 }
391 494
392 void BlimpCompositor::DestroyLayerTreeHost() { 495 void BlimpCompositor::DestroyLayerTreeHost() {
393 DCHECK(host_); 496 DCHECK(host_);
394 VLOG(1) << "Destroying LayerTreeHost.";
395 497
396 // Tear down the output surface connection with the old LayerTreeHost 498 // Tear down the output surface connection with the old LayerTreeHost
397 // instance. 499 // instance.
398 DestroyDelegatedContent(); 500 DestroyDelegatedContent();
399 surface_factory_.reset(); 501 surface_factory_.reset();
400 502
401 // Destroy the old LayerTreeHost state. 503 // Destroy the old LayerTreeHost state.
402 host_.reset(); 504 host_.reset();
403 505
404 // Cancel any outstanding CompositorFrameSink requests. That way if we get an 506 // Cancel any outstanding CompositorFrameSink requests. That way if we get an
405 // async callback related to the old request we know to drop it. 507 // async callback related to the old request we know to drop it.
406 compositor_frame_sink_request_pending_ = false; 508 compositor_frame_sink_request_pending_ = false;
407 509
408 // Make sure we don't have a receiver at this point. 510 // Make sure we don't have a receiver at this point.
409 DCHECK(!remote_proto_channel_receiver_); 511 DCHECK(!remote_proto_channel_receiver_);
410 } 512 }
411 513
412 void BlimpCompositor::CheckPendingCommitCounts(bool flush) {
413 for (auto it = pending_commit_trackers_.begin();
414 it != pending_commit_trackers_.end();) {
415 if (flush || --it->first == 0) {
416 it->second.Run();
417 it = pending_commit_trackers_.erase(it);
418 } else {
419 ++it;
420 }
421 }
422 }
423
424 } // namespace client 514 } // namespace client
425 } // namespace blimp 515 } // namespace blimp
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698