OLD | NEW |
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 "content/renderer/android/synchronous_compositor_proxy.h" | 5 #include "content/renderer/android/synchronous_compositor_proxy.h" |
6 | 6 |
7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/memory/shared_memory.h" | 9 #include "base/memory/shared_memory.h" |
10 #include "cc/ipc/cc_param_traits.h" | 10 #include "cc/ipc/cc_param_traits.h" |
11 #include "content/common/android/sync_compositor_messages.h" | 11 #include "content/common/android/sync_compositor_messages.h" |
12 #include "content/common/android/sync_compositor_statics.h" | 12 #include "content/common/android/sync_compositor_statics.h" |
13 #include "content/public/common/content_switches.h" | 13 #include "content/public/common/content_switches.h" |
14 #include "ipc/ipc_message.h" | 14 #include "ipc/ipc_message.h" |
15 #include "ipc/ipc_sender.h" | 15 #include "ipc/ipc_sender.h" |
16 #include "third_party/skia/include/core/SkBitmap.h" | 16 #include "third_party/skia/include/core/SkBitmap.h" |
17 #include "third_party/skia/include/core/SkCanvas.h" | 17 #include "third_party/skia/include/core/SkCanvas.h" |
18 #include "third_party/skia/include/core/SkImageInfo.h" | 18 #include "third_party/skia/include/core/SkImageInfo.h" |
19 #include "third_party/skia/include/core/SkRegion.h" | 19 #include "third_party/skia/include/core/SkRegion.h" |
20 #include "ui/gfx/skia_util.h" | 20 #include "ui/gfx/skia_util.h" |
21 | 21 |
22 namespace content { | 22 namespace content { |
23 | 23 |
24 SynchronousCompositorProxy::SynchronousCompositorProxy( | 24 SynchronousCompositorProxy::SynchronousCompositorProxy( |
25 int routing_id, | 25 int routing_id, |
26 IPC::Sender* sender, | 26 IPC::Sender* sender, |
27 SynchronousCompositorExternalBeginFrameSource* begin_frame_source, | |
28 ui::SynchronousInputHandlerProxy* input_handler_proxy) | 27 ui::SynchronousInputHandlerProxy* input_handler_proxy) |
29 : routing_id_(routing_id), | 28 : routing_id_(routing_id), |
30 sender_(sender), | 29 sender_(sender), |
31 begin_frame_source_(begin_frame_source), | |
32 input_handler_proxy_(input_handler_proxy), | 30 input_handler_proxy_(input_handler_proxy), |
33 use_in_process_zero_copy_software_draw_( | 31 use_in_process_zero_copy_software_draw_( |
34 base::CommandLine::ForCurrentProcess()->HasSwitch( | 32 base::CommandLine::ForCurrentProcess()->HasSwitch( |
35 switches::kSingleProcess)), | 33 switches::kSingleProcess)), |
36 output_surface_(nullptr), | 34 output_surface_(nullptr), |
37 inside_receive_(false), | 35 inside_receive_(false), |
38 hardware_draw_reply_(nullptr), | 36 hardware_draw_reply_(nullptr), |
39 software_draw_reply_(nullptr), | 37 software_draw_reply_(nullptr), |
40 version_(0u), | 38 version_(0u), |
41 page_scale_factor_(0.f), | 39 page_scale_factor_(0.f), |
42 min_page_scale_factor_(0.f), | 40 min_page_scale_factor_(0.f), |
43 max_page_scale_factor_(0.f), | 41 max_page_scale_factor_(0.f), |
44 need_animate_scroll_(false), | 42 need_animate_scroll_(false), |
45 need_invalidate_count_(0u), | 43 need_invalidate_count_(0u), |
46 need_begin_frame_(false), | |
47 did_activate_pending_tree_count_(0u) { | 44 did_activate_pending_tree_count_(0u) { |
48 DCHECK(begin_frame_source_); | |
49 DCHECK(input_handler_proxy_); | 45 DCHECK(input_handler_proxy_); |
50 begin_frame_source_->SetClient(this); | |
51 input_handler_proxy_->SetOnlySynchronouslyAnimateRootFlings(this); | 46 input_handler_proxy_->SetOnlySynchronouslyAnimateRootFlings(this); |
52 } | 47 } |
53 | 48 |
54 SynchronousCompositorProxy::~SynchronousCompositorProxy() { | 49 SynchronousCompositorProxy::~SynchronousCompositorProxy() { |
55 SetOutputSurface(nullptr); | 50 SetOutputSurface(nullptr); |
56 begin_frame_source_->SetClient(nullptr); | |
57 input_handler_proxy_->SetOnlySynchronouslyAnimateRootFlings(nullptr); | 51 input_handler_proxy_->SetOnlySynchronouslyAnimateRootFlings(nullptr); |
58 } | 52 } |
59 | 53 |
60 void SynchronousCompositorProxy::SetOutputSurface( | 54 void SynchronousCompositorProxy::SetOutputSurface( |
61 SynchronousCompositorOutputSurface* output_surface) { | 55 SynchronousCompositorOutputSurface* output_surface) { |
62 DCHECK_NE(output_surface_, output_surface); | 56 DCHECK_NE(output_surface_, output_surface); |
63 if (output_surface_) { | 57 if (output_surface_) { |
64 output_surface_->SetSyncClient(nullptr); | 58 output_surface_->SetSyncClient(nullptr); |
65 } | 59 } |
66 output_surface_ = output_surface; | 60 output_surface_ = output_surface; |
(...skipping 24 matching lines...) Expand all Loading... |
91 max_scroll_offset_ = max_scroll_offset; | 85 max_scroll_offset_ = max_scroll_offset; |
92 scrollable_size_ = scrollable_size; | 86 scrollable_size_ = scrollable_size; |
93 page_scale_factor_ = page_scale_factor; | 87 page_scale_factor_ = page_scale_factor; |
94 min_page_scale_factor_ = min_page_scale_factor; | 88 min_page_scale_factor_ = min_page_scale_factor; |
95 max_page_scale_factor_ = max_page_scale_factor; | 89 max_page_scale_factor_ = max_page_scale_factor; |
96 | 90 |
97 SendAsyncRendererStateIfNeeded(); | 91 SendAsyncRendererStateIfNeeded(); |
98 } | 92 } |
99 } | 93 } |
100 | 94 |
101 void SynchronousCompositorProxy::OnNeedsBeginFramesChange( | |
102 bool needs_begin_frames) { | |
103 if (need_begin_frame_ == needs_begin_frames) | |
104 return; | |
105 need_begin_frame_ = needs_begin_frames; | |
106 SendAsyncRendererStateIfNeeded(); | |
107 } | |
108 | |
109 void SynchronousCompositorProxy::Invalidate() { | 95 void SynchronousCompositorProxy::Invalidate() { |
110 ++need_invalidate_count_; | 96 ++need_invalidate_count_; |
111 SendAsyncRendererStateIfNeeded(); | 97 SendAsyncRendererStateIfNeeded(); |
112 } | 98 } |
113 | 99 |
114 void SynchronousCompositorProxy::DidActivatePendingTree() { | 100 void SynchronousCompositorProxy::DidActivatePendingTree() { |
115 ++did_activate_pending_tree_count_; | 101 ++did_activate_pending_tree_count_; |
116 SendAsyncRendererStateIfNeeded(); | 102 SendAsyncRendererStateIfNeeded(); |
117 } | 103 } |
118 | 104 |
119 void SynchronousCompositorProxy::SendAsyncRendererStateIfNeeded() { | 105 void SynchronousCompositorProxy::SendAsyncRendererStateIfNeeded() { |
120 if (inside_receive_) | 106 if (inside_receive_) |
121 return; | 107 return; |
122 SyncCompositorCommonRendererParams params; | 108 SyncCompositorCommonRendererParams params; |
123 PopulateCommonParams(¶ms); | 109 PopulateCommonParams(¶ms); |
124 Send(new SyncCompositorHostMsg_UpdateState(routing_id_, params)); | 110 Send(new SyncCompositorHostMsg_UpdateState(routing_id_, params)); |
125 } | 111 } |
126 | 112 |
127 void SynchronousCompositorProxy::PopulateCommonParams( | 113 void SynchronousCompositorProxy::PopulateCommonParams( |
128 SyncCompositorCommonRendererParams* params) const { | 114 SyncCompositorCommonRendererParams* params) const { |
129 params->version = ++version_; | 115 params->version = ++version_; |
130 params->total_scroll_offset = total_scroll_offset_; | 116 params->total_scroll_offset = total_scroll_offset_; |
131 params->max_scroll_offset = max_scroll_offset_; | 117 params->max_scroll_offset = max_scroll_offset_; |
132 params->scrollable_size = scrollable_size_; | 118 params->scrollable_size = scrollable_size_; |
133 params->page_scale_factor = page_scale_factor_; | 119 params->page_scale_factor = page_scale_factor_; |
134 params->min_page_scale_factor = min_page_scale_factor_; | 120 params->min_page_scale_factor = min_page_scale_factor_; |
135 params->max_page_scale_factor = max_page_scale_factor_; | 121 params->max_page_scale_factor = max_page_scale_factor_; |
136 params->need_animate_scroll = need_animate_scroll_; | 122 params->need_animate_scroll = need_animate_scroll_; |
137 params->need_invalidate_count = need_invalidate_count_; | 123 params->need_invalidate_count = need_invalidate_count_; |
138 params->need_begin_frame = need_begin_frame_; | |
139 params->did_activate_pending_tree_count = did_activate_pending_tree_count_; | 124 params->did_activate_pending_tree_count = did_activate_pending_tree_count_; |
140 } | 125 } |
141 | 126 |
142 void SynchronousCompositorProxy::OnMessageReceived( | 127 void SynchronousCompositorProxy::OnMessageReceived( |
143 const IPC::Message& message) { | 128 const IPC::Message& message) { |
144 if (output_surface_ && output_surface_->OnMessageReceived(message)) | 129 if (output_surface_ && output_surface_->OnMessageReceived(message)) |
145 return; | 130 return; |
146 | 131 |
147 IPC_BEGIN_MESSAGE_MAP(SynchronousCompositorProxy, message) | 132 IPC_BEGIN_MESSAGE_MAP(SynchronousCompositorProxy, message) |
148 IPC_MESSAGE_HANDLER(SyncCompositorMsg_BeginFrame, BeginFrame) | 133 IPC_MESSAGE_HANDLER(SyncCompositorMsg_SynchronizeRendererState, |
| 134 PopulateCommonParams) |
149 IPC_MESSAGE_HANDLER(SyncCompositorMsg_ComputeScroll, OnComputeScroll) | 135 IPC_MESSAGE_HANDLER(SyncCompositorMsg_ComputeScroll, OnComputeScroll) |
150 IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncCompositorMsg_DemandDrawHw, | 136 IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncCompositorMsg_DemandDrawHw, |
151 DemandDrawHw) | 137 DemandDrawHw) |
152 IPC_MESSAGE_HANDLER(SyncCompositorMsg_SetSharedMemory, SetSharedMemory) | 138 IPC_MESSAGE_HANDLER(SyncCompositorMsg_SetSharedMemory, SetSharedMemory) |
153 IPC_MESSAGE_HANDLER(SyncCompositorMsg_ZeroSharedMemory, ZeroSharedMemory) | 139 IPC_MESSAGE_HANDLER(SyncCompositorMsg_ZeroSharedMemory, ZeroSharedMemory) |
154 IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncCompositorMsg_DemandDrawSw, | 140 IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncCompositorMsg_DemandDrawSw, |
155 DemandDrawSw) | 141 DemandDrawSw) |
156 IPC_MESSAGE_HANDLER(SyncCompositorMsg_UpdateState, ProcessCommonParams) | |
157 IPC_MESSAGE_HANDLER(SyncCompositorMsg_ZoomBy, SynchronouslyZoomBy) | 142 IPC_MESSAGE_HANDLER(SyncCompositorMsg_ZoomBy, SynchronouslyZoomBy) |
158 IPC_MESSAGE_HANDLER(SyncCompositorMsg_SetScroll, SetScroll) | 143 IPC_MESSAGE_HANDLER(SyncCompositorMsg_SetScroll, SetScroll) |
159 IPC_END_MESSAGE_MAP() | 144 IPC_END_MESSAGE_MAP() |
160 } | 145 } |
161 | 146 |
162 bool SynchronousCompositorProxy::Send(IPC::Message* message) { | 147 bool SynchronousCompositorProxy::Send(IPC::Message* message) { |
163 return sender_->Send(message); | 148 return sender_->Send(message); |
164 } | 149 } |
165 | 150 |
166 void SynchronousCompositorProxy::BeginFrame( | |
167 const SyncCompositorCommonBrowserParams& common_params, | |
168 const cc::BeginFrameArgs& args, | |
169 SyncCompositorCommonRendererParams* common_renderer_params) { | |
170 DCHECK(!inside_receive_); | |
171 base::AutoReset<bool> scoped_inside_receive(&inside_receive_, true); | |
172 | |
173 ProcessCommonParams(common_params); | |
174 if (need_begin_frame_) { | |
175 begin_frame_source_->BeginFrame(args); | |
176 } | |
177 PopulateCommonParams(common_renderer_params); | |
178 } | |
179 | |
180 void SynchronousCompositorProxy::DemandDrawHw( | 151 void SynchronousCompositorProxy::DemandDrawHw( |
181 const SyncCompositorCommonBrowserParams& common_params, | |
182 const SyncCompositorDemandDrawHwParams& params, | 152 const SyncCompositorDemandDrawHwParams& params, |
183 IPC::Message* reply_message) { | 153 IPC::Message* reply_message) { |
184 DCHECK(!inside_receive_); | 154 DCHECK(!inside_receive_); |
185 DCHECK(reply_message); | 155 DCHECK(reply_message); |
186 | 156 |
187 inside_receive_ = true; | 157 inside_receive_ = true; |
188 ProcessCommonParams(common_params); | |
189 | 158 |
190 if (output_surface_) { | 159 if (output_surface_) { |
191 base::AutoReset<IPC::Message*> scoped_hardware_draw_reply( | 160 base::AutoReset<IPC::Message*> scoped_hardware_draw_reply( |
192 &hardware_draw_reply_, reply_message); | 161 &hardware_draw_reply_, reply_message); |
193 output_surface_->DemandDrawHw(params.surface_size, params.transform, | 162 output_surface_->DemandDrawHw(params.surface_size, params.transform, |
194 params.viewport, params.clip, | 163 params.viewport, params.clip, |
195 params.viewport_rect_for_tile_priority, | 164 params.viewport_rect_for_tile_priority, |
196 params.transform_for_tile_priority); | 165 params.transform_for_tile_priority); |
197 } | 166 } |
198 | 167 |
(...skipping 28 matching lines...) Expand all Loading... |
227 struct SynchronousCompositorProxy::SharedMemoryWithSize { | 196 struct SynchronousCompositorProxy::SharedMemoryWithSize { |
228 base::SharedMemory shm; | 197 base::SharedMemory shm; |
229 const size_t buffer_size; | 198 const size_t buffer_size; |
230 bool zeroed; | 199 bool zeroed; |
231 | 200 |
232 SharedMemoryWithSize(base::SharedMemoryHandle shm_handle, size_t buffer_size) | 201 SharedMemoryWithSize(base::SharedMemoryHandle shm_handle, size_t buffer_size) |
233 : shm(shm_handle, false), buffer_size(buffer_size), zeroed(true) {} | 202 : shm(shm_handle, false), buffer_size(buffer_size), zeroed(true) {} |
234 }; | 203 }; |
235 | 204 |
236 void SynchronousCompositorProxy::SetSharedMemory( | 205 void SynchronousCompositorProxy::SetSharedMemory( |
237 const SyncCompositorCommonBrowserParams& common_params, | |
238 const SyncCompositorSetSharedMemoryParams& params, | 206 const SyncCompositorSetSharedMemoryParams& params, |
239 bool* success, | 207 bool* success, |
240 SyncCompositorCommonRendererParams* common_renderer_params) { | 208 SyncCompositorCommonRendererParams* common_renderer_params) { |
241 DCHECK(!inside_receive_); | 209 DCHECK(!inside_receive_); |
242 base::AutoReset<bool> scoped_inside_receive(&inside_receive_, true); | 210 base::AutoReset<bool> scoped_inside_receive(&inside_receive_, true); |
243 | 211 |
244 *success = false; | 212 *success = false; |
245 ProcessCommonParams(common_params); | |
246 if (!base::SharedMemory::IsHandleValid(params.shm_handle)) | 213 if (!base::SharedMemory::IsHandleValid(params.shm_handle)) |
247 return; | 214 return; |
248 | 215 |
249 software_draw_shm_.reset( | 216 software_draw_shm_.reset( |
250 new SharedMemoryWithSize(params.shm_handle, params.buffer_size)); | 217 new SharedMemoryWithSize(params.shm_handle, params.buffer_size)); |
251 if (!software_draw_shm_->shm.Map(params.buffer_size)) | 218 if (!software_draw_shm_->shm.Map(params.buffer_size)) |
252 return; | 219 return; |
253 DCHECK(software_draw_shm_->shm.memory()); | 220 DCHECK(software_draw_shm_->shm.memory()); |
254 PopulateCommonParams(common_renderer_params); | 221 PopulateCommonParams(common_renderer_params); |
255 *success = true; | 222 *success = true; |
256 } | 223 } |
257 | 224 |
258 void SynchronousCompositorProxy::ZeroSharedMemory() { | 225 void SynchronousCompositorProxy::ZeroSharedMemory() { |
259 DCHECK(!software_draw_shm_->zeroed); | 226 // It is possible for this to get called twice, eg. if draw is called before |
| 227 // the OutputSurface is ready. Just ignore duplicated calls rather than |
| 228 // inventing a complicated system to avoid it. |
| 229 if (software_draw_shm_->zeroed) |
| 230 return; |
| 231 |
260 memset(software_draw_shm_->shm.memory(), 0, software_draw_shm_->buffer_size); | 232 memset(software_draw_shm_->shm.memory(), 0, software_draw_shm_->buffer_size); |
261 software_draw_shm_->zeroed = true; | 233 software_draw_shm_->zeroed = true; |
262 } | 234 } |
263 | 235 |
264 void SynchronousCompositorProxy::DemandDrawSw( | 236 void SynchronousCompositorProxy::DemandDrawSw( |
265 const SyncCompositorCommonBrowserParams& common_params, | |
266 const SyncCompositorDemandDrawSwParams& params, | 237 const SyncCompositorDemandDrawSwParams& params, |
267 IPC::Message* reply_message) { | 238 IPC::Message* reply_message) { |
268 DCHECK(!inside_receive_); | 239 DCHECK(!inside_receive_); |
269 inside_receive_ = true; | 240 inside_receive_ = true; |
270 ProcessCommonParams(common_params); | |
271 if (output_surface_) { | 241 if (output_surface_) { |
272 base::AutoReset<IPC::Message*> scoped_software_draw_reply( | 242 base::AutoReset<IPC::Message*> scoped_software_draw_reply( |
273 &software_draw_reply_, reply_message); | 243 &software_draw_reply_, reply_message); |
274 SkCanvas* sk_canvas_for_draw = SynchronousCompositorGetSkCanvas(); | 244 SkCanvas* sk_canvas_for_draw = SynchronousCompositorGetSkCanvas(); |
275 if (use_in_process_zero_copy_software_draw_) { | 245 if (use_in_process_zero_copy_software_draw_) { |
276 DCHECK(sk_canvas_for_draw); | 246 DCHECK(sk_canvas_for_draw); |
277 output_surface_->DemandDrawSw(sk_canvas_for_draw); | 247 output_surface_->DemandDrawSw(sk_canvas_for_draw); |
278 } else { | 248 } else { |
279 DCHECK(!sk_canvas_for_draw); | 249 DCHECK(!sk_canvas_for_draw); |
280 DoDemandDrawSw(params); | 250 DoDemandDrawSw(params); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 DCHECK(hardware_draw_reply_ || software_draw_reply_); | 304 DCHECK(hardware_draw_reply_ || software_draw_reply_); |
335 DCHECK(!(hardware_draw_reply_ && software_draw_reply_)); | 305 DCHECK(!(hardware_draw_reply_ && software_draw_reply_)); |
336 if (hardware_draw_reply_) { | 306 if (hardware_draw_reply_) { |
337 SwapBuffersHw(output_surface_id, frame); | 307 SwapBuffersHw(output_surface_id, frame); |
338 } else if (software_draw_reply_) { | 308 } else if (software_draw_reply_) { |
339 SwapBuffersSw(frame); | 309 SwapBuffersSw(frame); |
340 } | 310 } |
341 } | 311 } |
342 | 312 |
343 void SynchronousCompositorProxy::OnComputeScroll( | 313 void SynchronousCompositorProxy::OnComputeScroll( |
344 const SyncCompositorCommonBrowserParams& common_params, | |
345 base::TimeTicks animation_time) { | 314 base::TimeTicks animation_time) { |
346 ProcessCommonParams(common_params); | |
347 if (need_animate_scroll_) { | 315 if (need_animate_scroll_) { |
348 need_animate_scroll_ = false; | 316 need_animate_scroll_ = false; |
349 input_handler_proxy_->SynchronouslyAnimate(animation_time); | 317 input_handler_proxy_->SynchronouslyAnimate(animation_time); |
350 } | 318 } |
351 } | 319 } |
352 | 320 |
353 void SynchronousCompositorProxy::SynchronouslyZoomBy( | 321 void SynchronousCompositorProxy::SynchronouslyZoomBy( |
354 const SyncCompositorCommonBrowserParams& common_params, | |
355 float zoom_delta, | 322 float zoom_delta, |
356 const gfx::Point& anchor, | 323 const gfx::Point& anchor, |
357 SyncCompositorCommonRendererParams* common_renderer_params) { | 324 SyncCompositorCommonRendererParams* common_renderer_params) { |
358 DCHECK(!inside_receive_); | 325 DCHECK(!inside_receive_); |
359 base::AutoReset<bool> scoped_inside_receive(&inside_receive_, true); | 326 base::AutoReset<bool> scoped_inside_receive(&inside_receive_, true); |
360 ProcessCommonParams(common_params); | |
361 input_handler_proxy_->SynchronouslyZoomBy(zoom_delta, anchor); | 327 input_handler_proxy_->SynchronouslyZoomBy(zoom_delta, anchor); |
362 PopulateCommonParams(common_renderer_params); | 328 PopulateCommonParams(common_renderer_params); |
363 } | 329 } |
364 | 330 |
365 void SynchronousCompositorProxy::SetScroll( | 331 void SynchronousCompositorProxy::SetScroll( |
366 const gfx::ScrollOffset& new_total_scroll_offset) { | 332 const gfx::ScrollOffset& new_total_scroll_offset) { |
367 if (total_scroll_offset_ == new_total_scroll_offset) | 333 if (total_scroll_offset_ == new_total_scroll_offset) |
368 return; | 334 return; |
369 total_scroll_offset_ = new_total_scroll_offset; | 335 total_scroll_offset_ = new_total_scroll_offset; |
370 input_handler_proxy_->SynchronouslySetRootScrollOffset(total_scroll_offset_); | 336 input_handler_proxy_->SynchronouslySetRootScrollOffset(total_scroll_offset_); |
371 } | 337 } |
372 | 338 |
373 void SynchronousCompositorProxy::ProcessCommonParams( | |
374 const SyncCompositorCommonBrowserParams& common_params) { | |
375 begin_frame_source_->SetBeginFrameSourcePaused( | |
376 common_params.begin_frame_source_paused); | |
377 } | |
378 | |
379 } // namespace content | 339 } // namespace content |
OLD | NEW |