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

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: Made the BlackHoleBlimpMessageProcessor official! 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) {
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 RequestNewOutputSurface();
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() {
Khushal 2015/11/19 19:28:24 We should be able to simplify this. The visibility
David Trainor- moved to gerrit 2015/11/20 17:58:53 I think this will get simplified when we split out
Khushal 2015/11/23 17:40:11 SGTM.
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;
Khushal 2015/11/19 19:28:24 nit: Have a method HandlePendingOutputSurfaceReque
David Trainor- moved to gerrit 2015/11/20 17:58:53 Done.
114 DCHECK(widget); 150
151 // We might have had a request from a LayerTreeHost that was then
152 // hidden (and hidden means we don't have a native surface).
153 // Also make sure we only handle this once.
154 if (!host_->visible() || window_ == gfx::kNullAcceleratedWidget)
155 return;
115 156
116 scoped_refptr<BlimpContextProvider> context_provider = 157 scoped_refptr<BlimpContextProvider> context_provider =
117 BlimpContextProvider::Create(widget); 158 BlimpContextProvider::Create(window_);
118 159
119 host_->SetOutputSurface( 160 host_->SetOutputSurface(
120 make_scoped_ptr(new BlimpOutputSurface(context_provider))); 161 make_scoped_ptr(new BlimpOutputSurface(context_provider)));
121 } 162 }
122 163
123 void BlimpCompositor::DidInitializeOutputSurface() {} 164 void BlimpCompositor::DidInitializeOutputSurface() {
165 output_surface_request_pending_ = false;
166 }
124 167
125 void BlimpCompositor::DidFailToInitializeOutputSurface() {} 168 void BlimpCompositor::DidFailToInitializeOutputSurface() {}
126 169
127 void BlimpCompositor::WillCommit() {} 170 void BlimpCompositor::WillCommit() {}
128 171
129 void BlimpCompositor::DidCommit() {} 172 void BlimpCompositor::DidCommit() {}
130 173
131 void BlimpCompositor::DidCommitAndDrawFrame() {} 174 void BlimpCompositor::DidCommitAndDrawFrame() {}
132 175
133 void BlimpCompositor::DidCompleteSwapBuffers() {} 176 void BlimpCompositor::DidCompleteSwapBuffers() {}
134 177
135 void BlimpCompositor::DidCompletePageScaleAnimation() {} 178 void BlimpCompositor::DidCompletePageScaleAnimation() {}
136 179
137 void BlimpCompositor::RecordFrameTimingEvents( 180 void BlimpCompositor::RecordFrameTimingEvents(
138 scoped_ptr<cc::FrameTimingTracker::CompositeTimingSet> composite_events, 181 scoped_ptr<cc::FrameTimingTracker::CompositeTimingSet> composite_events,
139 scoped_ptr<cc::FrameTimingTracker::MainFrameTimingSet> main_frame_events) {} 182 scoped_ptr<cc::FrameTimingTracker::MainFrameTimingSet> main_frame_events) {}
140 183
184 void BlimpCompositor::SetProtoReceiver(ProtoReceiver* receiver) {
185 remote_proto_channel_receiver_ = receiver;
186 }
187
188 void BlimpCompositor::SendCompositorProto(
189 const cc::proto::CompositorMessage& proto) {
190 render_widget_processor_.SendCompositorMessage(kDummyTabId, proto);
191 }
192
193 void BlimpCompositor::OnRenderWidgetInitialized() {
194 // Tear down the output surface connection with the old compositor instance.
195 SetVisible(false);
196
197 // Destroy the old compositor instance.
198 host_.reset();
199
200 // Reset other state.
201 output_surface_request_pending_ = false;
202
203 // Make sure we don't have a receiver at this point.
204 DCHECK(!remote_proto_channel_receiver_);
205 }
206
207 void BlimpCompositor::OnCompositorMessageReceived(
208 scoped_ptr<cc::proto::CompositorMessage> message) {
209 // TODO(dtrainor, khushalsagar): Look into the CompositorMessage. If it is
210 // initialize or shutdown, create or destroy |host_|.
211
212 // We should have a receiver if we're getting compositor messages that aren't
213 // initialize.
214 DCHECK(remote_proto_channel_receiver_);
215 remote_proto_channel_receiver_->OnProtoReceived(message.Pass());
216 }
217
141 void BlimpCompositor::GenerateLayerTreeSettings( 218 void BlimpCompositor::GenerateLayerTreeSettings(
142 cc::LayerTreeSettings* settings) { 219 cc::LayerTreeSettings* settings) {
143 PopulateCommonLayerTreeSettings(settings); 220 PopulateCommonLayerTreeSettings(settings);
144 } 221 }
145 222
223 void BlimpCompositor::CreateLayerTreeHost(
224 scoped_ptr<cc::proto::CompositorMessage> message) {
225 if (!settings_) {
226 settings_.reset(new cc::LayerTreeSettings);
227 GenerateLayerTreeSettings(settings_.get());
228 }
229
230 // Create the LayerTreeHost
231 cc::LayerTreeHost::InitParams params;
232 params.client = this;
233 params.task_graph_runner = g_task_graph_runner.Pointer();
234 params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
235 params.settings = settings_.get();
236
237 // TODO(dtrainor): Swap this out with the remote client proxy when
238 // implemented.
239 host_ =
240 cc::LayerTreeHost::CreateThreaded(GetCompositorTaskRunner(), &params);
241
242 // If we're supposed to be visible and we have a valid gfx::AcceleratedWidget
243 // make our compositor visible.
244 if (host_should_be_visible_ && window_ != gfx::kNullAcceleratedWidget)
245 host_->SetVisible(true);
246
247 host_->SetViewportSize(viewport_size_);
248 host_->SetDeviceScaleFactor(device_scale_factor_);
249
250 // For testing, set the dummy Layer.
251 scoped_refptr<cc::Layer> root(cc::Layer::Create(cc::LayerSettings()));
252 host_->SetRootLayer(root);
253 g_dummy_layer_driver.Pointer()->SetParentLayer(root);
254 }
255
146 scoped_refptr<base::SingleThreadTaskRunner> 256 scoped_refptr<base::SingleThreadTaskRunner>
147 BlimpCompositor::GetCompositorTaskRunner() { 257 BlimpCompositor::GetCompositorTaskRunner() {
148 if (compositor_thread_) 258 if (compositor_thread_)
149 return compositor_thread_->task_runner(); 259 return compositor_thread_->task_runner();
150 260
151 base::Thread::Options thread_options; 261 base::Thread::Options thread_options;
152 #if defined(OS_ANDROID) 262 #if defined(OS_ANDROID)
153 thread_options.priority = base::ThreadPriority::DISPLAY; 263 thread_options.priority = base::ThreadPriority::DISPLAY;
154 #endif 264 #endif
155 compositor_thread_.reset(new base::Thread("Compositor")); 265 compositor_thread_.reset(new base::Thread("Compositor"));
156 compositor_thread_->StartWithOptions(thread_options); 266 compositor_thread_->StartWithOptions(thread_options);
157 267
158 scoped_refptr<base::SingleThreadTaskRunner> task_runner = 268 scoped_refptr<base::SingleThreadTaskRunner> task_runner =
159 compositor_thread_->task_runner(); 269 compositor_thread_->task_runner();
160 task_runner->PostTask( 270 task_runner->PostTask(
161 FROM_HERE, 271 FROM_HERE,
162 base::Bind(base::IgnoreResult(&base::ThreadRestrictions::SetIOAllowed), 272 base::Bind(base::IgnoreResult(&base::ThreadRestrictions::SetIOAllowed),
163 false)); 273 false));
164 // TODO(dtrainor): Determine whether or not we can disallow waiting. 274 // TODO(dtrainor): Determine whether or not we can disallow waiting.
165 275
166 return task_runner; 276 return task_runner;
167 } 277 }
168 278
169 } // namespace blimp 279 } // namespace blimp
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698