Chromium Code Reviews| 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 |