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 #if defined(OS_ANDROID) 11 #include "base/android/sys_utils.h" 12 #endif 13 14 #include "base/command_line.h" 15 #include "base/logging.h" 16 #include "base/strings/string_number_conversions.h" 17 #include "base/synchronization/lock.h" 18 #include "base/time/time.h" 19 #include "base/values.h" 20 #include "cc/base/latency_info_swap_promise.h" 21 #include "cc/base/latency_info_swap_promise_monitor.h" 22 #include "cc/base/switches.h" 23 #include "cc/debug/layer_tree_debug_state.h" 24 #include "cc/debug/micro_benchmark.h" 25 #include "cc/layers/layer.h" 26 #include "cc/output/copy_output_request.h" 27 #include "cc/output/copy_output_result.h" 28 #include "cc/resources/single_release_callback.h" 29 #include "cc/trees/layer_tree_host.h" 30 #include "content/child/child_shared_bitmap_manager.h" 31 #include "content/common/content_switches_internal.h" 32 #include "content/common/gpu/client/context_provider_command_buffer.h" 33 #include "content/public/common/content_switches.h" 34 #include "content/renderer/compositor_bindings/web_layer_impl.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/WebSize.h" 40 #include "third_party/WebKit/public/web/WebWidget.h" 41 #include "ui/gfx/frame_time.h" 42 #include "ui/gl/gl_switches.h" 43 #include "ui/native_theme/native_theme_switches.h" 44 45 #if defined(OS_ANDROID) 46 #include "content/renderer/android/synchronous_compositor_factory.h" 47 #endif 48 49 namespace base { 50 class Value; 51 } 52 53 namespace cc { 54 class Layer; 55 } 56 57 using blink::WebFloatPoint; 58 using blink::WebSize; 59 using blink::WebRect; 60 61 namespace content { 62 namespace { 63 64 bool GetSwitchValueAsInt( 65 const CommandLine& command_line, 66 const std::string& switch_string, 67 int min_value, 68 int max_value, 69 int* result) { 70 std::string string_value = command_line.GetSwitchValueASCII(switch_string); 71 int int_value; 72 if (base::StringToInt(string_value, &int_value) && 73 int_value >= min_value && int_value <= max_value) { 74 *result = int_value; 75 return true; 76 } else { 77 LOG(WARNING) << "Failed to parse switch " << switch_string << ": " << 78 string_value; 79 return false; 80 } 81 } 82 83 } // namespace 84 85 // static 86 scoped_ptr<RenderWidgetCompositor> RenderWidgetCompositor::Create( 87 RenderWidget* widget, 88 bool threaded) { 89 scoped_ptr<RenderWidgetCompositor> compositor( 90 new RenderWidgetCompositor(widget, threaded)); 91 92 CommandLine* cmd = CommandLine::ForCurrentProcess(); 93 94 cc::LayerTreeSettings settings; 95 96 // For web contents, layer transforms should scale up the contents of layers 97 // to keep content always crisp when possible. 98 settings.layer_transforms_should_scale_layer_contents = true; 99 100 settings.throttle_frame_production = 101 !cmd->HasSwitch(switches::kDisableGpuVsync); 102 settings.begin_frame_scheduling_enabled = 103 cmd->HasSwitch(switches::kEnableBeginFrameScheduling); 104 settings.main_frame_before_activation_enabled = 105 cmd->HasSwitch(cc::switches::kEnableMainFrameBeforeActivation) && 106 !cmd->HasSwitch(cc::switches::kDisableMainFrameBeforeActivation); 107 settings.main_frame_before_draw_enabled = 108 !cmd->HasSwitch(cc::switches::kDisableMainFrameBeforeDraw); 109 settings.report_overscroll_only_for_scrollable_axes = true; 110 settings.accelerated_animation_enabled = 111 !cmd->HasSwitch(cc::switches::kDisableThreadedAnimation); 112 settings.touch_hit_testing = 113 !cmd->HasSwitch(cc::switches::kDisableCompositorTouchHitTesting); 114 115 int default_tile_width = settings.default_tile_size.width(); 116 if (cmd->HasSwitch(switches::kDefaultTileWidth)) { 117 GetSwitchValueAsInt(*cmd, switches::kDefaultTileWidth, 1, 118 std::numeric_limits<int>::max(), &default_tile_width); 119 } 120 int default_tile_height = settings.default_tile_size.height(); 121 if (cmd->HasSwitch(switches::kDefaultTileHeight)) { 122 GetSwitchValueAsInt(*cmd, switches::kDefaultTileHeight, 1, 123 std::numeric_limits<int>::max(), &default_tile_height); 124 } 125 settings.default_tile_size = gfx::Size(default_tile_width, 126 default_tile_height); 127 128 int max_untiled_layer_width = settings.max_untiled_layer_size.width(); 129 if (cmd->HasSwitch(switches::kMaxUntiledLayerWidth)) { 130 GetSwitchValueAsInt(*cmd, switches::kMaxUntiledLayerWidth, 1, 131 std::numeric_limits<int>::max(), 132 &max_untiled_layer_width); 133 } 134 int max_untiled_layer_height = settings.max_untiled_layer_size.height(); 135 if (cmd->HasSwitch(switches::kMaxUntiledLayerHeight)) { 136 GetSwitchValueAsInt(*cmd, switches::kMaxUntiledLayerHeight, 1, 137 std::numeric_limits<int>::max(), 138 &max_untiled_layer_height); 139 } 140 141 settings.max_untiled_layer_size = gfx::Size(max_untiled_layer_width, 142 max_untiled_layer_height); 143 144 RenderThreadImpl* render_thread = RenderThreadImpl::current(); 145 // render_thread may be NULL in tests. 146 if (render_thread) { 147 settings.impl_side_painting = 148 render_thread->is_impl_side_painting_enabled(); 149 settings.gpu_rasterization_forced = 150 render_thread->is_gpu_rasterization_forced(); 151 settings.gpu_rasterization_enabled = 152 render_thread->is_gpu_rasterization_enabled(); 153 settings.create_low_res_tiling = render_thread->is_low_res_tiling_enabled(); 154 settings.can_use_lcd_text = render_thread->is_lcd_text_enabled(); 155 settings.use_distance_field_text = 156 render_thread->is_distance_field_text_enabled(); 157 settings.use_zero_copy = render_thread->is_zero_copy_enabled(); 158 settings.use_one_copy = render_thread->is_one_copy_enabled(); 159 } 160 161 if (cmd->HasSwitch(switches::kEnableBleedingEdgeRenderingFastPaths)) { 162 settings.recording_mode = cc::LayerTreeSettings::RecordWithSkRecord; 163 } 164 165 settings.calculate_top_controls_position = 166 cmd->HasSwitch(cc::switches::kEnableTopControlsPositionCalculation); 167 if (cmd->HasSwitch(cc::switches::kTopControlsHeight)) { 168 std::string controls_height_str = 169 cmd->GetSwitchValueASCII(cc::switches::kTopControlsHeight); 170 double controls_height; 171 if (base::StringToDouble(controls_height_str, &controls_height) && 172 controls_height > 0) 173 settings.top_controls_height = controls_height; 174 } 175 176 if (settings.calculate_top_controls_position && 177 settings.top_controls_height <= 0) { 178 DCHECK(false) 179 << "Top controls repositioning enabled without valid height set."; 180 settings.calculate_top_controls_position = false; 181 } 182 183 if (cmd->HasSwitch(cc::switches::kTopControlsShowThreshold)) { 184 std::string top_threshold_str = 185 cmd->GetSwitchValueASCII(cc::switches::kTopControlsShowThreshold); 186 double show_threshold; 187 if (base::StringToDouble(top_threshold_str, &show_threshold) && 188 show_threshold >= 0.f && show_threshold <= 1.f) 189 settings.top_controls_show_threshold = show_threshold; 190 } 191 192 if (cmd->HasSwitch(cc::switches::kTopControlsHideThreshold)) { 193 std::string top_threshold_str = 194 cmd->GetSwitchValueASCII(cc::switches::kTopControlsHideThreshold); 195 double hide_threshold; 196 if (base::StringToDouble(top_threshold_str, &hide_threshold) && 197 hide_threshold >= 0.f && hide_threshold <= 1.f) 198 settings.top_controls_hide_threshold = hide_threshold; 199 } 200 201 settings.use_pinch_virtual_viewport = 202 cmd->HasSwitch(cc::switches::kEnablePinchVirtualViewport); 203 settings.allow_antialiasing &= 204 !cmd->HasSwitch(cc::switches::kDisableCompositedAntialiasing); 205 206 // These flags should be mirrored by UI versions in ui/compositor/. 207 settings.initial_debug_state.show_debug_borders = 208 cmd->HasSwitch(cc::switches::kShowCompositedLayerBorders); 209 settings.initial_debug_state.show_fps_counter = 210 cmd->HasSwitch(cc::switches::kShowFPSCounter); 211 settings.initial_debug_state.show_layer_animation_bounds_rects = 212 cmd->HasSwitch(cc::switches::kShowLayerAnimationBounds); 213 settings.initial_debug_state.show_paint_rects = 214 cmd->HasSwitch(switches::kShowPaintRects); 215 settings.initial_debug_state.show_property_changed_rects = 216 cmd->HasSwitch(cc::switches::kShowPropertyChangedRects); 217 settings.initial_debug_state.show_surface_damage_rects = 218 cmd->HasSwitch(cc::switches::kShowSurfaceDamageRects); 219 settings.initial_debug_state.show_screen_space_rects = 220 cmd->HasSwitch(cc::switches::kShowScreenSpaceRects); 221 settings.initial_debug_state.show_replica_screen_space_rects = 222 cmd->HasSwitch(cc::switches::kShowReplicaScreenSpaceRects); 223 settings.initial_debug_state.show_occluding_rects = 224 cmd->HasSwitch(cc::switches::kShowOccludingRects); 225 settings.initial_debug_state.show_non_occluding_rects = 226 cmd->HasSwitch(cc::switches::kShowNonOccludingRects); 227 228 settings.initial_debug_state.SetRecordRenderingStats( 229 cmd->HasSwitch(cc::switches::kEnableGpuBenchmarking)); 230 231 if (cmd->HasSwitch(cc::switches::kSlowDownRasterScaleFactor)) { 232 const int kMinSlowDownScaleFactor = 0; 233 const int kMaxSlowDownScaleFactor = INT_MAX; 234 GetSwitchValueAsInt( 235 *cmd, 236 cc::switches::kSlowDownRasterScaleFactor, 237 kMinSlowDownScaleFactor, 238 kMaxSlowDownScaleFactor, 239 &settings.initial_debug_state.slow_down_raster_scale_factor); 240 } 241 242 if (cmd->HasSwitch(cc::switches::kMaxTilesForInterestArea)) { 243 int max_tiles_for_interest_area; 244 if (GetSwitchValueAsInt(*cmd, 245 cc::switches::kMaxTilesForInterestArea, 246 1, std::numeric_limits<int>::max(), 247 &max_tiles_for_interest_area)) 248 settings.max_tiles_for_interest_area = max_tiles_for_interest_area; 249 } 250 251 if (cmd->HasSwitch(cc::switches::kMaxUnusedResourceMemoryUsagePercentage)) { 252 int max_unused_resource_memory_percentage; 253 if (GetSwitchValueAsInt( 254 *cmd, 255 cc::switches::kMaxUnusedResourceMemoryUsagePercentage, 256 0, 100, 257 &max_unused_resource_memory_percentage)) { 258 settings.max_unused_resource_memory_percentage = 259 max_unused_resource_memory_percentage; 260 } 261 } 262 263 settings.strict_layer_property_change_checking = 264 cmd->HasSwitch(cc::switches::kStrictLayerPropertyChangeChecking); 265 266 #if defined(OS_ANDROID) 267 SynchronousCompositorFactory* synchronous_compositor_factory = 268 SynchronousCompositorFactory::GetInstance(); 269 270 settings.using_synchronous_renderer_compositor = 271 synchronous_compositor_factory; 272 settings.record_full_layer = 273 synchronous_compositor_factory && 274 synchronous_compositor_factory->RecordFullLayer(); 275 settings.report_overscroll_only_for_scrollable_axes = 276 !synchronous_compositor_factory; 277 settings.max_partial_texture_updates = 0; 278 if (synchronous_compositor_factory) { 279 // Android WebView uses system scrollbars, so make ours invisible. 280 settings.scrollbar_animator = cc::LayerTreeSettings::NoAnimator; 281 settings.solid_color_scrollbar_color = SK_ColorTRANSPARENT; 282 } else { 283 settings.scrollbar_animator = cc::LayerTreeSettings::LinearFade; 284 settings.scrollbar_fade_delay_ms = 300; 285 settings.scrollbar_fade_duration_ms = 300; 286 settings.solid_color_scrollbar_color = SkColorSetARGB(128, 128, 128, 128); 287 } 288 settings.highp_threshold_min = 2048; 289 // Android WebView handles root layer flings itself. 290 settings.ignore_root_layer_flings = 291 synchronous_compositor_factory; 292 // Memory policy on Android WebView does not depend on whether device is 293 // low end, so always use default policy. 294 bool is_low_end_device = 295 base::android::SysUtils::IsLowEndDevice() && 296 !synchronous_compositor_factory; 297 // RGBA_4444 textures are only enabled for low end devices 298 // and are disabled for Android WebView as it doesn't support the format. 299 settings.use_rgba_4444_textures = is_low_end_device; 300 if (is_low_end_device) { 301 // On low-end we want to be very carefull about killing other 302 // apps. So initially we use 50% more memory to avoid flickering 303 // or raster-on-demand. 304 settings.max_memory_for_prepaint_percentage = 67; 305 } else { 306 // On other devices we have increased memory excessively to avoid 307 // raster-on-demand already, so now we reserve 50% _only_ to avoid 308 // raster-on-demand, and use 50% of the memory otherwise. 309 settings.max_memory_for_prepaint_percentage = 50; 310 } 311 // Webview does not own the surface so should not clear it. 312 settings.should_clear_root_render_pass = 313 !synchronous_compositor_factory; 314 315 #elif !defined(OS_MACOSX) 316 if (ui::IsOverlayScrollbarEnabled()) { 317 settings.scrollbar_animator = cc::LayerTreeSettings::Thinning; 318 settings.solid_color_scrollbar_color = SkColorSetARGB(128, 128, 128, 128); 319 } else if (cmd->HasSwitch(cc::switches::kEnablePinchVirtualViewport)) { 320 // use_pinch_zoom_scrollbars is only true on desktop when non-overlay 321 // scrollbars are in use. 322 settings.use_pinch_zoom_scrollbars = true; 323 settings.scrollbar_animator = cc::LayerTreeSettings::LinearFade; 324 settings.solid_color_scrollbar_color = SkColorSetARGB(128, 128, 128, 128); 325 } 326 settings.scrollbar_fade_delay_ms = 500; 327 settings.scrollbar_fade_duration_ms = 300; 328 #endif 329 330 compositor->Initialize(settings); 331 332 return compositor.Pass(); 333 } 334 335 RenderWidgetCompositor::RenderWidgetCompositor(RenderWidget* widget, 336 bool threaded) 337 : threaded_(threaded), 338 suppress_schedule_composite_(false), 339 widget_(widget) { 340 } 341 342 RenderWidgetCompositor::~RenderWidgetCompositor() {} 343 344 const base::WeakPtr<cc::InputHandler>& 345 RenderWidgetCompositor::GetInputHandler() { 346 return layer_tree_host_->GetInputHandler(); 347 } 348 349 void RenderWidgetCompositor::SetSuppressScheduleComposite(bool suppress) { 350 if (suppress_schedule_composite_ == suppress) 351 return; 352 353 if (suppress) 354 TRACE_EVENT_ASYNC_BEGIN0("gpu", 355 "RenderWidgetCompositor::SetSuppressScheduleComposite", this); 356 else 357 TRACE_EVENT_ASYNC_END0("gpu", 358 "RenderWidgetCompositor::SetSuppressScheduleComposite", this); 359 suppress_schedule_composite_ = suppress; 360 } 361 362 bool RenderWidgetCompositor::BeginMainFrameRequested() const { 363 return layer_tree_host_->BeginMainFrameRequested(); 364 } 365 366 void RenderWidgetCompositor::UpdateAnimations(base::TimeTicks time) { 367 layer_tree_host_->UpdateClientAnimations(time); 368 } 369 370 void RenderWidgetCompositor::SetNeedsDisplayOnAllLayers() { 371 layer_tree_host_->SetNeedsDisplayOnAllLayers(); 372 } 373 374 void RenderWidgetCompositor::SetRasterizeOnlyVisibleContent() { 375 cc::LayerTreeDebugState current = layer_tree_host_->debug_state(); 376 current.rasterize_only_visible_content = true; 377 layer_tree_host_->SetDebugState(current); 378 } 379 380 void RenderWidgetCompositor::UpdateTopControlsState( 381 cc::TopControlsState constraints, 382 cc::TopControlsState current, 383 bool animate) { 384 layer_tree_host_->UpdateTopControlsState(constraints, 385 current, 386 animate); 387 } 388 389 void RenderWidgetCompositor::SetOverdrawBottomHeight( 390 float overdraw_bottom_height) { 391 layer_tree_host_->SetOverdrawBottomHeight(overdraw_bottom_height); 392 } 393 394 void RenderWidgetCompositor::SetNeedsRedrawRect(gfx::Rect damage_rect) { 395 layer_tree_host_->SetNeedsRedrawRect(damage_rect); 396 } 397 398 void RenderWidgetCompositor::SetNeedsForcedRedraw() { 399 layer_tree_host_->SetNextCommitForcesRedraw(); 400 setNeedsAnimate(); 401 } 402 403 scoped_ptr<cc::SwapPromiseMonitor> 404 RenderWidgetCompositor::CreateLatencyInfoSwapPromiseMonitor( 405 ui::LatencyInfo* latency) { 406 return scoped_ptr<cc::SwapPromiseMonitor>( 407 new cc::LatencyInfoSwapPromiseMonitor( 408 latency, layer_tree_host_.get(), NULL)); 409 } 410 411 void RenderWidgetCompositor::QueueSwapPromise( 412 scoped_ptr<cc::SwapPromise> swap_promise) { 413 layer_tree_host_->QueueSwapPromise(swap_promise.Pass()); 414 } 415 416 int RenderWidgetCompositor::GetLayerTreeId() const { 417 return layer_tree_host_->id(); 418 } 419 420 void RenderWidgetCompositor::NotifyInputThrottledUntilCommit() { 421 layer_tree_host_->NotifyInputThrottledUntilCommit(); 422 } 423 424 const cc::Layer* RenderWidgetCompositor::GetRootLayer() const { 425 return layer_tree_host_->root_layer(); 426 } 427 428 int RenderWidgetCompositor::ScheduleMicroBenchmark( 429 const std::string& name, 430 scoped_ptr<base::Value> value, 431 const base::Callback<void(scoped_ptr<base::Value>)>& callback) { 432 return layer_tree_host_->ScheduleMicroBenchmark(name, value.Pass(), callback); 433 } 434 435 bool RenderWidgetCompositor::SendMessageToMicroBenchmark( 436 int id, 437 scoped_ptr<base::Value> value) { 438 return layer_tree_host_->SendMessageToMicroBenchmark(id, value.Pass()); 439 } 440 441 void RenderWidgetCompositor::Initialize(cc::LayerTreeSettings settings) { 442 scoped_refptr<base::MessageLoopProxy> compositor_message_loop_proxy; 443 RenderThreadImpl* render_thread = RenderThreadImpl::current(); 444 cc::SharedBitmapManager* shared_bitmap_manager = NULL; 445 // render_thread may be NULL in tests. 446 if (render_thread) { 447 compositor_message_loop_proxy = 448 render_thread->compositor_message_loop_proxy(); 449 shared_bitmap_manager = render_thread->shared_bitmap_manager(); 450 } 451 if (compositor_message_loop_proxy.get()) { 452 layer_tree_host_ = cc::LayerTreeHost::CreateThreaded( 453 this, shared_bitmap_manager, settings, compositor_message_loop_proxy); 454 } else { 455 layer_tree_host_ = cc::LayerTreeHost::CreateSingleThreaded( 456 this, this, shared_bitmap_manager, settings); 457 } 458 DCHECK(layer_tree_host_); 459 } 460 461 void RenderWidgetCompositor::setSurfaceReady() { 462 layer_tree_host_->SetLayerTreeHostClientReady(); 463 } 464 465 void RenderWidgetCompositor::setRootLayer(const blink::WebLayer& layer) { 466 layer_tree_host_->SetRootLayer( 467 static_cast<const WebLayerImpl*>(&layer)->layer()); 468 } 469 470 void RenderWidgetCompositor::clearRootLayer() { 471 layer_tree_host_->SetRootLayer(scoped_refptr<cc::Layer>()); 472 } 473 474 void RenderWidgetCompositor::setViewportSize( 475 const WebSize&, 476 const WebSize& device_viewport_size) { 477 layer_tree_host_->SetViewportSize(device_viewport_size); 478 } 479 480 void RenderWidgetCompositor::setViewportSize( 481 const WebSize& device_viewport_size) { 482 layer_tree_host_->SetViewportSize(device_viewport_size); 483 } 484 485 WebSize RenderWidgetCompositor::layoutViewportSize() const { 486 return layer_tree_host_->device_viewport_size(); 487 } 488 489 WebSize RenderWidgetCompositor::deviceViewportSize() const { 490 return layer_tree_host_->device_viewport_size(); 491 } 492 493 WebFloatPoint RenderWidgetCompositor::adjustEventPointForPinchZoom( 494 const WebFloatPoint& point) const { 495 return point; 496 } 497 498 void RenderWidgetCompositor::setDeviceScaleFactor(float device_scale) { 499 layer_tree_host_->SetDeviceScaleFactor(device_scale); 500 } 501 502 float RenderWidgetCompositor::deviceScaleFactor() const { 503 return layer_tree_host_->device_scale_factor(); 504 } 505 506 void RenderWidgetCompositor::setBackgroundColor(blink::WebColor color) { 507 layer_tree_host_->set_background_color(color); 508 } 509 510 void RenderWidgetCompositor::setHasTransparentBackground(bool transparent) { 511 layer_tree_host_->set_has_transparent_background(transparent); 512 } 513 514 void RenderWidgetCompositor::setOverhangBitmap(const SkBitmap& bitmap) { 515 layer_tree_host_->SetOverhangBitmap(bitmap); 516 } 517 518 void RenderWidgetCompositor::setVisible(bool visible) { 519 layer_tree_host_->SetVisible(visible); 520 } 521 522 void RenderWidgetCompositor::setPageScaleFactorAndLimits( 523 float page_scale_factor, float minimum, float maximum) { 524 layer_tree_host_->SetPageScaleFactorAndLimits( 525 page_scale_factor, minimum, maximum); 526 } 527 528 void RenderWidgetCompositor::startPageScaleAnimation( 529 const blink::WebPoint& destination, 530 bool use_anchor, 531 float new_page_scale, 532 double duration_sec) { 533 base::TimeDelta duration = base::TimeDelta::FromMicroseconds( 534 duration_sec * base::Time::kMicrosecondsPerSecond); 535 layer_tree_host_->StartPageScaleAnimation( 536 gfx::Vector2d(destination.x, destination.y), 537 use_anchor, 538 new_page_scale, 539 duration); 540 } 541 542 void RenderWidgetCompositor::heuristicsForGpuRasterizationUpdated( 543 bool matches_heuristics) { 544 layer_tree_host_->SetHasGpuRasterizationTrigger(matches_heuristics); 545 } 546 547 void RenderWidgetCompositor::setNeedsAnimate() { 548 layer_tree_host_->SetNeedsAnimate(); 549 } 550 551 bool RenderWidgetCompositor::commitRequested() const { 552 return layer_tree_host_->CommitRequested(); 553 } 554 555 void RenderWidgetCompositor::didStopFlinging() { 556 layer_tree_host_->DidStopFlinging(); 557 } 558 559 void RenderWidgetCompositor::registerForAnimations(blink::WebLayer* layer) { 560 cc::Layer* cc_layer = static_cast<WebLayerImpl*>(layer)->layer(); 561 cc_layer->layer_animation_controller()->SetAnimationRegistrar( 562 layer_tree_host_->animation_registrar()); 563 } 564 565 void RenderWidgetCompositor::registerViewportLayers( 566 const blink::WebLayer* pageScaleLayer, 567 const blink::WebLayer* innerViewportScrollLayer, 568 const blink::WebLayer* outerViewportScrollLayer) { 569 layer_tree_host_->RegisterViewportLayers( 570 static_cast<const WebLayerImpl*>(pageScaleLayer)->layer(), 571 static_cast<const WebLayerImpl*>(innerViewportScrollLayer)->layer(), 572 // The outer viewport layer will only exist when using pinch virtual 573 // viewports. 574 outerViewportScrollLayer 575 ? static_cast<const WebLayerImpl*>(outerViewportScrollLayer)->layer() 576 : NULL); 577 } 578 579 void RenderWidgetCompositor::clearViewportLayers() { 580 layer_tree_host_->RegisterViewportLayers(scoped_refptr<cc::Layer>(), 581 scoped_refptr<cc::Layer>(), 582 scoped_refptr<cc::Layer>()); 583 } 584 585 void CompositeAndReadbackAsyncCallback( 586 blink::WebCompositeAndReadbackAsyncCallback* callback, 587 scoped_ptr<cc::CopyOutputResult> result) { 588 if (result->HasBitmap()) { 589 scoped_ptr<SkBitmap> result_bitmap = result->TakeBitmap(); 590 callback->didCompositeAndReadback(*result_bitmap); 591 } else { 592 callback->didCompositeAndReadback(SkBitmap()); 593 } 594 } 595 596 void RenderWidgetCompositor::compositeAndReadbackAsync( 597 blink::WebCompositeAndReadbackAsyncCallback* callback) { 598 DCHECK(layer_tree_host_->root_layer()); 599 scoped_ptr<cc::CopyOutputRequest> request = 600 cc::CopyOutputRequest::CreateBitmapRequest( 601 base::Bind(&CompositeAndReadbackAsyncCallback, callback)); 602 layer_tree_host_->root_layer()->RequestCopyOfOutput(request.Pass()); 603 if (!threaded_) { 604 widget_->webwidget()->animate(0.0); 605 widget_->webwidget()->layout(); 606 layer_tree_host_->Composite(gfx::FrameTime::Now()); 607 } 608 } 609 610 void RenderWidgetCompositor::finishAllRendering() { 611 layer_tree_host_->FinishAllRendering(); 612 } 613 614 void RenderWidgetCompositor::setDeferCommits(bool defer_commits) { 615 layer_tree_host_->SetDeferCommits(defer_commits); 616 } 617 618 void RenderWidgetCompositor::setShowFPSCounter(bool show) { 619 cc::LayerTreeDebugState debug_state = layer_tree_host_->debug_state(); 620 debug_state.show_fps_counter = show; 621 layer_tree_host_->SetDebugState(debug_state); 622 } 623 624 void RenderWidgetCompositor::setShowPaintRects(bool show) { 625 cc::LayerTreeDebugState debug_state = layer_tree_host_->debug_state(); 626 debug_state.show_paint_rects = show; 627 layer_tree_host_->SetDebugState(debug_state); 628 } 629 630 void RenderWidgetCompositor::setShowDebugBorders(bool show) { 631 cc::LayerTreeDebugState debug_state = layer_tree_host_->debug_state(); 632 debug_state.show_debug_borders = show; 633 layer_tree_host_->SetDebugState(debug_state); 634 } 635 636 void RenderWidgetCompositor::setContinuousPaintingEnabled(bool enabled) { 637 cc::LayerTreeDebugState debug_state = layer_tree_host_->debug_state(); 638 debug_state.continuous_painting = enabled; 639 layer_tree_host_->SetDebugState(debug_state); 640 } 641 642 void RenderWidgetCompositor::setShowScrollBottleneckRects(bool show) { 643 cc::LayerTreeDebugState debug_state = layer_tree_host_->debug_state(); 644 debug_state.show_touch_event_handler_rects = show; 645 debug_state.show_wheel_event_handler_rects = show; 646 debug_state.show_non_fast_scrollable_rects = show; 647 layer_tree_host_->SetDebugState(debug_state); 648 } 649 650 void RenderWidgetCompositor::WillBeginMainFrame(int frame_id) { 651 widget_->InstrumentWillBeginFrame(frame_id); 652 widget_->willBeginCompositorFrame(); 653 } 654 655 void RenderWidgetCompositor::DidBeginMainFrame() { 656 widget_->InstrumentDidBeginFrame(); 657 } 658 659 void RenderWidgetCompositor::Animate(base::TimeTicks frame_begin_time) { 660 widget_->webwidget()->animate( 661 (frame_begin_time - base::TimeTicks()).InSecondsF()); 662 } 663 664 void RenderWidgetCompositor::Layout() { 665 widget_->webwidget()->layout(); 666 } 667 668 void RenderWidgetCompositor::ApplyScrollAndScale( 669 const gfx::Vector2d& scroll_delta, 670 float page_scale) { 671 widget_->webwidget()->applyScrollAndScale(scroll_delta, page_scale); 672 } 673 674 scoped_ptr<cc::OutputSurface> RenderWidgetCompositor::CreateOutputSurface( 675 bool fallback) { 676 return widget_->CreateOutputSurface(fallback); 677 } 678 679 void RenderWidgetCompositor::DidInitializeOutputSurface() { 680 } 681 682 void RenderWidgetCompositor::WillCommit() { 683 widget_->InstrumentWillComposite(); 684 } 685 686 void RenderWidgetCompositor::DidCommit() { 687 widget_->DidCommitCompositorFrame(); 688 widget_->didBecomeReadyForAdditionalInput(); 689 } 690 691 void RenderWidgetCompositor::DidCommitAndDrawFrame() { 692 widget_->didCommitAndDrawCompositorFrame(); 693 } 694 695 void RenderWidgetCompositor::DidCompleteSwapBuffers() { 696 widget_->didCompleteSwapBuffers(); 697 if (!threaded_) 698 widget_->OnSwapBuffersComplete(); 699 } 700 701 void RenderWidgetCompositor::ScheduleComposite() { 702 if (!suppress_schedule_composite_) 703 widget_->scheduleComposite(); 704 } 705 706 void RenderWidgetCompositor::ScheduleAnimation() { 707 widget_->scheduleAnimation(); 708 } 709 710 void RenderWidgetCompositor::DidPostSwapBuffers() { 711 widget_->OnSwapBuffersPosted(); 712 } 713 714 void RenderWidgetCompositor::DidAbortSwapBuffers() { 715 widget_->OnSwapBuffersAborted(); 716 } 717 718 void RenderWidgetCompositor::RateLimitSharedMainThreadContext() { 719 cc::ContextProvider* provider = 720 RenderThreadImpl::current()->SharedMainThreadContextProvider().get(); 721 provider->ContextGL()->RateLimitOffscreenContextCHROMIUM(); 722 } 723 724 } // namespace content 725