1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "content/renderer/gpu/render_widget_compositor.h" 6 7 #include <limits> 8 #include <string> 9 10 #include "base/command_line.h" 11 #include "base/logging.h" 12 #include "base/strings/string_number_conversions.h" 13 #include "base/synchronization/lock.h" 14 #include "base/sys_info.h" 15 #include "base/time/time.h" 16 #include "base/values.h" 17 #include "cc/base/latency_info_swap_promise.h" 18 #include "cc/base/latency_info_swap_promise_monitor.h" 19 #include "cc/base/swap_promise.h" 20 #include "cc/base/switches.h" 21 #include "cc/blink/web_layer_impl.h" 22 #include "cc/debug/layer_tree_debug_state.h" 23 #include "cc/debug/micro_benchmark.h" 24 #include "cc/input/layer_selection_bound.h" 25 #include "cc/layers/layer.h" 26 #include "cc/output/begin_frame_args.h" 27 #include "cc/output/copy_output_request.h" 28 #include "cc/output/copy_output_result.h" 29 #include "cc/resources/single_release_callback.h" 30 #include "cc/trees/layer_tree_host.h" 31 #include "content/child/child_shared_bitmap_manager.h" 32 #include "content/common/content_switches_internal.h" 33 #include "content/common/gpu/client/context_provider_command_buffer.h" 34 #include "content/public/common/content_switches.h" 35 #include "content/renderer/input/input_handler_manager.h" 36 #include "content/renderer/render_thread_impl.h" 37 #include "gpu/command_buffer/client/gles2_interface.h" 38 #include "third_party/WebKit/public/platform/WebCompositeAndReadbackAsyncCallback.h" 39 #include "third_party/WebKit/public/platform/WebSelectionBound.h" 40 #include "third_party/WebKit/public/platform/WebSize.h" 41 #include "third_party/WebKit/public/web/WebKit.h" 42 #include "third_party/WebKit/public/web/WebWidget.h" 43 #include "ui/gfx/frame_time.h" 44 #include "ui/gl/gl_switches.h" 45 #include "ui/native_theme/native_theme_switches.h" 46 47 #if defined(OS_ANDROID) 48 #include "content/renderer/android/synchronous_compositor_factory.h" 49 #include "ui/gfx/android/device_display_info.h" 50 #endif 51 52 namespace base { 53 class Value; 54 } 55 56 namespace cc { 57 class Layer; 58 } 59 60 using blink::WebBeginFrameArgs; 61 using blink::WebFloatPoint; 62 using blink::WebRect; 63 using blink::WebSelectionBound; 64 using blink::WebSize; 65 66 namespace content { 67 namespace { 68 69 bool GetSwitchValueAsInt( 70 const CommandLine& command_line, 71 const std::string& switch_string, 72 int min_value, 73 int max_value, 74 int* result) { 75 std::string string_value = command_line.GetSwitchValueASCII(switch_string); 76 int int_value; 77 if (base::StringToInt(string_value, &int_value) && 78 int_value >= min_value && int_value <= max_value) { 79 *result = int_value; 80 return true; 81 } else { 82 LOG(WARNING) << "Failed to parse switch " << switch_string << ": " << 83 string_value; 84 return false; 85 } 86 } 87 88 cc::LayerSelectionBound ConvertWebSelectionBound( 89 const WebSelectionBound& web_bound) { 90 DCHECK(web_bound.layerId); 91 92 cc::LayerSelectionBound cc_bound; 93 switch (web_bound.type) { 94 case blink::WebSelectionBound::Caret: 95 cc_bound.type = cc::SELECTION_BOUND_CENTER; 96 break; 97 case blink::WebSelectionBound::SelectionLeft: 98 cc_bound.type = cc::SELECTION_BOUND_LEFT; 99 break; 100 case blink::WebSelectionBound::SelectionRight: 101 cc_bound.type = cc::SELECTION_BOUND_RIGHT; 102 break; 103 } 104 cc_bound.layer_id = web_bound.layerId; 105 cc_bound.edge_top = gfx::Point(web_bound.edgeTopInLayer); 106 cc_bound.edge_bottom = gfx::Point(web_bound.edgeBottomInLayer); 107 return cc_bound; 108 } 109 110 gfx::Size CalculateDefaultTileSize() { 111 int default_tile_size = 256; 112 #if defined(OS_ANDROID) 113 // TODO(epenner): unify this for all platforms if it 114 // makes sense (http://crbug.com/159524) 115 116 gfx::DeviceDisplayInfo info; 117 bool real_size_supported = true; 118 int display_width = info.GetPhysicalDisplayWidth(); 119 int display_height = info.GetPhysicalDisplayHeight(); 120 if (display_width == 0 || display_height == 0) { 121 real_size_supported = false; 122 display_width = info.GetDisplayWidth(); 123 display_height = info.GetDisplayHeight(); 124 } 125 126 int portrait_width = std::min(display_width, display_height); 127 int landscape_width = std::max(display_width, display_height); 128 129 if (real_size_supported) { 130 // Maximum HD dimensions should be 768x1280 131 // Maximum FHD dimensions should be 1200x1920 132 if (portrait_width > 768 || landscape_width > 1280) 133 default_tile_size = 384; 134 if (portrait_width > 1200 || landscape_width > 1920) 135 default_tile_size = 512; 136 137 // Adjust for some resolutions that barely straddle an extra 138 // tile when in portrait mode. This helps worst case scroll/raster 139 // by not needing a full extra tile for each row. 140 if (default_tile_size == 256 && portrait_width == 768) 141 default_tile_size += 32; 142 if (default_tile_size == 384 && portrait_width == 1200) 143 default_tile_size += 32; 144 } else { 145 // We don't know the exact resolution due to screen controls etc. 146 // So this just estimates the values above using tile counts. 147 int numTiles = (display_width * display_height) / (256 * 256); 148 if (numTiles > 16) 149 default_tile_size = 384; 150 if (numTiles >= 40) 151 default_tile_size = 512; 152 } 153 #endif 154 return gfx::Size(default_tile_size, default_tile_size); 155 } 156 157 } // namespace 158 159 // static 160 scoped_ptr<RenderWidgetCompositor> RenderWidgetCompositor::Create( 161 RenderWidget* widget, 162 bool threaded) { 163 scoped_ptr<RenderWidgetCompositor> compositor( 164 new RenderWidgetCompositor(widget, threaded)); 165 166 CommandLine* cmd = CommandLine::ForCurrentProcess(); 167 168 cc::LayerTreeSettings settings; 169 170 // For web contents, layer transforms should scale up the contents of layers 171 // to keep content always crisp when possible. 172 settings.layer_transforms_should_scale_layer_contents = true; 173 174 settings.throttle_frame_production = 175 !cmd->HasSwitch(switches::kDisableGpuVsync); 176 settings.begin_frame_scheduling_enabled = 177 cmd->HasSwitch(switches::kEnableBeginFrameScheduling); 178 settings.main_frame_before_activation_enabled = 179 cmd->HasSwitch(cc::switches::kEnableMainFrameBeforeActivation) && 180 !cmd->HasSwitch(cc::switches::kDisableMainFrameBeforeActivation); 181 settings.main_frame_before_draw_enabled = 182 !cmd->HasSwitch(cc::switches::kDisableMainFrameBeforeDraw); 183 settings.report_overscroll_only_for_scrollable_axes = true; 184 settings.accelerated_animation_enabled = 185 !cmd->HasSwitch(cc::switches::kDisableThreadedAnimation); 186 187 settings.default_tile_size = CalculateDefaultTileSize(); 188 if (cmd->HasSwitch(switches::kDefaultTileWidth)) { 189 int tile_width = 0; 190 GetSwitchValueAsInt(*cmd, 191 switches::kDefaultTileWidth, 192 1, 193 std::numeric_limits<int>::max(), 194 &tile_width); 195 settings.default_tile_size.set_width(tile_width); 196 } 197 if (cmd->HasSwitch(switches::kDefaultTileHeight)) { 198 int tile_height = 0; 199 GetSwitchValueAsInt(*cmd, 200 switches::kDefaultTileHeight, 201 1, 202 std::numeric_limits<int>::max(), 203 &tile_height); 204 settings.default_tile_size.set_height(tile_height); 205 } 206 207 int max_untiled_layer_width = settings.max_untiled_layer_size.width(); 208 if (cmd->HasSwitch(switches::kMaxUntiledLayerWidth)) { 209 GetSwitchValueAsInt(*cmd, switches::kMaxUntiledLayerWidth, 1, 210 std::numeric_limits<int>::max(), 211 &max_untiled_layer_width); 212 } 213 int max_untiled_layer_height = settings.max_untiled_layer_size.height(); 214 if (cmd->HasSwitch(switches::kMaxUntiledLayerHeight)) { 215 GetSwitchValueAsInt(*cmd, switches::kMaxUntiledLayerHeight, 1, 216 std::numeric_limits<int>::max(), 217 &max_untiled_layer_height); 218 } 219 220 settings.max_untiled_layer_size = gfx::Size(max_untiled_layer_width, 221 max_untiled_layer_height); 222 223 RenderThreadImpl* render_thread = RenderThreadImpl::current(); 224 // render_thread may be NULL in tests. 225 if (render_thread) { 226 settings.impl_side_painting = 227 render_thread->is_impl_side_painting_enabled(); 228 settings.gpu_rasterization_forced = 229 render_thread->is_gpu_rasterization_forced(); 230 settings.gpu_rasterization_enabled = 231 render_thread->is_gpu_rasterization_enabled(); 232 settings.can_use_lcd_text = render_thread->is_lcd_text_enabled(); 233 settings.use_distance_field_text = 234 render_thread->is_distance_field_text_enabled(); 235 settings.use_zero_copy = render_thread->is_zero_copy_enabled(); 236 settings.use_one_copy = render_thread->is_one_copy_enabled(); 237 } 238 239 if (cmd->HasSwitch(switches::kEnableBleedingEdgeRenderingFastPaths)) { 240 settings.recording_mode = cc::LayerTreeSettings::RecordWithSkRecord; 241 } 242 243 settings.calculate_top_controls_position = 244 cmd->HasSwitch(cc::switches::kEnableTopControlsPositionCalculation); 245 if (cmd->HasSwitch(cc::switches::kTopControlsHeight)) { 246 std::string controls_height_str = 247 cmd->GetSwitchValueASCII(cc::switches::kTopControlsHeight); 248 double controls_height; 249 if (base::StringToDouble(controls_height_str, &controls_height) && 250 controls_height > 0) 251 settings.top_controls_height = controls_height; 252 } 253 254 if (settings.calculate_top_controls_position && 255 settings.top_controls_height <= 0) { 256 DCHECK(false) 257 << "Top controls repositioning enabled without valid height set."; 258 settings.calculate_top_controls_position = false; 259 } 260 261 if (cmd->HasSwitch(cc::switches::kTopControlsShowThreshold)) { 262 std::string top_threshold_str = 263 cmd->GetSwitchValueASCII(cc::switches::kTopControlsShowThreshold); 264 double show_threshold; 265 if (base::StringToDouble(top_threshold_str, &show_threshold) && 266 show_threshold >= 0.f && show_threshold <= 1.f) 267 settings.top_controls_show_threshold = show_threshold; 268 } 269 270 if (cmd->HasSwitch(cc::switches::kTopControlsHideThreshold)) { 271 std::string top_threshold_str = 272 cmd->GetSwitchValueASCII(cc::switches::kTopControlsHideThreshold); 273 double hide_threshold; 274 if (base::StringToDouble(top_threshold_str, &hide_threshold) && 275 hide_threshold >= 0.f && hide_threshold <= 1.f) 276 settings.top_controls_hide_threshold = hide_threshold; 277 } 278 279 settings.use_pinch_virtual_viewport = 280 cmd->HasSwitch(cc::switches::kEnablePinchVirtualViewport); 281 settings.allow_antialiasing &= 282 !cmd->HasSwitch(cc::switches::kDisableCompositedAntialiasing); 283 settings.single_thread_proxy_scheduler = 284 !cmd->HasSwitch(switches::kDisableSingleThreadProxyScheduler); 285 286 // These flags should be mirrored by UI versions in ui/compositor/. 287 settings.initial_debug_state.show_debug_borders = 288 cmd->HasSwitch(cc::switches::kShowCompositedLayerBorders); 289 settings.initial_debug_state.show_fps_counter = 290 cmd->HasSwitch(cc::switches::kShowFPSCounter); 291 settings.initial_debug_state.show_layer_animation_bounds_rects = 292 cmd->HasSwitch(cc::switches::kShowLayerAnimationBounds); 293 settings.initial_debug_state.show_paint_rects = 294 cmd->HasSwitch(switches::kShowPaintRects); 295 settings.initial_debug_state.show_property_changed_rects = 296 cmd->HasSwitch(cc::switches::kShowPropertyChangedRects); 297 settings.initial_debug_state.show_surface_damage_rects = 298 cmd->HasSwitch(cc::switches::kShowSurfaceDamageRects); 299 settings.initial_debug_state.show_screen_space_rects = 300 cmd->HasSwitch(cc::switches::kShowScreenSpaceRects); 301 settings.initial_debug_state.show_replica_screen_space_rects = 302 cmd->HasSwitch(cc::switches::kShowReplicaScreenSpaceRects); 303 settings.initial_debug_state.show_occluding_rects = 304 cmd->HasSwitch(cc::switches::kShowOccludingRects); 305 settings.initial_debug_state.show_non_occluding_rects = 306 cmd->HasSwitch(cc::switches::kShowNonOccludingRects); 307 308 settings.initial_debug_state.SetRecordRenderingStats( 309 cmd->HasSwitch(cc::switches::kEnableGpuBenchmarking)); 310 311 if (cmd->HasSwitch(cc::switches::kSlowDownRasterScaleFactor)) { 312 const int kMinSlowDownScaleFactor = 0; 313 const int kMaxSlowDownScaleFactor = INT_MAX; 314 GetSwitchValueAsInt( 315 *cmd, 316 cc::switches::kSlowDownRasterScaleFactor, 317 kMinSlowDownScaleFactor, 318 kMaxSlowDownScaleFactor, 319 &settings.initial_debug_state.slow_down_raster_scale_factor); 320 } 321 322 if (cmd->HasSwitch(cc::switches::kMaxTilesForInterestArea)) { 323 int max_tiles_for_interest_area; 324 if (GetSwitchValueAsInt(*cmd, 325 cc::switches::kMaxTilesForInterestArea, 326 1, std::numeric_limits<int>::max(), 327 &max_tiles_for_interest_area)) 328 settings.max_tiles_for_interest_area = max_tiles_for_interest_area; 329 } 330 331 if (cmd->HasSwitch(cc::switches::kMaxUnusedResourceMemoryUsagePercentage)) { 332 int max_unused_resource_memory_percentage; 333 if (GetSwitchValueAsInt( 334 *cmd, 335 cc::switches::kMaxUnusedResourceMemoryUsagePercentage, 336 0, 100, 337 &max_unused_resource_memory_percentage)) { 338 settings.max_unused_resource_memory_percentage = 339 max_unused_resource_memory_percentage; 340 } 341 } 342 343 settings.strict_layer_property_change_checking = 344 cmd->HasSwitch(cc::switches::kStrictLayerPropertyChangeChecking); 345 346 #if defined(OS_ANDROID) 347 SynchronousCompositorFactory* synchronous_compositor_factory = 348 SynchronousCompositorFactory::GetInstance(); 349 350 settings.using_synchronous_renderer_compositor = 351 synchronous_compositor_factory; 352 settings.record_full_layer = 353 synchronous_compositor_factory && 354 synchronous_compositor_factory->RecordFullLayer(); 355 settings.report_overscroll_only_for_scrollable_axes = 356 !synchronous_compositor_factory; 357 settings.max_partial_texture_updates = 0; 358 if (synchronous_compositor_factory) { 359 // Android WebView uses system scrollbars, so make ours invisible. 360 settings.scrollbar_animator = cc::LayerTreeSettings::NoAnimator; 361 settings.solid_color_scrollbar_color = SK_ColorTRANSPARENT; 362 } else { 363 settings.scrollbar_animator = cc::LayerTreeSettings::LinearFade; 364 settings.scrollbar_fade_delay_ms = 300; 365 settings.scrollbar_fade_duration_ms = 300; 366 settings.solid_color_scrollbar_color = SkColorSetARGB(128, 128, 128, 128); 367 } 368 settings.highp_threshold_min = 2048; 369 // Android WebView handles root layer flings itself. 370 settings.ignore_root_layer_flings = 371 synchronous_compositor_factory; 372 // Memory policy on Android WebView does not depend on whether device is 373 // low end, so always use default policy. 374 bool is_low_end_device = 375 base::SysInfo::IsLowEndDevice() && !synchronous_compositor_factory; 376 // RGBA_4444 textures are only enabled for low end devices 377 // and are disabled for Android WebView as it doesn't support the format. 378 settings.use_rgba_4444_textures = is_low_end_device; 379 if (is_low_end_device) { 380 // On low-end we want to be very carefull about killing other 381 // apps. So initially we use 50% more memory to avoid flickering 382 // or raster-on-demand. 383 settings.max_memory_for_prepaint_percentage = 67; 384 } else { 385 // On other devices we have increased memory excessively to avoid 386 // raster-on-demand already, so now we reserve 50% _only_ to avoid 387 // raster-on-demand, and use 50% of the memory otherwise. 388 settings.max_memory_for_prepaint_percentage = 50; 389 } 390 // Webview does not own the surface so should not clear it. 391 settings.should_clear_root_render_pass = 392 !synchronous_compositor_factory; 393 394 // TODO(danakj): Only do this on low end devices. 395 settings.create_low_res_tiling = true; 396 397 #elif !defined(OS_MACOSX) 398 if (ui::IsOverlayScrollbarEnabled()) { 399 settings.scrollbar_animator = cc::LayerTreeSettings::Thinning; 400 settings.solid_color_scrollbar_color = SkColorSetARGB(128, 128, 128, 128); 401 } else if (cmd->HasSwitch(cc::switches::kEnablePinchVirtualViewport)) { 402 // use_pinch_zoom_scrollbars is only true on desktop when non-overlay 403 // scrollbars are in use. 404 settings.use_pinch_zoom_scrollbars = true; 405 settings.scrollbar_animator = cc::LayerTreeSettings::LinearFade; 406 settings.solid_color_scrollbar_color = SkColorSetARGB(128, 128, 128, 128); 407 } 408 settings.scrollbar_fade_delay_ms = 500; 409 settings.scrollbar_fade_duration_ms = 300; 410 #endif 411 412 if (cmd->HasSwitch(switches::kEnableLowResTiling)) 413 settings.create_low_res_tiling = true; 414 if (cmd->HasSwitch(switches::kDisableLowResTiling)) 415 settings.create_low_res_tiling = false; 416 417 compositor->Initialize(settings); 418 419 return compositor.Pass(); 420 } 421 422 RenderWidgetCompositor::RenderWidgetCompositor(RenderWidget* widget, 423 bool threaded) 424 : threaded_(threaded), 425 widget_(widget), 426 send_v8_idle_notification_after_commit_(true) { 427 CommandLine* cmd = CommandLine::ForCurrentProcess(); 428 429 if (cmd->HasSwitch(switches::kEnableV8IdleNotificationAfterCommit)) 430 send_v8_idle_notification_after_commit_ = true; 431 if (cmd->HasSwitch(switches::kDisableV8IdleNotificationAfterCommit)) 432 send_v8_idle_notification_after_commit_ = false; 433 } 434 435 RenderWidgetCompositor::~RenderWidgetCompositor() {} 436 437 const base::WeakPtr<cc::InputHandler>& 438 RenderWidgetCompositor::GetInputHandler() { 439 return layer_tree_host_->GetInputHandler(); 440 } 441 442 bool RenderWidgetCompositor::BeginMainFrameRequested() const { 443 return layer_tree_host_->BeginMainFrameRequested(); 444 } 445 446 void RenderWidgetCompositor::SetNeedsDisplayOnAllLayers() { 447 layer_tree_host_->SetNeedsDisplayOnAllLayers(); 448 } 449 450 void RenderWidgetCompositor::SetRasterizeOnlyVisibleContent() { 451 cc::LayerTreeDebugState current = layer_tree_host_->debug_state(); 452 current.rasterize_only_visible_content = true; 453 layer_tree_host_->SetDebugState(current); 454 } 455 456 void RenderWidgetCompositor::UpdateTopControlsState( 457 cc::TopControlsState constraints, 458 cc::TopControlsState current, 459 bool animate) { 460 layer_tree_host_->UpdateTopControlsState(constraints, 461 current, 462 animate); 463 } 464 465 void RenderWidgetCompositor::SetTopControlsLayoutHeight(float height) { 466 layer_tree_host_->SetTopControlsLayoutHeight(height); 467 } 468 469 void RenderWidgetCompositor::SetNeedsRedrawRect(gfx::Rect damage_rect) { 470 layer_tree_host_->SetNeedsRedrawRect(damage_rect); 471 } 472 473 void RenderWidgetCompositor::SetNeedsForcedRedraw() { 474 layer_tree_host_->SetNextCommitForcesRedraw(); 475 setNeedsAnimate(); 476 } 477 478 scoped_ptr<cc::SwapPromiseMonitor> 479 RenderWidgetCompositor::CreateLatencyInfoSwapPromiseMonitor( 480 ui::LatencyInfo* latency) { 481 return scoped_ptr<cc::SwapPromiseMonitor>( 482 new cc::LatencyInfoSwapPromiseMonitor( 483 latency, layer_tree_host_.get(), NULL)); 484 } 485 486 void RenderWidgetCompositor::QueueSwapPromise( 487 scoped_ptr<cc::SwapPromise> swap_promise) { 488 layer_tree_host_->QueueSwapPromise(swap_promise.Pass()); 489 } 490 491 int RenderWidgetCompositor::GetLayerTreeId() const { 492 return layer_tree_host_->id(); 493 } 494 495 int RenderWidgetCompositor::GetSourceFrameNumber() const { 496 return layer_tree_host_->source_frame_number(); 497 } 498 499 void RenderWidgetCompositor::SetNeedsCommit() { 500 layer_tree_host_->SetNeedsCommit(); 501 } 502 503 void RenderWidgetCompositor::NotifyInputThrottledUntilCommit() { 504 layer_tree_host_->NotifyInputThrottledUntilCommit(); 505 } 506 507 const cc::Layer* RenderWidgetCompositor::GetRootLayer() const { 508 return layer_tree_host_->root_layer(); 509 } 510 511 int RenderWidgetCompositor::ScheduleMicroBenchmark( 512 const std::string& name, 513 scoped_ptr<base::Value> value, 514 const base::Callback<void(scoped_ptr<base::Value>)>& callback) { 515 return layer_tree_host_->ScheduleMicroBenchmark(name, value.Pass(), callback); 516 } 517 518 bool RenderWidgetCompositor::SendMessageToMicroBenchmark( 519 int id, 520 scoped_ptr<base::Value> value) { 521 return layer_tree_host_->SendMessageToMicroBenchmark(id, value.Pass()); 522 } 523 524 void RenderWidgetCompositor::Initialize(cc::LayerTreeSettings settings) { 525 scoped_refptr<base::MessageLoopProxy> compositor_message_loop_proxy; 526 scoped_refptr<base::SingleThreadTaskRunner> 527 main_thread_compositor_task_runner(base::MessageLoopProxy::current()); 528 RenderThreadImpl* render_thread = RenderThreadImpl::current(); 529 cc::SharedBitmapManager* shared_bitmap_manager = NULL; 530 // render_thread may be NULL in tests. 531 if (render_thread) { 532 compositor_message_loop_proxy = 533 render_thread->compositor_message_loop_proxy(); 534 shared_bitmap_manager = render_thread->shared_bitmap_manager(); 535 main_thread_compositor_task_runner = 536 render_thread->main_thread_compositor_task_runner(); 537 } 538 if (compositor_message_loop_proxy.get()) { 539 layer_tree_host_ = 540 cc::LayerTreeHost::CreateThreaded(this, 541 shared_bitmap_manager, 542 settings, 543 main_thread_compositor_task_runner, 544 compositor_message_loop_proxy); 545 } else { 546 layer_tree_host_ = cc::LayerTreeHost::CreateSingleThreaded( 547 this, 548 this, 549 shared_bitmap_manager, 550 settings, 551 main_thread_compositor_task_runner); 552 } 553 DCHECK(layer_tree_host_); 554 } 555 556 void RenderWidgetCompositor::setSurfaceReady() { 557 // In tests without a RenderThreadImpl, don't set ready as this kicks 558 // off creating output surfaces that the test can't create. 559 if (RenderThreadImpl::current()) 560 layer_tree_host_->SetLayerTreeHostClientReady(); 561 } 562 563 void RenderWidgetCompositor::setRootLayer(const blink::WebLayer& layer) { 564 layer_tree_host_->SetRootLayer( 565 static_cast<const cc_blink::WebLayerImpl*>(&layer)->layer()); 566 } 567 568 void RenderWidgetCompositor::clearRootLayer() { 569 layer_tree_host_->SetRootLayer(scoped_refptr<cc::Layer>()); 570 } 571 572 void RenderWidgetCompositor::setViewportSize( 573 const WebSize&, 574 const WebSize& device_viewport_size) { 575 layer_tree_host_->SetViewportSize(device_viewport_size); 576 } 577 578 void RenderWidgetCompositor::setViewportSize( 579 const WebSize& device_viewport_size) { 580 layer_tree_host_->SetViewportSize(device_viewport_size); 581 } 582 583 WebSize RenderWidgetCompositor::layoutViewportSize() const { 584 return layer_tree_host_->device_viewport_size(); 585 } 586 587 WebSize RenderWidgetCompositor::deviceViewportSize() const { 588 return layer_tree_host_->device_viewport_size(); 589 } 590 591 WebFloatPoint RenderWidgetCompositor::adjustEventPointForPinchZoom( 592 const WebFloatPoint& point) const { 593 return point; 594 } 595 596 void RenderWidgetCompositor::setDeviceScaleFactor(float device_scale) { 597 layer_tree_host_->SetDeviceScaleFactor(device_scale); 598 } 599 600 float RenderWidgetCompositor::deviceScaleFactor() const { 601 return layer_tree_host_->device_scale_factor(); 602 } 603 604 void RenderWidgetCompositor::setBackgroundColor(blink::WebColor color) { 605 layer_tree_host_->set_background_color(color); 606 } 607 608 void RenderWidgetCompositor::setHasTransparentBackground(bool transparent) { 609 layer_tree_host_->set_has_transparent_background(transparent); 610 } 611 612 void RenderWidgetCompositor::setOverhangBitmap(const SkBitmap& bitmap) { 613 layer_tree_host_->SetOverhangBitmap(bitmap); 614 } 615 616 void RenderWidgetCompositor::setVisible(bool visible) { 617 layer_tree_host_->SetVisible(visible); 618 } 619 620 void RenderWidgetCompositor::setPageScaleFactorAndLimits( 621 float page_scale_factor, float minimum, float maximum) { 622 layer_tree_host_->SetPageScaleFactorAndLimits( 623 page_scale_factor, minimum, maximum); 624 } 625 626 void RenderWidgetCompositor::startPageScaleAnimation( 627 const blink::WebPoint& destination, 628 bool use_anchor, 629 float new_page_scale, 630 double duration_sec) { 631 base::TimeDelta duration = base::TimeDelta::FromMicroseconds( 632 duration_sec * base::Time::kMicrosecondsPerSecond); 633 layer_tree_host_->StartPageScaleAnimation( 634 gfx::Vector2d(destination.x, destination.y), 635 use_anchor, 636 new_page_scale, 637 duration); 638 } 639 640 void RenderWidgetCompositor::heuristicsForGpuRasterizationUpdated( 641 bool matches_heuristics) { 642 layer_tree_host_->SetHasGpuRasterizationTrigger(matches_heuristics); 643 } 644 645 void RenderWidgetCompositor::setNeedsAnimate() { 646 layer_tree_host_->SetNeedsAnimate(); 647 } 648 649 bool RenderWidgetCompositor::commitRequested() const { 650 return layer_tree_host_->CommitRequested(); 651 } 652 653 void RenderWidgetCompositor::didStopFlinging() { 654 layer_tree_host_->DidStopFlinging(); 655 } 656 657 void RenderWidgetCompositor::registerForAnimations(blink::WebLayer* layer) { 658 cc::Layer* cc_layer = static_cast<cc_blink::WebLayerImpl*>(layer)->layer(); 659 cc_layer->layer_animation_controller()->SetAnimationRegistrar( 660 layer_tree_host_->animation_registrar()); 661 } 662 663 void RenderWidgetCompositor::registerViewportLayers( 664 const blink::WebLayer* pageScaleLayer, 665 const blink::WebLayer* innerViewportScrollLayer, 666 const blink::WebLayer* outerViewportScrollLayer) { 667 layer_tree_host_->RegisterViewportLayers( 668 static_cast<const cc_blink::WebLayerImpl*>(pageScaleLayer)->layer(), 669 static_cast<const cc_blink::WebLayerImpl*>(innerViewportScrollLayer) 670 ->layer(), 671 // The outer viewport layer will only exist when using pinch virtual 672 // viewports. 673 outerViewportScrollLayer ? static_cast<const cc_blink::WebLayerImpl*>( 674 outerViewportScrollLayer)->layer() 675 : NULL); 676 } 677 678 void RenderWidgetCompositor::clearViewportLayers() { 679 layer_tree_host_->RegisterViewportLayers(scoped_refptr<cc::Layer>(), 680 scoped_refptr<cc::Layer>(), 681 scoped_refptr<cc::Layer>()); 682 } 683 684 void RenderWidgetCompositor::registerSelection( 685 const blink::WebSelectionBound& start, 686 const blink::WebSelectionBound& end) { 687 layer_tree_host_->RegisterSelection(ConvertWebSelectionBound(start), 688 ConvertWebSelectionBound(end)); 689 } 690 691 void RenderWidgetCompositor::clearSelection() { 692 cc::LayerSelectionBound empty_selection; 693 layer_tree_host_->RegisterSelection(empty_selection, empty_selection); 694 } 695 696 void CompositeAndReadbackAsyncCallback( 697 blink::WebCompositeAndReadbackAsyncCallback* callback, 698 scoped_ptr<cc::CopyOutputResult> result) { 699 if (result->HasBitmap()) { 700 scoped_ptr<SkBitmap> result_bitmap = result->TakeBitmap(); 701 callback->didCompositeAndReadback(*result_bitmap); 702 } else { 703 callback->didCompositeAndReadback(SkBitmap()); 704 } 705 } 706 707 void RenderWidgetCompositor::compositeAndReadbackAsync( 708 blink::WebCompositeAndReadbackAsyncCallback* callback) { 709 DCHECK(layer_tree_host_->root_layer()); 710 scoped_ptr<cc::CopyOutputRequest> request = 711 cc::CopyOutputRequest::CreateBitmapRequest( 712 base::Bind(&CompositeAndReadbackAsyncCallback, callback)); 713 layer_tree_host_->root_layer()->RequestCopyOfOutput(request.Pass()); 714 715 if (!threaded_ && 716 !layer_tree_host_->settings().single_thread_proxy_scheduler) { 717 layer_tree_host_->Composite(gfx::FrameTime::Now()); 718 } 719 } 720 721 void RenderWidgetCompositor::finishAllRendering() { 722 layer_tree_host_->FinishAllRendering(); 723 } 724 725 void RenderWidgetCompositor::setDeferCommits(bool defer_commits) { 726 layer_tree_host_->SetDeferCommits(defer_commits); 727 } 728 729 void RenderWidgetCompositor::setShowFPSCounter(bool show) { 730 cc::LayerTreeDebugState debug_state = layer_tree_host_->debug_state(); 731 debug_state.show_fps_counter = show; 732 layer_tree_host_->SetDebugState(debug_state); 733 } 734 735 void RenderWidgetCompositor::setShowPaintRects(bool show) { 736 cc::LayerTreeDebugState debug_state = layer_tree_host_->debug_state(); 737 debug_state.show_paint_rects = show; 738 layer_tree_host_->SetDebugState(debug_state); 739 } 740 741 void RenderWidgetCompositor::setShowDebugBorders(bool show) { 742 cc::LayerTreeDebugState debug_state = layer_tree_host_->debug_state(); 743 debug_state.show_debug_borders = show; 744 layer_tree_host_->SetDebugState(debug_state); 745 } 746 747 void RenderWidgetCompositor::setContinuousPaintingEnabled(bool enabled) { 748 cc::LayerTreeDebugState debug_state = layer_tree_host_->debug_state(); 749 debug_state.continuous_painting = enabled; 750 layer_tree_host_->SetDebugState(debug_state); 751 } 752 753 void RenderWidgetCompositor::setShowScrollBottleneckRects(bool show) { 754 cc::LayerTreeDebugState debug_state = layer_tree_host_->debug_state(); 755 debug_state.show_touch_event_handler_rects = show; 756 debug_state.show_wheel_event_handler_rects = show; 757 debug_state.show_non_fast_scrollable_rects = show; 758 layer_tree_host_->SetDebugState(debug_state); 759 } 760 761 void RenderWidgetCompositor::setTopControlsContentOffset(float offset) { 762 layer_tree_host_->SetTopControlsContentOffset(offset); 763 } 764 765 void RenderWidgetCompositor::WillBeginMainFrame(int frame_id) { 766 widget_->InstrumentWillBeginFrame(frame_id); 767 widget_->willBeginCompositorFrame(); 768 } 769 770 void RenderWidgetCompositor::DidBeginMainFrame() { 771 widget_->InstrumentDidBeginFrame(); 772 } 773 774 void RenderWidgetCompositor::BeginMainFrame(const cc::BeginFrameArgs& args) { 775 begin_main_frame_time_ = args.frame_time; 776 begin_main_frame_interval_ = args.interval; 777 double frame_time_sec = (args.frame_time - base::TimeTicks()).InSecondsF(); 778 double deadline_sec = (args.deadline - base::TimeTicks()).InSecondsF(); 779 double interval_sec = args.interval.InSecondsF(); 780 WebBeginFrameArgs web_begin_frame_args = 781 WebBeginFrameArgs(frame_time_sec, deadline_sec, interval_sec); 782 widget_->webwidget()->beginFrame(web_begin_frame_args); 783 } 784 785 void RenderWidgetCompositor::Layout() { 786 widget_->webwidget()->layout(); 787 } 788 789 void RenderWidgetCompositor::ApplyViewportDeltas( 790 const gfx::Vector2d& scroll_delta, 791 float page_scale, 792 float top_controls_delta) { 793 widget_->webwidget()->applyViewportDeltas( 794 scroll_delta, 795 page_scale, 796 top_controls_delta); 797 } 798 799 void RenderWidgetCompositor::RequestNewOutputSurface(bool fallback) { 800 layer_tree_host_->SetOutputSurface(widget_->CreateOutputSurface(fallback)); 801 } 802 803 void RenderWidgetCompositor::DidInitializeOutputSurface() { 804 } 805 806 void RenderWidgetCompositor::WillCommit() { 807 widget_->InstrumentWillComposite(); 808 } 809 810 void RenderWidgetCompositor::DidCommit() { 811 if (send_v8_idle_notification_after_commit_) { 812 base::TimeDelta idle_time = begin_main_frame_time_ + 813 begin_main_frame_interval_ - 814 gfx::FrameTime::Now(); 815 if (idle_time > base::TimeDelta()) { 816 // Convert to 32-bit microseconds first to avoid costly 64-bit division. 817 int32 idle_time_in_us = idle_time.InMicroseconds(); 818 int32 idle_time_in_ms = idle_time_in_us / 1000; 819 if (idle_time_in_ms) 820 blink::mainThreadIsolate()->IdleNotification(idle_time_in_ms); 821 } 822 } 823 824 widget_->DidCommitCompositorFrame(); 825 widget_->didBecomeReadyForAdditionalInput(); 826 widget_->webwidget()->didCommitFrameToCompositor(); 827 } 828 829 void RenderWidgetCompositor::DidCommitAndDrawFrame() { 830 widget_->didCommitAndDrawCompositorFrame(); 831 } 832 833 void RenderWidgetCompositor::DidCompleteSwapBuffers() { 834 widget_->didCompleteSwapBuffers(); 835 if (!threaded_) 836 widget_->OnSwapBuffersComplete(); 837 } 838 839 void RenderWidgetCompositor::ScheduleAnimation() { 840 widget_->scheduleAnimation(); 841 } 842 843 void RenderWidgetCompositor::DidPostSwapBuffers() { 844 widget_->OnSwapBuffersPosted(); 845 } 846 847 void RenderWidgetCompositor::DidAbortSwapBuffers() { 848 widget_->OnSwapBuffersAborted(); 849 } 850 851 void RenderWidgetCompositor::RateLimitSharedMainThreadContext() { 852 cc::ContextProvider* provider = 853 RenderThreadImpl::current()->SharedMainThreadContextProvider().get(); 854 provider->ContextGL()->RateLimitOffscreenContextCHROMIUM(); 855 } 856 857 } // namespace content 858