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

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

Issue 1450423002: Add glue between the client and engine for Blimp (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@blimp_ipc2
Patch Set: Address comments! Created 5 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/compositor/blimp_compositor.h" 5 #include "blimp/client/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/lazy_instance.h" 9 #include "base/lazy_instance.h"
10 #include "base/numerics/safe_conversions.h"
10 #include "base/single_thread_task_runner.h" 11 #include "base/single_thread_task_runner.h"
11 #include "base/thread_task_runner_handle.h" 12 #include "base/thread_task_runner_handle.h"
12 #include "base/threading/thread.h" 13 #include "base/threading/thread.h"
13 #include "base/threading/thread_local.h" 14 #include "base/threading/thread_local.h"
14 #include "base/threading/thread_restrictions.h" 15 #include "base/threading/thread_restrictions.h"
15 #include "blimp/client/compositor/blimp_context_provider.h" 16 #include "blimp/client/compositor/blimp_context_provider.h"
16 #include "blimp/client/compositor/blimp_layer_tree_settings.h" 17 #include "blimp/client/compositor/blimp_layer_tree_settings.h"
17 #include "blimp/client/compositor/blimp_output_surface.h" 18 #include "blimp/client/compositor/blimp_output_surface.h"
18 #include "blimp/client/compositor/test/dummy_layer_driver.h" 19 #include "blimp/client/compositor/test/dummy_layer_driver.h"
19 #include "blimp/common/compositor/blimp_task_graph_runner.h" 20 #include "blimp/common/compositor/blimp_task_graph_runner.h"
21 #include "blimp/common/proto/blimp_message.pb.h"
22 #include "blimp/common/proto/compositor.pb.h"
23 #include "blimp/common/proto/input.pb.h"
24 #include "blimp/common/proto/render_widget.pb.h"
25 #include "blimp/net/black_hole_blimp_message_processor.h"
20 #include "cc/layers/layer.h" 26 #include "cc/layers/layer.h"
21 #include "cc/layers/layer_settings.h" 27 #include "cc/layers/layer_settings.h"
22 #include "cc/output/output_surface.h" 28 #include "cc/output/output_surface.h"
29 #include "cc/proto/compositor_message.pb.h"
23 #include "cc/trees/layer_tree_host.h" 30 #include "cc/trees/layer_tree_host.h"
31 #include "net/base/net_errors.h"
24 #include "ui/gl/gl_surface.h" 32 #include "ui/gl/gl_surface.h"
25 33
26 namespace { 34 namespace {
27 35
28 base::LazyInstance<blimp::BlimpTaskGraphRunner> g_task_graph_runner = 36 base::LazyInstance<blimp::BlimpTaskGraphRunner> g_task_graph_runner =
29 LAZY_INSTANCE_INITIALIZER; 37 LAZY_INSTANCE_INITIALIZER;
30 38
39 const int kDummyTabId = 0;
40
41 base::LazyInstance<blimp::BlackHoleBlimpMessageProcessor>
42 g_black_hole_message_processor = LAZY_INSTANCE_INITIALIZER;
43
31 // TODO(dtrainor): Replace this when Layer content comes from the server (see 44 // TODO(dtrainor): Replace this when Layer content comes from the server (see
32 // crbug.com/527200 for details). 45 // crbug.com/527200 for details).
33 base::LazyInstance<blimp::DummyLayerDriver> g_dummy_layer_driver = 46 base::LazyInstance<blimp::DummyLayerDriver> g_dummy_layer_driver =
34 LAZY_INSTANCE_INITIALIZER; 47 LAZY_INSTANCE_INITIALIZER;
35 48
36 } // namespace 49 } // namespace
37 50
38 namespace blimp { 51 namespace blimp {
39 52
40 BlimpCompositor::BlimpCompositor(float dp_to_px) 53 BlimpCompositor::BlimpCompositor(float dp_to_px)
41 : device_scale_factor_(dp_to_px) {} 54 : device_scale_factor_(dp_to_px),
55 window_(gfx::kNullAcceleratedWidget),
56 host_should_be_visible_(false),
57 output_surface_request_pending_(false),
58 remote_proto_channel_receiver_(nullptr),
59 render_widget_processor_(g_black_hole_message_processor.Pointer()) {
60 render_widget_processor_.SetDelegate(kDummyTabId, this);
61 }
42 62
43 BlimpCompositor::~BlimpCompositor() { 63 BlimpCompositor::~BlimpCompositor() {
64 render_widget_processor_.RemoveDelegate(kDummyTabId);
65 SetVisible(false);
66
44 // Destroy |host_| first, as it has a reference to the |settings_| and runs 67 // Destroy |host_| first, as it has a reference to the |settings_| and runs
45 // tasks on |compositor_thread_|. 68 // tasks on |compositor_thread_|.
46 host_.reset(); 69 host_.reset();
47 settings_.reset(); 70 settings_.reset();
48 if (compositor_thread_) 71 if (compositor_thread_)
49 compositor_thread_->Stop(); 72 compositor_thread_->Stop();
50 } 73 }
51 74
52 void BlimpCompositor::SetVisible(bool visible) { 75 void BlimpCompositor::SetVisible(bool visible) {
53 if (visible && !host_) { 76 // For testing. Remove once we bind to the network layer.
54 if (!settings_) { 77 if (!host_)
55 settings_.reset(new cc::LayerTreeSettings); 78 CreateLayerTreeHost(nullptr);
56 GenerateLayerTreeSettings(settings_.get());
57 }
58 79
59 // Create the LayerTreeHost 80 host_should_be_visible_ = visible;
60 cc::LayerTreeHost::InitParams params; 81 if (!host_ || host_->visible() == visible)
61 params.client = this; 82 return;
62 params.task_graph_runner = g_task_graph_runner.Pointer();
63 params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
64 params.settings = settings_.get();
65 83
66 // TODO(dtrainor): Swap this out with the remote client proxy when 84 if (!visible) {
nyquist 2015/11/24 08:55:43 Nit: Why the flipped conditional? I often find it
David Trainor- moved to gerrit 2015/11/25 17:56:41 Done.
67 // implemented. 85 // If not visible, hide the compositor and have it drop it's output surface.
68 host_ = 86 DCHECK(host_->visible());
69 cc::LayerTreeHost::CreateThreaded(GetCompositorTaskRunner(), &params); 87 host_->SetVisible(false);
70 88 if (!host_->output_surface_lost())
89 host_->ReleaseOutputSurface();
90 } else {
91 // If visible, show the compositor. If the compositor had an outstanding
92 // output surface request, trigger the request again so we build the output
93 // surface.
71 host_->SetVisible(true); 94 host_->SetVisible(true);
72 host_->SetViewportSize(viewport_size_); 95 if (output_surface_request_pending_)
73 host_->SetDeviceScaleFactor(device_scale_factor_); 96 HandlePendingOutputSurfaceRequest();
74
75 // Build the root Layer.
76 scoped_refptr<cc::Layer> root(cc::Layer::Create(cc::LayerSettings()));
77 host_->SetRootLayer(root);
78
79 // For testing, set the dummy Layer.
80 g_dummy_layer_driver.Pointer()->SetParentLayer(root);
81
82 } else if (!visible && host_) {
83 // Release the LayerTreeHost to free all resources when the compositor is no
84 // longer visible. This will destroy the underlying compositor components.
85 host_.reset();
86 } 97 }
87 } 98 }
88 99
89 void BlimpCompositor::SetSize(const gfx::Size& size) { 100 void BlimpCompositor::SetSize(const gfx::Size& size) {
90 viewport_size_ = size; 101 viewport_size_ = size;
91 if (host_) 102 if (host_)
92 host_->SetViewportSize(viewport_size_); 103 host_->SetViewportSize(viewport_size_);
93 } 104 }
94 105
106 void BlimpCompositor::SetAcceleratedWidget(gfx::AcceleratedWidget widget) {
107 if (widget == window_)
108 return;
109
110 DCHECK(window_ == gfx::kNullAcceleratedWidget);
111 window_ = widget;
112
113 // The compositor should not be visible if there is no output surface.
114 DCHECK(!host_ || !host_->visible());
115
116 // This will properly set visibility and will build the output surface if
117 // necessary.
118 SetVisible(host_should_be_visible_);
119 }
120
121 void BlimpCompositor::ReleaseAcceleratedWidget() {
122 if (window_ == gfx::kNullAcceleratedWidget)
123 return;
124
125 // Hide the compositor and drop the output surface if necessary.
126 SetVisible(false);
127
128 window_ = gfx::kNullAcceleratedWidget;
129 }
130
95 void BlimpCompositor::WillBeginMainFrame() {} 131 void BlimpCompositor::WillBeginMainFrame() {}
96 132
97 void BlimpCompositor::DidBeginMainFrame() {} 133 void BlimpCompositor::DidBeginMainFrame() {}
98 134
99 void BlimpCompositor::BeginMainFrame(const cc::BeginFrameArgs& args) {} 135 void BlimpCompositor::BeginMainFrame(const cc::BeginFrameArgs& args) {}
100 136
101 void BlimpCompositor::BeginMainFrameNotExpectedSoon() {} 137 void BlimpCompositor::BeginMainFrameNotExpectedSoon() {}
102 138
103 void BlimpCompositor::UpdateLayerTreeHost() {} 139 void BlimpCompositor::UpdateLayerTreeHost() {}
104 140
105 void BlimpCompositor::ApplyViewportDeltas( 141 void BlimpCompositor::ApplyViewportDeltas(
106 const gfx::Vector2dF& inner_delta, 142 const gfx::Vector2dF& inner_delta,
107 const gfx::Vector2dF& outer_delta, 143 const gfx::Vector2dF& outer_delta,
108 const gfx::Vector2dF& elastic_overscroll_delta, 144 const gfx::Vector2dF& elastic_overscroll_delta,
109 float page_scale, 145 float page_scale,
110 float top_controls_delta) {} 146 float top_controls_delta) {}
111 147
112 void BlimpCompositor::RequestNewOutputSurface() { 148 void BlimpCompositor::RequestNewOutputSurface() {
113 gfx::AcceleratedWidget widget = GetWindow(); 149 output_surface_request_pending_ = true;
114 DCHECK(widget); 150 HandlePendingOutputSurfaceRequest();
115
116 scoped_refptr<BlimpContextProvider> context_provider =
117 BlimpContextProvider::Create(widget);
118
119 host_->SetOutputSurface(
120 make_scoped_ptr(new BlimpOutputSurface(context_provider)));
121 } 151 }
122 152
123 void BlimpCompositor::DidInitializeOutputSurface() {} 153 void BlimpCompositor::DidInitializeOutputSurface() {}
nyquist 2015/11/24 08:59:39 Should this method reset output_surface_request_pe
David Trainor- moved to gerrit 2015/11/25 17:56:41 We set it when we explicitly call SetOutputSurface
124 154
125 void BlimpCompositor::DidFailToInitializeOutputSurface() {} 155 void BlimpCompositor::DidFailToInitializeOutputSurface() {}
126 156
127 void BlimpCompositor::WillCommit() {} 157 void BlimpCompositor::WillCommit() {}
128 158
129 void BlimpCompositor::DidCommit() {} 159 void BlimpCompositor::DidCommit() {}
130 160
131 void BlimpCompositor::DidCommitAndDrawFrame() {} 161 void BlimpCompositor::DidCommitAndDrawFrame() {}
132 162
133 void BlimpCompositor::DidCompleteSwapBuffers() {} 163 void BlimpCompositor::DidCompleteSwapBuffers() {}
134 164
135 void BlimpCompositor::DidCompletePageScaleAnimation() {} 165 void BlimpCompositor::DidCompletePageScaleAnimation() {}
136 166
137 void BlimpCompositor::RecordFrameTimingEvents( 167 void BlimpCompositor::RecordFrameTimingEvents(
138 scoped_ptr<cc::FrameTimingTracker::CompositeTimingSet> composite_events, 168 scoped_ptr<cc::FrameTimingTracker::CompositeTimingSet> composite_events,
139 scoped_ptr<cc::FrameTimingTracker::MainFrameTimingSet> main_frame_events) {} 169 scoped_ptr<cc::FrameTimingTracker::MainFrameTimingSet> main_frame_events) {}
140 170
171 void BlimpCompositor::SetProtoReceiver(ProtoReceiver* receiver) {
172 remote_proto_channel_receiver_ = receiver;
173 }
174
175 void BlimpCompositor::SendCompositorProto(
176 const cc::proto::CompositorMessage& proto) {
177 render_widget_processor_.SendCompositorMessage(kDummyTabId, proto);
178 }
179
180 void BlimpCompositor::OnRenderWidgetInitialized() {
181 // Tear down the output surface connection with the old compositor instance.
182 SetVisible(false);
183
184 // Destroy the old compositor instance.
nyquist 2015/11/24 08:55:43 This comment is a little bit confusing to me. The
David Trainor- moved to gerrit 2015/11/25 17:56:41 Done.
185 host_.reset();
186
187 // Reset other state.
188 output_surface_request_pending_ = false;
189
190 // Make sure we don't have a receiver at this point.
191 DCHECK(!remote_proto_channel_receiver_);
192 }
193
194 void BlimpCompositor::OnCompositorMessageReceived(
195 scoped_ptr<cc::proto::CompositorMessage> message) {
196 // TODO(dtrainor, khushalsagar): Look into the CompositorMessage. If it is
197 // initialize or shutdown, create or destroy |host_|.
198
199 // We should have a receiver if we're getting compositor messages that aren't
200 // initialize.
201 DCHECK(remote_proto_channel_receiver_);
202 remote_proto_channel_receiver_->OnProtoReceived(message.Pass());
203 }
204
141 void BlimpCompositor::GenerateLayerTreeSettings( 205 void BlimpCompositor::GenerateLayerTreeSettings(
142 cc::LayerTreeSettings* settings) { 206 cc::LayerTreeSettings* settings) {
143 PopulateCommonLayerTreeSettings(settings); 207 PopulateCommonLayerTreeSettings(settings);
144 } 208 }
145 209
210 void BlimpCompositor::CreateLayerTreeHost(
211 scoped_ptr<cc::proto::CompositorMessage> message) {
212 if (!settings_) {
213 settings_.reset(new cc::LayerTreeSettings);
214 GenerateLayerTreeSettings(settings_.get());
215 }
216
217 // Create the LayerTreeHost
218 cc::LayerTreeHost::InitParams params;
219 params.client = this;
220 params.task_graph_runner = g_task_graph_runner.Pointer();
221 params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
222 params.settings = settings_.get();
223
224 // TODO(dtrainor): Swap this out with the remote client proxy when
225 // implemented.
226 host_ =
227 cc::LayerTreeHost::CreateThreaded(GetCompositorTaskRunner(), &params);
228
229 // If we're supposed to be visible and we have a valid gfx::AcceleratedWidget
230 // make our compositor visible.
231 if (host_should_be_visible_ && window_ != gfx::kNullAcceleratedWidget)
232 host_->SetVisible(true);
233
234 host_->SetViewportSize(viewport_size_);
235 host_->SetDeviceScaleFactor(device_scale_factor_);
236
237 // For testing, set the dummy Layer.
238 scoped_refptr<cc::Layer> root(cc::Layer::Create(cc::LayerSettings()));
239 host_->SetRootLayer(root);
240 g_dummy_layer_driver.Pointer()->SetParentLayer(root);
241 }
242
146 scoped_refptr<base::SingleThreadTaskRunner> 243 scoped_refptr<base::SingleThreadTaskRunner>
147 BlimpCompositor::GetCompositorTaskRunner() { 244 BlimpCompositor::GetCompositorTaskRunner() {
148 if (compositor_thread_) 245 if (compositor_thread_)
149 return compositor_thread_->task_runner(); 246 return compositor_thread_->task_runner();
150 247
151 base::Thread::Options thread_options; 248 base::Thread::Options thread_options;
152 #if defined(OS_ANDROID) 249 #if defined(OS_ANDROID)
153 thread_options.priority = base::ThreadPriority::DISPLAY; 250 thread_options.priority = base::ThreadPriority::DISPLAY;
154 #endif 251 #endif
155 compositor_thread_.reset(new base::Thread("Compositor")); 252 compositor_thread_.reset(new base::Thread("Compositor"));
156 compositor_thread_->StartWithOptions(thread_options); 253 compositor_thread_->StartWithOptions(thread_options);
157 254
158 scoped_refptr<base::SingleThreadTaskRunner> task_runner = 255 scoped_refptr<base::SingleThreadTaskRunner> task_runner =
159 compositor_thread_->task_runner(); 256 compositor_thread_->task_runner();
160 task_runner->PostTask( 257 task_runner->PostTask(
161 FROM_HERE, 258 FROM_HERE,
162 base::Bind(base::IgnoreResult(&base::ThreadRestrictions::SetIOAllowed), 259 base::Bind(base::IgnoreResult(&base::ThreadRestrictions::SetIOAllowed),
163 false)); 260 false));
164 // TODO(dtrainor): Determine whether or not we can disallow waiting. 261 // TODO(dtrainor): Determine whether or not we can disallow waiting.
165 262
166 return task_runner; 263 return task_runner;
167 } 264 }
168 265
266 void BlimpCompositor::HandlePendingOutputSurfaceRequest() {
267 DCHECK(output_surface_request_pending_);
268
269 // We might have had a request from a LayerTreeHost that was then
270 // hidden (and hidden means we don't have a native surface).
271 // Also make sure we only handle this once.
272 if (!host_->visible() || window_ == gfx::kNullAcceleratedWidget)
273 return;
274
275 scoped_refptr<BlimpContextProvider> context_provider =
276 BlimpContextProvider::Create(window_);
277
278 host_->SetOutputSurface(
279 make_scoped_ptr(new BlimpOutputSurface(context_provider)));
280 output_surface_request_pending_ = false;
281 }
282
169 } // namespace blimp 283 } // namespace blimp
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698