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