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

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: addressed comments + tests. 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 DCHECK(thread_checker_.CalledOnValidThread());
71 surface_manager_->RegisterSurfaceClientId(surface_id_allocator_->client_id());
72 }
38 73
39 BlimpCompositor::~BlimpCompositor() { 74 BlimpCompositor::~BlimpCompositor() {
75 DCHECK(thread_checker_.CalledOnValidThread());
76
40 if (host_) 77 if (host_)
41 DestroyLayerTreeHost(); 78 DestroyLayerTreeHost();
79 surface_manager_->InvalidateSurfaceClientId(
80 surface_id_allocator_->client_id());
42 } 81 }
43 82
44 void BlimpCompositor::SetVisible(bool visible) { 83 void BlimpCompositor::SetVisible(bool visible) {
45 host_should_be_visible_ = visible; 84 host_should_be_visible_ = visible;
46 SetVisibleInternal(host_should_be_visible_); 85 if (host_)
47 } 86 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 } 87 }
73 88
74 bool BlimpCompositor::OnTouchEvent(const ui::MotionEvent& motion_event) { 89 bool BlimpCompositor::OnTouchEvent(const ui::MotionEvent& motion_event) {
75 if (input_manager_) 90 if (input_manager_)
76 return input_manager_->OnTouchEvent(motion_event); 91 return input_manager_->OnTouchEvent(motion_event);
77 return false; 92 return false;
78 } 93 }
79 94
80 void BlimpCompositor::WillBeginMainFrame() {} 95 void BlimpCompositor::RequestNewOutputSurface() {
96 DCHECK(!surface_factory_)
97 << "Any connection to the old output surface should have been destroyed";
81 98
82 void BlimpCompositor::DidBeginMainFrame() {} 99 scoped_refptr<BlimpContextProvider> compositor_context_provider =
100 BlimpContextProvider::Create(gfx::kNullAcceleratedWidget,
101 client_->GetGpuMemoryBufferManager());
83 102
84 void BlimpCompositor::BeginMainFrame(const cc::BeginFrameArgs& args) {} 103 // TODO(khushalsagar): Make a worker context and bind it to the current
104 // thread:
105 // Worker context is bound to the main thread in RenderThreadImpl. One day
106 // that will change and then this will have to be removed.
107 // worker_context_provider->BindToCurrentThread();
85 108
86 void BlimpCompositor::BeginMainFrameNotExpectedSoon() {} 109 std::unique_ptr<DelegatedOutputSurface> delegated_output_surface =
110 base::MakeUnique<DelegatedOutputSurface>(
111 std::move(compositor_context_provider), nullptr,
112 base::ThreadTaskRunnerHandle::Get(), compositor_task_runner_, this);
87 113
88 void BlimpCompositor::UpdateLayerTreeHost() {} 114 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 } 115 }
101 116
102 void BlimpCompositor::DidInitializeOutputSurface() { 117 void BlimpCompositor::DidCommitAndDrawFrame() {
118 BlimpStats::GetInstance()->Add(BlimpStats::COMMIT, 1);
103 } 119 }
104 120
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) { 121 void BlimpCompositor::SetProtoReceiver(ProtoReceiver* receiver) {
122 remote_proto_channel_receiver_ = receiver; 122 remote_proto_channel_receiver_ = receiver;
123 } 123 }
124 124
125 void BlimpCompositor::SendCompositorProto( 125 void BlimpCompositor::SendCompositorProto(
126 const cc::proto::CompositorMessage& proto) { 126 const cc::proto::CompositorMessage& proto) {
127 client_->SendCompositorMessage(render_widget_id_, proto); 127 client_->SendCompositorMessage(render_widget_id_, proto);
128 } 128 }
129 129
130 void BlimpCompositor::OnCompositorMessageReceived( 130 void BlimpCompositor::OnCompositorMessageReceived(
(...skipping 26 matching lines...) Expand all
157 DCHECK(remote_proto_channel_receiver_); 157 DCHECK(remote_proto_channel_receiver_);
158 remote_proto_channel_receiver_->OnProtoReceived(std::move(message)); 158 remote_proto_channel_receiver_->OnProtoReceived(std::move(message));
159 } 159 }
160 } 160 }
161 161
162 void BlimpCompositor::SendWebGestureEvent( 162 void BlimpCompositor::SendWebGestureEvent(
163 const blink::WebGestureEvent& gesture_event) { 163 const blink::WebGestureEvent& gesture_event) {
164 client_->SendWebGestureEvent(render_widget_id_, gesture_event); 164 client_->SendWebGestureEvent(render_widget_id_, gesture_event);
165 } 165 }
166 166
167 void BlimpCompositor::SetVisibleInternal(bool visible) { 167 void BlimpCompositor::BindToOutputSurface(BlimpOutputSurface* output_surface) {
168 if (!host_) 168 DCHECK(thread_checker_.CalledOnValidThread());
169 DCHECK(!output_surface_);
170 DCHECK(!surface_factory_);
171
172 output_surface_ = output_surface;
173 surface_factory_ =
174 base::MakeUnique<cc::SurfaceFactory>(surface_manager_, this);
175 }
176
177 void BlimpCompositor::SwapCompositorFrame(cc::CompositorFrame frame) {
178 DCHECK(thread_checker_.CalledOnValidThread());
179 DCHECK(surface_factory_);
180
181 cc::RenderPass* root_pass =
182 frame.delegated_frame_data->render_pass_list.back().get();
183 gfx::Size surface_size = root_pass->output_rect.size();
184
185 if (surface_id_.is_null() || current_surface_size_ != surface_size) {
186 DestroyDelegatedContent();
187 DCHECK(layer_->children().empty());
188
189 surface_id_ = surface_id_allocator_->GenerateId();
190 surface_factory_->Create(surface_id_);
191 current_surface_size_ = surface_size;
192
193 // manager must outlive compositors using it.
David Trainor- moved to gerrit 2016/08/24 23:09:34 manager -> Manager
Khushal 2016/08/25 02:35:39 Done.
194 scoped_refptr<cc::SurfaceLayer> content_layer = cc::SurfaceLayer::Create(
195 base::Bind(&SatisfyCallback, base::Unretained(surface_manager_)),
196 base::Bind(&RequireCallback, base::Unretained(surface_manager_)));
197 content_layer->SetSurfaceId(surface_id_, 1.f, surface_size);
198 content_layer->SetBounds(current_surface_size_);
199 content_layer->SetIsDrawable(true);
200 content_layer->SetContentsOpaque(true);
201
202 layer_->AddChild(content_layer);
203 }
204
205 surface_factory_->SubmitCompositorFrame(surface_id_, std::move(frame),
206 base::Closure());
207 }
208
209 void BlimpCompositor::UnbindOutputSurface(BlimpOutputSurface* output_surface) {
210 DCHECK(thread_checker_.CalledOnValidThread());
211 DCHECK(surface_factory_);
212 DCHECK_EQ(output_surface_, output_surface);
213
214 DestroyDelegatedContent();
215 surface_factory_.reset();
216 output_surface_ = nullptr;
217 }
218
219 void BlimpCompositor::ReturnResources(
220 const cc::ReturnedResourceArray& resources) {
221 DCHECK(surface_factory_);
222 output_surface_->ReclaimCompositorResources(resources);
223 }
224
225 void BlimpCompositor::DestroyDelegatedContent() {
226 if (surface_id_.is_null())
169 return; 227 return;
170 228
171 VLOG(1) << "Setting visibility to: " << visible 229 // Remove any references for the surface layer that uses this |surface_id_|.
172 << " for render widget: " << render_widget_id_; 230 layer_->RemoveAllChildren();
173 231 surface_factory_->Destroy(surface_id_);
174 if (visible && window_ != gfx::kNullAcceleratedWidget) { 232 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 } 233 }
191 234
192 void BlimpCompositor::CreateLayerTreeHost( 235 void BlimpCompositor::CreateLayerTreeHost(
193 const cc::proto::InitializeImpl& initialize_message) { 236 const cc::proto::InitializeImpl& initialize_message) {
194 DCHECK(!host_); 237 DCHECK(!host_);
195 VLOG(1) << "Creating LayerTreeHost for render widget: " << render_widget_id_; 238 VLOG(1) << "Creating LayerTreeHost for render widget: " << render_widget_id_;
196 239
197 // Create the LayerTreeHost 240 // Create the LayerTreeHost
198 cc::LayerTreeHost::InitParams params; 241 cc::LayerTreeHost::InitParams params;
199 params.client = this; 242 params.client = this;
200 params.task_graph_runner = client_->GetTaskGraphRunner(); 243 params.task_graph_runner = client_->GetTaskGraphRunner();
201 params.gpu_memory_buffer_manager = client_->GetGpuMemoryBufferManager(); 244 params.gpu_memory_buffer_manager = client_->GetGpuMemoryBufferManager();
202 params.main_task_runner = base::ThreadTaskRunnerHandle::Get(); 245 params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
203 params.image_serialization_processor = 246 params.image_serialization_processor =
204 client_->GetImageSerializationProcessor(); 247 client_->GetImageSerializationProcessor();
205 params.settings = client_->GetLayerTreeSettings(); 248 params.settings = client_->GetLayerTreeSettings();
206 params.animation_host = cc::AnimationHost::CreateMainInstance(); 249 params.animation_host = cc::AnimationHost::CreateMainInstance();
207 250
208 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner = 251 compositor_task_runner_ = client_->GetCompositorTaskRunner();
209 client_->GetCompositorTaskRunner();
210 252
211 host_ = 253 host_ = cc::LayerTreeHost::CreateRemoteClient(
212 cc::LayerTreeHost::CreateRemoteClient(this /* remote_proto_channel */, 254 this /* remote_proto_channel */, compositor_task_runner_, &params);
213 compositor_task_runner, &params); 255 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 256
218 DCHECK(!input_manager_); 257 DCHECK(!input_manager_);
219 input_manager_ = 258 input_manager_ = BlimpInputManager::Create(
220 BlimpInputManager::Create(this, 259 this, base::ThreadTaskRunnerHandle::Get(), compositor_task_runner_,
221 base::ThreadTaskRunnerHandle::Get(), 260 host_->GetInputHandler());
222 compositor_task_runner,
223 host_->GetInputHandler());
224 } 261 }
225 262
226 void BlimpCompositor::DestroyLayerTreeHost() { 263 void BlimpCompositor::DestroyLayerTreeHost() {
227 DCHECK(host_); 264 DCHECK(host_);
228 VLOG(1) << "Destroying LayerTreeHost for render widget: " 265 VLOG(1) << "Destroying LayerTreeHost for render widget: "
229 << render_widget_id_; 266 << render_widget_id_;
230 // Tear down the output surface connection with the old LayerTreeHost 267 // Tear down the output surface connection with the old LayerTreeHost
231 // instance. 268 // instance.
232 SetVisibleInternal(false); 269 DestroyDelegatedContent();
270 surface_factory_.reset();
233 271
234 // Destroy the old LayerTreeHost state. 272 // Destroy the old LayerTreeHost state.
235 host_.reset(); 273 host_.reset();
236 274
237 // Destroy the old input manager state. 275 // Destroy the old input manager state.
238 // It is important to destroy the LayerTreeHost before destroying the input 276 // 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 277 // manager as it has a reference to the cc::InputHandlerClient owned by the
240 // BlimpInputManager. 278 // BlimpInputManager.
241 input_manager_.reset(); 279 input_manager_.reset();
242 280
243 // Reset other state.
244 output_surface_request_pending_ = false;
245
246 // Make sure we don't have a receiver at this point. 281 // Make sure we don't have a receiver at this point.
247 DCHECK(!remote_proto_channel_receiver_); 282 DCHECK(!remote_proto_channel_receiver_);
248 } 283 }
249 284
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 285 } // namespace client
287 } // namespace blimp 286 } // namespace blimp
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698