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

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

Issue 2266863003: blimp: Move BlimpCompositor to use delegated rendering. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: make gn happy Created 4 years, 4 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
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/feature/compositor/blimp_compositor.h" 5 #include "blimp/client/feature/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/numerics/safe_conversions.h" 10 #include "base/numerics/safe_conversions.h"
11 #include "base/single_thread_task_runner.h" 11 #include "base/single_thread_task_runner.h"
12 #include "base/threading/thread.h" 12 #include "base/threading/thread.h"
13 #include "base/threading/thread_local.h" 13 #include "base/threading/thread_local.h"
14 #include "base/threading/thread_restrictions.h" 14 #include "base/threading/thread_restrictions.h"
15 #include "base/threading/thread_task_runner_handle.h" 15 #include "base/threading/thread_task_runner_handle.h"
16 #include "blimp/client/core/compositor/delegated_output_surface.h"
16 #include "blimp/client/feature/compositor/blimp_context_provider.h" 17 #include "blimp/client/feature/compositor/blimp_context_provider.h"
17 #include "blimp/client/feature/compositor/blimp_delegating_output_surface.h" 18 #include "blimp/net/blimp_stats.h"
18 #include "blimp/client/feature/compositor/blimp_output_surface.h"
19 #include "cc/animation/animation_host.h" 19 #include "cc/animation/animation_host.h"
20 #include "cc/layers/layer.h" 20 #include "cc/layers/layer.h"
21 #include "cc/layers/surface_layer.h"
21 #include "cc/output/output_surface.h" 22 #include "cc/output/output_surface.h"
22 #include "cc/proto/compositor_message.pb.h" 23 #include "cc/proto/compositor_message.pb.h"
24 #include "cc/surfaces/surface.h"
25 #include "cc/surfaces/surface_factory.h"
26 #include "cc/surfaces/surface_id_allocator.h"
27 #include "cc/surfaces/surface_manager.h"
23 #include "cc/trees/layer_tree_host.h" 28 #include "cc/trees/layer_tree_host.h"
24 #include "net/base/net_errors.h" 29 #include "net/base/net_errors.h"
25 #include "ui/gl/gl_surface.h" 30 #include "ui/gl/gl_surface.h"
26 31
27 namespace blimp { 32 namespace blimp {
28 namespace client { 33 namespace client {
29 34
35 namespace {
36
37 void SatisfyCallback(cc::SurfaceManager* manager,
38 const cc::SurfaceSequence& sequence) {
39 std::vector<uint32_t> sequences;
40 sequences.push_back(sequence.sequence);
41 manager->DidSatisfySequences(sequence.client_id, &sequences);
42 }
43
44 void RequireCallback(cc::SurfaceManager* manager,
45 const cc::SurfaceId& id,
46 const cc::SurfaceSequence& sequence) {
47 cc::Surface* surface = manager->GetSurfaceForId(id);
48 if (!surface) {
49 LOG(ERROR) << "Attempting to require callback on nonexistent surface";
50 return;
51 }
52 surface->AddDestructionDependency(sequence);
53 }
54
55 } // namespace
56
30 BlimpCompositor::BlimpCompositor(int render_widget_id, 57 BlimpCompositor::BlimpCompositor(int render_widget_id,
58 cc::SurfaceManager* surface_manager,
59 uint32_t surface_client_id,
31 BlimpCompositorClient* client) 60 BlimpCompositorClient* client)
32 : render_widget_id_(render_widget_id), 61 : render_widget_id_(render_widget_id),
33 client_(client), 62 client_(client),
34 window_(gfx::kNullAcceleratedWidget),
35 host_should_be_visible_(false), 63 host_should_be_visible_(false),
36 output_surface_request_pending_(false), 64 output_surface_(nullptr),
37 remote_proto_channel_receiver_(nullptr) {} 65 surface_manager_(surface_manager),
66 surface_id_allocator_(
67 base::MakeUnique<cc::SurfaceIdAllocator>(surface_client_id)),
68 layer_(cc::Layer::Create()),
69 remote_proto_channel_receiver_(nullptr),
70 weak_factory_(this) {
71 DCHECK(thread_checker_.CalledOnValidThread());
72 surface_manager_->RegisterSurfaceClientId(surface_id_allocator_->client_id());
73 }
38 74
39 BlimpCompositor::~BlimpCompositor() { 75 BlimpCompositor::~BlimpCompositor() {
76 DCHECK(thread_checker_.CalledOnValidThread());
77
40 if (host_) 78 if (host_)
41 DestroyLayerTreeHost(); 79 DestroyLayerTreeHost();
80 surface_manager_->InvalidateSurfaceClientId(
81 surface_id_allocator_->client_id());
42 } 82 }
43 83
44 void BlimpCompositor::SetVisible(bool visible) { 84 void BlimpCompositor::SetVisible(bool visible) {
45 host_should_be_visible_ = visible; 85 host_should_be_visible_ = visible;
46 SetVisibleInternal(host_should_be_visible_); 86 if (host_)
47 } 87 host_->SetVisible(host_should_be_visible_);
48
49 void BlimpCompositor::SetAcceleratedWidget(gfx::AcceleratedWidget widget) {
50 if (widget == window_)
51 return;
52
53 DCHECK(window_ == gfx::kNullAcceleratedWidget);
54 window_ = widget;
55
56 // The compositor should not be visible if there is no output surface.
57 DCHECK(!host_ || !host_->visible());
58
59 // This will properly set visibility and will build the output surface if
60 // necessary.
61 SetVisibleInternal(host_should_be_visible_);
62 }
63
64 void BlimpCompositor::ReleaseAcceleratedWidget() {
65 if (window_ == gfx::kNullAcceleratedWidget)
66 return;
67
68 // Hide the compositor and drop the output surface if necessary.
69 SetVisibleInternal(false);
70
71 window_ = gfx::kNullAcceleratedWidget;
72 } 88 }
73 89
74 bool BlimpCompositor::OnTouchEvent(const ui::MotionEvent& motion_event) { 90 bool BlimpCompositor::OnTouchEvent(const ui::MotionEvent& motion_event) {
75 if (input_manager_) 91 if (input_manager_)
76 return input_manager_->OnTouchEvent(motion_event); 92 return input_manager_->OnTouchEvent(motion_event);
77 return false; 93 return false;
78 } 94 }
79 95
80 void BlimpCompositor::WillBeginMainFrame() {} 96 void BlimpCompositor::RequestNewOutputSurface() {
97 DCHECK(!surface_factory_)
98 << "Any connection to the old output surface should have been destroyed";
81 99
82 void BlimpCompositor::DidBeginMainFrame() {} 100 scoped_refptr<BlimpContextProvider> compositor_context_provider =
101 BlimpContextProvider::Create(gfx::kNullAcceleratedWidget,
102 client_->GetGpuMemoryBufferManager());
83 103
84 void BlimpCompositor::BeginMainFrame(const cc::BeginFrameArgs& args) {} 104 // TODO(khushalsagar): Make a worker context and bind it to the current
105 // thread:
106 // Worker context is bound to the main thread in RenderThreadImpl. One day
107 // that will change and then this will have to be removed.
108 // worker_context_provider->BindToCurrentThread();
85 109
86 void BlimpCompositor::BeginMainFrameNotExpectedSoon() {} 110 std::unique_ptr<DelegatedOutputSurface> delegated_output_surface =
111 base::MakeUnique<DelegatedOutputSurface>(
112 std::move(compositor_context_provider), nullptr,
113 base::ThreadTaskRunnerHandle::Get(), weak_factory_.GetWeakPtr());
87 114
88 void BlimpCompositor::UpdateLayerTreeHost() {} 115 host_->SetOutputSurface(std::move(delegated_output_surface));
89
90 void BlimpCompositor::ApplyViewportDeltas(
91 const gfx::Vector2dF& inner_delta,
92 const gfx::Vector2dF& outer_delta,
93 const gfx::Vector2dF& elastic_overscroll_delta,
94 float page_scale,
95 float top_controls_delta) {}
96
97 void BlimpCompositor::RequestNewOutputSurface() {
98 output_surface_request_pending_ = true;
99 HandlePendingOutputSurfaceRequest();
100 } 116 }
101 117
102 void BlimpCompositor::DidInitializeOutputSurface() { 118 void BlimpCompositor::DidCommitAndDrawFrame() {
119 BlimpStats::GetInstance()->Add(BlimpStats::COMMIT, 1);
103 } 120 }
104 121
105 void BlimpCompositor::DidFailToInitializeOutputSurface() {}
106
107 void BlimpCompositor::WillCommit() {}
108
109 void BlimpCompositor::DidCommit() {}
110
111 void BlimpCompositor::DidCommitAndDrawFrame() {
112 client_->DidCommitAndDrawFrame();
113 }
114
115 void BlimpCompositor::DidCompleteSwapBuffers() {
116 client_->DidCompleteSwapBuffers();
117 }
118
119 void BlimpCompositor::DidCompletePageScaleAnimation() {}
120
121 void BlimpCompositor::SetProtoReceiver(ProtoReceiver* receiver) { 122 void BlimpCompositor::SetProtoReceiver(ProtoReceiver* receiver) {
122 remote_proto_channel_receiver_ = receiver; 123 remote_proto_channel_receiver_ = receiver;
123 } 124 }
124 125
125 void BlimpCompositor::SendCompositorProto( 126 void BlimpCompositor::SendCompositorProto(
126 const cc::proto::CompositorMessage& proto) { 127 const cc::proto::CompositorMessage& proto) {
127 client_->SendCompositorMessage(render_widget_id_, proto); 128 client_->SendCompositorMessage(render_widget_id_, proto);
128 } 129 }
129 130
130 void BlimpCompositor::OnCompositorMessageReceived( 131 void BlimpCompositor::OnCompositorMessageReceived(
(...skipping 26 matching lines...) Expand all
157 DCHECK(remote_proto_channel_receiver_); 158 DCHECK(remote_proto_channel_receiver_);
158 remote_proto_channel_receiver_->OnProtoReceived(std::move(message)); 159 remote_proto_channel_receiver_->OnProtoReceived(std::move(message));
159 } 160 }
160 } 161 }
161 162
162 void BlimpCompositor::SendWebGestureEvent( 163 void BlimpCompositor::SendWebGestureEvent(
163 const blink::WebGestureEvent& gesture_event) { 164 const blink::WebGestureEvent& gesture_event) {
164 client_->SendWebGestureEvent(render_widget_id_, gesture_event); 165 client_->SendWebGestureEvent(render_widget_id_, gesture_event);
165 } 166 }
166 167
167 void BlimpCompositor::SetVisibleInternal(bool visible) { 168 void BlimpCompositor::BindToOutputSurface(
168 if (!host_) 169 base::WeakPtr<BlimpOutputSurface> output_surface) {
170 DCHECK(thread_checker_.CalledOnValidThread());
171 DCHECK(!output_surface_);
172 DCHECK(!surface_factory_);
173
174 output_surface_ = output_surface;
175 surface_factory_ =
176 base::MakeUnique<cc::SurfaceFactory>(surface_manager_, this);
177 }
178
179 void BlimpCompositor::SwapCompositorFrame(cc::CompositorFrame frame) {
180 DCHECK(thread_checker_.CalledOnValidThread());
181 DCHECK(surface_factory_);
182
183 cc::RenderPass* root_pass =
184 frame.delegated_frame_data->render_pass_list.back().get();
185 gfx::Size surface_size = root_pass->output_rect.size();
186
187 if (surface_id_.is_null() || current_surface_size_ != surface_size) {
188 DestroyDelegatedContent();
189 DCHECK(layer_->children().empty());
190
191 surface_id_ = surface_id_allocator_->GenerateId();
192 surface_factory_->Create(surface_id_);
193 current_surface_size_ = surface_size;
194
195 // Manager must outlive compositors using it.
196 scoped_refptr<cc::SurfaceLayer> content_layer = cc::SurfaceLayer::Create(
197 base::Bind(&SatisfyCallback, base::Unretained(surface_manager_)),
198 base::Bind(&RequireCallback, base::Unretained(surface_manager_)));
199 content_layer->SetSurfaceId(surface_id_, 1.f, surface_size);
200 content_layer->SetBounds(current_surface_size_);
201 content_layer->SetIsDrawable(true);
202 content_layer->SetContentsOpaque(true);
203
204 layer_->AddChild(content_layer);
205 }
206
207 surface_factory_->SubmitCompositorFrame(surface_id_, std::move(frame),
208 base::Closure());
209 }
210
211 void BlimpCompositor::UnbindOutputSurface() {
212 DCHECK(thread_checker_.CalledOnValidThread());
213 DCHECK(surface_factory_);
214
215 DestroyDelegatedContent();
216 surface_factory_.reset();
217 output_surface_ = nullptr;
218 }
219
220 void BlimpCompositor::ReturnResources(
221 const cc::ReturnedResourceArray& resources) {
222 DCHECK(surface_factory_);
223 compositor_task_runner_->PostTask(
224 FROM_HERE, base::Bind(&BlimpOutputSurface::ReclaimCompositorResources,
225 output_surface_, resources));
226 }
227
228 void BlimpCompositor::DestroyDelegatedContent() {
229 if (surface_id_.is_null())
169 return; 230 return;
170 231
171 VLOG(1) << "Setting visibility to: " << visible 232 // Remove any references for the surface layer that uses this |surface_id_|.
172 << " for render widget: " << render_widget_id_; 233 layer_->RemoveAllChildren();
173 234 surface_factory_->Destroy(surface_id_);
174 if (visible && window_ != gfx::kNullAcceleratedWidget) { 235 surface_id_ = cc::SurfaceId();
175 // If we're supposed to be visible and we have a valid
176 // gfx::AcceleratedWidget make our compositor visible. If the compositor
177 // had an outstanding output surface request, trigger the request again so
178 // we build the output surface.
179 host_->SetVisible(true);
180 if (output_surface_request_pending_)
181 HandlePendingOutputSurfaceRequest();
182 } else if (!visible) {
183 // If not visible, hide the compositor and have it drop it's output
184 // surface.
185 host_->SetVisible(false);
186 if (!host_->output_surface_lost()) {
187 host_->ReleaseOutputSurface();
188 }
189 }
190 } 236 }
191 237
192 void BlimpCompositor::CreateLayerTreeHost( 238 void BlimpCompositor::CreateLayerTreeHost(
193 const cc::proto::InitializeImpl& initialize_message) { 239 const cc::proto::InitializeImpl& initialize_message) {
194 DCHECK(!host_); 240 DCHECK(!host_);
195 VLOG(1) << "Creating LayerTreeHost for render widget: " << render_widget_id_; 241 VLOG(1) << "Creating LayerTreeHost for render widget: " << render_widget_id_;
196 242
197 // Create the LayerTreeHost 243 // Create the LayerTreeHost
198 cc::LayerTreeHost::InitParams params; 244 cc::LayerTreeHost::InitParams params;
199 params.client = this; 245 params.client = this;
200 params.task_graph_runner = client_->GetTaskGraphRunner(); 246 params.task_graph_runner = client_->GetTaskGraphRunner();
201 params.gpu_memory_buffer_manager = client_->GetGpuMemoryBufferManager(); 247 params.gpu_memory_buffer_manager = client_->GetGpuMemoryBufferManager();
202 params.main_task_runner = base::ThreadTaskRunnerHandle::Get(); 248 params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
203 params.image_serialization_processor = 249 params.image_serialization_processor =
204 client_->GetImageSerializationProcessor(); 250 client_->GetImageSerializationProcessor();
205 params.settings = client_->GetLayerTreeSettings(); 251 params.settings = client_->GetLayerTreeSettings();
206 params.animation_host = cc::AnimationHost::CreateMainInstance(); 252 params.animation_host = cc::AnimationHost::CreateMainInstance();
207 253
208 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner = 254 compositor_task_runner_ = client_->GetCompositorTaskRunner();
209 client_->GetCompositorTaskRunner();
210 255
211 host_ = 256 host_ = cc::LayerTreeHost::CreateRemoteClient(
212 cc::LayerTreeHost::CreateRemoteClient(this /* remote_proto_channel */, 257 this /* remote_proto_channel */, compositor_task_runner_, &params);
213 compositor_task_runner, &params); 258 host_->SetVisible(host_should_be_visible_);
214
215 // Now that we have a host, set the visiblity on it correctly.
216 SetVisibleInternal(host_should_be_visible_);
217 259
218 DCHECK(!input_manager_); 260 DCHECK(!input_manager_);
219 input_manager_ = 261 input_manager_ = BlimpInputManager::Create(
220 BlimpInputManager::Create(this, 262 this, base::ThreadTaskRunnerHandle::Get(), compositor_task_runner_,
221 base::ThreadTaskRunnerHandle::Get(), 263 host_->GetInputHandler());
222 compositor_task_runner,
223 host_->GetInputHandler());
224 } 264 }
225 265
226 void BlimpCompositor::DestroyLayerTreeHost() { 266 void BlimpCompositor::DestroyLayerTreeHost() {
227 DCHECK(host_); 267 DCHECK(host_);
228 VLOG(1) << "Destroying LayerTreeHost for render widget: " 268 VLOG(1) << "Destroying LayerTreeHost for render widget: "
229 << render_widget_id_; 269 << render_widget_id_;
230 // Tear down the output surface connection with the old LayerTreeHost 270 // Tear down the output surface connection with the old LayerTreeHost
231 // instance. 271 // instance.
232 SetVisibleInternal(false); 272 DestroyDelegatedContent();
273 surface_factory_.reset();
233 274
234 // Destroy the old LayerTreeHost state. 275 // Destroy the old LayerTreeHost state.
235 host_.reset(); 276 host_.reset();
236 277
237 // Destroy the old input manager state. 278 // Destroy the old input manager state.
238 // It is important to destroy the LayerTreeHost before destroying the input 279 // It is important to destroy the LayerTreeHost before destroying the input
239 // manager as it has a reference to the cc::InputHandlerClient owned by the 280 // manager as it has a reference to the cc::InputHandlerClient owned by the
240 // BlimpInputManager. 281 // BlimpInputManager.
241 input_manager_.reset(); 282 input_manager_.reset();
242 283
243 // Reset other state.
244 output_surface_request_pending_ = false;
245
246 // Make sure we don't have a receiver at this point. 284 // Make sure we don't have a receiver at this point.
247 DCHECK(!remote_proto_channel_receiver_); 285 DCHECK(!remote_proto_channel_receiver_);
248 } 286 }
249 287
250 void BlimpCompositor::HandlePendingOutputSurfaceRequest() {
251 DCHECK(output_surface_request_pending_);
252
253 // We might have had a request from a LayerTreeHost that was then
254 // hidden (and hidden means we don't have a native surface).
255 // Also make sure we only handle this once.
256 if (!host_->visible() || window_ == gfx::kNullAcceleratedWidget)
257 return;
258
259 scoped_refptr<BlimpContextProvider> display_context_provider =
260 BlimpContextProvider::Create(window_,
261 client_->GetGpuMemoryBufferManager());
262 scoped_refptr<BlimpContextProvider> compositor_context_provider =
263 BlimpContextProvider::Create(gfx::kNullAcceleratedWidget,
264 client_->GetGpuMemoryBufferManager());
265 scoped_refptr<BlimpContextProvider> worker_context_provider = nullptr;
266 // TODO(khushalsagar): Make a worker context and bind it to the current
267 // thread:
268 // Worker context is bound to the main thread in RenderThreadImpl. One day
269 // that will change and then this will have to be removed.
270 // worker_context_provider->BindToCurrentThread();
271
272 auto display_output_surface =
273 base::MakeUnique<BlimpOutputSurface>(std::move(display_context_provider));
274 auto delegating_output_surface =
275 base::MakeUnique<BlimpDelegatingOutputSurface>(
276 std::move(compositor_context_provider),
277 std::move(worker_context_provider), std::move(display_output_surface),
278 client_->GetGpuMemoryBufferManager(),
279 host_->settings().renderer_settings,
280 client_->GetCompositorTaskRunner().get());
281
282 host_->SetOutputSurface(std::move(delegating_output_surface));
283 output_surface_request_pending_ = false;
284 }
285
286 } // namespace client 288 } // namespace client
287 } // namespace blimp 289 } // 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