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

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

Powered by Google App Engine
This is Rietveld 408576698