OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "android_webview/browser/browser_view_renderer.h" | 5 #include "android_webview/browser/browser_view_renderer.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "android_webview/browser/browser_view_renderer_client.h" | 9 #include "android_webview/browser/browser_view_renderer_client.h" |
10 #include "android_webview/browser/child_frame.h" | 10 #include "android_webview/browser/child_frame.h" |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
85 content::WebContents* web_contents) { | 85 content::WebContents* web_contents) { |
86 return BrowserViewRendererUserData::GetBrowserViewRenderer(web_contents); | 86 return BrowserViewRendererUserData::GetBrowserViewRenderer(web_contents); |
87 } | 87 } |
88 | 88 |
89 BrowserViewRenderer::BrowserViewRenderer( | 89 BrowserViewRenderer::BrowserViewRenderer( |
90 BrowserViewRendererClient* client, | 90 BrowserViewRendererClient* client, |
91 const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner, | 91 const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner, |
92 bool disable_page_visibility) | 92 bool disable_page_visibility) |
93 : client_(client), | 93 : client_(client), |
94 ui_task_runner_(ui_task_runner), | 94 ui_task_runner_(ui_task_runner), |
95 render_thread_manager_(nullptr), | 95 compositor_frame_consumer_(nullptr), |
96 disable_page_visibility_(disable_page_visibility), | 96 disable_page_visibility_(disable_page_visibility), |
97 compositor_(NULL), | 97 compositor_(NULL), |
98 is_paused_(false), | 98 is_paused_(false), |
99 view_visible_(false), | 99 view_visible_(false), |
100 window_visible_(false), | 100 window_visible_(false), |
101 attached_to_window_(false), | 101 attached_to_window_(false), |
102 hardware_enabled_(false), | 102 hardware_enabled_(false), |
103 dip_scale_(0.f), | 103 dip_scale_(0.f), |
104 page_scale_factor_(1.f), | 104 page_scale_factor_(1.f), |
105 min_page_scale_factor_(0.f), | 105 min_page_scale_factor_(0.f), |
106 max_page_scale_factor_(0.f), | 106 max_page_scale_factor_(0.f), |
107 on_new_picture_enable_(false), | 107 on_new_picture_enable_(false), |
108 clear_view_(false), | 108 clear_view_(false), |
109 offscreen_pre_raster_(false), | 109 offscreen_pre_raster_(false), |
110 next_compositor_id_(1) {} | 110 next_compositor_id_(1) {} |
111 | 111 |
112 BrowserViewRenderer::~BrowserViewRenderer() { | 112 BrowserViewRenderer::~BrowserViewRenderer() { |
113 DCHECK(compositor_map_.empty()); | 113 DCHECK(compositor_map_.empty()); |
114 if (compositor_frame_consumer_) { | |
115 compositor_frame_consumer_->OnCompositorFrameProducerWillDestroy(); | |
boliu
2016/04/21 17:05:39
This seems redundant. Just do SetCompositorFrameCo
Tobias Sargeant
2016/04/21 17:21:12
OK.
Tobias Sargeant
2016/04/21 17:48:27
Done.
| |
116 } | |
114 } | 117 } |
115 | 118 |
116 void BrowserViewRenderer::SetRenderThreadManager( | 119 void BrowserViewRenderer::SetCompositorFrameConsumer( |
117 RenderThreadManager* render_thread_manager) { | 120 CompositorFrameConsumer* compositor_frame_consumer) { |
118 render_thread_manager_ = render_thread_manager; | 121 if (compositor_frame_consumer == compositor_frame_consumer_) { |
122 return; | |
123 } | |
124 if (compositor_frame_consumer_) { | |
125 compositor_frame_consumer_->SetCompositorFrameProducer(nullptr); | |
126 } | |
127 compositor_frame_consumer_ = compositor_frame_consumer; | |
128 if (compositor_frame_consumer_) { | |
129 compositor_frame_consumer_->SetCompositorFrameProducer(this); | |
130 } | |
119 } | 131 } |
120 | 132 |
121 void BrowserViewRenderer::RegisterWithWebContents( | 133 void BrowserViewRenderer::RegisterWithWebContents( |
122 content::WebContents* web_contents) { | 134 content::WebContents* web_contents) { |
123 web_contents->SetUserData(kBrowserViewRendererUserDataKey, | 135 web_contents->SetUserData(kBrowserViewRendererUserDataKey, |
124 new BrowserViewRendererUserData(this)); | 136 new BrowserViewRendererUserData(this)); |
125 } | 137 } |
126 | 138 |
127 void BrowserViewRenderer::TrimMemory() { | 139 void BrowserViewRenderer::TrimMemory() { |
128 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 140 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
129 TRACE_EVENT0("android_webview", "BrowserViewRenderer::TrimMemory"); | 141 TRACE_EVENT0("android_webview", "BrowserViewRenderer::TrimMemory"); |
130 // Just set the memory limit to 0 and drop all tiles. This will be reset to | 142 // Just set the memory limit to 0 and drop all tiles. This will be reset to |
131 // normal levels in the next DrawGL call. | 143 // normal levels in the next DrawGL call. |
132 // TODO(hush): need to setMemoryPolicy to 0 for non-current compositors too. | 144 // TODO(hush): need to setMemoryPolicy to 0 for non-current compositors too. |
133 // But WebView only has non-current compositors temporarily. So don't have to | 145 // But WebView only has non-current compositors temporarily. So don't have to |
134 // do it now. | 146 // do it now. |
135 if (!offscreen_pre_raster_) | 147 if (compositor_frame_consumer_ && !offscreen_pre_raster_) |
136 ReleaseHardware(); | 148 ReleaseHardware(compositor_frame_consumer_); |
boliu
2016/04/21 17:05:39
This code smells bad..
ReleaseHardware "mostly" m
Tobias Sargeant
2016/04/21 17:21:11
Yes. The test for whether there is a consumer shou
Tobias Sargeant
2016/04/21 17:48:27
Done.
| |
137 } | 149 } |
138 | 150 |
139 void BrowserViewRenderer::UpdateMemoryPolicy() { | 151 void BrowserViewRenderer::UpdateMemoryPolicy() { |
140 if (!compositor_) { | 152 if (!compositor_) { |
141 return; | 153 return; |
142 } | 154 } |
143 | 155 |
144 if (!hardware_enabled_) { | 156 if (!hardware_enabled_) { |
145 compositor_->SetMemoryPolicy(0u); | 157 compositor_->SetMemoryPolicy(0u); |
146 return; | 158 return; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
180 if (clear_view_) { | 192 if (clear_view_) { |
181 TRACE_EVENT_INSTANT0("android_webview", "EarlyOut_ClearView", | 193 TRACE_EVENT_INSTANT0("android_webview", "EarlyOut_ClearView", |
182 TRACE_EVENT_SCOPE_THREAD); | 194 TRACE_EVENT_SCOPE_THREAD); |
183 return false; | 195 return false; |
184 } | 196 } |
185 | 197 |
186 return true; | 198 return true; |
187 } | 199 } |
188 | 200 |
189 bool BrowserViewRenderer::OnDrawHardware() { | 201 bool BrowserViewRenderer::OnDrawHardware() { |
190 DCHECK(render_thread_manager_); | |
191 TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDrawHardware"); | 202 TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDrawHardware"); |
203 if (!compositor_frame_consumer_) { | |
boliu
2016/04/21 17:05:39
why did a DCHECK become a null check..? bad code s
Tobias Sargeant
2016/04/21 17:21:12
If RTM is destroyed before BVR, then unless there'
boliu
2016/04/21 17:25:46
hmm, should the gurantee should be that BVRClient
boliu
2016/04/21 18:01:32
No change?
For now at least, RTM is guaranteed to
| |
204 return false; | |
205 } | |
192 | 206 |
193 render_thread_manager_->InitializeHardwareDrawIfNeededOnUI(); | 207 compositor_frame_consumer_->InitializeHardwareDrawIfNeededOnUI(); |
194 | 208 |
195 if (!CanOnDraw()) { | 209 if (!CanOnDraw()) { |
196 return false; | 210 return false; |
197 } | 211 } |
198 | 212 |
199 render_thread_manager_->SetScrollOffsetOnUI(last_on_draw_scroll_offset_); | 213 compositor_frame_consumer_->SetScrollOffsetOnUI(last_on_draw_scroll_offset_); |
200 hardware_enabled_ = true; | 214 hardware_enabled_ = true; |
201 | 215 |
202 external_draw_constraints_ = | 216 external_draw_constraints_ = |
203 render_thread_manager_->GetParentDrawConstraintsOnUI(); | 217 compositor_frame_consumer_->GetParentDrawConstraintsOnUI(); |
204 | 218 |
205 ReturnResourceFromParent(); | 219 ReturnResourceFromParent(compositor_frame_consumer_); |
206 UpdateMemoryPolicy(); | 220 UpdateMemoryPolicy(); |
207 | 221 |
208 gfx::Size surface_size(size_); | 222 gfx::Size surface_size(size_); |
209 gfx::Rect viewport(surface_size); | 223 gfx::Rect viewport(surface_size); |
210 gfx::Rect clip = viewport; | 224 gfx::Rect clip = viewport; |
211 gfx::Transform transform_for_tile_priority = | 225 gfx::Transform transform_for_tile_priority = |
212 external_draw_constraints_.transform; | 226 external_draw_constraints_.transform; |
213 | 227 |
214 // If the WebView is on a layer, WebView does not know what transform is | 228 // If the WebView is on a layer, WebView does not know what transform is |
215 // applied onto the layer so global visible rect does not make sense here. | 229 // applied onto the layer so global visible rect does not make sense here. |
216 // In this case, just use the surface rect for tiling. | 230 // In this case, just use the surface rect for tiling. |
217 gfx::Rect viewport_rect_for_tile_priority; | 231 gfx::Rect viewport_rect_for_tile_priority; |
218 | 232 |
219 // Leave viewport_rect_for_tile_priority empty if offscreen_pre_raster_ is on. | 233 // Leave viewport_rect_for_tile_priority empty if offscreen_pre_raster_ is on. |
220 if (!offscreen_pre_raster_ && !external_draw_constraints_.is_layer) { | 234 if (!offscreen_pre_raster_ && !external_draw_constraints_.is_layer) { |
221 viewport_rect_for_tile_priority = last_on_draw_global_visible_rect_; | 235 viewport_rect_for_tile_priority = last_on_draw_global_visible_rect_; |
222 } | 236 } |
223 | 237 |
224 content::SynchronousCompositor::Frame frame = | 238 content::SynchronousCompositor::Frame frame = |
225 compositor_->DemandDrawHw(surface_size, | 239 compositor_->DemandDrawHw(surface_size, |
226 gfx::Transform(), | 240 gfx::Transform(), |
227 viewport, | 241 viewport, |
228 clip, | 242 clip, |
229 viewport_rect_for_tile_priority, | 243 viewport_rect_for_tile_priority, |
230 transform_for_tile_priority); | 244 transform_for_tile_priority); |
231 if (!frame.frame.get()) { | 245 if (!frame.frame.get()) { |
232 TRACE_EVENT_INSTANT0("android_webview", "NoNewFrame", | 246 TRACE_EVENT_INSTANT0("android_webview", "NoNewFrame", |
233 TRACE_EVENT_SCOPE_THREAD); | 247 TRACE_EVENT_SCOPE_THREAD); |
234 hardware_enabled_ = render_thread_manager_->HasFrameOnUI(); | 248 hardware_enabled_ = compositor_frame_consumer_->HasFrameOnUI(); |
235 if (!hardware_enabled_) | 249 if (!hardware_enabled_) |
236 UpdateMemoryPolicy(); | 250 UpdateMemoryPolicy(); |
237 return hardware_enabled_; | 251 return hardware_enabled_; |
238 } | 252 } |
239 | 253 |
240 std::unique_ptr<ChildFrame> child_frame = base::WrapUnique(new ChildFrame( | 254 std::unique_ptr<ChildFrame> child_frame = base::WrapUnique(new ChildFrame( |
241 frame.output_surface_id, std::move(frame.frame), | 255 frame.output_surface_id, std::move(frame.frame), |
242 GetCompositorID(compositor_), viewport_rect_for_tile_priority.IsEmpty(), | 256 GetCompositorID(compositor_), viewport_rect_for_tile_priority.IsEmpty(), |
243 transform_for_tile_priority, offscreen_pre_raster_, | 257 transform_for_tile_priority, offscreen_pre_raster_, |
244 external_draw_constraints_.is_layer)); | 258 external_draw_constraints_.is_layer)); |
245 | 259 |
246 ReturnUnusedResource(render_thread_manager_->PassUncommittedFrameOnUI()); | 260 ReturnUnusedResource(compositor_frame_consumer_->PassUncommittedFrameOnUI()); |
247 render_thread_manager_->SetFrameOnUI(std::move(child_frame)); | 261 compositor_frame_consumer_->SetFrameOnUI(std::move(child_frame)); |
248 return true; | 262 return true; |
249 } | 263 } |
250 | 264 |
251 void BrowserViewRenderer::OnParentDrawConstraintsUpdated() { | 265 void BrowserViewRenderer::OnParentDrawConstraintsUpdated( |
252 DCHECK(render_thread_manager_); | 266 CompositorFrameConsumer* compositor_frame_consumer) { |
267 DCHECK(compositor_frame_consumer_ == compositor_frame_consumer); | |
boliu
2016/04/21 17:05:39
there is DCHECK_EQ
boliu
2016/04/21 17:07:42
If it's supposed to be 1:many, how are these DCHEC
Tobias Sargeant
2016/04/21 17:21:12
Eventually I was envisaging that we have an active
boliu
2016/04/21 17:25:46
That's fine, but you need to make this CL consiste
Tobias Sargeant
2016/04/21 17:48:27
Done.
| |
253 PostInvalidate(); | 268 PostInvalidate(); |
254 external_draw_constraints_ = | 269 external_draw_constraints_ = |
255 render_thread_manager_->GetParentDrawConstraintsOnUI(); | 270 compositor_frame_consumer_->GetParentDrawConstraintsOnUI(); |
256 UpdateMemoryPolicy(); | 271 UpdateMemoryPolicy(); |
257 } | 272 } |
258 | 273 |
274 void BrowserViewRenderer::OnCompositorFrameConsumerWillDestroy( | |
275 CompositorFrameConsumer* compositor_frame_consumer) { | |
276 DCHECK(compositor_frame_consumer_ == compositor_frame_consumer); | |
277 compositor_frame_consumer_ = nullptr; | |
boliu
2016/04/21 17:05:39
SetCompositorFrameConsumer(nullptr)
Tobias Sargeant
2016/04/21 17:48:27
Done.
| |
278 } | |
279 | |
259 void BrowserViewRenderer::ReturnUnusedResource( | 280 void BrowserViewRenderer::ReturnUnusedResource( |
260 std::unique_ptr<ChildFrame> child_frame) { | 281 std::unique_ptr<ChildFrame> child_frame) { |
261 if (!child_frame.get() || !child_frame->frame.get()) | 282 if (!child_frame.get() || !child_frame->frame.get()) |
262 return; | 283 return; |
263 | 284 |
264 cc::CompositorFrameAck frame_ack; | 285 cc::CompositorFrameAck frame_ack; |
265 cc::TransferableResource::ReturnResources( | 286 cc::TransferableResource::ReturnResources( |
266 child_frame->frame->delegated_frame_data->resource_list, | 287 child_frame->frame->delegated_frame_data->resource_list, |
267 &frame_ack.resources); | 288 &frame_ack.resources); |
268 content::SynchronousCompositor* compositor = | 289 content::SynchronousCompositor* compositor = |
269 compositor_map_[child_frame->compositor_id]; | 290 compositor_map_[child_frame->compositor_id]; |
270 if (compositor && !frame_ack.resources.empty()) | 291 if (compositor && !frame_ack.resources.empty()) |
271 compositor->ReturnResources(child_frame->output_surface_id, frame_ack); | 292 compositor->ReturnResources(child_frame->output_surface_id, frame_ack); |
272 } | 293 } |
273 | 294 |
274 void BrowserViewRenderer::ReturnResourceFromParent() { | 295 void BrowserViewRenderer::ReturnResourceFromParent( |
275 DCHECK(render_thread_manager_); | 296 CompositorFrameConsumer* compositor_frame_consumer) { |
276 RenderThreadManager::ReturnedResourcesMap returned_resource_map; | 297 CompositorFrameConsumer::ReturnedResourcesMap returned_resource_map; |
277 render_thread_manager_->SwapReturnedResourcesOnUI(&returned_resource_map); | 298 compositor_frame_consumer->SwapReturnedResourcesOnUI(&returned_resource_map); |
278 for (auto iterator = returned_resource_map.begin(); | 299 for (auto iterator = returned_resource_map.begin(); |
279 iterator != returned_resource_map.end(); iterator++) { | 300 iterator != returned_resource_map.end(); iterator++) { |
280 uint32_t compositor_id = iterator->first; | 301 uint32_t compositor_id = iterator->first; |
281 content::SynchronousCompositor* compositor = compositor_map_[compositor_id]; | 302 content::SynchronousCompositor* compositor = compositor_map_[compositor_id]; |
282 cc::CompositorFrameAck frame_ack; | 303 cc::CompositorFrameAck frame_ack; |
283 frame_ack.resources.swap(iterator->second.resources); | 304 frame_ack.resources.swap(iterator->second.resources); |
284 | 305 |
285 if (compositor && !frame_ack.resources.empty()) { | 306 if (compositor && !frame_ack.resources.empty()) { |
286 compositor->ReturnResources(iterator->second.output_surface_id, | 307 compositor->ReturnResources(iterator->second.output_surface_id, |
287 frame_ack); | 308 frame_ack); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
394 attached_to_window_ = true; | 415 attached_to_window_ = true; |
395 size_.SetSize(width, height); | 416 size_.SetSize(width, height); |
396 if (offscreen_pre_raster_) | 417 if (offscreen_pre_raster_) |
397 UpdateMemoryPolicy(); | 418 UpdateMemoryPolicy(); |
398 UpdateCompositorIsActive(); | 419 UpdateCompositorIsActive(); |
399 } | 420 } |
400 | 421 |
401 void BrowserViewRenderer::OnDetachedFromWindow() { | 422 void BrowserViewRenderer::OnDetachedFromWindow() { |
402 TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDetachedFromWindow"); | 423 TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDetachedFromWindow"); |
403 attached_to_window_ = false; | 424 attached_to_window_ = false; |
404 ReleaseHardware(); | 425 if (compositor_frame_consumer_) { |
boliu
2016/04/21 17:05:39
ditto
Tobias Sargeant
2016/04/21 17:48:27
Done.
| |
426 ReleaseHardware(compositor_frame_consumer_); | |
427 } | |
405 UpdateCompositorIsActive(); | 428 UpdateCompositorIsActive(); |
406 } | 429 } |
407 | 430 |
408 void BrowserViewRenderer::ZoomBy(float delta) { | 431 void BrowserViewRenderer::ZoomBy(float delta) { |
409 if (!compositor_) | 432 if (!compositor_) |
410 return; | 433 return; |
411 compositor_->SynchronouslyZoomBy( | 434 compositor_->SynchronouslyZoomBy( |
412 delta, gfx::Point(size_.width() / 2, size_.height() / 2)); | 435 delta, gfx::Point(size_.width() / 2, size_.height() / 2)); |
413 } | 436 } |
414 | 437 |
415 void BrowserViewRenderer::OnComputeScroll(base::TimeTicks animation_time) { | 438 void BrowserViewRenderer::OnComputeScroll(base::TimeTicks animation_time) { |
416 if (!compositor_) | 439 if (!compositor_) |
417 return; | 440 return; |
418 TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnComputeScroll"); | 441 TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnComputeScroll"); |
419 compositor_->OnComputeScroll(animation_time); | 442 compositor_->OnComputeScroll(animation_time); |
420 } | 443 } |
421 | 444 |
422 void BrowserViewRenderer::ReleaseHardware() { | 445 void BrowserViewRenderer::ReleaseHardware( |
423 ReturnUnusedResource(render_thread_manager_->PassUncommittedFrameOnUI()); | 446 CompositorFrameConsumer* compositor_frame_consumer) { |
424 ReturnResourceFromParent(); | 447 ReturnUnusedResource(compositor_frame_consumer->PassUncommittedFrameOnUI()); |
425 DCHECK(render_thread_manager_->ReturnedResourcesEmptyOnUI()); | 448 ReturnResourceFromParent(compositor_frame_consumer); |
449 DCHECK(compositor_frame_consumer->ReturnedResourcesEmptyOnUI()); | |
426 hardware_enabled_ = false; | 450 hardware_enabled_ = false; |
427 UpdateMemoryPolicy(); | 451 UpdateMemoryPolicy(); |
428 } | 452 } |
429 | 453 |
430 bool BrowserViewRenderer::IsVisible() const { | 454 bool BrowserViewRenderer::IsVisible() const { |
431 // Ignore |window_visible_| if |attached_to_window_| is false. | 455 // Ignore |window_visible_| if |attached_to_window_| is false. |
432 return view_visible_ && (!attached_to_window_ || window_visible_); | 456 return view_visible_ && (!attached_to_window_ || window_visible_); |
433 } | 457 } |
434 | 458 |
435 bool BrowserViewRenderer::IsClientVisible() const { | 459 bool BrowserViewRenderer::IsClientVisible() const { |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
702 base::StringAppendF(&str, | 726 base::StringAppendF(&str, |
703 "overscroll_rounding_error_: %s ", | 727 "overscroll_rounding_error_: %s ", |
704 overscroll_rounding_error_.ToString().c_str()); | 728 overscroll_rounding_error_.ToString().c_str()); |
705 base::StringAppendF( | 729 base::StringAppendF( |
706 &str, "on_new_picture_enable: %d ", on_new_picture_enable_); | 730 &str, "on_new_picture_enable: %d ", on_new_picture_enable_); |
707 base::StringAppendF(&str, "clear_view: %d ", clear_view_); | 731 base::StringAppendF(&str, "clear_view: %d ", clear_view_); |
708 return str; | 732 return str; |
709 } | 733 } |
710 | 734 |
711 } // namespace android_webview | 735 } // namespace android_webview |
OLD | NEW |