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 #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/time/time.h"
     15 #include "cc/base/switches.h"
     16 #include "cc/debug/layer_tree_debug_state.h"
     17 #include "cc/layers/layer.h"
     18 #include "cc/trees/layer_tree_host.h"
     19 #include "content/common/gpu/client/context_provider_command_buffer.h"
     20 #include "content/public/common/content_switches.h"
     21 #include "content/renderer/gpu/input_handler_manager.h"
     22 #include "content/renderer/render_thread_impl.h"
     23 #include "third_party/WebKit/public/platform/WebSize.h"
     24 #include "third_party/WebKit/public/web/WebWidget.h"
     25 #include "ui/gl/gl_switches.h"
     26 #include "webkit/renderer/compositor_bindings/web_layer_impl.h"
     27 
     28 namespace cc {
     29 class Layer;
     30 }
     31 
     32 using WebKit::WebFloatPoint;
     33 using WebKit::WebSize;
     34 using WebKit::WebRect;
     35 
     36 namespace content {
     37 namespace {
     38 
     39 bool GetSwitchValueAsInt(
     40     const CommandLine& command_line,
     41     const std::string& switch_string,
     42     int min_value,
     43     int max_value,
     44     int* result) {
     45   std::string string_value = command_line.GetSwitchValueASCII(switch_string);
     46   int int_value;
     47   if (base::StringToInt(string_value, &int_value) &&
     48       int_value >= min_value && int_value <= max_value) {
     49     *result = int_value;
     50     return true;
     51   } else {
     52     LOG(WARNING) << "Failed to parse switch " << switch_string  << ": " <<
     53         string_value;
     54     return false;
     55   }
     56 }
     57 
     58 bool GetSwitchValueAsFloat(
     59     const CommandLine& command_line,
     60     const std::string& switch_string,
     61     float min_value,
     62     float max_value,
     63     float* result) {
     64   std::string string_value = command_line.GetSwitchValueASCII(switch_string);
     65   double double_value;
     66   if (base::StringToDouble(string_value, &double_value) &&
     67       double_value >= min_value && double_value <= max_value) {
     68     *result = static_cast<float>(double_value);
     69     return true;
     70   } else {
     71     LOG(WARNING) << "Failed to parse switch " << switch_string  << ": " <<
     72         string_value;
     73     return false;
     74   }
     75 }
     76 
     77 
     78 }  // namespace
     79 
     80 // static
     81 scoped_ptr<RenderWidgetCompositor> RenderWidgetCompositor::Create(
     82     RenderWidget* widget,
     83     bool threaded) {
     84   scoped_ptr<RenderWidgetCompositor> compositor(
     85       new RenderWidgetCompositor(widget, threaded));
     86 
     87   CommandLine* cmd = CommandLine::ForCurrentProcess();
     88 
     89   cc::LayerTreeSettings settings;
     90 
     91   // For web contents, layer transforms should scale up the contents of layers
     92   // to keep content always crisp when possible.
     93   settings.layer_transforms_should_scale_layer_contents = true;
     94 
     95   settings.throttle_frame_production =
     96       !cmd->HasSwitch(switches::kDisableGpuVsync);
     97   settings.begin_frame_scheduling_enabled =
     98       cmd->HasSwitch(switches::kEnableBeginFrameScheduling);
     99   settings.using_synchronous_renderer_compositor =
    100       widget->UsingSynchronousRendererCompositor();
    101   settings.per_tile_painting_enabled =
    102       cmd->HasSwitch(cc::switches::kEnablePerTilePainting);
    103   settings.accelerated_animation_enabled =
    104       !cmd->HasSwitch(cc::switches::kDisableThreadedAnimation);
    105   settings.force_direct_layer_drawing =
    106       cmd->HasSwitch(cc::switches::kForceDirectLayerDrawing);
    107   settings.touch_hit_testing =
    108       !cmd->HasSwitch(cc::switches::kDisableCompositorTouchHitTesting);
    109 
    110   int default_tile_width = settings.default_tile_size.width();
    111   if (cmd->HasSwitch(switches::kDefaultTileWidth)) {
    112     GetSwitchValueAsInt(*cmd, switches::kDefaultTileWidth, 1,
    113                         std::numeric_limits<int>::max(), &default_tile_width);
    114   }
    115   int default_tile_height = settings.default_tile_size.height();
    116   if (cmd->HasSwitch(switches::kDefaultTileHeight)) {
    117     GetSwitchValueAsInt(*cmd, switches::kDefaultTileHeight, 1,
    118                         std::numeric_limits<int>::max(), &default_tile_height);
    119   }
    120   settings.default_tile_size = gfx::Size(default_tile_width,
    121                                          default_tile_height);
    122 
    123   int max_untiled_layer_width = settings.max_untiled_layer_size.width();
    124   if (cmd->HasSwitch(switches::kMaxUntiledLayerWidth)) {
    125     GetSwitchValueAsInt(*cmd, switches::kMaxUntiledLayerWidth, 1,
    126                         std::numeric_limits<int>::max(),
    127                         &max_untiled_layer_width);
    128   }
    129   int max_untiled_layer_height = settings.max_untiled_layer_size.height();
    130   if (cmd->HasSwitch(switches::kMaxUntiledLayerHeight)) {
    131     GetSwitchValueAsInt(*cmd, switches::kMaxUntiledLayerHeight, 1,
    132                         std::numeric_limits<int>::max(),
    133                         &max_untiled_layer_height);
    134   }
    135 
    136   settings.max_untiled_layer_size = gfx::Size(max_untiled_layer_width,
    137                                            max_untiled_layer_height);
    138 
    139   settings.impl_side_painting = cc::switches::IsImplSidePaintingEnabled();
    140 
    141   settings.calculate_top_controls_position =
    142       cmd->HasSwitch(cc::switches::kEnableTopControlsPositionCalculation);
    143   if (cmd->HasSwitch(cc::switches::kTopControlsHeight)) {
    144     std::string controls_height_str =
    145         cmd->GetSwitchValueASCII(cc::switches::kTopControlsHeight);
    146     double controls_height;
    147     if (base::StringToDouble(controls_height_str, &controls_height) &&
    148         controls_height > 0)
    149       settings.top_controls_height = controls_height;
    150   }
    151 
    152   if (settings.calculate_top_controls_position &&
    153       settings.top_controls_height <= 0) {
    154     DCHECK(false)
    155         << "Top controls repositioning enabled without valid height set.";
    156     settings.calculate_top_controls_position = false;
    157   }
    158 
    159   if (cmd->HasSwitch(cc::switches::kTopControlsShowThreshold)) {
    160       std::string top_threshold_str =
    161           cmd->GetSwitchValueASCII(cc::switches::kTopControlsShowThreshold);
    162       double show_threshold;
    163       if (base::StringToDouble(top_threshold_str, &show_threshold) &&
    164           show_threshold >= 0.f && show_threshold <= 1.f)
    165         settings.top_controls_show_threshold = show_threshold;
    166   }
    167 
    168   if (cmd->HasSwitch(cc::switches::kTopControlsHideThreshold)) {
    169       std::string top_threshold_str =
    170           cmd->GetSwitchValueASCII(cc::switches::kTopControlsHideThreshold);
    171       double hide_threshold;
    172       if (base::StringToDouble(top_threshold_str, &hide_threshold) &&
    173           hide_threshold >= 0.f && hide_threshold <= 1.f)
    174         settings.top_controls_hide_threshold = hide_threshold;
    175   }
    176 
    177   settings.partial_swap_enabled = widget->AllowPartialSwap() &&
    178       cmd->HasSwitch(cc::switches::kEnablePartialSwap);
    179   settings.background_color_instead_of_checkerboard =
    180       cmd->HasSwitch(cc::switches::kBackgroundColorInsteadOfCheckerboard);
    181   settings.show_overdraw_in_tracing =
    182       cmd->HasSwitch(cc::switches::kTraceOverdraw);
    183   settings.use_pinch_virtual_viewport =
    184       cmd->HasSwitch(cc::switches::kEnablePinchVirtualViewport);
    185   settings.allow_antialiasing &=
    186       !cmd->HasSwitch(cc::switches::kDisableCompositedAntialiasing);
    187 
    188   // These flags should be mirrored by UI versions in ui/compositor/.
    189   settings.initial_debug_state.show_debug_borders =
    190       cmd->HasSwitch(cc::switches::kShowCompositedLayerBorders);
    191   settings.initial_debug_state.show_fps_counter =
    192       cmd->HasSwitch(cc::switches::kShowFPSCounter);
    193   settings.initial_debug_state.show_paint_rects =
    194       cmd->HasSwitch(switches::kShowPaintRects);
    195   settings.initial_debug_state.show_property_changed_rects =
    196       cmd->HasSwitch(cc::switches::kShowPropertyChangedRects);
    197   settings.initial_debug_state.show_surface_damage_rects =
    198       cmd->HasSwitch(cc::switches::kShowSurfaceDamageRects);
    199   settings.initial_debug_state.show_screen_space_rects =
    200       cmd->HasSwitch(cc::switches::kShowScreenSpaceRects);
    201   settings.initial_debug_state.show_replica_screen_space_rects =
    202       cmd->HasSwitch(cc::switches::kShowReplicaScreenSpaceRects);
    203   settings.initial_debug_state.show_occluding_rects =
    204       cmd->HasSwitch(cc::switches::kShowOccludingRects);
    205   settings.initial_debug_state.show_non_occluding_rects =
    206       cmd->HasSwitch(cc::switches::kShowNonOccludingRects);
    207 
    208   settings.initial_debug_state.SetRecordRenderingStats(
    209       cmd->HasSwitch(switches::kEnableGpuBenchmarking));
    210 
    211   if (cmd->HasSwitch(cc::switches::kSlowDownRasterScaleFactor)) {
    212     const int kMinSlowDownScaleFactor = 0;
    213     const int kMaxSlowDownScaleFactor = INT_MAX;
    214     GetSwitchValueAsInt(
    215         *cmd,
    216         cc::switches::kSlowDownRasterScaleFactor,
    217         kMinSlowDownScaleFactor,
    218         kMaxSlowDownScaleFactor,
    219         &settings.initial_debug_state.slow_down_raster_scale_factor);
    220   }
    221 
    222   if (cmd->HasSwitch(cc::switches::kNumRasterThreads)) {
    223     const int kMinRasterThreads = 1;
    224     const int kMaxRasterThreads = 64;
    225     int num_raster_threads;
    226     if (GetSwitchValueAsInt(*cmd, cc::switches::kNumRasterThreads,
    227                             kMinRasterThreads, kMaxRasterThreads,
    228                             &num_raster_threads))
    229       settings.num_raster_threads = num_raster_threads;
    230   }
    231 
    232   if (cmd->HasSwitch(cc::switches::kLowResolutionContentsScaleFactor)) {
    233     const int kMinScaleFactor = settings.minimum_contents_scale;
    234     const int kMaxScaleFactor = 1;
    235     GetSwitchValueAsFloat(*cmd,
    236                           cc::switches::kLowResolutionContentsScaleFactor,
    237                           kMinScaleFactor, kMaxScaleFactor,
    238                           &settings.low_res_contents_scale_factor);
    239   }
    240 
    241   if (cmd->HasSwitch(cc::switches::kMaxTilesForInterestArea)) {
    242     int max_tiles_for_interest_area;
    243     if (GetSwitchValueAsInt(*cmd,
    244                             cc::switches::kMaxTilesForInterestArea,
    245                             1, std::numeric_limits<int>::max(),
    246                             &max_tiles_for_interest_area))
    247       settings.max_tiles_for_interest_area = max_tiles_for_interest_area;
    248   }
    249 
    250   if (cmd->HasSwitch(cc::switches::kMaxUnusedResourceMemoryUsagePercentage)) {
    251     int max_unused_resource_memory_percentage;
    252     if (GetSwitchValueAsInt(
    253             *cmd,
    254             cc::switches::kMaxUnusedResourceMemoryUsagePercentage,
    255             0, 100,
    256             &max_unused_resource_memory_percentage)) {
    257       settings.max_unused_resource_memory_percentage =
    258           max_unused_resource_memory_percentage;
    259     }
    260   }
    261 
    262   settings.strict_layer_property_change_checking =
    263       cmd->HasSwitch(cc::switches::kStrictLayerPropertyChangeChecking);
    264 
    265   settings.use_map_image = cmd->HasSwitch(cc::switches::kUseMapImage);
    266 
    267 #if defined(OS_ANDROID)
    268   // TODO(danakj): Move these to the android code.
    269   settings.can_use_lcd_text = false;
    270   settings.max_partial_texture_updates = 0;
    271   settings.use_linear_fade_scrollbar_animator = true;
    272   settings.solid_color_scrollbars = true;
    273   settings.solid_color_scrollbar_color =
    274       cmd->HasSwitch(switches::kHideScrollbars)
    275           ? SK_ColorTRANSPARENT
    276           : SkColorSetARGB(128, 128, 128, 128);
    277   settings.solid_color_scrollbar_thickness_dip = 3;
    278   settings.highp_threshold_min = 2048;
    279   // Android WebView handles root layer flings itself.
    280   settings.ignore_root_layer_flings =
    281       widget->UsingSynchronousRendererCompositor();
    282   settings.always_overscroll = widget->UsingSynchronousRendererCompositor();
    283 #elif !defined(OS_MACOSX)
    284   if (cmd->HasSwitch(switches::kEnableOverlayScrollbars)) {
    285     settings.use_linear_fade_scrollbar_animator = true;
    286     settings.solid_color_scrollbars = true;
    287     settings.solid_color_scrollbar_color = SkColorSetARGB(128, 128, 128, 128);
    288     settings.solid_color_scrollbar_thickness_dip = 3;
    289   }
    290 #endif
    291 
    292   if (!compositor->initialize(settings))
    293     return scoped_ptr<RenderWidgetCompositor>();
    294 
    295   return compositor.Pass();
    296 }
    297 
    298 RenderWidgetCompositor::RenderWidgetCompositor(RenderWidget* widget,
    299                                                bool threaded)
    300     : threaded_(threaded),
    301       suppress_schedule_composite_(false),
    302       widget_(widget) {
    303 }
    304 
    305 RenderWidgetCompositor::~RenderWidgetCompositor() {}
    306 
    307 const base::WeakPtr<cc::InputHandler>&
    308 RenderWidgetCompositor::GetInputHandler() {
    309   return layer_tree_host_->GetInputHandler();
    310 }
    311 
    312 void RenderWidgetCompositor::SetSuppressScheduleComposite(bool suppress) {
    313   if (suppress_schedule_composite_ == suppress)
    314     return;
    315 
    316   if (suppress)
    317     TRACE_EVENT_ASYNC_BEGIN0("gpu",
    318         "RenderWidgetCompositor::SetSuppressScheduleComposite", this);
    319   else
    320     TRACE_EVENT_ASYNC_END0("gpu",
    321         "RenderWidgetCompositor::SetSuppressScheduleComposite", this);
    322   suppress_schedule_composite_ = suppress;
    323 }
    324 
    325 void RenderWidgetCompositor::Animate(base::TimeTicks time) {
    326   layer_tree_host_->UpdateClientAnimations(time);
    327 }
    328 
    329 void RenderWidgetCompositor::Composite(base::TimeTicks frame_begin_time) {
    330   layer_tree_host_->Composite(frame_begin_time);
    331 }
    332 
    333 void RenderWidgetCompositor::SetNeedsDisplayOnAllLayers() {
    334   layer_tree_host_->SetNeedsDisplayOnAllLayers();
    335 }
    336 
    337 void RenderWidgetCompositor::SetRasterizeOnlyVisibleContent() {
    338   cc::LayerTreeDebugState current = layer_tree_host_->debug_state();
    339   current.rasterize_only_visible_content = true;
    340   layer_tree_host_->SetDebugState(current);
    341 }
    342 
    343 void RenderWidgetCompositor::GetRenderingStats(cc::RenderingStats* stats) {
    344   layer_tree_host_->CollectRenderingStats(stats);
    345 }
    346 
    347 void RenderWidgetCompositor::UpdateTopControlsState(
    348     cc::TopControlsState constraints,
    349     cc::TopControlsState current,
    350     bool animate) {
    351   layer_tree_host_->UpdateTopControlsState(constraints,
    352                                            current,
    353                                            animate);
    354 }
    355 
    356 void RenderWidgetCompositor::SetOverdrawBottomHeight(
    357     float overdraw_bottom_height) {
    358   layer_tree_host_->SetOverdrawBottomHeight(overdraw_bottom_height);
    359 }
    360 
    361 void RenderWidgetCompositor::SetNeedsRedrawRect(gfx::Rect damage_rect) {
    362   layer_tree_host_->SetNeedsRedrawRect(damage_rect);
    363 }
    364 
    365 void RenderWidgetCompositor::SetLatencyInfo(
    366     const ui::LatencyInfo& latency_info) {
    367   layer_tree_host_->SetLatencyInfo(latency_info);
    368 }
    369 
    370 int RenderWidgetCompositor::GetLayerTreeId() const {
    371   return layer_tree_host_->id();
    372 }
    373 
    374 void RenderWidgetCompositor::NotifyInputThrottledUntilCommit() {
    375   layer_tree_host_->NotifyInputThrottledUntilCommit();
    376 }
    377 
    378 bool RenderWidgetCompositor::initialize(cc::LayerTreeSettings settings) {
    379   scoped_refptr<base::MessageLoopProxy> compositor_message_loop_proxy =
    380       RenderThreadImpl::current()->compositor_message_loop_proxy();
    381   layer_tree_host_ = cc::LayerTreeHost::Create(this,
    382                                                settings,
    383                                                compositor_message_loop_proxy);
    384   return layer_tree_host_;
    385 }
    386 
    387 void RenderWidgetCompositor::setSurfaceReady() {
    388   layer_tree_host_->SetLayerTreeHostClientReady();
    389 }
    390 
    391 void RenderWidgetCompositor::setRootLayer(const WebKit::WebLayer& layer) {
    392   layer_tree_host_->SetRootLayer(
    393       static_cast<const webkit::WebLayerImpl*>(&layer)->layer());
    394 }
    395 
    396 void RenderWidgetCompositor::clearRootLayer() {
    397   layer_tree_host_->SetRootLayer(scoped_refptr<cc::Layer>());
    398 }
    399 
    400 void RenderWidgetCompositor::setViewportSize(
    401     const WebSize&,
    402     const WebSize& device_viewport_size) {
    403   layer_tree_host_->SetViewportSize(device_viewport_size);
    404 }
    405 
    406 WebSize RenderWidgetCompositor::layoutViewportSize() const {
    407   return layer_tree_host_->device_viewport_size();
    408 }
    409 
    410 WebSize RenderWidgetCompositor::deviceViewportSize() const {
    411   return layer_tree_host_->device_viewport_size();
    412 }
    413 
    414 WebFloatPoint RenderWidgetCompositor::adjustEventPointForPinchZoom(
    415     const WebFloatPoint& point) const {
    416   return point;
    417 }
    418 
    419 void RenderWidgetCompositor::setDeviceScaleFactor(float device_scale) {
    420   layer_tree_host_->SetDeviceScaleFactor(device_scale);
    421 }
    422 
    423 float RenderWidgetCompositor::deviceScaleFactor() const {
    424   return layer_tree_host_->device_scale_factor();
    425 }
    426 
    427 void RenderWidgetCompositor::setBackgroundColor(WebKit::WebColor color) {
    428   layer_tree_host_->set_background_color(color);
    429 }
    430 
    431 void RenderWidgetCompositor::setHasTransparentBackground(bool transparent) {
    432   layer_tree_host_->set_has_transparent_background(transparent);
    433 }
    434 
    435 void RenderWidgetCompositor::setVisible(bool visible) {
    436   layer_tree_host_->SetVisible(visible);
    437 }
    438 
    439 void RenderWidgetCompositor::setPageScaleFactorAndLimits(
    440     float page_scale_factor, float minimum, float maximum) {
    441   layer_tree_host_->SetPageScaleFactorAndLimits(
    442       page_scale_factor, minimum, maximum);
    443 }
    444 
    445 void RenderWidgetCompositor::startPageScaleAnimation(
    446     const WebKit::WebPoint& destination,
    447     bool use_anchor,
    448     float new_page_scale,
    449     double duration_sec) {
    450   base::TimeDelta duration = base::TimeDelta::FromMicroseconds(
    451       duration_sec * base::Time::kMicrosecondsPerSecond);
    452   layer_tree_host_->StartPageScaleAnimation(
    453       gfx::Vector2d(destination.x, destination.y),
    454       use_anchor,
    455       new_page_scale,
    456       duration);
    457 }
    458 
    459 void RenderWidgetCompositor::setNeedsAnimate() {
    460   layer_tree_host_->SetNeedsAnimate();
    461 }
    462 
    463 void RenderWidgetCompositor::setNeedsRedraw() {
    464   if (threaded_)
    465     layer_tree_host_->SetNeedsAnimate();
    466   else
    467     widget_->scheduleAnimation();
    468 }
    469 
    470 bool RenderWidgetCompositor::commitRequested() const {
    471   return layer_tree_host_->CommitRequested();
    472 }
    473 
    474 void RenderWidgetCompositor::didStopFlinging() {
    475   layer_tree_host_->DidStopFlinging();
    476 }
    477 
    478 void RenderWidgetCompositor::registerForAnimations(WebKit::WebLayer* layer) {
    479   cc::Layer* cc_layer = static_cast<webkit::WebLayerImpl*>(layer)->layer();
    480   cc_layer->layer_animation_controller()->SetAnimationRegistrar(
    481       layer_tree_host_->animation_registrar());
    482 }
    483 
    484 bool RenderWidgetCompositor::compositeAndReadback(
    485     void *pixels, const WebRect& rect_in_device_viewport) {
    486   return layer_tree_host_->CompositeAndReadback(pixels,
    487                                                 rect_in_device_viewport);
    488 }
    489 
    490 void RenderWidgetCompositor::finishAllRendering() {
    491   layer_tree_host_->FinishAllRendering();
    492 }
    493 
    494 void RenderWidgetCompositor::setDeferCommits(bool defer_commits) {
    495   layer_tree_host_->SetDeferCommits(defer_commits);
    496 }
    497 
    498 void RenderWidgetCompositor::setShowFPSCounter(bool show) {
    499   cc::LayerTreeDebugState debug_state = layer_tree_host_->debug_state();
    500   debug_state.show_fps_counter = show;
    501   layer_tree_host_->SetDebugState(debug_state);
    502 }
    503 
    504 void RenderWidgetCompositor::setShowPaintRects(bool show) {
    505   cc::LayerTreeDebugState debug_state = layer_tree_host_->debug_state();
    506   debug_state.show_paint_rects = show;
    507   layer_tree_host_->SetDebugState(debug_state);
    508 }
    509 
    510 void RenderWidgetCompositor::setShowDebugBorders(bool show) {
    511   cc::LayerTreeDebugState debug_state = layer_tree_host_->debug_state();
    512   debug_state.show_debug_borders = show;
    513   layer_tree_host_->SetDebugState(debug_state);
    514 }
    515 
    516 void RenderWidgetCompositor::setContinuousPaintingEnabled(bool enabled) {
    517   cc::LayerTreeDebugState debug_state = layer_tree_host_->debug_state();
    518   debug_state.continuous_painting = enabled;
    519   layer_tree_host_->SetDebugState(debug_state);
    520 }
    521 
    522 void RenderWidgetCompositor::setShowScrollBottleneckRects(bool show) {
    523   cc::LayerTreeDebugState debug_state = layer_tree_host_->debug_state();
    524   debug_state.show_touch_event_handler_rects = show;
    525   debug_state.show_wheel_event_handler_rects = show;
    526   debug_state.show_non_fast_scrollable_rects = show;
    527   layer_tree_host_->SetDebugState(debug_state);
    528 }
    529 
    530 void RenderWidgetCompositor::WillBeginFrame() {
    531   widget_->InstrumentWillBeginFrame();
    532   widget_->willBeginCompositorFrame();
    533 }
    534 
    535 void RenderWidgetCompositor::DidBeginFrame() {
    536   widget_->InstrumentDidBeginFrame();
    537 }
    538 
    539 void RenderWidgetCompositor::Animate(double frame_begin_time) {
    540   widget_->webwidget()->animate(frame_begin_time);
    541 }
    542 
    543 void RenderWidgetCompositor::Layout() {
    544   widget_->webwidget()->layout();
    545 }
    546 
    547 void RenderWidgetCompositor::ApplyScrollAndScale(gfx::Vector2d scroll_delta,
    548                                                  float page_scale) {
    549   widget_->webwidget()->applyScrollAndScale(scroll_delta, page_scale);
    550 }
    551 
    552 scoped_ptr<cc::OutputSurface> RenderWidgetCompositor::CreateOutputSurface(
    553     bool fallback) {
    554   return widget_->CreateOutputSurface(fallback);
    555 }
    556 
    557 void RenderWidgetCompositor::DidInitializeOutputSurface(bool success) {
    558   if (!success)
    559     widget_->webwidget()->didExitCompositingMode();
    560 }
    561 
    562 void RenderWidgetCompositor::WillCommit() {
    563   widget_->InstrumentWillComposite();
    564 }
    565 
    566 void RenderWidgetCompositor::DidCommit() {
    567   widget_->DidCommitCompositorFrame();
    568   widget_->didBecomeReadyForAdditionalInput();
    569 }
    570 
    571 void RenderWidgetCompositor::DidCommitAndDrawFrame() {
    572   widget_->didCommitAndDrawCompositorFrame();
    573 }
    574 
    575 void RenderWidgetCompositor::DidCompleteSwapBuffers() {
    576   widget_->didCompleteSwapBuffers();
    577 }
    578 
    579 void RenderWidgetCompositor::ScheduleComposite() {
    580   if (!suppress_schedule_composite_)
    581     widget_->scheduleComposite();
    582 }
    583 
    584 scoped_refptr<cc::ContextProvider>
    585 RenderWidgetCompositor::OffscreenContextProviderForMainThread() {
    586   return RenderThreadImpl::current()->OffscreenContextProviderForMainThread();
    587 }
    588 
    589 scoped_refptr<cc::ContextProvider>
    590 RenderWidgetCompositor::OffscreenContextProviderForCompositorThread() {
    591   return RenderThreadImpl::current()->
    592       OffscreenContextProviderForCompositorThread();
    593 }
    594 
    595 }  // namespace content
    596