| 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), |
| 97 is_paused_(false), | 101 is_paused_(false), |
| 98 view_visible_(false), | 102 view_visible_(false), |
| 99 window_visible_(false), | 103 window_visible_(false), |
| 100 attached_to_window_(false), | 104 attached_to_window_(false), |
| 101 hardware_enabled_(false), | 105 hardware_enabled_(false), |
| 102 dip_scale_(0.f), | 106 dip_scale_(0.f), |
| 103 page_scale_factor_(1.f), | 107 page_scale_factor_(1.f), |
| 104 min_page_scale_factor_(0.f), | 108 min_page_scale_factor_(0.f), |
| 105 max_page_scale_factor_(0.f), | 109 max_page_scale_factor_(0.f), |
| 106 on_new_picture_enable_(false), | 110 on_new_picture_enable_(false), |
| 107 clear_view_(false), | 111 clear_view_(false), |
| 108 offscreen_pre_raster_(false), | 112 offscreen_pre_raster_(false) {} |
| 109 next_compositor_id_(1) {} | |
| 110 | 113 |
| 111 BrowserViewRenderer::~BrowserViewRenderer() { | 114 BrowserViewRenderer::~BrowserViewRenderer() { |
| 112 DCHECK(compositor_map_.empty()); | 115 DCHECK(compositor_map_.empty()); |
| 113 SetCurrentCompositorFrameConsumer(nullptr); | 116 SetCurrentCompositorFrameConsumer(nullptr); |
| 114 while (compositor_frame_consumers_.size()) { | 117 while (compositor_frame_consumers_.size()) { |
| 115 RemoveCompositorFrameConsumer(*compositor_frame_consumers_.begin()); | 118 RemoveCompositorFrameConsumer(*compositor_frame_consumers_.begin()); |
| 116 } | 119 } |
| 117 } | 120 } |
| 118 | 121 |
| 119 void BrowserViewRenderer::SetCurrentCompositorFrameConsumer( | 122 void BrowserViewRenderer::SetCurrentCompositorFrameConsumer( |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 clip, | 243 clip, |
| 241 viewport_rect_for_tile_priority, | 244 viewport_rect_for_tile_priority, |
| 242 transform_for_tile_priority); | 245 transform_for_tile_priority); |
| 243 if (!frame.frame.get()) { | 246 if (!frame.frame.get()) { |
| 244 TRACE_EVENT_INSTANT0("android_webview", "NoNewFrame", | 247 TRACE_EVENT_INSTANT0("android_webview", "NoNewFrame", |
| 245 TRACE_EVENT_SCOPE_THREAD); | 248 TRACE_EVENT_SCOPE_THREAD); |
| 246 return current_compositor_frame_consumer_->HasFrameOnUI(); | 249 return current_compositor_frame_consumer_->HasFrameOnUI(); |
| 247 } | 250 } |
| 248 | 251 |
| 249 std::unique_ptr<ChildFrame> child_frame = base::WrapUnique(new ChildFrame( | 252 std::unique_ptr<ChildFrame> child_frame = base::WrapUnique(new ChildFrame( |
| 250 frame.output_surface_id, std::move(frame.frame), | 253 frame.output_surface_id, std::move(frame.frame), compositor_id_, |
| 251 GetCompositorID(compositor_), viewport_rect_for_tile_priority.IsEmpty(), | 254 viewport_rect_for_tile_priority.IsEmpty(), transform_for_tile_priority, |
| 252 transform_for_tile_priority, offscreen_pre_raster_, | 255 offscreen_pre_raster_, external_draw_constraints_.is_layer)); |
| 253 external_draw_constraints_.is_layer)); | |
| 254 | 256 |
| 255 ReturnUnusedResource( | 257 ReturnUnusedResource( |
| 256 current_compositor_frame_consumer_->PassUncommittedFrameOnUI()); | 258 current_compositor_frame_consumer_->PassUncommittedFrameOnUI()); |
| 257 current_compositor_frame_consumer_->SetFrameOnUI(std::move(child_frame)); | 259 current_compositor_frame_consumer_->SetFrameOnUI(std::move(child_frame)); |
| 258 return true; | 260 return true; |
| 259 } | 261 } |
| 260 | 262 |
| 261 void BrowserViewRenderer::OnParentDrawConstraintsUpdated( | 263 void BrowserViewRenderer::OnParentDrawConstraintsUpdated( |
| 262 CompositorFrameConsumer* compositor_frame_consumer) { | 264 CompositorFrameConsumer* compositor_frame_consumer) { |
| 263 DCHECK(compositor_frame_consumer); | 265 DCHECK(compositor_frame_consumer); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 content::SynchronousCompositor* compositor = | 299 content::SynchronousCompositor* compositor = |
| 298 compositor_map_[child_frame->compositor_id]; | 300 compositor_map_[child_frame->compositor_id]; |
| 299 if (compositor && !frame_ack.resources.empty()) | 301 if (compositor && !frame_ack.resources.empty()) |
| 300 compositor->ReturnResources(child_frame->output_surface_id, frame_ack); | 302 compositor->ReturnResources(child_frame->output_surface_id, frame_ack); |
| 301 } | 303 } |
| 302 | 304 |
| 303 void BrowserViewRenderer::ReturnResourceFromParent( | 305 void BrowserViewRenderer::ReturnResourceFromParent( |
| 304 CompositorFrameConsumer* compositor_frame_consumer) { | 306 CompositorFrameConsumer* compositor_frame_consumer) { |
| 305 CompositorFrameConsumer::ReturnedResourcesMap returned_resource_map; | 307 CompositorFrameConsumer::ReturnedResourcesMap returned_resource_map; |
| 306 compositor_frame_consumer->SwapReturnedResourcesOnUI(&returned_resource_map); | 308 compositor_frame_consumer->SwapReturnedResourcesOnUI(&returned_resource_map); |
| 307 for (auto iterator = returned_resource_map.begin(); | 309 for (auto& pair : returned_resource_map) { |
| 308 iterator != returned_resource_map.end(); iterator++) { | 310 CompositorID compositor_id = pair.first; |
| 309 uint32_t compositor_id = iterator->first; | |
| 310 content::SynchronousCompositor* compositor = compositor_map_[compositor_id]; | 311 content::SynchronousCompositor* compositor = compositor_map_[compositor_id]; |
| 311 cc::CompositorFrameAck frame_ack; | 312 cc::CompositorFrameAck frame_ack; |
| 312 frame_ack.resources.swap(iterator->second.resources); | 313 frame_ack.resources.swap(pair.second.resources); |
| 313 | 314 |
| 314 if (compositor && !frame_ack.resources.empty()) { | 315 if (compositor && !frame_ack.resources.empty()) { |
| 315 compositor->ReturnResources(iterator->second.output_surface_id, | 316 compositor->ReturnResources(pair.second.output_surface_id, frame_ack); |
| 316 frame_ack); | |
| 317 } | 317 } |
| 318 } | 318 } |
| 319 } | 319 } |
| 320 | 320 |
| 321 bool BrowserViewRenderer::OnDrawSoftware(SkCanvas* canvas) { | 321 bool BrowserViewRenderer::OnDrawSoftware(SkCanvas* canvas) { |
| 322 return CanOnDraw() && CompositeSW(canvas); | 322 return CanOnDraw() && CompositeSW(canvas); |
| 323 } | 323 } |
| 324 | 324 |
| 325 sk_sp<SkPicture> BrowserViewRenderer::CapturePicture(int width, | 325 sk_sp<SkPicture> BrowserViewRenderer::CapturePicture(int width, |
| 326 int height) { | 326 int height) { |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 } | 464 } |
| 465 | 465 |
| 466 bool BrowserViewRenderer::IsClientVisible() const { | 466 bool BrowserViewRenderer::IsClientVisible() const { |
| 467 return !is_paused_ && (!attached_to_window_ || window_visible_); | 467 return !is_paused_ && (!attached_to_window_ || window_visible_); |
| 468 } | 468 } |
| 469 | 469 |
| 470 gfx::Rect BrowserViewRenderer::GetScreenRect() const { | 470 gfx::Rect BrowserViewRenderer::GetScreenRect() const { |
| 471 return gfx::Rect(client_->GetLocationOnScreen(), size_); | 471 return gfx::Rect(client_->GetLocationOnScreen(), size_); |
| 472 } | 472 } |
| 473 | 473 |
| 474 uint32_t BrowserViewRenderer::GetCompositorID( | |
| 475 content::SynchronousCompositor* compositor) { | |
| 476 for (auto iterator = compositor_map_.begin(); | |
| 477 iterator != compositor_map_.end(); iterator++) { | |
| 478 if (iterator->second == compositor) { | |
| 479 return iterator->first; | |
| 480 } | |
| 481 } | |
| 482 | |
| 483 DCHECK(false); | |
| 484 // Return an invalid ID (0), because ID starts with 1. | |
| 485 return 0; | |
| 486 } | |
| 487 | |
| 488 void BrowserViewRenderer::DidInitializeCompositor( | 474 void BrowserViewRenderer::DidInitializeCompositor( |
| 489 content::SynchronousCompositor* compositor) { | 475 content::SynchronousCompositor* compositor, |
| 476 int process_id, |
| 477 int routing_id) { |
| 490 TRACE_EVENT_INSTANT0("android_webview", | 478 TRACE_EVENT_INSTANT0("android_webview", |
| 491 "BrowserViewRenderer::DidInitializeCompositor", | 479 "BrowserViewRenderer::DidInitializeCompositor", |
| 492 TRACE_EVENT_SCOPE_THREAD); | 480 TRACE_EVENT_SCOPE_THREAD); |
| 493 DCHECK(compositor); | 481 DCHECK(compositor); |
| 494 // This happens when id overflows to 0, unlikely in practice. | 482 CompositorID compositor_id(process_id, routing_id); |
| 495 if (next_compositor_id_ == 0) | 483 // This assumes that a RenderViewHost has at most 1 synchronous compositor |
| 496 ++next_compositor_id_; | 484 // througout its lifetime. |
| 485 DCHECK(compositor_map_.count(compositor_id) == 0); |
| 486 compositor_map_[compositor_id] = compositor; |
| 497 | 487 |
| 498 DCHECK(compositor_map_.find(next_compositor_id_) == compositor_map_.end()); | 488 // At this point, the RVHChanged event for the new RVH that contains the |
| 499 compositor_map_[next_compositor_id_] = compositor; | 489 // |compositor| might have been fired already, in which case just set the |
| 500 next_compositor_id_++; | 490 // current compositor with the new compositor. |
| 491 if (!compositor_ && compositor_id == compositor_id_) { |
| 492 compositor_ = compositor; |
| 493 } |
| 501 } | 494 } |
| 502 | 495 |
| 503 void BrowserViewRenderer::DidDestroyCompositor( | 496 void BrowserViewRenderer::DidDestroyCompositor( |
| 504 content::SynchronousCompositor* compositor) { | 497 content::SynchronousCompositor* compositor, |
| 498 int process_id, |
| 499 int routing_id) { |
| 505 TRACE_EVENT_INSTANT0("android_webview", | 500 TRACE_EVENT_INSTANT0("android_webview", |
| 506 "BrowserViewRenderer::DidDestroyCompositor", | 501 "BrowserViewRenderer::DidDestroyCompositor", |
| 507 TRACE_EVENT_SCOPE_THREAD); | 502 TRACE_EVENT_SCOPE_THREAD); |
| 503 CompositorID compositor_id(process_id, routing_id); |
| 508 DCHECK(compositor_); | 504 DCHECK(compositor_); |
| 509 if (compositor_ == compositor) | 505 DCHECK(compositor_map_.count(compositor_id)); |
| 506 if (compositor_ == compositor) { |
| 510 compositor_ = nullptr; | 507 compositor_ = nullptr; |
| 508 compositor_id_ = CompositorID(); |
| 509 } |
| 510 |
| 511 compositor->SetIsActive(false); | 511 compositor->SetIsActive(false); |
| 512 compositor_map_.erase(GetCompositorID(compositor)); | 512 compositor_map_.erase(compositor_id); |
| 513 } | 513 } |
| 514 | 514 |
| 515 void BrowserViewRenderer::DidBecomeCurrent( | 515 void BrowserViewRenderer::RenderViewHostChanged( |
| 516 content::SynchronousCompositor* compositor) { | 516 content::RenderViewHost* old_host, |
| 517 TRACE_EVENT_INSTANT0("android_webview", | 517 content::RenderViewHost* new_host) { |
| 518 "BrowserViewRenderer::DidBecomeCurrent", | 518 DCHECK(new_host); |
| 519 TRACE_EVENT_SCOPE_THREAD); | |
| 520 DCHECK(compositor); | |
| 521 DCHECK(GetCompositorID(compositor)); | |
| 522 if (compositor_) | 519 if (compositor_) |
| 523 compositor_->SetIsActive(false); | 520 compositor_->SetIsActive(false); |
| 524 | 521 |
| 525 compositor_ = compositor; | 522 int process_id = new_host->GetProcess()->GetID(); |
| 526 UpdateCompositorIsActive(); | 523 int routing_id = new_host->GetRoutingID(); |
| 524 CompositorID compositor_id(process_id, routing_id); |
| 525 // At this point, the current RVH may or may not contain a compositor. So |
| 526 // compositor_ may be nullptr, in which case DidInitializeCompositor() |
| 527 // callback is time when the new compositor is constructed. |
| 528 if (compositor_map_.count(compositor_id)) { |
| 529 compositor_ = compositor_map_[compositor_id]; |
| 530 compositor_id_ = compositor_id; |
| 531 // Now transfer states to the new compositor, like memory policy and root |
| 532 // layer scroll offset. |
| 533 UpdateCompositorIsActive(); |
| 534 UpdateMemoryPolicy(); |
| 535 compositor_->DidChangeRootLayerScrollOffset( |
| 536 gfx::ScrollOffset(scroll_offset_dip_)); |
| 537 } else { |
| 538 compositor_ = nullptr; |
| 539 compositor_id_ = compositor_id; |
| 540 } |
| 527 } | 541 } |
| 528 | 542 |
| 529 void BrowserViewRenderer::SetDipScale(float dip_scale) { | 543 void BrowserViewRenderer::SetDipScale(float dip_scale) { |
| 530 dip_scale_ = dip_scale; | 544 dip_scale_ = dip_scale; |
| 531 CHECK_GT(dip_scale_, 0.f); | 545 CHECK_GT(dip_scale_, 0.f); |
| 532 } | 546 } |
| 533 | 547 |
| 534 gfx::Vector2d BrowserViewRenderer::max_scroll_offset() const { | 548 gfx::Vector2d BrowserViewRenderer::max_scroll_offset() const { |
| 535 DCHECK_GT(dip_scale_, 0.f); | 549 DCHECK_GT(dip_scale_, 0.f); |
| 536 return gfx::ToCeiledVector2d(gfx::ScaleVector2d( | 550 return gfx::ToCeiledVector2d(gfx::ScaleVector2d( |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 730 base::StringAppendF(&str, | 744 base::StringAppendF(&str, |
| 731 "overscroll_rounding_error_: %s ", | 745 "overscroll_rounding_error_: %s ", |
| 732 overscroll_rounding_error_.ToString().c_str()); | 746 overscroll_rounding_error_.ToString().c_str()); |
| 733 base::StringAppendF( | 747 base::StringAppendF( |
| 734 &str, "on_new_picture_enable: %d ", on_new_picture_enable_); | 748 &str, "on_new_picture_enable: %d ", on_new_picture_enable_); |
| 735 base::StringAppendF(&str, "clear_view: %d ", clear_view_); | 749 base::StringAppendF(&str, "clear_view: %d ", clear_view_); |
| 736 return str; | 750 return str; |
| 737 } | 751 } |
| 738 | 752 |
| 739 } // namespace android_webview | 753 } // namespace android_webview |
| OLD | NEW |