Home | History | Annotate | Download | only in gpu
      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