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