OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "content/browser/android/in_process/synchronous_compositor_impl.h" | 5 #include "content/browser/android/in_process/synchronous_compositor_impl.h" |
6 | 6 |
7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 base::LazyInstance<SynchronousCompositorFactoryImpl>::Leaky g_factory = | 44 base::LazyInstance<SynchronousCompositorFactoryImpl>::Leaky g_factory = |
45 LAZY_INSTANCE_INITIALIZER; | 45 LAZY_INSTANCE_INITIALIZER; |
46 | 46 |
47 } // namespace | 47 } // namespace |
48 | 48 |
49 DEFINE_WEB_CONTENTS_USER_DATA_KEY(SynchronousCompositorImpl); | 49 DEFINE_WEB_CONTENTS_USER_DATA_KEY(SynchronousCompositorImpl); |
50 | 50 |
51 // static | 51 // static |
52 SynchronousCompositorImpl* SynchronousCompositorImpl::FromID(int process_id, | 52 SynchronousCompositorImpl* SynchronousCompositorImpl::FromID(int process_id, |
53 int routing_id) { | 53 int routing_id) { |
54 if (g_factory == NULL) | 54 if (g_factory == nullptr) |
55 return NULL; | 55 return nullptr; |
56 RenderViewHost* rvh = RenderViewHost::FromID(process_id, routing_id); | 56 RenderViewHost* rvh = RenderViewHost::FromID(process_id, routing_id); |
57 if (!rvh) | 57 if (!rvh) |
58 return NULL; | 58 return nullptr; |
59 WebContents* contents = WebContents::FromRenderViewHost(rvh); | 59 WebContents* contents = WebContents::FromRenderViewHost(rvh); |
60 if (!contents) | 60 if (!contents) |
61 return NULL; | 61 return nullptr; |
62 return FromWebContents(contents); | 62 return FromWebContents(contents); |
63 } | 63 } |
64 | 64 |
65 SynchronousCompositorImpl* SynchronousCompositorImpl::FromRoutingID( | 65 SynchronousCompositorImpl* SynchronousCompositorImpl::FromRoutingID( |
66 int routing_id) { | 66 int routing_id) { |
67 return FromID(GetInProcessRendererId(), routing_id); | 67 return FromID(GetInProcessRendererId(), routing_id); |
68 } | 68 } |
69 | 69 |
70 SynchronousCompositorImpl::SynchronousCompositorImpl(WebContents* contents) | 70 SynchronousCompositorImpl::SynchronousCompositorImpl(WebContents* contents) |
71 : compositor_client_(NULL), | 71 : compositor_client_(nullptr), |
72 output_surface_(NULL), | 72 output_surface_(nullptr), |
73 begin_frame_source_(nullptr), | 73 begin_frame_source_(nullptr), |
74 contents_(contents), | 74 contents_(contents), |
75 routing_id_(contents->GetRoutingID()), | 75 routing_id_(contents->GetRoutingID()), |
76 input_handler_(NULL), | 76 input_handler_(nullptr), |
77 is_active_(false), | 77 registered_with_client_(false), |
| 78 is_active_(true), |
78 renderer_needs_begin_frames_(false), | 79 renderer_needs_begin_frames_(false), |
79 weak_ptr_factory_(this) { | 80 weak_ptr_factory_(this) { |
80 DCHECK(contents); | 81 DCHECK(contents); |
81 DCHECK_NE(routing_id_, MSG_ROUTING_NONE); | 82 DCHECK_NE(routing_id_, MSG_ROUTING_NONE); |
82 } | 83 } |
83 | 84 |
84 SynchronousCompositorImpl::~SynchronousCompositorImpl() { | 85 SynchronousCompositorImpl::~SynchronousCompositorImpl() { |
85 DCHECK(!output_surface_); | 86 DCHECK(!output_surface_); |
86 DCHECK(!begin_frame_source_); | 87 DCHECK(!begin_frame_source_); |
87 DCHECK(!input_handler_); | 88 DCHECK(!input_handler_); |
(...skipping 13 matching lines...) Expand all Loading... |
101 compositor_client_ = compositor_client; | 102 compositor_client_ = compositor_client; |
102 | 103 |
103 // SetClient is essentially the constructor and destructor of | 104 // SetClient is essentially the constructor and destructor of |
104 // SynchronousCompositorImpl. | 105 // SynchronousCompositorImpl. |
105 if (compositor_client_) { | 106 if (compositor_client_) { |
106 SynchronousCompositorRegistry::GetInstance()->RegisterCompositor( | 107 SynchronousCompositorRegistry::GetInstance()->RegisterCompositor( |
107 routing_id_, this); | 108 routing_id_, this); |
108 } | 109 } |
109 } | 110 } |
110 | 111 |
| 112 void SynchronousCompositorImpl::RegisterWithClient() { |
| 113 DCHECK(CalledOnValidThread()); |
| 114 DCHECK(compositor_client_); |
| 115 DCHECK(output_surface_); |
| 116 DCHECK(input_handler_); |
| 117 DCHECK(!registered_with_client_); |
| 118 registered_with_client_ = true; |
| 119 |
| 120 compositor_client_->DidInitializeCompositor(this); |
| 121 |
| 122 output_surface_->SetTreeActivationCallback( |
| 123 base::Bind(&SynchronousCompositorImpl::DidActivatePendingTree, |
| 124 weak_ptr_factory_.GetWeakPtr())); |
| 125 |
| 126 // Setting the delegate causes UpdateRootLayerState immediately so do it |
| 127 // after setting the client. |
| 128 input_handler_->SetRootLayerScrollOffsetDelegate(this); |
| 129 } |
| 130 |
111 // static | 131 // static |
112 void SynchronousCompositor::SetGpuService( | 132 void SynchronousCompositor::SetGpuService( |
113 scoped_refptr<gpu::InProcessCommandBuffer::Service> service) { | 133 scoped_refptr<gpu::InProcessCommandBuffer::Service> service) { |
114 g_factory.Get().SetDeferredGpuService(service); | 134 g_factory.Get().SetDeferredGpuService(service); |
115 } | 135 } |
116 | 136 |
117 // static | 137 // static |
118 void SynchronousCompositor::SetRecordFullDocument(bool record_full_document) { | 138 void SynchronousCompositor::SetRecordFullDocument(bool record_full_document) { |
119 g_factory.Get().SetRecordFullDocument(record_full_document); | 139 g_factory.Get().SetRecordFullDocument(record_full_document); |
120 } | 140 } |
121 | 141 |
122 void SynchronousCompositorImpl::DidInitializeRendererObjects( | 142 void SynchronousCompositorImpl::DidInitializeRendererObjects( |
123 SynchronousCompositorOutputSurface* output_surface, | 143 SynchronousCompositorOutputSurface* output_surface, |
124 SynchronousCompositorExternalBeginFrameSource* begin_frame_source, | 144 SynchronousCompositorExternalBeginFrameSource* begin_frame_source, |
125 cc::InputHandler* input_handler) { | 145 cc::InputHandler* input_handler) { |
126 DCHECK(!output_surface_); | 146 DCHECK(!output_surface_); |
127 DCHECK(!begin_frame_source_); | 147 DCHECK(!begin_frame_source_); |
128 DCHECK(output_surface); | 148 DCHECK(output_surface); |
129 DCHECK(begin_frame_source); | 149 DCHECK(begin_frame_source); |
130 DCHECK(compositor_client_); | 150 DCHECK(compositor_client_); |
131 DCHECK(input_handler); | 151 DCHECK(input_handler); |
132 | 152 |
133 output_surface_ = output_surface; | 153 output_surface_ = output_surface; |
134 begin_frame_source_ = begin_frame_source; | 154 begin_frame_source_ = begin_frame_source; |
| 155 input_handler_ = input_handler; |
135 | 156 |
| 157 output_surface_->SetCompositor(this); |
136 begin_frame_source_->SetCompositor(this); | 158 begin_frame_source_->SetCompositor(this); |
137 output_surface_->SetCompositor(this); | |
138 | |
139 output_surface_->SetTreeActivationCallback( | |
140 base::Bind(&SynchronousCompositorImpl::DidActivatePendingTree, | |
141 weak_ptr_factory_.GetWeakPtr())); | |
142 | |
143 OnNeedsBeginFramesChange(begin_frame_source_->NeedsBeginFrames()); | |
144 | |
145 compositor_client_->DidInitializeCompositor(this); | |
146 | |
147 SetInputHandler(input_handler); | |
148 } | 159 } |
149 | 160 |
150 void SynchronousCompositorImpl::DidDestroyRendererObjects() { | 161 void SynchronousCompositorImpl::DidDestroyRendererObjects() { |
151 DCHECK(output_surface_); | 162 DCHECK(output_surface_); |
152 DCHECK(begin_frame_source_); | 163 DCHECK(begin_frame_source_); |
153 DCHECK(compositor_client_); | 164 DCHECK(compositor_client_); |
154 | 165 |
| 166 if (registered_with_client_) { |
| 167 input_handler_->SetRootLayerScrollOffsetDelegate(nullptr); |
| 168 output_surface_->SetTreeActivationCallback(base::Closure()); |
| 169 compositor_client_->DidDestroyCompositor(this); |
| 170 registered_with_client_ = false; |
| 171 } |
| 172 |
155 begin_frame_source_->SetCompositor(nullptr); | 173 begin_frame_source_->SetCompositor(nullptr); |
156 output_surface_->SetCompositor(nullptr); | 174 output_surface_->SetCompositor(nullptr); |
157 SetInputHandler(nullptr); | 175 |
158 compositor_client_->DidDestroyCompositor(this); | 176 input_handler_ = nullptr; |
| 177 begin_frame_source_ = nullptr; |
159 output_surface_ = nullptr; | 178 output_surface_ = nullptr; |
160 begin_frame_source_ = nullptr; | |
161 } | 179 } |
162 | 180 |
163 scoped_ptr<cc::CompositorFrame> SynchronousCompositorImpl::DemandDrawHw( | 181 scoped_ptr<cc::CompositorFrame> SynchronousCompositorImpl::DemandDrawHw( |
164 gfx::Size surface_size, | 182 gfx::Size surface_size, |
165 const gfx::Transform& transform, | 183 const gfx::Transform& transform, |
166 gfx::Rect viewport, | 184 gfx::Rect viewport, |
167 gfx::Rect clip, | 185 gfx::Rect clip, |
168 gfx::Rect viewport_rect_for_tile_priority, | 186 gfx::Rect viewport_rect_for_tile_priority, |
169 const gfx::Transform& transform_for_tile_priority) { | 187 const gfx::Transform& transform_for_tile_priority) { |
170 DCHECK(CalledOnValidThread()); | 188 DCHECK(CalledOnValidThread()); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 if (bytes_limit && !current_bytes_limit) { | 244 if (bytes_limit && !current_bytes_limit) { |
227 g_factory.Get().CompositorInitializedHardwareDraw(); | 245 g_factory.Get().CompositorInitializedHardwareDraw(); |
228 } else if (!bytes_limit && current_bytes_limit) { | 246 } else if (!bytes_limit && current_bytes_limit) { |
229 g_factory.Get().CompositorReleasedHardwareDraw(); | 247 g_factory.Get().CompositorReleasedHardwareDraw(); |
230 } | 248 } |
231 } | 249 } |
232 | 250 |
233 void SynchronousCompositorImpl::PostInvalidate() { | 251 void SynchronousCompositorImpl::PostInvalidate() { |
234 DCHECK(CalledOnValidThread()); | 252 DCHECK(CalledOnValidThread()); |
235 DCHECK(compositor_client_); | 253 DCHECK(compositor_client_); |
236 compositor_client_->PostInvalidate(); | 254 if (registered_with_client_) |
| 255 compositor_client_->PostInvalidate(); |
237 } | 256 } |
238 | 257 |
239 void SynchronousCompositorImpl::DidChangeRootLayerScrollOffset() { | 258 void SynchronousCompositorImpl::DidChangeRootLayerScrollOffset() { |
240 if (input_handler_) | 259 if (input_handler_) |
241 input_handler_->OnRootLayerDelegatedScrollOffsetChanged(); | 260 input_handler_->OnRootLayerDelegatedScrollOffsetChanged(); |
242 } | 261 } |
243 | 262 |
244 void SynchronousCompositorImpl::SetIsActive(bool is_active) { | 263 void SynchronousCompositorImpl::SetIsActive(bool is_active) { |
245 TRACE_EVENT1("cc", "SynchronousCompositorImpl::SetIsActive", "is_active", | 264 TRACE_EVENT1("cc", "SynchronousCompositorImpl::SetIsActive", "is_active", |
246 is_active); | 265 is_active); |
247 is_active_ = is_active; | 266 is_active_ = is_active; |
248 UpdateNeedsBeginFrames(); | 267 UpdateNeedsBeginFrames(); |
249 } | 268 } |
250 | 269 |
251 void SynchronousCompositorImpl::OnNeedsBeginFramesChange( | 270 void SynchronousCompositorImpl::OnNeedsBeginFramesChange( |
252 bool needs_begin_frames) { | 271 bool needs_begin_frames) { |
253 renderer_needs_begin_frames_ = needs_begin_frames; | 272 renderer_needs_begin_frames_ = needs_begin_frames; |
254 UpdateNeedsBeginFrames(); | 273 UpdateNeedsBeginFrames(); |
255 } | 274 } |
256 | 275 |
257 void SynchronousCompositorImpl::BeginFrame(const cc::BeginFrameArgs& args) { | 276 void SynchronousCompositorImpl::BeginFrame(const cc::BeginFrameArgs& args) { |
| 277 if (!registered_with_client_) { |
| 278 RegisterWithClient(); |
| 279 DCHECK(registered_with_client_); |
| 280 } |
258 if (begin_frame_source_) | 281 if (begin_frame_source_) |
259 begin_frame_source_->BeginFrame(args); | 282 begin_frame_source_->BeginFrame(args); |
260 } | 283 } |
261 | 284 |
262 void SynchronousCompositorImpl::UpdateNeedsBeginFrames() { | 285 void SynchronousCompositorImpl::UpdateNeedsBeginFrames() { |
263 RenderWidgetHostViewAndroid* rwhv = static_cast<RenderWidgetHostViewAndroid*>( | 286 RenderWidgetHostViewAndroid* rwhv = static_cast<RenderWidgetHostViewAndroid*>( |
264 contents_->GetRenderWidgetHostView()); | 287 contents_->GetRenderWidgetHostView()); |
265 if (rwhv) | 288 if (rwhv) |
266 rwhv->OnSetNeedsBeginFrames(is_active_ && renderer_needs_begin_frames_); | 289 rwhv->OnSetNeedsBeginFrames(is_active_ && renderer_needs_begin_frames_); |
267 } | 290 } |
268 | 291 |
269 void SynchronousCompositorImpl::SetInputHandler( | |
270 cc::InputHandler* input_handler) { | |
271 DCHECK(CalledOnValidThread()); | |
272 | |
273 if (input_handler_) | |
274 input_handler_->SetRootLayerScrollOffsetDelegate(NULL); | |
275 | |
276 input_handler_ = input_handler; | |
277 | |
278 if (input_handler_) | |
279 input_handler_->SetRootLayerScrollOffsetDelegate(this); | |
280 } | |
281 | |
282 void SynchronousCompositorImpl::DidOverscroll( | 292 void SynchronousCompositorImpl::DidOverscroll( |
283 const DidOverscrollParams& params) { | 293 const DidOverscrollParams& params) { |
284 DCHECK(compositor_client_); | 294 DCHECK(compositor_client_); |
285 compositor_client_->DidOverscroll(params.accumulated_overscroll, | 295 if (registered_with_client_) { |
286 params.latest_overscroll_delta, | 296 compositor_client_->DidOverscroll(params.accumulated_overscroll, |
287 params.current_fling_velocity); | 297 params.latest_overscroll_delta, |
| 298 params.current_fling_velocity); |
| 299 } |
288 } | 300 } |
289 | 301 |
290 void SynchronousCompositorImpl::DidStopFlinging() { | 302 void SynchronousCompositorImpl::DidStopFlinging() { |
291 // It's important that the fling-end notification follow the same path as it | 303 // It's important that the fling-end notification follow the same path as it |
292 // takes on other platforms (using an IPC). This ensures consistent | 304 // takes on other platforms (using an IPC). This ensures consistent |
293 // bookkeeping at all stages of the input pipeline. | 305 // bookkeeping at all stages of the input pipeline. |
294 contents_->GetRenderProcessHost()->OnMessageReceived( | 306 contents_->GetRenderProcessHost()->OnMessageReceived( |
295 InputHostMsg_DidStopFlinging(routing_id_)); | 307 InputHostMsg_DidStopFlinging(routing_id_)); |
296 } | 308 } |
297 | 309 |
(...skipping 10 matching lines...) Expand all Loading... |
308 RenderProcessHost* rph = contents_->GetRenderProcessHost(); | 320 RenderProcessHost* rph = contents_->GetRenderProcessHost(); |
309 for (ScopedVector<IPC::Message>::const_iterator i = messages.begin(); | 321 for (ScopedVector<IPC::Message>::const_iterator i = messages.begin(); |
310 i != messages.end(); | 322 i != messages.end(); |
311 ++i) { | 323 ++i) { |
312 rph->OnMessageReceived(**i); | 324 rph->OnMessageReceived(**i); |
313 } | 325 } |
314 } | 326 } |
315 | 327 |
316 void SynchronousCompositorImpl::DidActivatePendingTree() { | 328 void SynchronousCompositorImpl::DidActivatePendingTree() { |
317 DCHECK(compositor_client_); | 329 DCHECK(compositor_client_); |
318 compositor_client_->DidUpdateContent(); | 330 if (registered_with_client_) |
| 331 compositor_client_->DidUpdateContent(); |
319 DeliverMessages(); | 332 DeliverMessages(); |
320 } | 333 } |
321 | 334 |
322 gfx::ScrollOffset SynchronousCompositorImpl::GetTotalScrollOffset() { | 335 gfx::ScrollOffset SynchronousCompositorImpl::GetTotalScrollOffset() { |
323 DCHECK(CalledOnValidThread()); | 336 DCHECK(CalledOnValidThread()); |
324 DCHECK(compositor_client_); | 337 DCHECK(compositor_client_); |
| 338 if (!registered_with_client_) |
| 339 return gfx::ScrollOffset(); |
325 // TODO(miletus): Make GetTotalRootLayerScrollOffset return | 340 // TODO(miletus): Make GetTotalRootLayerScrollOffset return |
326 // ScrollOffset. crbug.com/414283. | 341 // ScrollOffset. crbug.com/414283. |
327 return gfx::ScrollOffset( | 342 return gfx::ScrollOffset( |
328 compositor_client_->GetTotalRootLayerScrollOffset()); | 343 compositor_client_->GetTotalRootLayerScrollOffset()); |
329 } | 344 } |
330 | 345 |
331 bool SynchronousCompositorImpl::IsExternalFlingActive() const { | 346 bool SynchronousCompositorImpl::IsExternalFlingActive() const { |
332 DCHECK(CalledOnValidThread()); | 347 DCHECK(CalledOnValidThread()); |
333 DCHECK(compositor_client_); | 348 DCHECK(compositor_client_); |
| 349 if (!registered_with_client_) |
| 350 return false; |
334 return compositor_client_->IsExternalFlingActive(); | 351 return compositor_client_->IsExternalFlingActive(); |
335 } | 352 } |
336 | 353 |
337 void SynchronousCompositorImpl::UpdateRootLayerState( | 354 void SynchronousCompositorImpl::UpdateRootLayerState( |
338 const gfx::ScrollOffset& total_scroll_offset, | 355 const gfx::ScrollOffset& total_scroll_offset, |
339 const gfx::ScrollOffset& max_scroll_offset, | 356 const gfx::ScrollOffset& max_scroll_offset, |
340 const gfx::SizeF& scrollable_size, | 357 const gfx::SizeF& scrollable_size, |
341 float page_scale_factor, | 358 float page_scale_factor, |
342 float min_page_scale_factor, | 359 float min_page_scale_factor, |
343 float max_page_scale_factor) { | 360 float max_page_scale_factor) { |
344 DCHECK(CalledOnValidThread()); | 361 DCHECK(CalledOnValidThread()); |
345 DCHECK(compositor_client_); | 362 DCHECK(compositor_client_); |
346 | 363 |
347 // TODO(miletus): Pass in ScrollOffset. crbug.com/414283. | 364 if (registered_with_client_) { |
348 compositor_client_->UpdateRootLayerState( | 365 // TODO(miletus): Pass in ScrollOffset. crbug.com/414283. |
349 gfx::ScrollOffsetToVector2dF(total_scroll_offset), | 366 compositor_client_->UpdateRootLayerState( |
350 gfx::ScrollOffsetToVector2dF(max_scroll_offset), | 367 gfx::ScrollOffsetToVector2dF(total_scroll_offset), |
351 scrollable_size, | 368 gfx::ScrollOffsetToVector2dF(max_scroll_offset), |
352 page_scale_factor, | 369 scrollable_size, |
353 min_page_scale_factor, | 370 page_scale_factor, |
354 max_page_scale_factor); | 371 min_page_scale_factor, |
| 372 max_page_scale_factor); |
| 373 } |
355 } | 374 } |
356 | 375 |
357 // Not using base::NonThreadSafe as we want to enforce a more exacting threading | 376 // Not using base::NonThreadSafe as we want to enforce a more exacting threading |
358 // requirement: SynchronousCompositorImpl() must only be used on the UI thread. | 377 // requirement: SynchronousCompositorImpl() must only be used on the UI thread. |
359 bool SynchronousCompositorImpl::CalledOnValidThread() const { | 378 bool SynchronousCompositorImpl::CalledOnValidThread() const { |
360 return BrowserThread::CurrentlyOn(BrowserThread::UI); | 379 return BrowserThread::CurrentlyOn(BrowserThread::UI); |
361 } | 380 } |
362 | 381 |
363 // static | 382 // static |
364 void SynchronousCompositor::SetClientForWebContents( | 383 void SynchronousCompositor::SetClientForWebContents( |
365 WebContents* contents, | 384 WebContents* contents, |
366 SynchronousCompositorClient* client) { | 385 SynchronousCompositorClient* client) { |
367 DCHECK(contents); | 386 DCHECK(contents); |
368 if (client) { | 387 if (client) { |
369 g_factory.Get(); // Ensure it's initialized. | 388 g_factory.Get(); // Ensure it's initialized. |
370 SynchronousCompositorImpl::CreateForWebContents(contents); | 389 SynchronousCompositorImpl::CreateForWebContents(contents); |
371 } | 390 } |
372 SynchronousCompositorImpl* instance = | 391 SynchronousCompositorImpl* instance = |
373 SynchronousCompositorImpl::FromWebContents(contents); | 392 SynchronousCompositorImpl::FromWebContents(contents); |
374 DCHECK(instance); | 393 DCHECK(instance); |
375 instance->SetClient(client); | 394 instance->SetClient(client); |
376 } | 395 } |
377 | 396 |
378 } // namespace content | 397 } // namespace content |
OLD | NEW |