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" |
11 #include "android_webview/browser/compositor_frame_consumer.h" | 11 #include "android_webview/browser/compositor_frame_consumer.h" |
12 #include "base/auto_reset.h" | 12 #include "base/auto_reset.h" |
13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
16 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
17 #include "base/strings/stringprintf.h" | 17 #include "base/strings/stringprintf.h" |
18 #include "base/supports_user_data.h" | 18 #include "base/supports_user_data.h" |
19 #include "base/trace_event/trace_event_argument.h" | 19 #include "base/trace_event/trace_event_argument.h" |
20 #include "cc/output/compositor_frame.h" | 20 #include "cc/output/compositor_frame.h" |
21 #include "cc/output/compositor_frame_ack.h" | 21 #include "cc/output/compositor_frame_ack.h" |
22 #include "content/public/browser/render_process_host.h" | |
23 #include "content/public/browser/render_view_host.h" | |
22 #include "content/public/browser/web_contents.h" | 24 #include "content/public/browser/web_contents.h" |
23 #include "content/public/common/content_switches.h" | 25 #include "content/public/common/content_switches.h" |
24 #include "gpu/command_buffer/service/gpu_switches.h" | 26 #include "gpu/command_buffer/service/gpu_switches.h" |
25 #include "third_party/skia/include/core/SkBitmap.h" | 27 #include "third_party/skia/include/core/SkBitmap.h" |
26 #include "third_party/skia/include/core/SkCanvas.h" | 28 #include "third_party/skia/include/core/SkCanvas.h" |
27 #include "third_party/skia/include/core/SkPicture.h" | 29 #include "third_party/skia/include/core/SkPicture.h" |
28 #include "third_party/skia/include/core/SkPictureRecorder.h" | 30 #include "third_party/skia/include/core/SkPictureRecorder.h" |
29 #include "ui/gfx/geometry/point.h" | 31 #include "ui/gfx/geometry/point.h" |
30 #include "ui/gfx/geometry/scroll_offset.h" | 32 #include "ui/gfx/geometry/scroll_offset.h" |
31 #include "ui/gfx/geometry/vector2d_conversions.h" | 33 #include "ui/gfx/geometry/vector2d_conversions.h" |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
81 } | 83 } |
82 } | 84 } |
83 | 85 |
84 // static | 86 // static |
85 BrowserViewRenderer* BrowserViewRenderer::FromWebContents( | 87 BrowserViewRenderer* BrowserViewRenderer::FromWebContents( |
86 content::WebContents* web_contents) { | 88 content::WebContents* web_contents) { |
87 return BrowserViewRendererUserData::GetBrowserViewRenderer(web_contents); | 89 return BrowserViewRendererUserData::GetBrowserViewRenderer(web_contents); |
88 } | 90 } |
89 | 91 |
90 BrowserViewRenderer::BrowserViewRenderer( | 92 BrowserViewRenderer::BrowserViewRenderer( |
93 content::WebContents* web_contents, | |
91 BrowserViewRendererClient* client, | 94 BrowserViewRendererClient* client, |
92 const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner) | 95 const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner) |
93 : client_(client), | 96 : content::WebContentsObserver(web_contents), |
97 client_(client), | |
94 ui_task_runner_(ui_task_runner), | 98 ui_task_runner_(ui_task_runner), |
95 current_compositor_frame_consumer_(nullptr), | 99 current_compositor_frame_consumer_(nullptr), |
96 compositor_(NULL), | 100 compositor_(nullptr), |
101 compositor_id_(web_contents->GetRenderProcessHost()->GetID(), | |
102 web_contents->GetRenderViewHost()->GetRoutingID()), | |
97 is_paused_(false), | 103 is_paused_(false), |
98 view_visible_(false), | 104 view_visible_(false), |
99 window_visible_(false), | 105 window_visible_(false), |
100 attached_to_window_(false), | 106 attached_to_window_(false), |
101 hardware_enabled_(false), | 107 hardware_enabled_(false), |
102 dip_scale_(0.f), | 108 dip_scale_(0.f), |
103 page_scale_factor_(1.f), | 109 page_scale_factor_(1.f), |
104 min_page_scale_factor_(0.f), | 110 min_page_scale_factor_(0.f), |
105 max_page_scale_factor_(0.f), | 111 max_page_scale_factor_(0.f), |
106 on_new_picture_enable_(false), | 112 on_new_picture_enable_(false), |
107 clear_view_(false), | 113 clear_view_(false), |
108 offscreen_pre_raster_(false), | 114 offscreen_pre_raster_(false) {} |
109 next_compositor_id_(1) {} | |
110 | 115 |
111 BrowserViewRenderer::~BrowserViewRenderer() { | 116 BrowserViewRenderer::~BrowserViewRenderer() { |
112 DCHECK(compositor_map_.empty()); | 117 DCHECK(compositor_map_.empty()); |
113 SetCurrentCompositorFrameConsumer(nullptr); | 118 SetCurrentCompositorFrameConsumer(nullptr); |
114 while (compositor_frame_consumers_.size()) { | 119 while (compositor_frame_consumers_.size()) { |
115 RemoveCompositorFrameConsumer(*compositor_frame_consumers_.begin()); | 120 RemoveCompositorFrameConsumer(*compositor_frame_consumers_.begin()); |
116 } | 121 } |
117 } | 122 } |
118 | 123 |
119 void BrowserViewRenderer::SetCurrentCompositorFrameConsumer( | 124 void BrowserViewRenderer::SetCurrentCompositorFrameConsumer( |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
240 clip, | 245 clip, |
241 viewport_rect_for_tile_priority, | 246 viewport_rect_for_tile_priority, |
242 transform_for_tile_priority); | 247 transform_for_tile_priority); |
243 if (!frame.frame.get()) { | 248 if (!frame.frame.get()) { |
244 TRACE_EVENT_INSTANT0("android_webview", "NoNewFrame", | 249 TRACE_EVENT_INSTANT0("android_webview", "NoNewFrame", |
245 TRACE_EVENT_SCOPE_THREAD); | 250 TRACE_EVENT_SCOPE_THREAD); |
246 return current_compositor_frame_consumer_->HasFrameOnUI(); | 251 return current_compositor_frame_consumer_->HasFrameOnUI(); |
247 } | 252 } |
248 | 253 |
249 std::unique_ptr<ChildFrame> child_frame = base::WrapUnique(new ChildFrame( | 254 std::unique_ptr<ChildFrame> child_frame = base::WrapUnique(new ChildFrame( |
250 frame.output_surface_id, std::move(frame.frame), | 255 frame.output_surface_id, std::move(frame.frame), compositor_id_, |
251 GetCompositorID(compositor_), viewport_rect_for_tile_priority.IsEmpty(), | 256 viewport_rect_for_tile_priority.IsEmpty(), transform_for_tile_priority, |
252 transform_for_tile_priority, offscreen_pre_raster_, | 257 offscreen_pre_raster_, external_draw_constraints_.is_layer)); |
253 external_draw_constraints_.is_layer)); | |
254 | 258 |
255 ReturnUnusedResource( | 259 ReturnUnusedResource( |
256 current_compositor_frame_consumer_->PassUncommittedFrameOnUI()); | 260 current_compositor_frame_consumer_->PassUncommittedFrameOnUI()); |
257 current_compositor_frame_consumer_->SetFrameOnUI(std::move(child_frame)); | 261 current_compositor_frame_consumer_->SetFrameOnUI(std::move(child_frame)); |
258 return true; | 262 return true; |
259 } | 263 } |
260 | 264 |
261 void BrowserViewRenderer::OnParentDrawConstraintsUpdated( | 265 void BrowserViewRenderer::OnParentDrawConstraintsUpdated( |
262 CompositorFrameConsumer* compositor_frame_consumer) { | 266 CompositorFrameConsumer* compositor_frame_consumer) { |
263 DCHECK(compositor_frame_consumer); | 267 DCHECK(compositor_frame_consumer); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
297 content::SynchronousCompositor* compositor = | 301 content::SynchronousCompositor* compositor = |
298 compositor_map_[child_frame->compositor_id]; | 302 compositor_map_[child_frame->compositor_id]; |
299 if (compositor && !frame_ack.resources.empty()) | 303 if (compositor && !frame_ack.resources.empty()) |
300 compositor->ReturnResources(child_frame->output_surface_id, frame_ack); | 304 compositor->ReturnResources(child_frame->output_surface_id, frame_ack); |
301 } | 305 } |
302 | 306 |
303 void BrowserViewRenderer::ReturnResourceFromParent( | 307 void BrowserViewRenderer::ReturnResourceFromParent( |
304 CompositorFrameConsumer* compositor_frame_consumer) { | 308 CompositorFrameConsumer* compositor_frame_consumer) { |
305 CompositorFrameConsumer::ReturnedResourcesMap returned_resource_map; | 309 CompositorFrameConsumer::ReturnedResourcesMap returned_resource_map; |
306 compositor_frame_consumer->SwapReturnedResourcesOnUI(&returned_resource_map); | 310 compositor_frame_consumer->SwapReturnedResourcesOnUI(&returned_resource_map); |
307 for (auto iterator = returned_resource_map.begin(); | 311 for (auto& pair : returned_resource_map) { |
308 iterator != returned_resource_map.end(); iterator++) { | 312 CompositorID compositor_id = pair.first; |
309 uint32_t compositor_id = iterator->first; | |
310 content::SynchronousCompositor* compositor = compositor_map_[compositor_id]; | 313 content::SynchronousCompositor* compositor = compositor_map_[compositor_id]; |
311 cc::CompositorFrameAck frame_ack; | 314 cc::CompositorFrameAck frame_ack; |
312 frame_ack.resources.swap(iterator->second.resources); | 315 frame_ack.resources.swap(pair.second.resources); |
313 | 316 |
314 if (compositor && !frame_ack.resources.empty()) { | 317 if (compositor && !frame_ack.resources.empty()) { |
315 compositor->ReturnResources(iterator->second.output_surface_id, | 318 compositor->ReturnResources(pair.second.output_surface_id, frame_ack); |
316 frame_ack); | |
317 } | 319 } |
318 } | 320 } |
319 } | 321 } |
320 | 322 |
321 bool BrowserViewRenderer::OnDrawSoftware(SkCanvas* canvas) { | 323 bool BrowserViewRenderer::OnDrawSoftware(SkCanvas* canvas) { |
322 return CanOnDraw() && CompositeSW(canvas); | 324 return CanOnDraw() && CompositeSW(canvas); |
323 } | 325 } |
324 | 326 |
325 sk_sp<SkPicture> BrowserViewRenderer::CapturePicture(int width, | 327 sk_sp<SkPicture> BrowserViewRenderer::CapturePicture(int width, |
326 int height) { | 328 int height) { |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
460 } | 462 } |
461 | 463 |
462 bool BrowserViewRenderer::IsClientVisible() const { | 464 bool BrowserViewRenderer::IsClientVisible() const { |
463 return !is_paused_ && (!attached_to_window_ || window_visible_); | 465 return !is_paused_ && (!attached_to_window_ || window_visible_); |
464 } | 466 } |
465 | 467 |
466 gfx::Rect BrowserViewRenderer::GetScreenRect() const { | 468 gfx::Rect BrowserViewRenderer::GetScreenRect() const { |
467 return gfx::Rect(client_->GetLocationOnScreen(), size_); | 469 return gfx::Rect(client_->GetLocationOnScreen(), size_); |
468 } | 470 } |
469 | 471 |
470 uint32_t BrowserViewRenderer::GetCompositorID( | |
471 content::SynchronousCompositor* compositor) { | |
472 for (auto iterator = compositor_map_.begin(); | |
473 iterator != compositor_map_.end(); iterator++) { | |
474 if (iterator->second == compositor) { | |
475 return iterator->first; | |
476 } | |
477 } | |
478 | |
479 DCHECK(false); | |
480 // Return an invalid ID (0), because ID starts with 1. | |
481 return 0; | |
482 } | |
483 | |
484 void BrowserViewRenderer::DidInitializeCompositor( | 472 void BrowserViewRenderer::DidInitializeCompositor( |
485 content::SynchronousCompositor* compositor) { | 473 content::SynchronousCompositor* compositor, |
474 int process_id, | |
475 int routing_id) { | |
486 TRACE_EVENT_INSTANT0("android_webview", | 476 TRACE_EVENT_INSTANT0("android_webview", |
487 "BrowserViewRenderer::DidInitializeCompositor", | 477 "BrowserViewRenderer::DidInitializeCompositor", |
488 TRACE_EVENT_SCOPE_THREAD); | 478 TRACE_EVENT_SCOPE_THREAD); |
489 DCHECK(compositor); | 479 DCHECK(compositor); |
490 // This happens when id overflows to 0, unlikely in practice. | 480 CompositorID compositor_id(process_id, routing_id); |
491 if (next_compositor_id_ == 0) | 481 // This assumes that a RenderViewHost has at most 1 synchronous compositor |
492 ++next_compositor_id_; | 482 // througout its lifetime. |
483 DCHECK(compositor_map_.count(compositor_id) == 0); | |
484 compositor_map_[compositor_id] = compositor; | |
493 | 485 |
494 DCHECK(compositor_map_.find(next_compositor_id_) == compositor_map_.end()); | 486 // At this point, the RVHChanged event for the new RVH that contains the |
495 compositor_map_[next_compositor_id_] = compositor; | 487 // |compositor| might have been fired already, in which case just set the |
496 next_compositor_id_++; | 488 // current compositor with the new compositor. |
489 if (!compositor_ && compositor_id == compositor_id_) | |
490 compositor_ = compositor; | |
497 } | 491 } |
498 | 492 |
499 void BrowserViewRenderer::DidDestroyCompositor( | 493 void BrowserViewRenderer::DidDestroyCompositor( |
500 content::SynchronousCompositor* compositor) { | 494 content::SynchronousCompositor* compositor, |
495 int process_id, | |
496 int routing_id) { | |
501 TRACE_EVENT_INSTANT0("android_webview", | 497 TRACE_EVENT_INSTANT0("android_webview", |
502 "BrowserViewRenderer::DidDestroyCompositor", | 498 "BrowserViewRenderer::DidDestroyCompositor", |
503 TRACE_EVENT_SCOPE_THREAD); | 499 TRACE_EVENT_SCOPE_THREAD); |
504 DCHECK(compositor_); | 500 CompositorID compositor_id(process_id, routing_id); |
505 if (compositor_ == compositor) | 501 DCHECK(compositor_map_.count(compositor_id)); |
502 if (compositor_ == compositor) { | |
506 compositor_ = nullptr; | 503 compositor_ = nullptr; |
507 compositor_map_.erase(GetCompositorID(compositor)); | 504 compositor_id_ = CompositorID(); |
boliu
2016/06/13 15:30:44
hmm, would this be more consistent that only OnRVC
hush (inactive)
2016/06/14 23:48:28
removed
| |
505 } | |
506 | |
507 compositor_map_.erase(compositor_id); | |
508 } | 508 } |
509 | 509 |
510 void BrowserViewRenderer::DidBecomeCurrent( | 510 void BrowserViewRenderer::RenderViewHostChanged( |
511 content::SynchronousCompositor* compositor) { | 511 content::RenderViewHost* old_host, |
512 TRACE_EVENT_INSTANT0("android_webview", | 512 content::RenderViewHost* new_host) { |
513 "BrowserViewRenderer::DidBecomeCurrent", | 513 DCHECK(new_host); |
514 TRACE_EVENT_SCOPE_THREAD); | 514 |
515 DCHECK(compositor); | 515 int process_id = new_host->GetProcess()->GetID(); |
516 DCHECK(GetCompositorID(compositor)); | 516 int routing_id = new_host->GetRoutingID(); |
517 compositor_ = compositor; | 517 CompositorID compositor_id(process_id, routing_id); |
518 // At this point, the current RVH may or may not contain a compositor. So | |
519 // compositor_ may be nullptr, in which case DidInitializeCompositor() | |
520 // callback is time when the new compositor is constructed. | |
521 if (compositor_map_.count(compositor_id)) { | |
522 compositor_ = compositor_map_[compositor_id]; | |
523 compositor_id_ = compositor_id; | |
524 // Now transfer states to the new compositor, like memory policy and root | |
525 // layer scroll offset. | |
526 UpdateMemoryPolicy(); | |
boliu
2016/06/13 15:30:44
if these two lines are new, then can we add these
hush (inactive)
2016/06/14 23:48:28
sure.
| |
527 compositor_->DidChangeRootLayerScrollOffset( | |
528 gfx::ScrollOffset(scroll_offset_dip_)); | |
529 } else { | |
530 compositor_ = nullptr; | |
boliu
2016/06/13 15:30:44
ditto about "compositor_id_ always point to active
hush (inactive)
2016/06/14 23:48:28
let's discuss in person on this one....
| |
531 compositor_id_ = compositor_id; | |
532 } | |
518 } | 533 } |
519 | 534 |
520 void BrowserViewRenderer::SetDipScale(float dip_scale) { | 535 void BrowserViewRenderer::SetDipScale(float dip_scale) { |
521 dip_scale_ = dip_scale; | 536 dip_scale_ = dip_scale; |
522 CHECK_GT(dip_scale_, 0.f); | 537 CHECK_GT(dip_scale_, 0.f); |
523 } | 538 } |
524 | 539 |
525 gfx::Vector2d BrowserViewRenderer::max_scroll_offset() const { | 540 gfx::Vector2d BrowserViewRenderer::max_scroll_offset() const { |
526 DCHECK_GT(dip_scale_, 0.f); | 541 DCHECK_GT(dip_scale_, 0.f); |
527 return gfx::ToCeiledVector2d(gfx::ScaleVector2d( | 542 return gfx::ToCeiledVector2d(gfx::ScaleVector2d( |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
714 base::StringAppendF(&str, | 729 base::StringAppendF(&str, |
715 "overscroll_rounding_error_: %s ", | 730 "overscroll_rounding_error_: %s ", |
716 overscroll_rounding_error_.ToString().c_str()); | 731 overscroll_rounding_error_.ToString().c_str()); |
717 base::StringAppendF( | 732 base::StringAppendF( |
718 &str, "on_new_picture_enable: %d ", on_new_picture_enable_); | 733 &str, "on_new_picture_enable: %d ", on_new_picture_enable_); |
719 base::StringAppendF(&str, "clear_view: %d ", clear_view_); | 734 base::StringAppendF(&str, "clear_view: %d ", clear_view_); |
720 return str; | 735 return str; |
721 } | 736 } |
722 | 737 |
723 } // namespace android_webview | 738 } // namespace android_webview |
OLD | NEW |