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

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

Issue 2624903006: Remove all blimp client code. (Closed)
Patch Set: Update buildbot configuration Created 3 years, 11 months 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "blimp/client/core/compositor/blimp_compositor.h"
6
7 #include "base/bind_helpers.h"
8 #include "base/command_line.h"
9 #include "base/memory/ptr_util.h"
10 #include "base/metrics/histogram_macros.h"
11 #include "base/numerics/safe_conversions.h"
12 #include "base/single_thread_task_runner.h"
13 #include "base/threading/thread.h"
14 #include "base/threading/thread_local.h"
15 #include "base/threading/thread_restrictions.h"
16 #include "base/threading/thread_task_runner_handle.h"
17 #include "blimp/client/core/compositor/blimp_compositor_dependencies.h"
18 #include "blimp/client/core/compositor/blimp_compositor_frame_sink.h"
19 #include "blimp/client/public/compositor/compositor_dependencies.h"
20 #include "blimp/net/blimp_stats.h"
21 #include "cc/animation/animation_host.h"
22 #include "cc/blimp/client_picture_cache.h"
23 #include "cc/blimp/compositor_state_deserializer.h"
24 #include "cc/blimp/image_serialization_processor.h"
25 #include "cc/layers/layer.h"
26 #include "cc/layers/surface_layer.h"
27 #include "cc/output/compositor_frame_sink.h"
28 #include "cc/proto/compositor_message.pb.h"
29 #include "cc/surfaces/surface.h"
30 #include "cc/surfaces/surface_factory.h"
31 #include "cc/surfaces/surface_id_allocator.h"
32 #include "cc/surfaces/surface_manager.h"
33 #include "cc/trees/layer_tree_host_in_process.h"
34 #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
35 #include "net/base/net_errors.h"
36 #include "ui/gl/gl_surface.h"
37
38 namespace blimp {
39 namespace client {
40
41 class BlimpCompositor::FrameTrackingSwapPromise : public cc::SwapPromise {
42 public:
43 FrameTrackingSwapPromise(
44 std::unique_ptr<cc::CopyOutputRequest> copy_request,
45 base::WeakPtr<BlimpCompositor> compositor,
46 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner)
47 : copy_request_(std::move(copy_request)),
48 compositor_weak_ptr_(compositor),
49 main_task_runner_(std::move(main_task_runner)) {}
50 ~FrameTrackingSwapPromise() override = default;
51
52 // cc::SwapPromise implementation.
53 void DidActivate() override {}
54 void WillSwap(cc::CompositorFrameMetadata* metadata) override {}
55 void DidSwap() override {
56 // DidSwap could be called on compositor thread and we need this to run on
57 // the main thread.
58 main_task_runner_->PostTask(
59 FROM_HERE,
60 base::Bind(&BlimpCompositor::MakeCopyRequestOnNextSwap,
61 compositor_weak_ptr_, base::Passed(&copy_request_)));
62 }
63 DidNotSwapAction DidNotSwap(DidNotSwapReason reason) override {
64 switch (reason) {
65 case DidNotSwapReason::SWAP_FAILS:
66 // The swap will fail if there is no frame damage, we can queue the
67 // request right away.
68 main_task_runner_->PostTask(
69 FROM_HERE, base::Bind(&BlimpCompositor::RequestCopyOfOutput,
70 compositor_weak_ptr_,
71 base::Passed(&copy_request_), false));
72 break;
73 case DidNotSwapReason::COMMIT_FAILS:
74 // The commit fails when the host is going away.
75 break;
76 case DidNotSwapReason::COMMIT_NO_UPDATE:
77 main_task_runner_->PostTask(
78 FROM_HERE, base::Bind(&BlimpCompositor::RequestCopyOfOutput,
79 compositor_weak_ptr_,
80 base::Passed(&copy_request_), false));
81 break;
82 case DidNotSwapReason::ACTIVATION_FAILS:
83 // Failure to activate the pending tree implies either the host in going
84 // away or the FrameSink was lost.
85 break;
86 }
87 return DidNotSwapAction::BREAK_PROMISE;
88 }
89 int64_t TraceId() const override { return 0; }
90
91 private:
92 std::unique_ptr<cc::CopyOutputRequest> copy_request_;
93 base::WeakPtr<BlimpCompositor> compositor_weak_ptr_;
94 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
95 };
96
97 // static
98 std::unique_ptr<BlimpCompositor> BlimpCompositor::Create(
99 BlimpCompositorDependencies* compositor_dependencies,
100 BlimpCompositorClient* client) {
101 std::unique_ptr<BlimpCompositor> compositor =
102 base::WrapUnique(new BlimpCompositor(compositor_dependencies, client));
103 compositor->Initialize();
104 return compositor;
105 }
106
107 BlimpCompositor::BlimpCompositor(
108 BlimpCompositorDependencies* compositor_dependencies,
109 BlimpCompositorClient* client)
110 : client_(client),
111 compositor_dependencies_(compositor_dependencies),
112 frame_sink_id_(compositor_dependencies_->GetEmbedderDependencies()
113 ->AllocateFrameSinkId()),
114 proxy_client_(nullptr),
115 bound_to_proxy_(false),
116 compositor_frame_sink_request_pending_(false),
117 layer_(cc::Layer::Create()),
118 weak_ptr_factory_(this) {
119 DCHECK(thread_checker_.CalledOnValidThread());
120 }
121
122 void BlimpCompositor::Initialize() {
123 surface_id_allocator_ = base::MakeUnique<cc::SurfaceIdAllocator>();
124 GetEmbedderDeps()->GetSurfaceManager()->RegisterFrameSinkId(frame_sink_id_);
125 surface_factory_ = base::MakeUnique<cc::SurfaceFactory>(
126 frame_sink_id_, GetEmbedderDeps()->GetSurfaceManager(), this);
127 animation_host_ = cc::AnimationHost::CreateMainInstance();
128 host_ = CreateLayerTreeHost();
129
130 std::unique_ptr<cc::ClientPictureCache> client_picture_cache =
131 compositor_dependencies_->GetImageSerializationProcessor()
132 ->CreateClientPictureCache();
133 compositor_state_deserializer_ =
134 base::MakeUnique<cc::CompositorStateDeserializer>(
135 host_.get(), std::move(client_picture_cache), this);
136 }
137
138 BlimpCompositor::~BlimpCompositor() {
139 DCHECK(thread_checker_.CalledOnValidThread());
140
141 DestroyLayerTreeHost();
142 GetEmbedderDeps()->GetSurfaceManager()->InvalidateFrameSinkId(frame_sink_id_);
143 }
144
145 void BlimpCompositor::SetVisible(bool visible) {
146 host_->SetVisible(visible);
147 }
148
149 bool BlimpCompositor::IsVisible() const {
150 return host_->IsVisible();
151 }
152
153 bool BlimpCompositor::HasPendingFrameUpdateFromEngine() const {
154 return pending_frame_update_.get() != nullptr;
155 }
156
157 void BlimpCompositor::RequestCopyOfOutput(
158 std::unique_ptr<cc::CopyOutputRequest> copy_request,
159 bool flush_pending_update) {
160 // If we don't have a FrameSink, fail right away.
161 if (!bound_to_proxy_)
162 return;
163
164 if (flush_pending_update) {
165 // Always request a commit when queuing the promise to make sure that any
166 // frames pending draws are cleared from the pipeline.
167 host_->QueueSwapPromise(base::MakeUnique<FrameTrackingSwapPromise>(
168 std::move(copy_request), weak_ptr_factory_.GetWeakPtr(),
169 base::ThreadTaskRunnerHandle::Get()));
170 host_->SetNeedsCommit();
171 } else if (local_frame_id_.is_valid()) {
172 // Make a copy request for the surface directly.
173 surface_factory_->RequestCopyOfSurface(std::move(copy_request));
174 }
175 }
176
177 void BlimpCompositor::UpdateLayerTreeHost() {
178 // UpdateLayerTreeHost marks the end of reporting of any deltas from the impl
179 // thread. So send a client state update if the local state was modified now.
180 FlushClientState();
181
182 if (pending_frame_update_) {
183 compositor_state_deserializer_->DeserializeCompositorUpdate(
184 pending_frame_update_->layer_tree_host());
185 pending_frame_update_ = nullptr;
186 cc::proto::CompositorMessage frame_ack;
187 frame_ack.set_frame_ack(true);
188 client_->SendCompositorMessage(frame_ack);
189 }
190
191 // Send back any deltas that have not yet been resolved on the main thread
192 // back to the impl thread.
193 compositor_state_deserializer_->SendUnappliedDeltasToLayerTreeHost();
194 }
195
196 void BlimpCompositor::ApplyViewportDeltas(
197 const gfx::Vector2dF& inner_delta,
198 const gfx::Vector2dF& outer_delta,
199 const gfx::Vector2dF& elastic_overscroll_delta,
200 float page_scale,
201 float top_controls_delta) {
202 compositor_state_deserializer_->ApplyViewportDeltas(
203 inner_delta, outer_delta, elastic_overscroll_delta, page_scale,
204 top_controls_delta);
205 }
206
207 void BlimpCompositor::RequestNewCompositorFrameSink() {
208 DCHECK(!bound_to_proxy_);
209 DCHECK(!compositor_frame_sink_request_pending_);
210
211 compositor_frame_sink_request_pending_ = true;
212 GetEmbedderDeps()->GetContextProviders(
213 base::Bind(&BlimpCompositor::OnContextProvidersCreated,
214 weak_ptr_factory_.GetWeakPtr()));
215 }
216
217 void BlimpCompositor::DidInitializeCompositorFrameSink() {
218 compositor_frame_sink_request_pending_ = false;
219 }
220
221 void BlimpCompositor::DidCommitAndDrawFrame() {}
222
223 void BlimpCompositor::OnCompositorMessageReceived(
224 std::unique_ptr<cc::proto::CompositorMessage> message) {
225 cc::proto::CompositorMessage* message_received = message.get();
226
227 if (message_received->has_layer_tree_host()) {
228 DCHECK(!pending_frame_update_)
229 << "We should have only a single frame in flight";
230
231 UMA_HISTOGRAM_MEMORY_KB("Blimp.Compositor.CommitSizeKb",
232 (float)message->ByteSize() / 1024);
233 BlimpStats::GetInstance()->Add(BlimpStats::COMMIT, 1);
234
235 pending_frame_update_ = std::move(message);
236 host_->SetNeedsAnimate();
237 }
238
239 if (message_received->client_state_update_ack()) {
240 DCHECK(client_state_update_ack_pending_);
241
242 client_state_update_ack_pending_ = false;
243 compositor_state_deserializer_->DidApplyStateUpdatesOnEngine();
244
245 // If there are any updates that we have queued because we were waiting for
246 // an ack, send them now.
247 FlushClientState();
248 }
249 }
250
251 const base::WeakPtr<cc::InputHandler>& BlimpCompositor::GetInputHandler() {
252 return host_->GetInputHandler();
253 }
254
255 void BlimpCompositor::OnContextProvidersCreated(
256 const scoped_refptr<cc::ContextProvider>& compositor_context_provider,
257 const scoped_refptr<cc::ContextProvider>& worker_context_provider) {
258 DCHECK(!bound_to_proxy_) << "Any connection to the old CompositorFrameSink "
259 "should have been destroyed";
260
261 // Make sure we still have a host and we're still expecting a
262 // CompositorFrameSink. This can happen if the host dies while the request is
263 // outstanding and we build a new one that hasn't asked for a surface yet.
264 if (!compositor_frame_sink_request_pending_)
265 return;
266
267 // Try again if the context creation failed.
268 if (!compositor_context_provider) {
269 GetEmbedderDeps()->GetContextProviders(
270 base::Bind(&BlimpCompositor::OnContextProvidersCreated,
271 weak_ptr_factory_.GetWeakPtr()));
272 return;
273 }
274
275 auto compositor_frame_sink = base::MakeUnique<BlimpCompositorFrameSink>(
276 std::move(compositor_context_provider),
277 std::move(worker_context_provider),
278 GetEmbedderDeps()->GetGpuMemoryBufferManager(), nullptr,
279 base::ThreadTaskRunnerHandle::Get(), weak_ptr_factory_.GetWeakPtr());
280
281 host_->SetCompositorFrameSink(std::move(compositor_frame_sink));
282 }
283
284 void BlimpCompositor::BindToProxyClient(
285 base::WeakPtr<BlimpCompositorFrameSinkProxyClient> proxy_client) {
286 DCHECK(thread_checker_.CalledOnValidThread());
287 DCHECK(!bound_to_proxy_);
288
289 bound_to_proxy_ = true;
290 proxy_client_ = proxy_client;
291 }
292
293 void BlimpCompositor::SubmitCompositorFrame(cc::CompositorFrame frame) {
294 DCHECK(thread_checker_.CalledOnValidThread());
295 DCHECK(bound_to_proxy_);
296
297 cc::RenderPass* root_pass = frame.render_pass_list.back().get();
298 gfx::Size surface_size = root_pass->output_rect.size();
299
300 if (!local_frame_id_.is_valid() || current_surface_size_ != surface_size) {
301 DestroyDelegatedContent();
302 DCHECK(layer_->children().empty());
303
304 local_frame_id_ = surface_id_allocator_->GenerateId();
305 current_surface_size_ = surface_size;
306
307 // manager must outlive compositors using it.
308 cc::SurfaceManager* surface_manager =
309 GetEmbedderDeps()->GetSurfaceManager();
310 auto content_layer =
311 cc::SurfaceLayer::Create(surface_manager->reference_factory());
312 cc::SurfaceId surface_id(surface_factory_->frame_sink_id(),
313 local_frame_id_);
314 content_layer->SetSurfaceInfo(
315 cc::SurfaceInfo(surface_id, 1.f, surface_size));
316 content_layer->SetBounds(current_surface_size_);
317 content_layer->SetIsDrawable(true);
318 content_layer->SetContentsOpaque(true);
319
320 layer_->AddChild(content_layer);
321 }
322
323 surface_factory_->SubmitCompositorFrame(
324 local_frame_id_, std::move(frame),
325 base::Bind(&BlimpCompositor::SubmitCompositorFrameAck,
326 weak_ptr_factory_.GetWeakPtr()));
327
328 for (auto& copy_request : copy_requests_for_next_swap_) {
329 surface_factory_->RequestCopyOfSurface(std::move(copy_request));
330 }
331 copy_requests_for_next_swap_.clear();
332 }
333
334 void BlimpCompositor::SubmitCompositorFrameAck() {
335 compositor_dependencies_->GetCompositorTaskRunner()->PostTask(
336 FROM_HERE,
337 base::Bind(&BlimpCompositorFrameSinkProxyClient::SubmitCompositorFrameAck,
338 proxy_client_));
339 }
340
341 void BlimpCompositor::MakeCopyRequestOnNextSwap(
342 std::unique_ptr<cc::CopyOutputRequest> copy_request) {
343 copy_requests_for_next_swap_.push_back(std::move(copy_request));
344 }
345
346 void BlimpCompositor::UnbindProxyClient() {
347 DCHECK(thread_checker_.CalledOnValidThread());
348 DCHECK(bound_to_proxy_);
349
350 DestroyDelegatedContent();
351 surface_factory_->Reset();
352 bound_to_proxy_ = false;
353 proxy_client_ = nullptr;
354 }
355
356 void BlimpCompositor::ReturnResources(
357 const cc::ReturnedResourceArray& resources) {
358 DCHECK(bound_to_proxy_);
359 compositor_dependencies_->GetCompositorTaskRunner()->PostTask(
360 FROM_HERE,
361 base::Bind(
362 &BlimpCompositorFrameSinkProxyClient::ReclaimCompositorResources,
363 proxy_client_, resources));
364 }
365
366 void BlimpCompositor::DidUpdateLocalState() {
367 client_state_dirty_ = true;
368 }
369
370 void BlimpCompositor::FlushClientState() {
371 // If the client state has not been modified, we don't need to send an update.
372 if (!client_state_dirty_)
373 return;
374
375 // If we had sent an update and an ack for it is still pending, we can't send
376 // another update till the ack is received.
377 if (client_state_update_ack_pending_)
378 return;
379
380 cc::proto::CompositorMessage message;
381 message.set_frame_ack(false);
382 compositor_state_deserializer_->PullClientStateUpdate(
383 message.mutable_client_state_update());
384
385 client_state_dirty_ = false;
386 client_state_update_ack_pending_ = true;
387 client_->SendCompositorMessage(message);
388 }
389
390 CompositorDependencies* BlimpCompositor::GetEmbedderDeps() {
391 return compositor_dependencies_->GetEmbedderDependencies();
392 }
393
394 void BlimpCompositor::DestroyDelegatedContent() {
395 if (!local_frame_id_.is_valid())
396 return;
397
398 // Remove any references for the surface layer that uses this
399 // |local_frame_id_|.
400 layer_->RemoveAllChildren();
401 surface_factory_->EvictSurface();
402 local_frame_id_ = cc::LocalFrameId();
403 }
404
405 std::unique_ptr<cc::LayerTreeHostInProcess>
406 BlimpCompositor::CreateLayerTreeHost() {
407 DCHECK(animation_host_);
408 std::unique_ptr<cc::LayerTreeHostInProcess> host;
409
410 cc::LayerTreeHostInProcess::InitParams params;
411 params.client = this;
412 params.task_graph_runner = compositor_dependencies_->GetTaskGraphRunner();
413 params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
414 params.image_serialization_processor =
415 compositor_dependencies_->GetImageSerializationProcessor();
416
417 cc::LayerTreeSettings* settings =
418 compositor_dependencies_->GetLayerTreeSettings();
419 params.settings = settings;
420 params.mutator_host = animation_host_.get();
421
422 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner =
423 compositor_dependencies_->GetCompositorTaskRunner();
424
425 host = cc::LayerTreeHostInProcess::CreateThreaded(compositor_task_runner,
426 &params);
427
428 return host;
429 }
430
431 void BlimpCompositor::DestroyLayerTreeHost() {
432 DCHECK(host_);
433
434 // Tear down the output surface connection with the old LayerTreeHost
435 // instance.
436 DestroyDelegatedContent();
437
438 // Destroy the old LayerTreeHost state.
439 host_.reset();
440
441 // Cancel any outstanding CompositorFrameSink requests. That way if we get an
442 // async callback related to the old request we know to drop it.
443 compositor_frame_sink_request_pending_ = false;
444 }
445
446 } // namespace client
447 } // namespace blimp
OLDNEW
« no previous file with comments | « blimp/client/core/compositor/blimp_compositor.h ('k') | blimp/client/core/compositor/blimp_compositor_dependencies.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698