[ServiceWorker] Implement WebServiceWorkerContextClient::openWindow().
[chromium-blink-merge.git] / content / renderer / gpu / render_widget_compositor.cc
blobc9148f2b066b8da29990cb3d0c00a2684a197994
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"
7 #include <limits>
8 #include <string>
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/scheduler/begin_frame_source.h"
31 #include "cc/trees/layer_tree_host.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/scheduler/renderer_scheduler.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"
50 #endif
52 namespace base {
53 class Value;
56 namespace cc {
57 class Layer;
60 using blink::WebBeginFrameArgs;
61 using blink::WebFloatPoint;
62 using blink::WebRect;
63 using blink::WebSelectionBound;
64 using blink::WebSize;
66 namespace content {
67 namespace {
69 bool GetSwitchValueAsInt(const base::CommandLine& command_line,
70 const std::string& switch_string,
71 int min_value,
72 int max_value,
73 int* result) {
74 std::string string_value = command_line.GetSwitchValueASCII(switch_string);
75 int int_value;
76 if (base::StringToInt(string_value, &int_value) &&
77 int_value >= min_value && int_value <= max_value) {
78 *result = int_value;
79 return true;
80 } else {
81 LOG(WARNING) << "Failed to parse switch " << switch_string << ": " <<
82 string_value;
83 return false;
87 cc::LayerSelectionBound ConvertWebSelectionBound(
88 const WebSelectionBound& web_bound) {
89 DCHECK(web_bound.layerId);
91 cc::LayerSelectionBound cc_bound;
92 switch (web_bound.type) {
93 case blink::WebSelectionBound::Caret:
94 cc_bound.type = cc::SELECTION_BOUND_CENTER;
95 break;
96 case blink::WebSelectionBound::SelectionLeft:
97 cc_bound.type = cc::SELECTION_BOUND_LEFT;
98 break;
99 case blink::WebSelectionBound::SelectionRight:
100 cc_bound.type = cc::SELECTION_BOUND_RIGHT;
101 break;
103 cc_bound.layer_id = web_bound.layerId;
104 cc_bound.edge_top = gfx::Point(web_bound.edgeTopInLayer);
105 cc_bound.edge_bottom = gfx::Point(web_bound.edgeBottomInLayer);
106 return cc_bound;
109 gfx::Size CalculateDefaultTileSize() {
110 int default_tile_size = 256;
111 #if defined(OS_ANDROID)
112 // TODO(epenner): unify this for all platforms if it
113 // makes sense (http://crbug.com/159524)
115 gfx::DeviceDisplayInfo info;
116 bool real_size_supported = true;
117 int display_width = info.GetPhysicalDisplayWidth();
118 int display_height = info.GetPhysicalDisplayHeight();
119 if (display_width == 0 || display_height == 0) {
120 real_size_supported = false;
121 display_width = info.GetDisplayWidth();
122 display_height = info.GetDisplayHeight();
125 int portrait_width = std::min(display_width, display_height);
126 int landscape_width = std::max(display_width, display_height);
128 if (real_size_supported) {
129 // Maximum HD dimensions should be 768x1280
130 // Maximum FHD dimensions should be 1200x1920
131 if (portrait_width > 768 || landscape_width > 1280)
132 default_tile_size = 384;
133 if (portrait_width > 1200 || landscape_width > 1920)
134 default_tile_size = 512;
136 // Adjust for some resolutions that barely straddle an extra
137 // tile when in portrait mode. This helps worst case scroll/raster
138 // by not needing a full extra tile for each row.
139 if (default_tile_size == 256 && portrait_width == 768)
140 default_tile_size += 32;
141 if (default_tile_size == 384 && portrait_width == 1200)
142 default_tile_size += 32;
143 } else {
144 // We don't know the exact resolution due to screen controls etc.
145 // So this just estimates the values above using tile counts.
146 int numTiles = (display_width * display_height) / (256 * 256);
147 if (numTiles > 16)
148 default_tile_size = 384;
149 if (numTiles >= 40)
150 default_tile_size = 512;
152 #endif
153 return gfx::Size(default_tile_size, default_tile_size);
156 } // namespace
158 // static
159 scoped_ptr<RenderWidgetCompositor> RenderWidgetCompositor::Create(
160 RenderWidget* widget,
161 CompositorDependencies* compositor_deps) {
162 scoped_ptr<RenderWidgetCompositor> compositor(
163 new RenderWidgetCompositor(widget, compositor_deps));
164 compositor->Initialize();
165 return compositor;
168 RenderWidgetCompositor::RenderWidgetCompositor(
169 RenderWidget* widget,
170 CompositorDependencies* compositor_deps)
171 : num_failed_recreate_attempts_(0),
172 widget_(widget),
173 compositor_deps_(compositor_deps),
174 weak_factory_(this) {
177 void RenderWidgetCompositor::Initialize() {
178 base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
180 cc::LayerTreeSettings settings;
182 // For web contents, layer transforms should scale up the contents of layers
183 // to keep content always crisp when possible.
184 settings.layer_transforms_should_scale_layer_contents = true;
186 settings.throttle_frame_production =
187 !cmd->HasSwitch(switches::kDisableGpuVsync);
188 settings.use_external_begin_frame_source =
189 cmd->HasSwitch(switches::kEnableBeginFrameScheduling);
190 settings.main_frame_before_activation_enabled =
191 cmd->HasSwitch(cc::switches::kEnableMainFrameBeforeActivation) &&
192 !cmd->HasSwitch(cc::switches::kDisableMainFrameBeforeActivation);
193 settings.report_overscroll_only_for_scrollable_axes =
194 !compositor_deps_->IsElasticOverscrollEnabled();
195 settings.accelerated_animation_enabled =
196 !cmd->HasSwitch(cc::switches::kDisableThreadedAnimation);
197 settings.use_display_lists = cmd->HasSwitch(switches::kEnableSlimmingPaint);
199 settings.default_tile_size = CalculateDefaultTileSize();
200 if (cmd->HasSwitch(switches::kDefaultTileWidth)) {
201 int tile_width = 0;
202 GetSwitchValueAsInt(*cmd,
203 switches::kDefaultTileWidth,
205 std::numeric_limits<int>::max(),
206 &tile_width);
207 settings.default_tile_size.set_width(tile_width);
209 if (cmd->HasSwitch(switches::kDefaultTileHeight)) {
210 int tile_height = 0;
211 GetSwitchValueAsInt(*cmd,
212 switches::kDefaultTileHeight,
214 std::numeric_limits<int>::max(),
215 &tile_height);
216 settings.default_tile_size.set_height(tile_height);
219 int max_untiled_layer_width = settings.max_untiled_layer_size.width();
220 if (cmd->HasSwitch(switches::kMaxUntiledLayerWidth)) {
221 GetSwitchValueAsInt(*cmd, switches::kMaxUntiledLayerWidth, 1,
222 std::numeric_limits<int>::max(),
223 &max_untiled_layer_width);
225 int max_untiled_layer_height = settings.max_untiled_layer_size.height();
226 if (cmd->HasSwitch(switches::kMaxUntiledLayerHeight)) {
227 GetSwitchValueAsInt(*cmd, switches::kMaxUntiledLayerHeight, 1,
228 std::numeric_limits<int>::max(),
229 &max_untiled_layer_height);
232 settings.max_untiled_layer_size = gfx::Size(max_untiled_layer_width,
233 max_untiled_layer_height);
235 settings.gpu_rasterization_msaa_sample_count =
236 compositor_deps_->GetGpuRasterizationMSAASampleCount();
237 settings.impl_side_painting = compositor_deps_->IsImplSidePaintingEnabled();
238 settings.gpu_rasterization_forced =
239 compositor_deps_->IsGpuRasterizationForced();
240 settings.gpu_rasterization_enabled =
241 compositor_deps_->IsGpuRasterizationEnabled();
242 settings.threaded_gpu_rasterization_enabled =
243 compositor_deps_->IsThreadedGpuRasterizationEnabled();
244 settings.can_use_lcd_text = compositor_deps_->IsLcdTextEnabled();
245 settings.use_distance_field_text =
246 compositor_deps_->IsDistanceFieldTextEnabled();
247 settings.use_zero_copy = compositor_deps_->IsZeroCopyEnabled();
248 settings.use_one_copy = compositor_deps_->IsOneCopyEnabled();
249 settings.enable_elastic_overscroll =
250 compositor_deps_->IsElasticOverscrollEnabled();
251 settings.use_image_texture_target = compositor_deps_->GetImageTextureTarget();
253 settings.calculate_top_controls_position =
254 cmd->HasSwitch(cc::switches::kEnableTopControlsPositionCalculation);
255 if (cmd->HasSwitch(cc::switches::kTopControlsShowThreshold)) {
256 std::string top_threshold_str =
257 cmd->GetSwitchValueASCII(cc::switches::kTopControlsShowThreshold);
258 double show_threshold;
259 if (base::StringToDouble(top_threshold_str, &show_threshold) &&
260 show_threshold >= 0.f && show_threshold <= 1.f)
261 settings.top_controls_show_threshold = show_threshold;
264 if (cmd->HasSwitch(cc::switches::kTopControlsHideThreshold)) {
265 std::string top_threshold_str =
266 cmd->GetSwitchValueASCII(cc::switches::kTopControlsHideThreshold);
267 double hide_threshold;
268 if (base::StringToDouble(top_threshold_str, &hide_threshold) &&
269 hide_threshold >= 0.f && hide_threshold <= 1.f)
270 settings.top_controls_hide_threshold = hide_threshold;
273 settings.use_pinch_virtual_viewport =
274 cmd->HasSwitch(cc::switches::kEnablePinchVirtualViewport);
275 settings.renderer_settings.allow_antialiasing &=
276 !cmd->HasSwitch(cc::switches::kDisableCompositedAntialiasing);
277 settings.single_thread_proxy_scheduler =
278 compositor_deps_->UseSingleThreadScheduler();
280 // These flags should be mirrored by UI versions in ui/compositor/.
281 settings.initial_debug_state.show_debug_borders =
282 cmd->HasSwitch(cc::switches::kShowCompositedLayerBorders);
283 settings.initial_debug_state.show_fps_counter =
284 cmd->HasSwitch(cc::switches::kShowFPSCounter);
285 settings.initial_debug_state.show_layer_animation_bounds_rects =
286 cmd->HasSwitch(cc::switches::kShowLayerAnimationBounds);
287 settings.initial_debug_state.show_paint_rects =
288 cmd->HasSwitch(switches::kShowPaintRects);
289 settings.initial_debug_state.show_property_changed_rects =
290 cmd->HasSwitch(cc::switches::kShowPropertyChangedRects);
291 settings.initial_debug_state.show_surface_damage_rects =
292 cmd->HasSwitch(cc::switches::kShowSurfaceDamageRects);
293 settings.initial_debug_state.show_screen_space_rects =
294 cmd->HasSwitch(cc::switches::kShowScreenSpaceRects);
295 settings.initial_debug_state.show_replica_screen_space_rects =
296 cmd->HasSwitch(cc::switches::kShowReplicaScreenSpaceRects);
297 settings.initial_debug_state.show_occluding_rects =
298 cmd->HasSwitch(cc::switches::kShowOccludingRects);
299 settings.initial_debug_state.show_non_occluding_rects =
300 cmd->HasSwitch(cc::switches::kShowNonOccludingRects);
302 settings.initial_debug_state.SetRecordRenderingStats(
303 cmd->HasSwitch(cc::switches::kEnableGpuBenchmarking));
305 if (cmd->HasSwitch(cc::switches::kSlowDownRasterScaleFactor)) {
306 const int kMinSlowDownScaleFactor = 0;
307 const int kMaxSlowDownScaleFactor = INT_MAX;
308 GetSwitchValueAsInt(
309 *cmd,
310 cc::switches::kSlowDownRasterScaleFactor,
311 kMinSlowDownScaleFactor,
312 kMaxSlowDownScaleFactor,
313 &settings.initial_debug_state.slow_down_raster_scale_factor);
316 if (cmd->HasSwitch(cc::switches::kMaxTilesForInterestArea)) {
317 int max_tiles_for_interest_area;
318 if (GetSwitchValueAsInt(*cmd,
319 cc::switches::kMaxTilesForInterestArea,
320 1, std::numeric_limits<int>::max(),
321 &max_tiles_for_interest_area))
322 settings.max_tiles_for_interest_area = max_tiles_for_interest_area;
325 if (cmd->HasSwitch(cc::switches::kMaxUnusedResourceMemoryUsagePercentage)) {
326 int max_unused_resource_memory_percentage;
327 if (GetSwitchValueAsInt(
328 *cmd,
329 cc::switches::kMaxUnusedResourceMemoryUsagePercentage,
330 0, 100,
331 &max_unused_resource_memory_percentage)) {
332 settings.max_unused_resource_memory_percentage =
333 max_unused_resource_memory_percentage;
337 settings.strict_layer_property_change_checking =
338 cmd->HasSwitch(cc::switches::kStrictLayerPropertyChangeChecking);
340 #if defined(OS_ANDROID)
341 SynchronousCompositorFactory* synchronous_compositor_factory =
342 SynchronousCompositorFactory::GetInstance();
344 // We can't use GPU rasterization on low-end devices, because the Ganesh
345 // cache would consume too much memory.
346 if (base::SysInfo::IsLowEndDevice())
347 settings.gpu_rasterization_enabled = false;
348 settings.using_synchronous_renderer_compositor =
349 synchronous_compositor_factory;
350 settings.record_full_layer = widget_->DoesRecordFullLayer();
351 settings.report_overscroll_only_for_scrollable_axes =
352 !synchronous_compositor_factory;
353 settings.max_partial_texture_updates = 0;
354 if (synchronous_compositor_factory) {
355 // Android WebView uses system scrollbars, so make ours invisible.
356 settings.scrollbar_animator = cc::LayerTreeSettings::NoAnimator;
357 settings.solid_color_scrollbar_color = SK_ColorTRANSPARENT;
358 } else {
359 settings.scrollbar_animator = cc::LayerTreeSettings::LinearFade;
360 settings.scrollbar_fade_delay_ms = 300;
361 settings.scrollbar_fade_resize_delay_ms = 2000;
362 settings.scrollbar_fade_duration_ms = 300;
363 settings.solid_color_scrollbar_color = SkColorSetARGB(128, 128, 128, 128);
365 settings.renderer_settings.highp_threshold_min = 2048;
366 // Android WebView handles root layer flings itself.
367 settings.ignore_root_layer_flings =
368 synchronous_compositor_factory;
369 // Memory policy on Android WebView does not depend on whether device is
370 // low end, so always use default policy.
371 bool use_low_memory_policy =
372 base::SysInfo::IsLowEndDevice() && !synchronous_compositor_factory;
373 // RGBA_4444 textures are only enabled for low end devices
374 // and are disabled for Android WebView as it doesn't support the format.
375 settings.renderer_settings.use_rgba_4444_textures = use_low_memory_policy;
376 if (use_low_memory_policy) {
377 // On low-end we want to be very carefull about killing other
378 // apps. So initially we use 50% more memory to avoid flickering
379 // or raster-on-demand.
380 settings.max_memory_for_prepaint_percentage = 67;
381 } else {
382 // On other devices we have increased memory excessively to avoid
383 // raster-on-demand already, so now we reserve 50% _only_ to avoid
384 // raster-on-demand, and use 50% of the memory otherwise.
385 settings.max_memory_for_prepaint_percentage = 50;
387 // Webview does not own the surface so should not clear it.
388 settings.renderer_settings.should_clear_root_render_pass =
389 !synchronous_compositor_factory;
391 // TODO(danakj): Only do this on low end devices.
392 settings.create_low_res_tiling = true;
394 #elif !defined(OS_MACOSX)
395 if (ui::IsOverlayScrollbarEnabled()) {
396 settings.scrollbar_animator = cc::LayerTreeSettings::Thinning;
397 settings.solid_color_scrollbar_color = SkColorSetARGB(128, 128, 128, 128);
398 } else if (cmd->HasSwitch(cc::switches::kEnablePinchVirtualViewport)) {
399 // use_pinch_zoom_scrollbars is only true on desktop when non-overlay
400 // scrollbars are in use.
401 settings.use_pinch_zoom_scrollbars = true;
402 settings.scrollbar_animator = cc::LayerTreeSettings::LinearFade;
403 settings.solid_color_scrollbar_color = SkColorSetARGB(128, 128, 128, 128);
405 settings.scrollbar_fade_delay_ms = 500;
406 settings.scrollbar_fade_resize_delay_ms = 500;
407 settings.scrollbar_fade_duration_ms = 300;
409 // When pinching in, only show the pinch-viewport overlay scrollbars if the
410 // page scale is at least some threshold away from the minimum. i.e. don't
411 // show the pinch scrollbars when at minimum scale.
412 settings.scrollbar_show_scale_threshold = 1.05f;
413 #endif
415 if (cmd->HasSwitch(switches::kEnableLowResTiling))
416 settings.create_low_res_tiling = true;
417 if (cmd->HasSwitch(switches::kDisableLowResTiling))
418 settings.create_low_res_tiling = false;
420 scoped_refptr<base::SingleThreadTaskRunner> compositor_thread_task_runner =
421 compositor_deps_->GetCompositorImplThreadTaskRunner();
422 scoped_refptr<base::SingleThreadTaskRunner>
423 main_thread_compositor_task_runner =
424 compositor_deps_->GetCompositorMainThreadTaskRunner();
425 cc::SharedBitmapManager* shared_bitmap_manager =
426 compositor_deps_->GetSharedBitmapManager();
427 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager =
428 compositor_deps_->GetGpuMemoryBufferManager();
430 scoped_ptr<cc::BeginFrameSource> external_begin_frame_source;
431 if (settings.use_external_begin_frame_source) {
432 external_begin_frame_source =
433 compositor_deps_->CreateExternalBeginFrameSource(widget_->routing_id());
436 if (compositor_thread_task_runner.get()) {
437 layer_tree_host_ = cc::LayerTreeHost::CreateThreaded(
438 this, shared_bitmap_manager, gpu_memory_buffer_manager, settings,
439 main_thread_compositor_task_runner, compositor_thread_task_runner,
440 external_begin_frame_source.Pass());
441 } else {
442 layer_tree_host_ = cc::LayerTreeHost::CreateSingleThreaded(
443 this, this, shared_bitmap_manager, gpu_memory_buffer_manager, settings,
444 main_thread_compositor_task_runner, external_begin_frame_source.Pass());
446 DCHECK(layer_tree_host_);
449 RenderWidgetCompositor::~RenderWidgetCompositor() {}
451 const base::WeakPtr<cc::InputHandler>&
452 RenderWidgetCompositor::GetInputHandler() {
453 return layer_tree_host_->GetInputHandler();
456 bool RenderWidgetCompositor::BeginMainFrameRequested() const {
457 return layer_tree_host_->BeginMainFrameRequested();
460 void RenderWidgetCompositor::SetNeedsDisplayOnAllLayers() {
461 layer_tree_host_->SetNeedsDisplayOnAllLayers();
464 void RenderWidgetCompositor::SetRasterizeOnlyVisibleContent() {
465 cc::LayerTreeDebugState current = layer_tree_host_->debug_state();
466 current.rasterize_only_visible_content = true;
467 layer_tree_host_->SetDebugState(current);
470 void RenderWidgetCompositor::UpdateTopControlsState(
471 cc::TopControlsState constraints,
472 cc::TopControlsState current,
473 bool animate) {
474 layer_tree_host_->UpdateTopControlsState(constraints,
475 current,
476 animate);
479 void RenderWidgetCompositor::SetTopControlsShrinkBlinkSize(bool shrink) {
480 layer_tree_host_->SetTopControlsShrinkBlinkSize(shrink);
483 void RenderWidgetCompositor::SetTopControlsHeight(float height) {
484 layer_tree_host_->SetTopControlsHeight(height);
487 void RenderWidgetCompositor::SetNeedsRedrawRect(gfx::Rect damage_rect) {
488 layer_tree_host_->SetNeedsRedrawRect(damage_rect);
491 void RenderWidgetCompositor::SetNeedsForcedRedraw() {
492 layer_tree_host_->SetNextCommitForcesRedraw();
493 setNeedsAnimate();
496 scoped_ptr<cc::SwapPromiseMonitor>
497 RenderWidgetCompositor::CreateLatencyInfoSwapPromiseMonitor(
498 ui::LatencyInfo* latency) {
499 return scoped_ptr<cc::SwapPromiseMonitor>(
500 new cc::LatencyInfoSwapPromiseMonitor(
501 latency, layer_tree_host_.get(), NULL));
504 void RenderWidgetCompositor::QueueSwapPromise(
505 scoped_ptr<cc::SwapPromise> swap_promise) {
506 layer_tree_host_->QueueSwapPromise(swap_promise.Pass());
509 int RenderWidgetCompositor::GetLayerTreeId() const {
510 return layer_tree_host_->id();
513 int RenderWidgetCompositor::GetSourceFrameNumber() const {
514 return layer_tree_host_->source_frame_number();
517 void RenderWidgetCompositor::SetNeedsCommit() {
518 layer_tree_host_->SetNeedsCommit();
521 void RenderWidgetCompositor::NotifyInputThrottledUntilCommit() {
522 layer_tree_host_->NotifyInputThrottledUntilCommit();
525 const cc::Layer* RenderWidgetCompositor::GetRootLayer() const {
526 return layer_tree_host_->root_layer();
529 int RenderWidgetCompositor::ScheduleMicroBenchmark(
530 const std::string& name,
531 scoped_ptr<base::Value> value,
532 const base::Callback<void(scoped_ptr<base::Value>)>& callback) {
533 return layer_tree_host_->ScheduleMicroBenchmark(name, value.Pass(), callback);
536 bool RenderWidgetCompositor::SendMessageToMicroBenchmark(
537 int id,
538 scoped_ptr<base::Value> value) {
539 return layer_tree_host_->SendMessageToMicroBenchmark(id, value.Pass());
542 void RenderWidgetCompositor::StartCompositor() {
543 layer_tree_host_->SetLayerTreeHostClientReady();
546 void RenderWidgetCompositor::setRootLayer(const blink::WebLayer& layer) {
547 layer_tree_host_->SetRootLayer(
548 static_cast<const cc_blink::WebLayerImpl*>(&layer)->layer());
551 void RenderWidgetCompositor::clearRootLayer() {
552 layer_tree_host_->SetRootLayer(scoped_refptr<cc::Layer>());
555 void RenderWidgetCompositor::setViewportSize(
556 const WebSize&,
557 const WebSize& device_viewport_size) {
558 layer_tree_host_->SetViewportSize(device_viewport_size);
561 void RenderWidgetCompositor::setViewportSize(
562 const WebSize& device_viewport_size) {
563 layer_tree_host_->SetViewportSize(device_viewport_size);
566 WebSize RenderWidgetCompositor::layoutViewportSize() const {
567 return layer_tree_host_->device_viewport_size();
570 WebSize RenderWidgetCompositor::deviceViewportSize() const {
571 return layer_tree_host_->device_viewport_size();
574 WebFloatPoint RenderWidgetCompositor::adjustEventPointForPinchZoom(
575 const WebFloatPoint& point) const {
576 return point;
579 void RenderWidgetCompositor::setDeviceScaleFactor(float device_scale) {
580 layer_tree_host_->SetDeviceScaleFactor(device_scale);
583 float RenderWidgetCompositor::deviceScaleFactor() const {
584 return layer_tree_host_->device_scale_factor();
587 void RenderWidgetCompositor::setBackgroundColor(blink::WebColor color) {
588 layer_tree_host_->set_background_color(color);
591 void RenderWidgetCompositor::setHasTransparentBackground(bool transparent) {
592 layer_tree_host_->set_has_transparent_background(transparent);
595 void RenderWidgetCompositor::setVisible(bool visible) {
596 layer_tree_host_->SetVisible(visible);
599 void RenderWidgetCompositor::setPageScaleFactorAndLimits(
600 float page_scale_factor, float minimum, float maximum) {
601 layer_tree_host_->SetPageScaleFactorAndLimits(
602 page_scale_factor, minimum, maximum);
605 void RenderWidgetCompositor::startPageScaleAnimation(
606 const blink::WebPoint& destination,
607 bool use_anchor,
608 float new_page_scale,
609 double duration_sec) {
610 base::TimeDelta duration = base::TimeDelta::FromMicroseconds(
611 duration_sec * base::Time::kMicrosecondsPerSecond);
612 layer_tree_host_->StartPageScaleAnimation(
613 gfx::Vector2d(destination.x, destination.y),
614 use_anchor,
615 new_page_scale,
616 duration);
619 void RenderWidgetCompositor::heuristicsForGpuRasterizationUpdated(
620 bool matches_heuristics) {
621 layer_tree_host_->SetHasGpuRasterizationTrigger(matches_heuristics);
624 void RenderWidgetCompositor::setNeedsAnimate() {
625 layer_tree_host_->SetNeedsAnimate();
628 bool RenderWidgetCompositor::commitRequested() const {
629 return layer_tree_host_->CommitRequested();
632 void RenderWidgetCompositor::didStopFlinging() {
633 layer_tree_host_->DidStopFlinging();
636 void RenderWidgetCompositor::registerForAnimations(blink::WebLayer* layer) {
637 cc::Layer* cc_layer = static_cast<cc_blink::WebLayerImpl*>(layer)->layer();
638 cc_layer->layer_animation_controller()->SetAnimationRegistrar(
639 layer_tree_host_->animation_registrar());
642 void RenderWidgetCompositor::registerViewportLayers(
643 const blink::WebLayer* overscrollElasticityLayer,
644 const blink::WebLayer* pageScaleLayer,
645 const blink::WebLayer* innerViewportScrollLayer,
646 const blink::WebLayer* outerViewportScrollLayer) {
647 layer_tree_host_->RegisterViewportLayers(
648 // The scroll elasticity layer will only exist when using pinch virtual
649 // viewports.
650 overscrollElasticityLayer
651 ? static_cast<const cc_blink::WebLayerImpl*>(
652 overscrollElasticityLayer)->layer()
653 : NULL,
654 static_cast<const cc_blink::WebLayerImpl*>(pageScaleLayer)->layer(),
655 static_cast<const cc_blink::WebLayerImpl*>(innerViewportScrollLayer)
656 ->layer(),
657 // The outer viewport layer will only exist when using pinch virtual
658 // viewports.
659 outerViewportScrollLayer
660 ? static_cast<const cc_blink::WebLayerImpl*>(outerViewportScrollLayer)
661 ->layer()
662 : NULL);
665 void RenderWidgetCompositor::clearViewportLayers() {
666 layer_tree_host_->RegisterViewportLayers(
667 scoped_refptr<cc::Layer>(), scoped_refptr<cc::Layer>(),
668 scoped_refptr<cc::Layer>(), scoped_refptr<cc::Layer>());
671 void RenderWidgetCompositor::registerSelection(
672 const blink::WebSelectionBound& start,
673 const blink::WebSelectionBound& end) {
674 layer_tree_host_->RegisterSelection(ConvertWebSelectionBound(start),
675 ConvertWebSelectionBound(end));
678 void RenderWidgetCompositor::clearSelection() {
679 cc::LayerSelectionBound empty_selection;
680 layer_tree_host_->RegisterSelection(empty_selection, empty_selection);
683 void CompositeAndReadbackAsyncCallback(
684 blink::WebCompositeAndReadbackAsyncCallback* callback,
685 scoped_ptr<cc::CopyOutputResult> result) {
686 if (result->HasBitmap()) {
687 scoped_ptr<SkBitmap> result_bitmap = result->TakeBitmap();
688 callback->didCompositeAndReadback(*result_bitmap);
689 } else {
690 callback->didCompositeAndReadback(SkBitmap());
694 void RenderWidgetCompositor::compositeAndReadbackAsync(
695 blink::WebCompositeAndReadbackAsyncCallback* callback) {
696 DCHECK(!temporary_copy_output_request_);
697 temporary_copy_output_request_ =
698 cc::CopyOutputRequest::CreateBitmapRequest(
699 base::Bind(&CompositeAndReadbackAsyncCallback, callback));
700 // Force a commit to happen. The temporary copy output request will
701 // be installed after layout which will happen as a part of the commit, when
702 // there is guaranteed to be a root layer.
703 bool threaded = !!compositor_deps_->GetCompositorImplThreadTaskRunner().get();
704 if (!threaded &&
705 !layer_tree_host_->settings().single_thread_proxy_scheduler) {
706 layer_tree_host_->Composite(gfx::FrameTime::Now());
707 } else {
708 layer_tree_host_->SetNeedsCommit();
712 void RenderWidgetCompositor::finishAllRendering() {
713 layer_tree_host_->FinishAllRendering();
716 void RenderWidgetCompositor::setDeferCommits(bool defer_commits) {
717 layer_tree_host_->SetDeferCommits(defer_commits);
720 void RenderWidgetCompositor::setShowFPSCounter(bool show) {
721 cc::LayerTreeDebugState debug_state = layer_tree_host_->debug_state();
722 debug_state.show_fps_counter = show;
723 layer_tree_host_->SetDebugState(debug_state);
726 void RenderWidgetCompositor::setShowPaintRects(bool show) {
727 cc::LayerTreeDebugState debug_state = layer_tree_host_->debug_state();
728 debug_state.show_paint_rects = show;
729 layer_tree_host_->SetDebugState(debug_state);
732 void RenderWidgetCompositor::setShowDebugBorders(bool show) {
733 cc::LayerTreeDebugState debug_state = layer_tree_host_->debug_state();
734 debug_state.show_debug_borders = show;
735 layer_tree_host_->SetDebugState(debug_state);
738 void RenderWidgetCompositor::setContinuousPaintingEnabled(bool enabled) {
739 cc::LayerTreeDebugState debug_state = layer_tree_host_->debug_state();
740 debug_state.continuous_painting = enabled;
741 layer_tree_host_->SetDebugState(debug_state);
744 void RenderWidgetCompositor::setShowScrollBottleneckRects(bool show) {
745 cc::LayerTreeDebugState debug_state = layer_tree_host_->debug_state();
746 debug_state.show_touch_event_handler_rects = show;
747 debug_state.show_wheel_event_handler_rects = show;
748 debug_state.show_non_fast_scrollable_rects = show;
749 layer_tree_host_->SetDebugState(debug_state);
752 void RenderWidgetCompositor::setTopControlsContentOffset(float offset) {
753 layer_tree_host_->SetTopControlsContentOffset(offset);
756 void RenderWidgetCompositor::WillBeginMainFrame() {
757 widget_->willBeginCompositorFrame();
760 void RenderWidgetCompositor::DidBeginMainFrame() {
763 void RenderWidgetCompositor::BeginMainFrame(const cc::BeginFrameArgs& args) {
764 double frame_time_sec = (args.frame_time - base::TimeTicks()).InSecondsF();
765 double deadline_sec = (args.deadline - base::TimeTicks()).InSecondsF();
766 double interval_sec = args.interval.InSecondsF();
767 WebBeginFrameArgs web_begin_frame_args =
768 WebBeginFrameArgs(frame_time_sec, deadline_sec, interval_sec);
769 compositor_deps_->GetRendererScheduler()->WillBeginFrame(args);
770 widget_->webwidget()->beginFrame(web_begin_frame_args);
773 void RenderWidgetCompositor::Layout() {
774 widget_->webwidget()->layout();
776 if (temporary_copy_output_request_) {
777 DCHECK(layer_tree_host_->root_layer());
778 layer_tree_host_->root_layer()->RequestCopyOfOutput(
779 temporary_copy_output_request_.Pass());
783 void RenderWidgetCompositor::ApplyViewportDeltas(
784 const gfx::Vector2dF& inner_delta,
785 const gfx::Vector2dF& outer_delta,
786 const gfx::Vector2dF& elastic_overscroll_delta,
787 float page_scale,
788 float top_controls_delta) {
789 widget_->webwidget()->applyViewportDeltas(
790 inner_delta,
791 outer_delta,
792 elastic_overscroll_delta,
793 page_scale,
794 top_controls_delta);
797 void RenderWidgetCompositor::ApplyViewportDeltas(
798 const gfx::Vector2d& scroll_delta,
799 float page_scale,
800 float top_controls_delta) {
801 widget_->webwidget()->applyViewportDeltas(
802 scroll_delta,
803 page_scale,
804 top_controls_delta);
807 void RenderWidgetCompositor::RequestNewOutputSurface() {
808 // If the host is closing, then no more compositing is possible. This
809 // prevents shutdown races between handling the close message and
810 // the CreateOutputSurface task.
811 if (widget_->host_closing())
812 return;
814 bool fallback =
815 num_failed_recreate_attempts_ >= OUTPUT_SURFACE_RETRIES_BEFORE_FALLBACK;
816 scoped_ptr<cc::OutputSurface> surface(widget_->CreateOutputSurface(fallback));
818 if (!surface) {
819 DidFailToInitializeOutputSurface();
820 return;
823 layer_tree_host_->SetOutputSurface(surface.Pass());
826 void RenderWidgetCompositor::DidInitializeOutputSurface() {
827 num_failed_recreate_attempts_ = 0;
830 void RenderWidgetCompositor::DidFailToInitializeOutputSurface() {
831 ++num_failed_recreate_attempts_;
832 // Tolerate a certain number of recreation failures to work around races
833 // in the output-surface-lost machinery.
834 LOG_IF(FATAL, (num_failed_recreate_attempts_ >= MAX_OUTPUT_SURFACE_RETRIES))
835 << "Failed to create a fallback OutputSurface.";
837 base::MessageLoop::current()->PostTask(
838 FROM_HERE, base::Bind(&RenderWidgetCompositor::RequestNewOutputSurface,
839 weak_factory_.GetWeakPtr()));
842 void RenderWidgetCompositor::WillCommit() {
845 void RenderWidgetCompositor::DidCommit() {
846 DCHECK(!temporary_copy_output_request_);
847 widget_->DidCommitCompositorFrame();
848 widget_->didBecomeReadyForAdditionalInput();
849 compositor_deps_->GetRendererScheduler()->DidCommitFrameToCompositor();
852 void RenderWidgetCompositor::DidCommitAndDrawFrame() {
853 widget_->didCommitAndDrawCompositorFrame();
856 void RenderWidgetCompositor::DidCompleteSwapBuffers() {
857 widget_->didCompleteSwapBuffers();
858 bool threaded = !!compositor_deps_->GetCompositorImplThreadTaskRunner().get();
859 if (!threaded)
860 widget_->OnSwapBuffersComplete();
863 void RenderWidgetCompositor::DidCompletePageScaleAnimation() {
864 widget_->DidCompletePageScaleAnimation();
867 void RenderWidgetCompositor::ScheduleAnimation() {
868 widget_->scheduleAnimation();
871 void RenderWidgetCompositor::DidPostSwapBuffers() {
872 widget_->OnSwapBuffersPosted();
875 void RenderWidgetCompositor::DidAbortSwapBuffers() {
876 widget_->OnSwapBuffersAborted();
879 void RenderWidgetCompositor::RateLimitSharedMainThreadContext() {
880 cc::ContextProvider* provider =
881 compositor_deps_->GetSharedMainThreadContextProvider();
882 provider->ContextGL()->RateLimitOffscreenContextCHROMIUM();
885 } // namespace content