| 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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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( |
| 91 BrowserViewRendererClient* client, | 93 BrowserViewRendererClient* client, |
| 92 const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner) | 94 const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner) |
| 93 : client_(client), | 95 : client_(client), |
| 94 ui_task_runner_(ui_task_runner), | 96 ui_task_runner_(ui_task_runner), |
| 95 current_compositor_frame_consumer_(nullptr), | 97 current_compositor_frame_consumer_(nullptr), |
| 96 compositor_(NULL), | 98 compositor_(nullptr), |
| 97 is_paused_(false), | 99 is_paused_(false), |
| 98 view_visible_(false), | 100 view_visible_(false), |
| 99 window_visible_(false), | 101 window_visible_(false), |
| 100 attached_to_window_(false), | 102 attached_to_window_(false), |
| 101 hardware_enabled_(false), | 103 hardware_enabled_(false), |
| 102 dip_scale_(0.f), | 104 dip_scale_(0.f), |
| 103 page_scale_factor_(1.f), | 105 page_scale_factor_(1.f), |
| 104 min_page_scale_factor_(0.f), | 106 min_page_scale_factor_(0.f), |
| 105 max_page_scale_factor_(0.f), | 107 max_page_scale_factor_(0.f), |
| 106 on_new_picture_enable_(false), | 108 on_new_picture_enable_(false), |
| 107 clear_view_(false), | 109 clear_view_(false), |
| 108 offscreen_pre_raster_(false), | 110 offscreen_pre_raster_(false) {} |
| 109 next_compositor_id_(1) {} | |
| 110 | 111 |
| 111 BrowserViewRenderer::~BrowserViewRenderer() { | 112 BrowserViewRenderer::~BrowserViewRenderer() { |
| 112 DCHECK(compositor_map_.empty()); | 113 DCHECK(compositor_map_.empty()); |
| 113 SetCurrentCompositorFrameConsumer(nullptr); | 114 SetCurrentCompositorFrameConsumer(nullptr); |
| 114 while (compositor_frame_consumers_.size()) { | 115 while (compositor_frame_consumers_.size()) { |
| 115 RemoveCompositorFrameConsumer(*compositor_frame_consumers_.begin()); | 116 RemoveCompositorFrameConsumer(*compositor_frame_consumers_.begin()); |
| 116 } | 117 } |
| 117 } | 118 } |
| 118 | 119 |
| 119 void BrowserViewRenderer::SetCurrentCompositorFrameConsumer( | 120 void BrowserViewRenderer::SetCurrentCompositorFrameConsumer( |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 clip, | 241 clip, |
| 241 viewport_rect_for_tile_priority, | 242 viewport_rect_for_tile_priority, |
| 242 transform_for_tile_priority); | 243 transform_for_tile_priority); |
| 243 if (!frame.frame.get()) { | 244 if (!frame.frame.get()) { |
| 244 TRACE_EVENT_INSTANT0("android_webview", "NoNewFrame", | 245 TRACE_EVENT_INSTANT0("android_webview", "NoNewFrame", |
| 245 TRACE_EVENT_SCOPE_THREAD); | 246 TRACE_EVENT_SCOPE_THREAD); |
| 246 return current_compositor_frame_consumer_->HasFrameOnUI(); | 247 return current_compositor_frame_consumer_->HasFrameOnUI(); |
| 247 } | 248 } |
| 248 | 249 |
| 249 std::unique_ptr<ChildFrame> child_frame = base::WrapUnique(new ChildFrame( | 250 std::unique_ptr<ChildFrame> child_frame = base::WrapUnique(new ChildFrame( |
| 250 frame.output_surface_id, std::move(frame.frame), | 251 frame.output_surface_id, std::move(frame.frame), compositor_id_, |
| 251 GetCompositorID(compositor_), viewport_rect_for_tile_priority.IsEmpty(), | 252 viewport_rect_for_tile_priority.IsEmpty(), transform_for_tile_priority, |
| 252 transform_for_tile_priority, offscreen_pre_raster_, | 253 offscreen_pre_raster_, external_draw_constraints_.is_layer)); |
| 253 external_draw_constraints_.is_layer)); | |
| 254 | 254 |
| 255 ReturnUnusedResource( | 255 ReturnUnusedResource( |
| 256 current_compositor_frame_consumer_->PassUncommittedFrameOnUI()); | 256 current_compositor_frame_consumer_->PassUncommittedFrameOnUI()); |
| 257 current_compositor_frame_consumer_->SetFrameOnUI(std::move(child_frame)); | 257 current_compositor_frame_consumer_->SetFrameOnUI(std::move(child_frame)); |
| 258 return true; | 258 return true; |
| 259 } | 259 } |
| 260 | 260 |
| 261 void BrowserViewRenderer::OnParentDrawConstraintsUpdated( | 261 void BrowserViewRenderer::OnParentDrawConstraintsUpdated( |
| 262 CompositorFrameConsumer* compositor_frame_consumer) { | 262 CompositorFrameConsumer* compositor_frame_consumer) { |
| 263 DCHECK(compositor_frame_consumer); | 263 DCHECK(compositor_frame_consumer); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 content::SynchronousCompositor* compositor = | 297 content::SynchronousCompositor* compositor = |
| 298 compositor_map_[child_frame->compositor_id]; | 298 compositor_map_[child_frame->compositor_id]; |
| 299 if (compositor && !frame_ack.resources.empty()) | 299 if (compositor && !frame_ack.resources.empty()) |
| 300 compositor->ReturnResources(child_frame->output_surface_id, frame_ack); | 300 compositor->ReturnResources(child_frame->output_surface_id, frame_ack); |
| 301 } | 301 } |
| 302 | 302 |
| 303 void BrowserViewRenderer::ReturnResourceFromParent( | 303 void BrowserViewRenderer::ReturnResourceFromParent( |
| 304 CompositorFrameConsumer* compositor_frame_consumer) { | 304 CompositorFrameConsumer* compositor_frame_consumer) { |
| 305 CompositorFrameConsumer::ReturnedResourcesMap returned_resource_map; | 305 CompositorFrameConsumer::ReturnedResourcesMap returned_resource_map; |
| 306 compositor_frame_consumer->SwapReturnedResourcesOnUI(&returned_resource_map); | 306 compositor_frame_consumer->SwapReturnedResourcesOnUI(&returned_resource_map); |
| 307 for (auto iterator = returned_resource_map.begin(); | 307 for (auto& pair : returned_resource_map) { |
| 308 iterator != returned_resource_map.end(); iterator++) { | 308 CompositorID compositor_id = pair.first; |
| 309 uint32_t compositor_id = iterator->first; | |
| 310 content::SynchronousCompositor* compositor = compositor_map_[compositor_id]; | 309 content::SynchronousCompositor* compositor = compositor_map_[compositor_id]; |
| 311 cc::CompositorFrameAck frame_ack; | 310 cc::CompositorFrameAck frame_ack; |
| 312 frame_ack.resources.swap(iterator->second.resources); | 311 frame_ack.resources.swap(pair.second.resources); |
| 313 | 312 |
| 314 if (compositor && !frame_ack.resources.empty()) { | 313 if (compositor && !frame_ack.resources.empty()) { |
| 315 compositor->ReturnResources(iterator->second.output_surface_id, | 314 compositor->ReturnResources(pair.second.output_surface_id, frame_ack); |
| 316 frame_ack); | |
| 317 } | 315 } |
| 318 } | 316 } |
| 319 } | 317 } |
| 320 | 318 |
| 321 bool BrowserViewRenderer::OnDrawSoftware(SkCanvas* canvas) { | 319 bool BrowserViewRenderer::OnDrawSoftware(SkCanvas* canvas) { |
| 322 return CanOnDraw() && CompositeSW(canvas); | 320 return CanOnDraw() && CompositeSW(canvas); |
| 323 } | 321 } |
| 324 | 322 |
| 325 sk_sp<SkPicture> BrowserViewRenderer::CapturePicture(int width, | 323 sk_sp<SkPicture> BrowserViewRenderer::CapturePicture(int width, |
| 326 int height) { | 324 int height) { |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 } | 458 } |
| 461 | 459 |
| 462 bool BrowserViewRenderer::IsClientVisible() const { | 460 bool BrowserViewRenderer::IsClientVisible() const { |
| 463 return !is_paused_ && (!attached_to_window_ || window_visible_); | 461 return !is_paused_ && (!attached_to_window_ || window_visible_); |
| 464 } | 462 } |
| 465 | 463 |
| 466 gfx::Rect BrowserViewRenderer::GetScreenRect() const { | 464 gfx::Rect BrowserViewRenderer::GetScreenRect() const { |
| 467 return gfx::Rect(client_->GetLocationOnScreen(), size_); | 465 return gfx::Rect(client_->GetLocationOnScreen(), size_); |
| 468 } | 466 } |
| 469 | 467 |
| 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( | 468 void BrowserViewRenderer::DidInitializeCompositor( |
| 485 content::SynchronousCompositor* compositor) { | 469 content::SynchronousCompositor* compositor, |
| 470 int process_id, |
| 471 int routing_id) { |
| 486 TRACE_EVENT_INSTANT0("android_webview", | 472 TRACE_EVENT_INSTANT0("android_webview", |
| 487 "BrowserViewRenderer::DidInitializeCompositor", | 473 "BrowserViewRenderer::DidInitializeCompositor", |
| 488 TRACE_EVENT_SCOPE_THREAD); | 474 TRACE_EVENT_SCOPE_THREAD); |
| 489 DCHECK(compositor); | 475 DCHECK(compositor); |
| 490 // This happens when id overflows to 0, unlikely in practice. | 476 CompositorID compositor_id(process_id, routing_id); |
| 491 if (next_compositor_id_ == 0) | 477 // This assumes that a RenderViewHost has at most 1 synchronous compositor |
| 492 ++next_compositor_id_; | 478 // througout its lifetime. |
| 479 DCHECK(compositor_map_.count(compositor_id) == 0); |
| 480 compositor_map_[compositor_id] = compositor; |
| 493 | 481 |
| 494 DCHECK(compositor_map_.find(next_compositor_id_) == compositor_map_.end()); | 482 // At this point, the RVHChanged event for the new RVH that contains the |
| 495 compositor_map_[next_compositor_id_] = compositor; | 483 // |compositor| might have been fired already, in which case just set the |
| 496 next_compositor_id_++; | 484 // current compositor with the new compositor. |
| 485 if (!compositor_ && compositor_id.Equals(compositor_id_)) |
| 486 compositor_ = compositor; |
| 497 } | 487 } |
| 498 | 488 |
| 499 void BrowserViewRenderer::DidDestroyCompositor( | 489 void BrowserViewRenderer::DidDestroyCompositor( |
| 500 content::SynchronousCompositor* compositor) { | 490 content::SynchronousCompositor* compositor, |
| 491 int process_id, |
| 492 int routing_id) { |
| 501 TRACE_EVENT_INSTANT0("android_webview", | 493 TRACE_EVENT_INSTANT0("android_webview", |
| 502 "BrowserViewRenderer::DidDestroyCompositor", | 494 "BrowserViewRenderer::DidDestroyCompositor", |
| 503 TRACE_EVENT_SCOPE_THREAD); | 495 TRACE_EVENT_SCOPE_THREAD); |
| 504 DCHECK(compositor_); | 496 CompositorID compositor_id(process_id, routing_id); |
| 505 if (compositor_ == compositor) | 497 DCHECK(compositor_map_.count(compositor_id)); |
| 498 if (compositor_ == compositor) { |
| 506 compositor_ = nullptr; | 499 compositor_ = nullptr; |
| 507 compositor_map_.erase(GetCompositorID(compositor)); | 500 } |
| 501 |
| 502 compositor_map_.erase(compositor_id); |
| 508 } | 503 } |
| 509 | 504 |
| 510 void BrowserViewRenderer::DidBecomeCurrent( | 505 void BrowserViewRenderer::SetActiveCompositorID( |
| 511 content::SynchronousCompositor* compositor) { | 506 const CompositorID& compositor_id) { |
| 512 TRACE_EVENT_INSTANT0("android_webview", | 507 if (compositor_map_.count(compositor_id)) { |
| 513 "BrowserViewRenderer::DidBecomeCurrent", | 508 compositor_ = compositor_map_[compositor_id]; |
| 514 TRACE_EVENT_SCOPE_THREAD); | 509 // TODO(hush): Now transfer states to the new compositor, like memory policy |
| 515 DCHECK(compositor); | 510 // and root layer scroll offset. |
| 516 DCHECK(GetCompositorID(compositor)); | 511 } else { |
| 517 compositor_ = compositor; | 512 compositor_ = nullptr; |
| 513 } |
| 514 compositor_id_ = compositor_id; |
| 518 } | 515 } |
| 519 | 516 |
| 520 void BrowserViewRenderer::SetDipScale(float dip_scale) { | 517 void BrowserViewRenderer::SetDipScale(float dip_scale) { |
| 521 dip_scale_ = dip_scale; | 518 dip_scale_ = dip_scale; |
| 522 CHECK_GT(dip_scale_, 0.f); | 519 CHECK_GT(dip_scale_, 0.f); |
| 523 } | 520 } |
| 524 | 521 |
| 525 gfx::Vector2d BrowserViewRenderer::max_scroll_offset() const { | 522 gfx::Vector2d BrowserViewRenderer::max_scroll_offset() const { |
| 526 DCHECK_GT(dip_scale_, 0.f); | 523 DCHECK_GT(dip_scale_, 0.f); |
| 527 return gfx::ToCeiledVector2d(gfx::ScaleVector2d( | 524 return gfx::ToCeiledVector2d(gfx::ScaleVector2d( |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 714 base::StringAppendF(&str, | 711 base::StringAppendF(&str, |
| 715 "overscroll_rounding_error_: %s ", | 712 "overscroll_rounding_error_: %s ", |
| 716 overscroll_rounding_error_.ToString().c_str()); | 713 overscroll_rounding_error_.ToString().c_str()); |
| 717 base::StringAppendF( | 714 base::StringAppendF( |
| 718 &str, "on_new_picture_enable: %d ", on_new_picture_enable_); | 715 &str, "on_new_picture_enable: %d ", on_new_picture_enable_); |
| 719 base::StringAppendF(&str, "clear_view: %d ", clear_view_); | 716 base::StringAppendF(&str, "clear_view: %d ", clear_view_); |
| 720 return str; | 717 return str; |
| 721 } | 718 } |
| 722 | 719 |
| 723 } // namespace android_webview | 720 } // namespace android_webview |
| OLD | NEW |