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

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

Issue 2292723003: Move remaining Blimp feature code to core. (Closed)
Patch Set: Fix build break Created 4 years, 3 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/feature/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/numerics/safe_conversions.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/threading/thread.h"
13 #include "base/threading/thread_local.h"
14 #include "base/threading/thread_restrictions.h"
15 #include "base/threading/thread_task_runner_handle.h"
16 #include "blimp/client/core/compositor/blimp_compositor_dependencies.h"
17 #include "blimp/client/core/compositor/delegated_output_surface.h"
18 #include "blimp/client/public/compositor/compositor_dependencies.h"
19 #include "blimp/net/blimp_stats.h"
20 #include "cc/animation/animation_host.h"
21 #include "cc/layers/layer.h"
22 #include "cc/layers/surface_layer.h"
23 #include "cc/output/output_surface.h"
24 #include "cc/proto/compositor_message.pb.h"
25 #include "cc/surfaces/surface.h"
26 #include "cc/surfaces/surface_factory.h"
27 #include "cc/surfaces/surface_id_allocator.h"
28 #include "cc/surfaces/surface_manager.h"
29 #include "cc/trees/layer_tree_host.h"
30 #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
31 #include "net/base/net_errors.h"
32 #include "ui/gl/gl_surface.h"
33
34 namespace blimp {
35 namespace client {
36
37 namespace {
38
39 void SatisfyCallback(cc::SurfaceManager* manager,
40 const cc::SurfaceSequence& sequence) {
41 std::vector<uint32_t> sequences;
42 sequences.push_back(sequence.sequence);
43 manager->DidSatisfySequences(sequence.client_id, &sequences);
44 }
45
46 void RequireCallback(cc::SurfaceManager* manager,
47 const cc::SurfaceId& id,
48 const cc::SurfaceSequence& sequence) {
49 cc::Surface* surface = manager->GetSurfaceForId(id);
50 if (!surface) {
51 LOG(ERROR) << "Attempting to require callback on nonexistent surface";
52 return;
53 }
54 surface->AddDestructionDependency(sequence);
55 }
56
57 } // namespace
58
59 BlimpCompositor::BlimpCompositor(
60 int render_widget_id,
61 BlimpCompositorDependencies* compositor_dependencies,
62 BlimpCompositorClient* client)
63 : render_widget_id_(render_widget_id),
64 client_(client),
65 compositor_dependencies_(compositor_dependencies),
66 host_should_be_visible_(false),
67 output_surface_(nullptr),
68 output_surface_request_pending_(false),
69 layer_(cc::Layer::Create()),
70 remote_proto_channel_receiver_(nullptr),
71 weak_ptr_factory_(this) {
72 DCHECK(thread_checker_.CalledOnValidThread());
73
74 surface_id_allocator_ = base::MakeUnique<cc::SurfaceIdAllocator>(
75 GetEmbedderDeps()->AllocateSurfaceId());
76 GetEmbedderDeps()->GetSurfaceManager()->RegisterSurfaceClientId(
77 surface_id_allocator_->client_id());
78 }
79
80 BlimpCompositor::~BlimpCompositor() {
81 DCHECK(thread_checker_.CalledOnValidThread());
82
83 if (host_)
84 DestroyLayerTreeHost();
85
86 GetEmbedderDeps()->GetSurfaceManager()->InvalidateSurfaceClientId(
87 surface_id_allocator_->client_id());
88 }
89
90 void BlimpCompositor::SetVisible(bool visible) {
91 host_should_be_visible_ = visible;
92 if (host_)
93 host_->SetVisible(host_should_be_visible_);
94 }
95
96 bool BlimpCompositor::OnTouchEvent(const ui::MotionEvent& motion_event) {
97 if (input_manager_)
98 return input_manager_->OnTouchEvent(motion_event);
99 return false;
100 }
101
102 void BlimpCompositor::RequestNewOutputSurface() {
103 DCHECK(!surface_factory_);
104 DCHECK(!output_surface_request_pending_);
105
106 output_surface_request_pending_ = true;
107 GetEmbedderDeps()->GetContextProvider(
108 base::Bind(&BlimpCompositor::OnContextProviderCreated,
109 weak_ptr_factory_.GetWeakPtr()));
110 }
111
112 void BlimpCompositor::DidInitializeOutputSurface() {
113 output_surface_request_pending_ = false;
114 }
115
116 void BlimpCompositor::DidCommitAndDrawFrame() {
117 BlimpStats::GetInstance()->Add(BlimpStats::COMMIT, 1);
118 }
119
120 void BlimpCompositor::SetProtoReceiver(ProtoReceiver* receiver) {
121 remote_proto_channel_receiver_ = receiver;
122 }
123
124 void BlimpCompositor::SendCompositorProto(
125 const cc::proto::CompositorMessage& proto) {
126 client_->SendCompositorMessage(render_widget_id_, proto);
127 }
128
129 void BlimpCompositor::OnCompositorMessageReceived(
130 std::unique_ptr<cc::proto::CompositorMessage> message) {
131 DCHECK(message->has_to_impl());
132 const cc::proto::CompositorMessageToImpl& to_impl_proto =
133 message->to_impl();
134
135 DCHECK(to_impl_proto.has_message_type());
136 switch (to_impl_proto.message_type()) {
137 case cc::proto::CompositorMessageToImpl::UNKNOWN:
138 NOTIMPLEMENTED() << "Ignoring message of UNKNOWN type";
139 break;
140 case cc::proto::CompositorMessageToImpl::INITIALIZE_IMPL:
141 DCHECK(!host_);
142 DCHECK(to_impl_proto.has_initialize_impl_message());
143
144 // Create the remote client LayerTreeHost for the compositor.
145 CreateLayerTreeHost(to_impl_proto.initialize_impl_message());
146 break;
147 case cc::proto::CompositorMessageToImpl::CLOSE_IMPL:
148 DCHECK(host_);
149
150 // Destroy the remote client LayerTreeHost for the compositor.
151 DestroyLayerTreeHost();
152 break;
153 default:
154 // We should have a receiver if we're getting compositor messages that
155 // are not INITIALIZE_IMPL or CLOSE_IMPL.
156 DCHECK(remote_proto_channel_receiver_);
157 remote_proto_channel_receiver_->OnProtoReceived(std::move(message));
158 }
159 }
160
161 void BlimpCompositor::OnContextProviderCreated(
162 const scoped_refptr<cc::ContextProvider>& provider) {
163 DCHECK(!surface_factory_)
164 << "Any connection to the old output surface should have been destroyed";
165
166 // Make sure we still have a host and we're still expecting an output surface.
167 // This can happen if the host dies while the request is outstanding and we
168 // build a new one that hasn't asked for a surface yet.
169 if (!output_surface_request_pending_)
170 return;
171
172 // TODO(khushalsagar): Make a worker context and bind it to the current
173 // thread:
174 // Worker context is bound to the main thread in RenderThreadImpl. One day
175 // that will change and then this will have to be removed.
176 // worker_context_provider->BindToCurrentThread();
177 std::unique_ptr<DelegatedOutputSurface> delegated_output_surface =
178 base::MakeUnique<DelegatedOutputSurface>(
179 provider, nullptr, base::ThreadTaskRunnerHandle::Get(),
180 weak_ptr_factory_.GetWeakPtr());
181
182 host_->SetOutputSurface(std::move(delegated_output_surface));
183 }
184
185 void BlimpCompositor::SendWebGestureEvent(
186 const blink::WebGestureEvent& gesture_event) {
187 client_->SendWebGestureEvent(render_widget_id_, gesture_event);
188 }
189
190 void BlimpCompositor::BindToOutputSurface(
191 base::WeakPtr<BlimpOutputSurface> output_surface) {
192 DCHECK(thread_checker_.CalledOnValidThread());
193 DCHECK(!surface_factory_);
194
195 output_surface_ = output_surface;
196 surface_factory_ = base::MakeUnique<cc::SurfaceFactory>(
197 GetEmbedderDeps()->GetSurfaceManager(), this);
198 }
199
200 void BlimpCompositor::SwapCompositorFrame(cc::CompositorFrame frame) {
201 DCHECK(thread_checker_.CalledOnValidThread());
202 DCHECK(surface_factory_);
203
204 cc::RenderPass* root_pass =
205 frame.delegated_frame_data->render_pass_list.back().get();
206 gfx::Size surface_size = root_pass->output_rect.size();
207
208 if (surface_id_.is_null() || current_surface_size_ != surface_size) {
209 DestroyDelegatedContent();
210 DCHECK(layer_->children().empty());
211
212 surface_id_ = surface_id_allocator_->GenerateId();
213 surface_factory_->Create(surface_id_);
214 current_surface_size_ = surface_size;
215
216 // manager must outlive compositors using it.
217 cc::SurfaceManager* surface_manager =
218 GetEmbedderDeps()->GetSurfaceManager();
219 scoped_refptr<cc::SurfaceLayer> content_layer = cc::SurfaceLayer::Create(
220 base::Bind(&SatisfyCallback, base::Unretained(surface_manager)),
221 base::Bind(&RequireCallback, base::Unretained(surface_manager)));
222 content_layer->SetSurfaceId(surface_id_, 1.f, surface_size);
223 content_layer->SetBounds(current_surface_size_);
224 content_layer->SetIsDrawable(true);
225 content_layer->SetContentsOpaque(true);
226
227 layer_->AddChild(content_layer);
228 }
229
230 surface_factory_->SubmitCompositorFrame(surface_id_, std::move(frame),
231 base::Closure());
232 }
233
234 void BlimpCompositor::UnbindOutputSurface() {
235 DCHECK(thread_checker_.CalledOnValidThread());
236 DCHECK(surface_factory_);
237
238 DestroyDelegatedContent();
239 surface_factory_.reset();
240 output_surface_ = nullptr;
241 }
242
243 void BlimpCompositor::ReturnResources(
244 const cc::ReturnedResourceArray& resources) {
245 DCHECK(surface_factory_);
246 compositor_dependencies_->GetCompositorTaskRunner()->PostTask(
247 FROM_HERE, base::Bind(&BlimpOutputSurface::ReclaimCompositorResources,
248 output_surface_, resources));
249 }
250
251 CompositorDependencies* BlimpCompositor::GetEmbedderDeps() {
252 return compositor_dependencies_->GetEmbedderDependencies();
253 }
254
255 void BlimpCompositor::DestroyDelegatedContent() {
256 if (surface_id_.is_null())
257 return;
258
259 // Remove any references for the surface layer that uses this |surface_id_|.
260 layer_->RemoveAllChildren();
261 surface_factory_->Destroy(surface_id_);
262 surface_id_ = cc::SurfaceId();
263 }
264
265 void BlimpCompositor::CreateLayerTreeHost(
266 const cc::proto::InitializeImpl& initialize_message) {
267 DCHECK(!host_);
268 VLOG(1) << "Creating LayerTreeHost for render widget: " << render_widget_id_;
269
270 // Create the LayerTreeHost
271 cc::LayerTreeHost::InitParams params;
272 params.client = this;
273 params.task_graph_runner = compositor_dependencies_->GetTaskGraphRunner();
274 params.gpu_memory_buffer_manager =
275 GetEmbedderDeps()->GetGpuMemoryBufferManager();
276 params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
277 params.image_serialization_processor =
278 compositor_dependencies_->GetImageSerializationProcessor();
279 params.settings = GetEmbedderDeps()->GetLayerTreeSettings();
280 params.animation_host = cc::AnimationHost::CreateMainInstance();
281
282 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner =
283 compositor_dependencies_->GetCompositorTaskRunner();
284
285 host_ = cc::LayerTreeHost::CreateRemoteClient(
286 this /* remote_proto_channel */, compositor_task_runner, &params);
287 host_->SetVisible(host_should_be_visible_);
288
289 DCHECK(!input_manager_);
290 input_manager_ = BlimpInputManager::Create(
291 this, base::ThreadTaskRunnerHandle::Get(), compositor_task_runner,
292 host_->GetInputHandler());
293 }
294
295 void BlimpCompositor::DestroyLayerTreeHost() {
296 DCHECK(host_);
297 VLOG(1) << "Destroying LayerTreeHost for render widget: "
298 << render_widget_id_;
299 // Tear down the output surface connection with the old LayerTreeHost
300 // instance.
301 DestroyDelegatedContent();
302 surface_factory_.reset();
303
304 // Destroy the old LayerTreeHost state.
305 host_.reset();
306
307 // Destroy the old input manager state.
308 // It is important to destroy the LayerTreeHost before destroying the input
309 // manager as it has a reference to the cc::InputHandlerClient owned by the
310 // BlimpInputManager.
311 input_manager_.reset();
312
313 // Cancel any outstanding OutputSurface requests. That way if we get an async
314 // callback related to the old request we know to drop it.
315 output_surface_request_pending_ = false;
316
317 // Make sure we don't have a receiver at this point.
318 DCHECK(!remote_proto_channel_receiver_);
319 }
320
321 } // namespace client
322 } // namespace blimp
OLDNEW
« no previous file with comments | « blimp/client/feature/compositor/blimp_compositor.h ('k') | blimp/client/feature/compositor/blimp_compositor_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698