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.
5 #include "content/renderer/gpu/render_widget_compositor.h"
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"
47 #if defined(OS_ANDROID)
48 #include "content/renderer/android/synchronous_compositor_factory.h"
49 #include "ui/gfx/android/device_display_info.h"
60 using blink::WebBeginFrameArgs
;
61 using blink::WebFloatPoint
;
63 using blink::WebSelectionBound
;
69 bool GetSwitchValueAsInt(
70 const CommandLine
& command_line
,
71 const std::string
& switch_string
,
75 std::string string_value
= command_line
.GetSwitchValueASCII(switch_string
);
77 if (base::StringToInt(string_value
, &int_value
) &&
78 int_value
>= min_value
&& int_value
<= max_value
) {
82 LOG(WARNING
) << "Failed to parse switch " << switch_string
<< ": " <<
88 cc::LayerSelectionBound
ConvertWebSelectionBound(
89 const WebSelectionBound
& web_bound
) {
90 DCHECK(web_bound
.layerId
);
92 cc::LayerSelectionBound cc_bound
;
93 switch (web_bound
.type
) {
94 case blink::WebSelectionBound::Caret
:
95 cc_bound
.type
= cc::SELECTION_BOUND_CENTER
;
97 case blink::WebSelectionBound::SelectionLeft
:
98 cc_bound
.type
= cc::SELECTION_BOUND_LEFT
;
100 case blink::WebSelectionBound::SelectionRight
:
101 cc_bound
.type
= cc::SELECTION_BOUND_RIGHT
;
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
);
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)
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();
126 int portrait_width
= std::min(display_width
, display_height
);
127 int landscape_width
= std::max(display_width
, display_height
);
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;
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;
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);
149 default_tile_size
= 384;
151 default_tile_size
= 512;
154 return gfx::Size(default_tile_size
, default_tile_size
);
160 scoped_ptr
<RenderWidgetCompositor
> RenderWidgetCompositor::Create(
161 RenderWidget
* widget
,
163 scoped_ptr
<RenderWidgetCompositor
> compositor(
164 new RenderWidgetCompositor(widget
, threaded
));
166 CommandLine
* cmd
= CommandLine::ForCurrentProcess();
168 cc::LayerTreeSettings settings
;
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;
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
);
187 settings
.default_tile_size
= CalculateDefaultTileSize();
188 if (cmd
->HasSwitch(switches::kDefaultTileWidth
)) {
190 GetSwitchValueAsInt(*cmd
,
191 switches::kDefaultTileWidth
,
193 std::numeric_limits
<int>::max(),
195 settings
.default_tile_size
.set_width(tile_width
);
197 if (cmd
->HasSwitch(switches::kDefaultTileHeight
)) {
199 GetSwitchValueAsInt(*cmd
,
200 switches::kDefaultTileHeight
,
202 std::numeric_limits
<int>::max(),
204 settings
.default_tile_size
.set_height(tile_height
);
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
);
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
);
220 settings
.max_untiled_layer_size
= gfx::Size(max_untiled_layer_width
,
221 max_untiled_layer_height
);
223 RenderThreadImpl
* render_thread
= RenderThreadImpl::current();
224 // render_thread may be NULL in tests.
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
.create_low_res_tiling
= render_thread
->is_low_res_tiling_enabled();
233 settings
.can_use_lcd_text
= render_thread
->is_lcd_text_enabled();
234 settings
.use_distance_field_text
=
235 render_thread
->is_distance_field_text_enabled();
236 settings
.use_zero_copy
= render_thread
->is_zero_copy_enabled();
237 settings
.use_one_copy
= render_thread
->is_one_copy_enabled();
240 if (cmd
->HasSwitch(switches::kEnableBleedingEdgeRenderingFastPaths
)) {
241 settings
.recording_mode
= cc::LayerTreeSettings::RecordWithSkRecord
;
244 settings
.calculate_top_controls_position
=
245 cmd
->HasSwitch(cc::switches::kEnableTopControlsPositionCalculation
);
246 if (cmd
->HasSwitch(cc::switches::kTopControlsHeight
)) {
247 std::string controls_height_str
=
248 cmd
->GetSwitchValueASCII(cc::switches::kTopControlsHeight
);
249 double controls_height
;
250 if (base::StringToDouble(controls_height_str
, &controls_height
) &&
252 settings
.top_controls_height
= controls_height
;
255 if (settings
.calculate_top_controls_position
&&
256 settings
.top_controls_height
<= 0) {
258 << "Top controls repositioning enabled without valid height set.";
259 settings
.calculate_top_controls_position
= false;
262 if (cmd
->HasSwitch(cc::switches::kTopControlsShowThreshold
)) {
263 std::string top_threshold_str
=
264 cmd
->GetSwitchValueASCII(cc::switches::kTopControlsShowThreshold
);
265 double show_threshold
;
266 if (base::StringToDouble(top_threshold_str
, &show_threshold
) &&
267 show_threshold
>= 0.f
&& show_threshold
<= 1.f
)
268 settings
.top_controls_show_threshold
= show_threshold
;
271 if (cmd
->HasSwitch(cc::switches::kTopControlsHideThreshold
)) {
272 std::string top_threshold_str
=
273 cmd
->GetSwitchValueASCII(cc::switches::kTopControlsHideThreshold
);
274 double hide_threshold
;
275 if (base::StringToDouble(top_threshold_str
, &hide_threshold
) &&
276 hide_threshold
>= 0.f
&& hide_threshold
<= 1.f
)
277 settings
.top_controls_hide_threshold
= hide_threshold
;
280 settings
.use_pinch_virtual_viewport
=
281 cmd
->HasSwitch(cc::switches::kEnablePinchVirtualViewport
);
282 settings
.allow_antialiasing
&=
283 !cmd
->HasSwitch(cc::switches::kDisableCompositedAntialiasing
);
284 settings
.single_thread_proxy_scheduler
=
285 !cmd
->HasSwitch(switches::kDisableSingleThreadProxyScheduler
);
287 // These flags should be mirrored by UI versions in ui/compositor/.
288 settings
.initial_debug_state
.show_debug_borders
=
289 cmd
->HasSwitch(cc::switches::kShowCompositedLayerBorders
);
290 settings
.initial_debug_state
.show_fps_counter
=
291 cmd
->HasSwitch(cc::switches::kShowFPSCounter
);
292 settings
.initial_debug_state
.show_layer_animation_bounds_rects
=
293 cmd
->HasSwitch(cc::switches::kShowLayerAnimationBounds
);
294 settings
.initial_debug_state
.show_paint_rects
=
295 cmd
->HasSwitch(switches::kShowPaintRects
);
296 settings
.initial_debug_state
.show_property_changed_rects
=
297 cmd
->HasSwitch(cc::switches::kShowPropertyChangedRects
);
298 settings
.initial_debug_state
.show_surface_damage_rects
=
299 cmd
->HasSwitch(cc::switches::kShowSurfaceDamageRects
);
300 settings
.initial_debug_state
.show_screen_space_rects
=
301 cmd
->HasSwitch(cc::switches::kShowScreenSpaceRects
);
302 settings
.initial_debug_state
.show_replica_screen_space_rects
=
303 cmd
->HasSwitch(cc::switches::kShowReplicaScreenSpaceRects
);
304 settings
.initial_debug_state
.show_occluding_rects
=
305 cmd
->HasSwitch(cc::switches::kShowOccludingRects
);
306 settings
.initial_debug_state
.show_non_occluding_rects
=
307 cmd
->HasSwitch(cc::switches::kShowNonOccludingRects
);
309 settings
.initial_debug_state
.SetRecordRenderingStats(
310 cmd
->HasSwitch(cc::switches::kEnableGpuBenchmarking
));
312 if (cmd
->HasSwitch(cc::switches::kSlowDownRasterScaleFactor
)) {
313 const int kMinSlowDownScaleFactor
= 0;
314 const int kMaxSlowDownScaleFactor
= INT_MAX
;
317 cc::switches::kSlowDownRasterScaleFactor
,
318 kMinSlowDownScaleFactor
,
319 kMaxSlowDownScaleFactor
,
320 &settings
.initial_debug_state
.slow_down_raster_scale_factor
);
323 if (cmd
->HasSwitch(cc::switches::kMaxTilesForInterestArea
)) {
324 int max_tiles_for_interest_area
;
325 if (GetSwitchValueAsInt(*cmd
,
326 cc::switches::kMaxTilesForInterestArea
,
327 1, std::numeric_limits
<int>::max(),
328 &max_tiles_for_interest_area
))
329 settings
.max_tiles_for_interest_area
= max_tiles_for_interest_area
;
332 if (cmd
->HasSwitch(cc::switches::kMaxUnusedResourceMemoryUsagePercentage
)) {
333 int max_unused_resource_memory_percentage
;
334 if (GetSwitchValueAsInt(
336 cc::switches::kMaxUnusedResourceMemoryUsagePercentage
,
338 &max_unused_resource_memory_percentage
)) {
339 settings
.max_unused_resource_memory_percentage
=
340 max_unused_resource_memory_percentage
;
344 settings
.strict_layer_property_change_checking
=
345 cmd
->HasSwitch(cc::switches::kStrictLayerPropertyChangeChecking
);
347 #if defined(OS_ANDROID)
348 SynchronousCompositorFactory
* synchronous_compositor_factory
=
349 SynchronousCompositorFactory::GetInstance();
351 settings
.using_synchronous_renderer_compositor
=
352 synchronous_compositor_factory
;
353 settings
.record_full_layer
=
354 synchronous_compositor_factory
&&
355 synchronous_compositor_factory
->RecordFullLayer();
356 settings
.report_overscroll_only_for_scrollable_axes
=
357 !synchronous_compositor_factory
;
358 settings
.max_partial_texture_updates
= 0;
359 if (synchronous_compositor_factory
) {
360 // Android WebView uses system scrollbars, so make ours invisible.
361 settings
.scrollbar_animator
= cc::LayerTreeSettings::NoAnimator
;
362 settings
.solid_color_scrollbar_color
= SK_ColorTRANSPARENT
;
364 settings
.scrollbar_animator
= cc::LayerTreeSettings::LinearFade
;
365 settings
.scrollbar_fade_delay_ms
= 300;
366 settings
.scrollbar_fade_duration_ms
= 300;
367 settings
.solid_color_scrollbar_color
= SkColorSetARGB(128, 128, 128, 128);
369 settings
.highp_threshold_min
= 2048;
370 // Android WebView handles root layer flings itself.
371 settings
.ignore_root_layer_flings
=
372 synchronous_compositor_factory
;
373 // Memory policy on Android WebView does not depend on whether device is
374 // low end, so always use default policy.
375 bool is_low_end_device
=
376 base::SysInfo::IsLowEndDevice() && !synchronous_compositor_factory
;
377 // RGBA_4444 textures are only enabled for low end devices
378 // and are disabled for Android WebView as it doesn't support the format.
379 settings
.use_rgba_4444_textures
= is_low_end_device
;
380 if (is_low_end_device
) {
381 // On low-end we want to be very carefull about killing other
382 // apps. So initially we use 50% more memory to avoid flickering
383 // or raster-on-demand.
384 settings
.max_memory_for_prepaint_percentage
= 67;
386 // On other devices we have increased memory excessively to avoid
387 // raster-on-demand already, so now we reserve 50% _only_ to avoid
388 // raster-on-demand, and use 50% of the memory otherwise.
389 settings
.max_memory_for_prepaint_percentage
= 50;
391 // Webview does not own the surface so should not clear it.
392 settings
.should_clear_root_render_pass
=
393 !synchronous_compositor_factory
;
395 #elif !defined(OS_MACOSX)
396 if (ui::IsOverlayScrollbarEnabled()) {
397 settings
.scrollbar_animator
= cc::LayerTreeSettings::Thinning
;
398 settings
.solid_color_scrollbar_color
= SkColorSetARGB(128, 128, 128, 128);
399 } else if (cmd
->HasSwitch(cc::switches::kEnablePinchVirtualViewport
)) {
400 // use_pinch_zoom_scrollbars is only true on desktop when non-overlay
401 // scrollbars are in use.
402 settings
.use_pinch_zoom_scrollbars
= true;
403 settings
.scrollbar_animator
= cc::LayerTreeSettings::LinearFade
;
404 settings
.solid_color_scrollbar_color
= SkColorSetARGB(128, 128, 128, 128);
406 settings
.scrollbar_fade_delay_ms
= 500;
407 settings
.scrollbar_fade_duration_ms
= 300;
410 compositor
->Initialize(settings
);
412 return compositor
.Pass();
415 RenderWidgetCompositor::RenderWidgetCompositor(RenderWidget
* widget
,
417 : threaded_(threaded
),
419 send_v8_idle_notification_after_commit_(false) {
420 CommandLine
* cmd
= CommandLine::ForCurrentProcess();
422 if (cmd
->HasSwitch(switches::kSendV8IdleNotificationAfterCommit
))
423 send_v8_idle_notification_after_commit_
= true;
426 RenderWidgetCompositor::~RenderWidgetCompositor() {}
428 const base::WeakPtr
<cc::InputHandler
>&
429 RenderWidgetCompositor::GetInputHandler() {
430 return layer_tree_host_
->GetInputHandler();
433 bool RenderWidgetCompositor::BeginMainFrameRequested() const {
434 return layer_tree_host_
->BeginMainFrameRequested();
437 void RenderWidgetCompositor::SetNeedsDisplayOnAllLayers() {
438 layer_tree_host_
->SetNeedsDisplayOnAllLayers();
441 void RenderWidgetCompositor::SetRasterizeOnlyVisibleContent() {
442 cc::LayerTreeDebugState current
= layer_tree_host_
->debug_state();
443 current
.rasterize_only_visible_content
= true;
444 layer_tree_host_
->SetDebugState(current
);
447 void RenderWidgetCompositor::UpdateTopControlsState(
448 cc::TopControlsState constraints
,
449 cc::TopControlsState current
,
451 layer_tree_host_
->UpdateTopControlsState(constraints
,
456 void RenderWidgetCompositor::SetTopControlsLayoutHeight(
457 float top_controls_layout_height
) {
458 layer_tree_host_
->SetTopControlsLayoutHeight(top_controls_layout_height
);
461 void RenderWidgetCompositor::SetNeedsRedrawRect(gfx::Rect damage_rect
) {
462 layer_tree_host_
->SetNeedsRedrawRect(damage_rect
);
465 void RenderWidgetCompositor::SetNeedsForcedRedraw() {
466 layer_tree_host_
->SetNextCommitForcesRedraw();
470 scoped_ptr
<cc::SwapPromiseMonitor
>
471 RenderWidgetCompositor::CreateLatencyInfoSwapPromiseMonitor(
472 ui::LatencyInfo
* latency
) {
473 return scoped_ptr
<cc::SwapPromiseMonitor
>(
474 new cc::LatencyInfoSwapPromiseMonitor(
475 latency
, layer_tree_host_
.get(), NULL
));
478 void RenderWidgetCompositor::QueueSwapPromise(
479 scoped_ptr
<cc::SwapPromise
> swap_promise
) {
480 layer_tree_host_
->QueueSwapPromise(swap_promise
.Pass());
483 int RenderWidgetCompositor::GetLayerTreeId() const {
484 return layer_tree_host_
->id();
487 int RenderWidgetCompositor::GetSourceFrameNumber() const {
488 return layer_tree_host_
->source_frame_number();
491 void RenderWidgetCompositor::SetNeedsCommit() {
492 layer_tree_host_
->SetNeedsCommit();
495 void RenderWidgetCompositor::NotifyInputThrottledUntilCommit() {
496 layer_tree_host_
->NotifyInputThrottledUntilCommit();
499 const cc::Layer
* RenderWidgetCompositor::GetRootLayer() const {
500 return layer_tree_host_
->root_layer();
503 int RenderWidgetCompositor::ScheduleMicroBenchmark(
504 const std::string
& name
,
505 scoped_ptr
<base::Value
> value
,
506 const base::Callback
<void(scoped_ptr
<base::Value
>)>& callback
) {
507 return layer_tree_host_
->ScheduleMicroBenchmark(name
, value
.Pass(), callback
);
510 bool RenderWidgetCompositor::SendMessageToMicroBenchmark(
512 scoped_ptr
<base::Value
> value
) {
513 return layer_tree_host_
->SendMessageToMicroBenchmark(id
, value
.Pass());
516 void RenderWidgetCompositor::Initialize(cc::LayerTreeSettings settings
) {
517 scoped_refptr
<base::MessageLoopProxy
> compositor_message_loop_proxy
;
518 RenderThreadImpl
* render_thread
= RenderThreadImpl::current();
519 cc::SharedBitmapManager
* shared_bitmap_manager
= NULL
;
520 // render_thread may be NULL in tests.
522 compositor_message_loop_proxy
=
523 render_thread
->compositor_message_loop_proxy();
524 shared_bitmap_manager
= render_thread
->shared_bitmap_manager();
526 if (compositor_message_loop_proxy
.get()) {
527 layer_tree_host_
= cc::LayerTreeHost::CreateThreaded(
529 shared_bitmap_manager
,
531 base::MessageLoopProxy::current(),
532 compositor_message_loop_proxy
);
534 layer_tree_host_
= cc::LayerTreeHost::CreateSingleThreaded(
537 shared_bitmap_manager
,
539 base::MessageLoopProxy::current());
541 DCHECK(layer_tree_host_
);
544 void RenderWidgetCompositor::setSurfaceReady() {
545 // In tests without a RenderThreadImpl, don't set ready as this kicks
546 // off creating output surfaces that the test can't create.
547 if (RenderThreadImpl::current())
548 layer_tree_host_
->SetLayerTreeHostClientReady();
551 void RenderWidgetCompositor::setRootLayer(const blink::WebLayer
& layer
) {
552 layer_tree_host_
->SetRootLayer(
553 static_cast<const cc_blink::WebLayerImpl
*>(&layer
)->layer());
556 void RenderWidgetCompositor::clearRootLayer() {
557 layer_tree_host_
->SetRootLayer(scoped_refptr
<cc::Layer
>());
560 void RenderWidgetCompositor::setViewportSize(
562 const WebSize
& device_viewport_size
) {
563 layer_tree_host_
->SetViewportSize(device_viewport_size
);
566 void RenderWidgetCompositor::setViewportSize(
567 const WebSize
& device_viewport_size
) {
568 layer_tree_host_
->SetViewportSize(device_viewport_size
);
571 WebSize
RenderWidgetCompositor::layoutViewportSize() const {
572 return layer_tree_host_
->device_viewport_size();
575 WebSize
RenderWidgetCompositor::deviceViewportSize() const {
576 return layer_tree_host_
->device_viewport_size();
579 WebFloatPoint
RenderWidgetCompositor::adjustEventPointForPinchZoom(
580 const WebFloatPoint
& point
) const {
584 void RenderWidgetCompositor::setDeviceScaleFactor(float device_scale
) {
585 layer_tree_host_
->SetDeviceScaleFactor(device_scale
);
588 float RenderWidgetCompositor::deviceScaleFactor() const {
589 return layer_tree_host_
->device_scale_factor();
592 void RenderWidgetCompositor::setBackgroundColor(blink::WebColor color
) {
593 layer_tree_host_
->set_background_color(color
);
596 void RenderWidgetCompositor::setHasTransparentBackground(bool transparent
) {
597 layer_tree_host_
->set_has_transparent_background(transparent
);
600 void RenderWidgetCompositor::setOverhangBitmap(const SkBitmap
& bitmap
) {
601 layer_tree_host_
->SetOverhangBitmap(bitmap
);
604 void RenderWidgetCompositor::setVisible(bool visible
) {
605 layer_tree_host_
->SetVisible(visible
);
608 void RenderWidgetCompositor::setPageScaleFactorAndLimits(
609 float page_scale_factor
, float minimum
, float maximum
) {
610 layer_tree_host_
->SetPageScaleFactorAndLimits(
611 page_scale_factor
, minimum
, maximum
);
614 void RenderWidgetCompositor::startPageScaleAnimation(
615 const blink::WebPoint
& destination
,
617 float new_page_scale
,
618 double duration_sec
) {
619 base::TimeDelta duration
= base::TimeDelta::FromMicroseconds(
620 duration_sec
* base::Time::kMicrosecondsPerSecond
);
621 layer_tree_host_
->StartPageScaleAnimation(
622 gfx::Vector2d(destination
.x
, destination
.y
),
628 void RenderWidgetCompositor::heuristicsForGpuRasterizationUpdated(
629 bool matches_heuristics
) {
630 layer_tree_host_
->SetHasGpuRasterizationTrigger(matches_heuristics
);
633 void RenderWidgetCompositor::setNeedsAnimate() {
634 layer_tree_host_
->SetNeedsAnimate();
637 bool RenderWidgetCompositor::commitRequested() const {
638 return layer_tree_host_
->CommitRequested();
641 void RenderWidgetCompositor::didStopFlinging() {
642 layer_tree_host_
->DidStopFlinging();
645 void RenderWidgetCompositor::registerForAnimations(blink::WebLayer
* layer
) {
646 cc::Layer
* cc_layer
= static_cast<cc_blink::WebLayerImpl
*>(layer
)->layer();
647 cc_layer
->layer_animation_controller()->SetAnimationRegistrar(
648 layer_tree_host_
->animation_registrar());
651 void RenderWidgetCompositor::registerViewportLayers(
652 const blink::WebLayer
* pageScaleLayer
,
653 const blink::WebLayer
* innerViewportScrollLayer
,
654 const blink::WebLayer
* outerViewportScrollLayer
) {
655 layer_tree_host_
->RegisterViewportLayers(
656 static_cast<const cc_blink::WebLayerImpl
*>(pageScaleLayer
)->layer(),
657 static_cast<const cc_blink::WebLayerImpl
*>(innerViewportScrollLayer
)
659 // The outer viewport layer will only exist when using pinch virtual
661 outerViewportScrollLayer
? static_cast<const cc_blink::WebLayerImpl
*>(
662 outerViewportScrollLayer
)->layer()
666 void RenderWidgetCompositor::clearViewportLayers() {
667 layer_tree_host_
->RegisterViewportLayers(scoped_refptr
<cc::Layer
>(),
668 scoped_refptr
<cc::Layer
>(),
669 scoped_refptr
<cc::Layer
>());
672 void RenderWidgetCompositor::registerSelection(
673 const blink::WebSelectionBound
& start
,
674 const blink::WebSelectionBound
& end
) {
675 layer_tree_host_
->RegisterSelection(ConvertWebSelectionBound(start
),
676 ConvertWebSelectionBound(end
));
679 void RenderWidgetCompositor::clearSelection() {
680 cc::LayerSelectionBound empty_selection
;
681 layer_tree_host_
->RegisterSelection(empty_selection
, empty_selection
);
684 void CompositeAndReadbackAsyncCallback(
685 blink::WebCompositeAndReadbackAsyncCallback
* callback
,
686 scoped_ptr
<cc::CopyOutputResult
> result
) {
687 if (result
->HasBitmap()) {
688 scoped_ptr
<SkBitmap
> result_bitmap
= result
->TakeBitmap();
689 callback
->didCompositeAndReadback(*result_bitmap
);
691 callback
->didCompositeAndReadback(SkBitmap());
695 void RenderWidgetCompositor::compositeAndReadbackAsync(
696 blink::WebCompositeAndReadbackAsyncCallback
* callback
) {
697 DCHECK(layer_tree_host_
->root_layer());
698 scoped_ptr
<cc::CopyOutputRequest
> request
=
699 cc::CopyOutputRequest::CreateBitmapRequest(
700 base::Bind(&CompositeAndReadbackAsyncCallback
, callback
));
701 layer_tree_host_
->root_layer()->RequestCopyOfOutput(request
.Pass());
704 !layer_tree_host_
->settings().single_thread_proxy_scheduler
) {
705 layer_tree_host_
->Composite(gfx::FrameTime::Now());
709 void RenderWidgetCompositor::finishAllRendering() {
710 layer_tree_host_
->FinishAllRendering();
713 void RenderWidgetCompositor::setDeferCommits(bool defer_commits
) {
714 layer_tree_host_
->SetDeferCommits(defer_commits
);
717 void RenderWidgetCompositor::setShowFPSCounter(bool show
) {
718 cc::LayerTreeDebugState debug_state
= layer_tree_host_
->debug_state();
719 debug_state
.show_fps_counter
= show
;
720 layer_tree_host_
->SetDebugState(debug_state
);
723 void RenderWidgetCompositor::setShowPaintRects(bool show
) {
724 cc::LayerTreeDebugState debug_state
= layer_tree_host_
->debug_state();
725 debug_state
.show_paint_rects
= show
;
726 layer_tree_host_
->SetDebugState(debug_state
);
729 void RenderWidgetCompositor::setShowDebugBorders(bool show
) {
730 cc::LayerTreeDebugState debug_state
= layer_tree_host_
->debug_state();
731 debug_state
.show_debug_borders
= show
;
732 layer_tree_host_
->SetDebugState(debug_state
);
735 void RenderWidgetCompositor::setContinuousPaintingEnabled(bool enabled
) {
736 cc::LayerTreeDebugState debug_state
= layer_tree_host_
->debug_state();
737 debug_state
.continuous_painting
= enabled
;
738 layer_tree_host_
->SetDebugState(debug_state
);
741 void RenderWidgetCompositor::setShowScrollBottleneckRects(bool show
) {
742 cc::LayerTreeDebugState debug_state
= layer_tree_host_
->debug_state();
743 debug_state
.show_touch_event_handler_rects
= show
;
744 debug_state
.show_wheel_event_handler_rects
= show
;
745 debug_state
.show_non_fast_scrollable_rects
= show
;
746 layer_tree_host_
->SetDebugState(debug_state
);
749 void RenderWidgetCompositor::WillBeginMainFrame(int frame_id
) {
750 widget_
->InstrumentWillBeginFrame(frame_id
);
751 widget_
->willBeginCompositorFrame();
754 void RenderWidgetCompositor::DidBeginMainFrame() {
755 widget_
->InstrumentDidBeginFrame();
758 void RenderWidgetCompositor::BeginMainFrame(const cc::BeginFrameArgs
& args
) {
759 begin_main_frame_time_
= args
.frame_time
;
760 begin_main_frame_interval_
= args
.interval
;
761 double frame_time
= (args
.frame_time
- base::TimeTicks()).InSecondsF();
762 WebBeginFrameArgs web_begin_frame_args
= WebBeginFrameArgs(frame_time
);
763 widget_
->webwidget()->beginFrame(web_begin_frame_args
);
766 void RenderWidgetCompositor::Layout() {
767 widget_
->webwidget()->layout();
770 void RenderWidgetCompositor::ApplyScrollAndScale(
771 const gfx::Vector2d
& scroll_delta
,
773 widget_
->webwidget()->applyScrollAndScale(scroll_delta
, page_scale
);
776 scoped_ptr
<cc::OutputSurface
> RenderWidgetCompositor::CreateOutputSurface(
778 return widget_
->CreateOutputSurface(fallback
);
781 void RenderWidgetCompositor::DidInitializeOutputSurface() {
784 void RenderWidgetCompositor::WillCommit() {
785 widget_
->InstrumentWillComposite();
788 void RenderWidgetCompositor::DidCommit() {
789 if (send_v8_idle_notification_after_commit_
) {
790 base::TimeDelta idle_time
= begin_main_frame_time_
+
791 begin_main_frame_interval_
-
792 gfx::FrameTime::Now();
793 if (idle_time
> base::TimeDelta()) {
794 // Convert to 32-bit microseconds first to avoid costly 64-bit division.
795 int32 idle_time_in_us
= idle_time
.InMicroseconds();
796 int32 idle_time_in_ms
= idle_time_in_us
/ 1000;
797 blink::mainThreadIsolate()->IdleNotification(idle_time_in_ms
);
801 widget_
->DidCommitCompositorFrame();
802 widget_
->didBecomeReadyForAdditionalInput();
805 void RenderWidgetCompositor::DidCommitAndDrawFrame() {
806 widget_
->didCommitAndDrawCompositorFrame();
809 void RenderWidgetCompositor::DidCompleteSwapBuffers() {
810 widget_
->didCompleteSwapBuffers();
812 widget_
->OnSwapBuffersComplete();
815 void RenderWidgetCompositor::ScheduleAnimation() {
816 widget_
->scheduleAnimation();
819 void RenderWidgetCompositor::DidPostSwapBuffers() {
820 widget_
->OnSwapBuffersPosted();
823 void RenderWidgetCompositor::DidAbortSwapBuffers() {
824 widget_
->OnSwapBuffersAborted();
827 void RenderWidgetCompositor::RateLimitSharedMainThreadContext() {
828 cc::ContextProvider
* provider
=
829 RenderThreadImpl::current()->SharedMainThreadContextProvider().get();
830 provider
->ContextGL()->RateLimitOffscreenContextCHROMIUM();
833 } // namespace content