summaryrefslogtreecommitdiff
path: root/chromium/cc
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-08-14 11:38:45 +0200
committerAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-08-14 17:16:47 +0000
commit3a97ca8dd9b96b599ae2d33e40df0dd2f7ea5859 (patch)
tree43cc572ba067417c7341db81f71ae7cc6e0fcc3e /chromium/cc
parentf61ab1ac7f855cd281809255c0aedbb1895e1823 (diff)
downloadqtwebengine-chromium-3a97ca8dd9b96b599ae2d33e40df0dd2f7ea5859.tar.gz
BASELINE: Update chromium to 45.0.2454.40
Change-Id: Id2121d9f11a8fc633677236c65a3e41feef589e4 Reviewed-by: Andras Becsi <andras.becsi@theqtcompany.com>
Diffstat (limited to 'chromium/cc')
-rw-r--r--chromium/cc/BUILD.gn146
-rw-r--r--chromium/cc/OWNERS3
-rw-r--r--chromium/cc/PRESUBMIT.py28
-rw-r--r--chromium/cc/animation/animation.h3
-rw-r--r--chromium/cc/animation/animation_host.cc511
-rw-r--r--chromium/cc/animation/animation_host.h167
-rw-r--r--chromium/cc/animation/animation_host_unittest.cc75
-rw-r--r--chromium/cc/animation/animation_id_provider.cc10
-rw-r--r--chromium/cc/animation/animation_id_provider.h2
-rw-r--r--chromium/cc/animation/animation_player.cc189
-rw-r--r--chromium/cc/animation/animation_player.h114
-rw-r--r--chromium/cc/animation/animation_player_unittest.cc336
-rw-r--r--chromium/cc/animation/animation_timeline.cc120
-rw-r--r--chromium/cc/animation/animation_timeline.h77
-rw-r--r--chromium/cc/animation/animation_timeline_unittest.cc99
-rw-r--r--chromium/cc/animation/element_animations.cc250
-rw-r--r--chromium/cc/animation/element_animations.h119
-rw-r--r--chromium/cc/animation/element_animations_unittest.cc218
-rw-r--r--chromium/cc/animation/layer_animation_controller.cc36
-rw-r--r--chromium/cc/animation/layer_animation_controller.h4
-rw-r--r--chromium/cc/animation/layer_animation_controller_unittest.cc154
-rw-r--r--chromium/cc/animation/scroll_offset_animation_curve.cc17
-rw-r--r--chromium/cc/animation/scroll_offset_animation_curve_unittest.cc23
-rw-r--r--chromium/cc/animation/transform_operation.cc4
-rw-r--r--chromium/cc/animation/transform_operations.cc36
-rw-r--r--chromium/cc/animation/transform_operations_unittest.cc148
-rw-r--r--chromium/cc/base/BUILD.gn7
-rw-r--r--chromium/cc/base/histograms.cc50
-rw-r--r--chromium/cc/base/histograms.h76
-rw-r--r--chromium/cc/base/histograms_unittest.cc65
-rw-r--r--chromium/cc/base/list_container.cc520
-rw-r--r--chromium/cc/base/list_container.h483
-rw-r--r--chromium/cc/base/list_container_unittest.cc1081
-rw-r--r--chromium/cc/base/math_util.h23
-rw-r--r--chromium/cc/base/math_util_unittest.cc54
-rw-r--r--chromium/cc/base/resource_id.h16
-rw-r--r--chromium/cc/base/sidecar_list_container.h97
-rw-r--r--chromium/cc/base/sidecar_list_container_unittest.cc198
-rw-r--r--chromium/cc/base/switches.cc7
-rw-r--r--chromium/cc/base/switches.h3
-rw-r--r--chromium/cc/base/unique_notifier.cc7
-rw-r--r--chromium/cc/base/unique_notifier.h3
-rw-r--r--chromium/cc/base/unique_notifier_unittest.cc16
-rw-r--r--chromium/cc/base/util.h31
-rw-r--r--chromium/cc/base/util_unittest.cc67
-rw-r--r--chromium/cc/blink/BUILD.gn5
-rw-r--r--chromium/cc/blink/cc_blink.gyp4
-rw-r--r--chromium/cc/blink/web_compositor_animation_player_impl.cc66
-rw-r--r--chromium/cc/blink/web_compositor_animation_player_impl.h48
-rw-r--r--chromium/cc/blink/web_compositor_animation_timeline_impl.cc46
-rw-r--r--chromium/cc/blink/web_compositor_animation_timeline_impl.h45
-rw-r--r--chromium/cc/blink/web_compositor_support_impl.cc25
-rw-r--r--chromium/cc/blink/web_compositor_support_impl.h7
-rw-r--r--chromium/cc/blink/web_content_layer_impl.cc34
-rw-r--r--chromium/cc/blink/web_content_layer_impl.h3
-rw-r--r--chromium/cc/blink/web_display_item_list_impl.cc138
-rw-r--r--chromium/cc/blink/web_display_item_list_impl.h10
-rw-r--r--chromium/cc/blink/web_external_texture_layer_impl.cc11
-rw-r--r--chromium/cc/blink/web_filter_operations_impl.cc4
-rw-r--r--chromium/cc/blink/web_filter_operations_impl.h1
-rw-r--r--chromium/cc/blink/web_image_layer_impl.cc23
-rw-r--r--chromium/cc/blink/web_layer_impl.cc16
-rw-r--r--chromium/cc/blink/web_layer_impl.h6
-rw-r--r--chromium/cc/blink/web_layer_impl_fixed_bounds_unittest.cc19
-rw-r--r--chromium/cc/blink/web_nine_patch_layer_impl.cc3
-rw-r--r--chromium/cc/blink/web_scrollbar_layer_impl.cc4
-rw-r--r--chromium/cc/cc.gyp119
-rw-r--r--chromium/cc/cc_tests.gyp42
-rw-r--r--chromium/cc/debug/debug_rect_history.cc76
-rw-r--r--chromium/cc/debug/devtools_instrumentation.h16
-rw-r--r--chromium/cc/debug/frame_rate_counter.h2
-rw-r--r--chromium/cc/debug/frame_timing_request.h4
-rw-r--r--chromium/cc/debug/frame_timing_tracker.cc27
-rw-r--r--chromium/cc/debug/frame_timing_tracker.h17
-rw-r--r--chromium/cc/debug/frame_timing_tracker_unittest.cc85
-rw-r--r--chromium/cc/debug/invalidation_benchmark.cc18
-rw-r--r--chromium/cc/debug/lap_timer.cc12
-rw-r--r--chromium/cc/debug/lap_timer.h2
-rw-r--r--chromium/cc/debug/micro_benchmark_controller_unittest.cc23
-rw-r--r--chromium/cc/debug/picture_debug_util.cc11
-rw-r--r--chromium/cc/debug/picture_record_benchmark.cc6
-rw-r--r--chromium/cc/debug/rasterize_and_record_benchmark.cc18
-rw-r--r--chromium/cc/debug/rasterize_and_record_benchmark_impl.cc26
-rw-r--r--chromium/cc/debug/rasterize_and_record_benchmark_impl.h2
-rw-r--r--chromium/cc/debug/rendering_stats_instrumentation.cc20
-rw-r--r--chromium/cc/debug/rendering_stats_instrumentation.h4
-rw-r--r--chromium/cc/debug/traced_display_item_list.cc27
-rw-r--r--chromium/cc/debug/traced_display_item_list.h42
-rw-r--r--chromium/cc/debug/traced_picture.cc10
-rw-r--r--chromium/cc/input/input_handler.h5
-rw-r--r--chromium/cc/input/layer_scroll_offset_delegate.h11
-rw-r--r--chromium/cc/input/top_controls_manager.cc3
-rw-r--r--chromium/cc/input/top_controls_manager_unittest.cc13
-rw-r--r--chromium/cc/layers/append_quads_data.h4
-rw-r--r--chromium/cc/layers/content_layer.cc139
-rw-r--r--chromium/cc/layers/content_layer.h73
-rw-r--r--chromium/cc/layers/content_layer_client.h4
-rw-r--r--chromium/cc/layers/contents_scaling_layer.cc63
-rw-r--r--chromium/cc/layers/contents_scaling_layer.h40
-rw-r--r--chromium/cc/layers/contents_scaling_layer_unittest.cc78
-rw-r--r--chromium/cc/layers/delegated_frame_provider_unittest.cc24
-rw-r--r--chromium/cc/layers/delegated_renderer_layer.cc11
-rw-r--r--chromium/cc/layers/delegated_renderer_layer.h5
-rw-r--r--chromium/cc/layers/delegated_renderer_layer_impl.cc87
-rw-r--r--chromium/cc/layers/delegated_renderer_layer_impl.h4
-rw-r--r--chromium/cc/layers/delegated_renderer_layer_impl_unittest.cc166
-rw-r--r--chromium/cc/layers/delegated_renderer_layer_unittest.cc12
-rw-r--r--chromium/cc/layers/draw_properties.h46
-rw-r--r--chromium/cc/layers/heads_up_display_layer.cc8
-rw-r--r--chromium/cc/layers/heads_up_display_layer.h5
-rw-r--r--chromium/cc/layers/heads_up_display_layer_impl.cc10
-rw-r--r--chromium/cc/layers/heads_up_display_layer_impl_unittest.cc6
-rw-r--r--chromium/cc/layers/heads_up_display_unittest.cc2
-rw-r--r--chromium/cc/layers/image_layer.cc99
-rw-r--r--chromium/cc/layers/image_layer.h56
-rw-r--r--chromium/cc/layers/io_surface_layer.cc15
-rw-r--r--chromium/cc/layers/io_surface_layer.h7
-rw-r--r--chromium/cc/layers/io_surface_layer_impl.cc6
-rw-r--r--chromium/cc/layers/io_surface_layer_impl_unittest.cc3
-rw-r--r--chromium/cc/layers/layer.cc288
-rw-r--r--chromium/cc/layers/layer.h92
-rw-r--r--chromium/cc/layers/layer_impl.cc438
-rw-r--r--chromium/cc/layers/layer_impl.h80
-rw-r--r--chromium/cc/layers/layer_impl_unittest.cc32
-rw-r--r--chromium/cc/layers/layer_iterator.h86
-rw-r--r--chromium/cc/layers/layer_iterator_unittest.cc290
-rw-r--r--chromium/cc/layers/layer_perftest.cc12
-rw-r--r--chromium/cc/layers/layer_position_constraint_unittest.cc1165
-rw-r--r--chromium/cc/layers/layer_unittest.cc249
-rw-r--r--chromium/cc/layers/layer_utils.cc14
-rw-r--r--chromium/cc/layers/nine_patch_layer.cc12
-rw-r--r--chromium/cc/layers/nine_patch_layer.h4
-rw-r--r--chromium/cc/layers/nine_patch_layer_impl.cc6
-rw-r--r--chromium/cc/layers/nine_patch_layer_impl_unittest.cc17
-rw-r--r--chromium/cc/layers/nine_patch_layer_unittest.cc18
-rw-r--r--chromium/cc/layers/painted_scrollbar_layer.cc24
-rw-r--r--chromium/cc/layers/painted_scrollbar_layer.h9
-rw-r--r--chromium/cc/layers/painted_scrollbar_layer_impl.cc7
-rw-r--r--chromium/cc/layers/painted_scrollbar_layer_impl_unittest.cc3
-rw-r--r--chromium/cc/layers/picture_image_layer.cc21
-rw-r--r--chromium/cc/layers/picture_image_layer.h7
-rw-r--r--chromium/cc/layers/picture_image_layer_impl_unittest.cc23
-rw-r--r--chromium/cc/layers/picture_image_layer_unittest.cc45
-rw-r--r--chromium/cc/layers/picture_layer.cc44
-rw-r--r--chromium/cc/layers/picture_layer.h15
-rw-r--r--chromium/cc/layers/picture_layer_impl.cc186
-rw-r--r--chromium/cc/layers/picture_layer_impl.h6
-rw-r--r--chromium/cc/layers/picture_layer_impl_perftest.cc102
-rw-r--r--chromium/cc/layers/picture_layer_impl_unittest.cc505
-rw-r--r--chromium/cc/layers/picture_layer_unittest.cc58
-rw-r--r--chromium/cc/layers/render_surface.h8
-rw-r--r--chromium/cc/layers/render_surface_impl.cc28
-rw-r--r--chromium/cc/layers/render_surface_impl.h5
-rw-r--r--chromium/cc/layers/render_surface_impl_unittest.cc3
-rw-r--r--chromium/cc/layers/render_surface_unittest.cc20
-rw-r--r--chromium/cc/layers/scrollbar_layer_impl_base.cc12
-rw-r--r--chromium/cc/layers/scrollbar_layer_impl_base.h2
-rw-r--r--chromium/cc/layers/scrollbar_layer_unittest.cc225
-rw-r--r--chromium/cc/layers/solid_color_layer.cc10
-rw-r--r--chromium/cc/layers/solid_color_layer.h4
-rw-r--r--chromium/cc/layers/solid_color_layer_impl.cc26
-rw-r--r--chromium/cc/layers/solid_color_layer_impl.h4
-rw-r--r--chromium/cc/layers/solid_color_layer_impl_unittest.cc58
-rw-r--r--chromium/cc/layers/solid_color_scrollbar_layer.cc17
-rw-r--r--chromium/cc/layers/solid_color_scrollbar_layer.h4
-rw-r--r--chromium/cc/layers/solid_color_scrollbar_layer_impl.cc4
-rw-r--r--chromium/cc/layers/solid_color_scrollbar_layer_impl_unittest.cc3
-rw-r--r--chromium/cc/layers/surface_layer.cc19
-rw-r--r--chromium/cc/layers/surface_layer.h8
-rw-r--r--chromium/cc/layers/surface_layer_impl.cc29
-rw-r--r--chromium/cc/layers/surface_layer_impl.h4
-rw-r--r--chromium/cc/layers/surface_layer_impl_unittest.cc5
-rw-r--r--chromium/cc/layers/surface_layer_unittest.cc50
-rw-r--r--chromium/cc/layers/texture_layer.cc23
-rw-r--r--chromium/cc/layers/texture_layer.h7
-rw-r--r--chromium/cc/layers/texture_layer_impl.cc30
-rw-r--r--chromium/cc/layers/texture_layer_impl.h4
-rw-r--r--chromium/cc/layers/texture_layer_impl_unittest.cc29
-rw-r--r--chromium/cc/layers/texture_layer_unittest.cc126
-rw-r--r--chromium/cc/layers/tiled_layer.cc869
-rw-r--r--chromium/cc/layers/tiled_layer.h146
-rw-r--r--chromium/cc/layers/tiled_layer_impl.cc324
-rw-r--r--chromium/cc/layers/tiled_layer_impl.h87
-rw-r--r--chromium/cc/layers/tiled_layer_impl_unittest.cc389
-rw-r--r--chromium/cc/layers/tiled_layer_unittest.cc1762
-rw-r--r--chromium/cc/layers/ui_resource_layer.cc14
-rw-r--r--chromium/cc/layers/ui_resource_layer.h4
-rw-r--r--chromium/cc/layers/ui_resource_layer_impl.cc6
-rw-r--r--chromium/cc/layers/ui_resource_layer_impl_unittest.cc21
-rw-r--r--chromium/cc/layers/ui_resource_layer_unittest.cc42
-rw-r--r--chromium/cc/layers/video_frame_provider_client_impl.h4
-rw-r--r--chromium/cc/layers/video_frame_provider_client_impl_unittest.cc166
-rw-r--r--chromium/cc/layers/video_layer.cc13
-rw-r--r--chromium/cc/layers/video_layer.h10
-rw-r--r--chromium/cc/layers/video_layer_impl.cc67
-rw-r--r--chromium/cc/layers/video_layer_impl.h13
-rw-r--r--chromium/cc/layers/video_layer_impl_unittest.cc49
-rw-r--r--chromium/cc/layers/viewport.cc79
-rw-r--r--chromium/cc/layers/viewport.h23
-rw-r--r--chromium/cc/output/begin_frame_args.cc8
-rw-r--r--chromium/cc/output/begin_frame_args.h1
-rw-r--r--chromium/cc/output/begin_frame_args_unittest.cc4
-rw-r--r--chromium/cc/output/bsp_walk_action.cc4
-rw-r--r--chromium/cc/output/context_provider.h3
-rw-r--r--chromium/cc/output/delegating_renderer.cc23
-rw-r--r--chromium/cc/output/direct_renderer.cc24
-rw-r--r--chromium/cc/output/gl_renderer.cc513
-rw-r--r--chromium/cc/output/gl_renderer.h24
-rw-r--r--chromium/cc/output/gl_renderer_unittest.cc189
-rw-r--r--chromium/cc/output/latency_info_swap_promise.cc8
-rw-r--r--chromium/cc/output/latency_info_swap_promise.h1
-rw-r--r--chromium/cc/output/managed_memory_policy.cc18
-rw-r--r--chromium/cc/output/managed_memory_policy.h2
-rw-r--r--chromium/cc/output/output_surface.cc32
-rw-r--r--chromium/cc/output/output_surface.h7
-rw-r--r--chromium/cc/output/output_surface_unittest.cc1
-rw-r--r--chromium/cc/output/overlay_candidate.h2
-rw-r--r--chromium/cc/output/overlay_processor.cc15
-rw-r--r--chromium/cc/output/overlay_processor.h3
-rw-r--r--chromium/cc/output/overlay_strategy_common.cc52
-rw-r--r--chromium/cc/output/overlay_strategy_common.h15
-rw-r--r--chromium/cc/output/overlay_strategy_single_on_top.cc61
-rw-r--r--chromium/cc/output/overlay_strategy_single_on_top.h11
-rw-r--r--chromium/cc/output/overlay_strategy_underlay.cc33
-rw-r--r--chromium/cc/output/overlay_strategy_underlay.h11
-rw-r--r--chromium/cc/output/overlay_unittest.cc94
-rw-r--r--chromium/cc/output/program_binding.cc5
-rw-r--r--chromium/cc/output/program_binding.h8
-rw-r--r--chromium/cc/output/renderer_pixeltest.cc394
-rw-r--r--chromium/cc/output/renderer_settings.cc1
-rw-r--r--chromium/cc/output/renderer_settings.h1
-rw-r--r--chromium/cc/output/renderer_unittest.cc5
-rw-r--r--chromium/cc/output/software_renderer.cc72
-rw-r--r--chromium/cc/output/software_renderer.h2
-rw-r--r--chromium/cc/output/software_renderer_unittest.cc55
-rw-r--r--chromium/cc/output/swap_promise.h2
-rw-r--r--chromium/cc/output/texture_mailbox_deleter.cc10
-rw-r--r--chromium/cc/output/texture_mailbox_deleter.h2
-rw-r--r--chromium/cc/output/texture_mailbox_deleter_unittest.cc26
-rw-r--r--chromium/cc/output/vsync_parameter_observer.h18
-rw-r--r--chromium/cc/playback/clip_display_item.cc17
-rw-r--r--chromium/cc/playback/clip_display_item.h9
-rw-r--r--chromium/cc/playback/clip_path_display_item.cc16
-rw-r--r--chromium/cc/playback/clip_path_display_item.h9
-rw-r--r--chromium/cc/playback/compositing_display_item.cc19
-rw-r--r--chromium/cc/playback/compositing_display_item.h9
-rw-r--r--chromium/cc/playback/display_item.h17
-rw-r--r--chromium/cc/playback/display_item_list.cc185
-rw-r--r--chromium/cc/playback/display_item_list.h60
-rw-r--r--chromium/cc/playback/display_item_list_settings.cc18
-rw-r--r--chromium/cc/playback/display_item_list_settings.h29
-rw-r--r--chromium/cc/playback/display_item_list_unittest.cc171
-rw-r--r--chromium/cc/playback/display_list_raster_source.cc59
-rw-r--r--chromium/cc/playback/display_list_raster_source.h10
-rw-r--r--chromium/cc/playback/display_list_raster_source_unittest.cc556
-rw-r--r--chromium/cc/playback/display_list_recording_source.cc110
-rw-r--r--chromium/cc/playback/display_list_recording_source.h14
-rw-r--r--chromium/cc/playback/display_list_recording_source_unittest.cc146
-rw-r--r--chromium/cc/playback/drawing_display_item.cc15
-rw-r--r--chromium/cc/playback/drawing_display_item.h5
-rw-r--r--chromium/cc/playback/filter_display_item.cc15
-rw-r--r--chromium/cc/playback/filter_display_item.h9
-rw-r--r--chromium/cc/playback/float_clip_display_item.cc14
-rw-r--r--chromium/cc/playback/float_clip_display_item.h9
-rw-r--r--chromium/cc/playback/picture.cc2
-rw-r--r--chromium/cc/playback/picture_pile.cc15
-rw-r--r--chromium/cc/playback/picture_pile_impl.cc14
-rw-r--r--chromium/cc/playback/picture_pile_impl.h7
-rw-r--r--chromium/cc/playback/picture_pile_impl_perftest.cc3
-rw-r--r--chromium/cc/playback/picture_pile_impl_unittest.cc7
-rw-r--r--chromium/cc/playback/pixel_ref_map.cc32
-rw-r--r--chromium/cc/playback/raster_source.h3
-rw-r--r--chromium/cc/playback/raster_source_helper.cc38
-rw-r--r--chromium/cc/playback/raster_source_helper.h3
-rw-r--r--chromium/cc/playback/recording_source_unittest.cc5
-rw-r--r--chromium/cc/playback/transform_display_item.cc14
-rw-r--r--chromium/cc/playback/transform_display_item.h9
-rw-r--r--chromium/cc/quads/checkerboard_draw_quad.cc3
-rw-r--r--chromium/cc/quads/checkerboard_draw_quad.h2
-rw-r--r--chromium/cc/quads/debug_border_draw_quad.cc3
-rw-r--r--chromium/cc/quads/debug_border_draw_quad.h2
-rw-r--r--chromium/cc/quads/draw_polygon.cc4
-rw-r--r--chromium/cc/quads/draw_polygon.h2
-rw-r--r--chromium/cc/quads/draw_quad.cc26
-rw-r--r--chromium/cc/quads/draw_quad.h45
-rw-r--r--chromium/cc/quads/draw_quad_perftest.cc113
-rw-r--r--chromium/cc/quads/draw_quad_unittest.cc200
-rw-r--r--chromium/cc/quads/io_surface_draw_quad.cc18
-rw-r--r--chromium/cc/quads/io_surface_draw_quad.h7
-rw-r--r--chromium/cc/quads/list_container.cc720
-rw-r--r--chromium/cc/quads/list_container.h242
-rw-r--r--chromium/cc/quads/list_container_unittest.cc667
-rw-r--r--chromium/cc/quads/picture_draw_quad.cc6
-rw-r--r--chromium/cc/quads/picture_draw_quad.h3
-rw-r--r--chromium/cc/quads/render_pass.cc15
-rw-r--r--chromium/cc/quads/render_pass.h9
-rw-r--r--chromium/cc/quads/render_pass_draw_quad.cc25
-rw-r--r--chromium/cc/quads/render_pass_draw_quad.h11
-rw-r--r--chromium/cc/quads/render_pass_id.cc3
-rw-r--r--chromium/cc/quads/render_pass_id.h5
-rw-r--r--chromium/cc/quads/render_pass_unittest.cc7
-rw-r--r--chromium/cc/quads/shared_quad_state.cc20
-rw-r--r--chromium/cc/quads/shared_quad_state.h19
-rw-r--r--chromium/cc/quads/solid_color_draw_quad.cc3
-rw-r--r--chromium/cc/quads/solid_color_draw_quad.h2
-rw-r--r--chromium/cc/quads/stream_video_draw_quad.cc29
-rw-r--r--chromium/cc/quads/stream_video_draw_quad.h23
-rw-r--r--chromium/cc/quads/surface_draw_quad.cc3
-rw-r--r--chromium/cc/quads/surface_draw_quad.h2
-rw-r--r--chromium/cc/quads/texture_draw_quad.cc25
-rw-r--r--chromium/cc/quads/texture_draw_quad.h27
-rw-r--r--chromium/cc/quads/tile_draw_quad.cc16
-rw-r--r--chromium/cc/quads/tile_draw_quad.h8
-rw-r--r--chromium/cc/quads/yuv_video_draw_quad.cc46
-rw-r--r--chromium/cc/quads/yuv_video_draw_quad.h24
-rw-r--r--chromium/cc/raster/bitmap_tile_task_worker_pool.cc46
-rw-r--r--chromium/cc/raster/bitmap_tile_task_worker_pool.h7
-rw-r--r--chromium/cc/raster/gpu_rasterizer.cc6
-rw-r--r--chromium/cc/raster/gpu_rasterizer.h3
-rw-r--r--chromium/cc/raster/gpu_tile_task_worker_pool.cc45
-rw-r--r--chromium/cc/raster/gpu_tile_task_worker_pool.h7
-rw-r--r--chromium/cc/raster/one_copy_tile_task_worker_pool.cc301
-rw-r--r--chromium/cc/raster/one_copy_tile_task_worker_pool.h53
-rw-r--r--chromium/cc/raster/pixel_buffer_tile_task_worker_pool.cc62
-rw-r--r--chromium/cc/raster/pixel_buffer_tile_task_worker_pool.h9
-rw-r--r--chromium/cc/raster/raster_buffer.h4
-rw-r--r--chromium/cc/raster/task_graph_runner.h8
-rw-r--r--chromium/cc/raster/texture_compressor_etc1_unittest.cc1
-rw-r--r--chromium/cc/raster/tile_task_runner.h9
-rw-r--r--chromium/cc/raster/tile_task_worker_pool.cc28
-rw-r--r--chromium/cc/raster/tile_task_worker_pool.h21
-rw-r--r--chromium/cc/raster/tile_task_worker_pool_perftest.cc21
-rw-r--r--chromium/cc/raster/tile_task_worker_pool_unittest.cc46
-rw-r--r--chromium/cc/raster/zero_copy_tile_task_worker_pool.cc28
-rw-r--r--chromium/cc/raster/zero_copy_tile_task_worker_pool.h7
-rw-r--r--chromium/cc/resources/bitmap_content_layer_updater.cc107
-rw-r--r--chromium/cc/resources/bitmap_content_layer_updater.h78
-rw-r--r--chromium/cc/resources/bitmap_skpicture_content_layer_updater.cc79
-rw-r--r--chromium/cc/resources/bitmap_skpicture_content_layer_updater.h57
-rw-r--r--chromium/cc/resources/content_layer_updater.cc118
-rw-r--r--chromium/cc/resources/content_layer_updater.h66
-rw-r--r--chromium/cc/resources/image_layer_updater.cc68
-rw-r--r--chromium/cc/resources/image_layer_updater.h60
-rw-r--r--chromium/cc/resources/layer_painter.h27
-rw-r--r--chromium/cc/resources/layer_updater.cc16
-rw-r--r--chromium/cc/resources/layer_updater.h76
-rw-r--r--chromium/cc/resources/memory_history.cc17
-rw-r--r--chromium/cc/resources/memory_history.h3
-rw-r--r--chromium/cc/resources/prioritized_resource.cc203
-rw-r--r--chromium/cc/resources/prioritized_resource.h184
-rw-r--r--chromium/cc/resources/prioritized_resource_manager.cc547
-rw-r--r--chromium/cc/resources/prioritized_resource_manager.h235
-rw-r--r--chromium/cc/resources/prioritized_resource_unittest.cc1117
-rw-r--r--chromium/cc/resources/priority_calculator.cc116
-rw-r--r--chromium/cc/resources/priority_calculator.h47
-rw-r--r--chromium/cc/resources/resource.cc17
-rw-r--r--chromium/cc/resources/resource.h41
-rw-r--r--chromium/cc/resources/resource_pool.cc70
-rw-r--r--chromium/cc/resources/resource_pool.h17
-rw-r--r--chromium/cc/resources/resource_pool_unittest.cc141
-rw-r--r--chromium/cc/resources/resource_provider.cc414
-rw-r--r--chromium/cc/resources/resource_provider.h92
-rw-r--r--chromium/cc/resources/resource_provider_unittest.cc786
-rw-r--r--chromium/cc/resources/resource_update.cc32
-rw-r--r--chromium/cc/resources/resource_update.h37
-rw-r--r--chromium/cc/resources/resource_update_controller.cc164
-rw-r--r--chromium/cc/resources/resource_update_controller.h88
-rw-r--r--chromium/cc/resources/resource_update_controller_unittest.cc516
-rw-r--r--chromium/cc/resources/resource_update_queue.cc56
-rw-r--r--chromium/cc/resources/resource_update_queue.h43
-rw-r--r--chromium/cc/resources/returned_resource.h3
-rw-r--r--chromium/cc/resources/scoped_resource_unittest.cc38
-rw-r--r--chromium/cc/resources/skpicture_content_layer_updater.cc50
-rw-r--r--chromium/cc/resources/skpicture_content_layer_updater.h42
-rw-r--r--chromium/cc/resources/texture_mailbox.cc21
-rw-r--r--chromium/cc/resources/texture_mailbox.h14
-rw-r--r--chromium/cc/resources/texture_uploader.cc315
-rw-r--r--chromium/cc/resources/texture_uploader.h118
-rw-r--r--chromium/cc/resources/texture_uploader_unittest.cc255
-rw-r--r--chromium/cc/resources/transferable_resource.cc1
-rw-r--r--chromium/cc/resources/transferable_resource.h4
-rw-r--r--chromium/cc/resources/ui_resource_bitmap.cc3
-rw-r--r--chromium/cc/resources/video_resource_updater.cc115
-rw-r--r--chromium/cc/resources/video_resource_updater.h7
-rw-r--r--chromium/cc/resources/video_resource_updater_unittest.cc42
-rw-r--r--chromium/cc/scheduler/begin_frame_source.cc79
-rw-r--r--chromium/cc/scheduler/begin_frame_source.h69
-rw-r--r--chromium/cc/scheduler/begin_frame_source_unittest.cc96
-rw-r--r--chromium/cc/scheduler/begin_frame_tracker.cc123
-rw-r--r--chromium/cc/scheduler/begin_frame_tracker.h97
-rw-r--r--chromium/cc/scheduler/compositor_timing_history.cc217
-rw-r--r--chromium/cc/scheduler/compositor_timing_history.h75
-rw-r--r--chromium/cc/scheduler/compositor_timing_history_unittest.cc140
-rw-r--r--chromium/cc/scheduler/delay_based_time_source.cc164
-rw-r--r--chromium/cc/scheduler/delay_based_time_source.h96
-rw-r--r--chromium/cc/scheduler/delay_based_time_source_unittest.cc72
-rw-r--r--chromium/cc/scheduler/scheduler.cc379
-rw-r--r--chromium/cc/scheduler/scheduler.h114
-rw-r--r--chromium/cc/scheduler/scheduler_settings.cc16
-rw-r--r--chromium/cc/scheduler/scheduler_settings.h11
-rw-r--r--chromium/cc/scheduler/scheduler_state_machine.cc145
-rw-r--r--chromium/cc/scheduler/scheduler_state_machine.h17
-rw-r--r--chromium/cc/scheduler/scheduler_state_machine_unittest.cc212
-rw-r--r--chromium/cc/scheduler/scheduler_unittest.cc1338
-rw-r--r--chromium/cc/surfaces/BUILD.gn3
-rw-r--r--chromium/cc/surfaces/OWNERS2
-rw-r--r--chromium/cc/surfaces/display.cc111
-rw-r--r--chromium/cc/surfaces/display.h19
-rw-r--r--chromium/cc/surfaces/display_client.h3
-rw-r--r--chromium/cc/surfaces/display_scheduler.cc286
-rw-r--r--chromium/cc/surfaces/display_scheduler.h93
-rw-r--r--chromium/cc/surfaces/display_scheduler_unittest.cc347
-rw-r--r--chromium/cc/surfaces/display_unittest.cc248
-rw-r--r--chromium/cc/surfaces/onscreen_display_client.cc72
-rw-r--r--chromium/cc/surfaces/onscreen_display_client.h23
-rw-r--r--chromium/cc/surfaces/surface.cc40
-rw-r--r--chromium/cc/surfaces/surface.h13
-rw-r--r--chromium/cc/surfaces/surface_aggregator.cc293
-rw-r--r--chromium/cc/surfaces/surface_aggregator.h21
-rw-r--r--chromium/cc/surfaces/surface_aggregator_perftest.cc10
-rw-r--r--chromium/cc/surfaces/surface_aggregator_test_helpers.cc17
-rw-r--r--chromium/cc/surfaces/surface_aggregator_test_helpers.h6
-rw-r--r--chromium/cc/surfaces/surface_aggregator_unittest.cc139
-rw-r--r--chromium/cc/surfaces/surface_display_output_surface.cc4
-rw-r--r--chromium/cc/surfaces/surface_display_output_surface_unittest.cc19
-rw-r--r--chromium/cc/surfaces/surface_factory_unittest.cc132
-rw-r--r--chromium/cc/surfaces/surface_id_allocator.cc15
-rw-r--r--chromium/cc/surfaces/surface_id_allocator.h12
-rw-r--r--chromium/cc/surfaces/surface_manager.cc57
-rw-r--r--chromium/cc/surfaces/surface_manager.h15
-rw-r--r--chromium/cc/surfaces/surface_resource_holder.cc2
-rw-r--r--chromium/cc/surfaces/surface_resource_holder.h6
-rw-r--r--chromium/cc/surfaces/surfaces_pixeltest.cc14
-rw-r--r--chromium/cc/tiles/layer_tiling_data.cc116
-rw-r--r--chromium/cc/tiles/layer_tiling_data.h102
-rw-r--r--chromium/cc/tiles/picture_layer_tiling.cc117
-rw-r--r--chromium/cc/tiles/picture_layer_tiling.h56
-rw-r--r--chromium/cc/tiles/picture_layer_tiling_perftest.cc11
-rw-r--r--chromium/cc/tiles/picture_layer_tiling_set.cc55
-rw-r--r--chromium/cc/tiles/picture_layer_tiling_set.h15
-rw-r--r--chromium/cc/tiles/picture_layer_tiling_set_unittest.cc83
-rw-r--r--chromium/cc/tiles/picture_layer_tiling_unittest.cc1
-rw-r--r--chromium/cc/tiles/tile.cc15
-rw-r--r--chromium/cc/tiles/tile.h17
-rw-r--r--chromium/cc/tiles/tile_draw_info.cc11
-rw-r--r--chromium/cc/tiles/tile_draw_info.h15
-rw-r--r--chromium/cc/tiles/tile_manager.cc339
-rw-r--r--chromium/cc/tiles/tile_manager.h65
-rw-r--r--chromium/cc/tiles/tile_manager_perftest.cc22
-rw-r--r--chromium/cc/tiles/tile_manager_unittest.cc151
-rw-r--r--chromium/cc/tiles/tile_priority.cc10
-rw-r--r--chromium/cc/tiles/tiling_set_eviction_queue.cc30
-rw-r--r--chromium/cc/tiles/tiling_set_raster_queue_all.cc136
-rw-r--r--chromium/cc/tiles/tiling_set_raster_queue_all.h8
-rw-r--r--chromium/cc/tiles/tiling_set_raster_queue_required.cc2
-rw-r--r--chromium/cc/trees/blocking_task_runner.cc1
-rw-r--r--chromium/cc/trees/damage_tracker.cc6
-rw-r--r--chromium/cc/trees/damage_tracker_unittest.cc32
-rw-r--r--chromium/cc/trees/draw_property_utils.cc60
-rw-r--r--chromium/cc/trees/draw_property_utils.h51
-rw-r--r--chromium/cc/trees/layer_tree_host.cc572
-rw-r--r--chromium/cc/trees/layer_tree_host.h103
-rw-r--r--chromium/cc/trees/layer_tree_host_client.h7
-rw-r--r--chromium/cc/trees/layer_tree_host_common.cc446
-rw-r--r--chromium/cc/trees/layer_tree_host_common.h31
-rw-r--r--chromium/cc/trees/layer_tree_host_common_perftest.cc87
-rw-r--r--chromium/cc/trees/layer_tree_host_common_unittest.cc3350
-rw-r--r--chromium/cc/trees/layer_tree_host_impl.cc831
-rw-r--r--chromium/cc/trees/layer_tree_host_impl.h107
-rw-r--r--chromium/cc/trees/layer_tree_host_impl_unittest.cc998
-rw-r--r--chromium/cc/trees/layer_tree_host_perftest.cc36
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_blending.cc6
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_masks.cc60
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_readback.cc12
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc8
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc214
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest.cc2004
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_animation.cc230
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_animation_timelines.cc923
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_context.cc448
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc168
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_damage.cc74
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_delegated.cc53
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_no_message_loop.cc248
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_occlusion.cc32
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_picture.cc79
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_proxy.cc16
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_scroll.cc131
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_video.cc6
-rw-r--r--chromium/cc/trees/layer_tree_impl.cc349
-rw-r--r--chromium/cc/trees/layer_tree_impl.h46
-rw-r--r--chromium/cc/trees/layer_tree_impl_unittest.cc196
-rw-r--r--chromium/cc/trees/layer_tree_settings.cc28
-rw-r--r--chromium/cc/trees/layer_tree_settings.h17
-rw-r--r--chromium/cc/trees/mutator_host_client.h45
-rw-r--r--chromium/cc/trees/occlusion_tracker.cc196
-rw-r--r--chromium/cc/trees/occlusion_tracker.h24
-rw-r--r--chromium/cc/trees/occlusion_tracker_perftest.cc38
-rw-r--r--chromium/cc/trees/occlusion_tracker_unittest.cc1727
-rw-r--r--chromium/cc/trees/property_tree.cc139
-rw-r--r--chromium/cc/trees/property_tree.h95
-rw-r--r--chromium/cc/trees/property_tree_builder.cc159
-rw-r--r--chromium/cc/trees/property_tree_builder.h4
-rw-r--r--chromium/cc/trees/property_tree_unittest.cc120
-rw-r--r--chromium/cc/trees/proxy.cc1
-rw-r--r--chromium/cc/trees/proxy.h3
-rw-r--r--chromium/cc/trees/proxy_timing_history.cc124
-rw-r--r--chromium/cc/trees/proxy_timing_history.h46
-rw-r--r--chromium/cc/trees/single_thread_proxy.cc201
-rw-r--r--chromium/cc/trees/single_thread_proxy.h18
-rw-r--r--chromium/cc/trees/thread_proxy.cc232
-rw-r--r--chromium/cc/trees/thread_proxy.h44
-rw-r--r--chromium/cc/trees/tree_synchronizer.cc8
-rw-r--r--chromium/cc/trees/tree_synchronizer.h2
-rw-r--r--chromium/cc/trees/tree_synchronizer_unittest.cc143
515 files changed, 24652 insertions, 27473 deletions
diff --git a/chromium/cc/BUILD.gn b/chromium/cc/BUILD.gn
index 7001440e61a..5cd45c2749c 100644
--- a/chromium/cc/BUILD.gn
+++ b/chromium/cc/BUILD.gn
@@ -13,10 +13,18 @@ component("cc") {
"animation/animation_delegate.h",
"animation/animation_events.cc",
"animation/animation_events.h",
+ "animation/animation_host.cc",
+ "animation/animation_host.h",
"animation/animation_id_provider.cc",
"animation/animation_id_provider.h",
+ "animation/animation_player.cc",
+ "animation/animation_player.h",
"animation/animation_registrar.cc",
"animation/animation_registrar.h",
+ "animation/animation_timeline.cc",
+ "animation/animation_timeline.h",
+ "animation/element_animations.cc",
+ "animation/element_animations.h",
"animation/keyframed_animation_curve.cc",
"animation/keyframed_animation_curve.h",
"animation/layer_animation_controller.cc",
@@ -82,6 +90,8 @@ component("cc") {
"debug/rendering_stats_instrumentation.cc",
"debug/rendering_stats_instrumentation.h",
"debug/ring_buffer.h",
+ "debug/traced_display_item_list.cc",
+ "debug/traced_display_item_list.h",
"debug/traced_picture.cc",
"debug/traced_picture.h",
"debug/traced_value.cc",
@@ -104,11 +114,7 @@ component("cc") {
"input/top_controls_manager.h",
"input/top_controls_manager_client.h",
"layers/append_quads_data.h",
- "layers/content_layer.cc",
- "layers/content_layer.h",
"layers/content_layer_client.h",
- "layers/contents_scaling_layer.cc",
- "layers/contents_scaling_layer.h",
"layers/delegated_frame_provider.cc",
"layers/delegated_frame_provider.h",
"layers/delegated_frame_resource_collection.cc",
@@ -122,8 +128,6 @@ component("cc") {
"layers/heads_up_display_layer.h",
"layers/heads_up_display_layer_impl.cc",
"layers/heads_up_display_layer_impl.h",
- "layers/image_layer.cc",
- "layers/image_layer.h",
"layers/io_surface_layer.cc",
"layers/io_surface_layer.h",
"layers/io_surface_layer_impl.cc",
@@ -182,10 +186,6 @@ component("cc") {
"layers/texture_layer_client.h",
"layers/texture_layer_impl.cc",
"layers/texture_layer_impl.h",
- "layers/tiled_layer.cc",
- "layers/tiled_layer.h",
- "layers/tiled_layer_impl.cc",
- "layers/tiled_layer_impl.h",
"layers/ui_resource_layer.cc",
"layers/ui_resource_layer.h",
"layers/ui_resource_layer_impl.cc",
@@ -282,7 +282,6 @@ component("cc") {
"output/texture_mailbox_deleter.h",
"output/viewport_selection_bound.cc",
"output/viewport_selection_bound.h",
- "output/vsync_parameter_observer.h",
"playback/clip_display_item.cc",
"playback/clip_display_item.h",
"playback/clip_path_display_item.cc",
@@ -293,6 +292,8 @@ component("cc") {
"playback/display_item.h",
"playback/display_item_list.cc",
"playback/display_item_list.h",
+ "playback/display_item_list_settings.cc",
+ "playback/display_item_list_settings.h",
"playback/display_list_raster_source.cc",
"playback/display_list_raster_source.h",
"playback/display_list_recording_source.cc",
@@ -332,8 +333,6 @@ component("cc") {
"quads/io_surface_draw_quad.h",
"quads/largest_draw_quad.cc",
"quads/largest_draw_quad.h",
- "quads/list_container.cc",
- "quads/list_container.h",
"quads/picture_draw_quad.cc",
"quads/picture_draw_quad.h",
"quads/render_pass.cc",
@@ -382,28 +381,10 @@ component("cc") {
"raster/tile_task_worker_pool.h",
"raster/zero_copy_tile_task_worker_pool.cc",
"raster/zero_copy_tile_task_worker_pool.h",
- "resources/bitmap_content_layer_updater.cc",
- "resources/bitmap_content_layer_updater.h",
- "resources/bitmap_skpicture_content_layer_updater.cc",
- "resources/bitmap_skpicture_content_layer_updater.h",
- "resources/content_layer_updater.cc",
- "resources/content_layer_updater.h",
- "resources/image_layer_updater.cc",
- "resources/image_layer_updater.h",
- "resources/layer_painter.h",
- "resources/layer_updater.cc",
- "resources/layer_updater.h",
"resources/memory_history.cc",
"resources/memory_history.h",
"resources/platform_color.h",
- "resources/prioritized_resource.cc",
- "resources/prioritized_resource.h",
- "resources/prioritized_resource_manager.cc",
- "resources/prioritized_resource_manager.h",
- "resources/priority_calculator.cc",
- "resources/priority_calculator.h",
"resources/release_callback.h",
- "resources/resource.cc",
"resources/resource.h",
"resources/resource_format.cc",
"resources/resource_format.h",
@@ -411,12 +392,6 @@ component("cc") {
"resources/resource_pool.h",
"resources/resource_provider.cc",
"resources/resource_provider.h",
- "resources/resource_update.cc",
- "resources/resource_update.h",
- "resources/resource_update_controller.cc",
- "resources/resource_update_controller.h",
- "resources/resource_update_queue.cc",
- "resources/resource_update_queue.h",
"resources/returned_resource.h",
"resources/scoped_resource.cc",
"resources/scoped_resource.h",
@@ -429,12 +404,8 @@ component("cc") {
"resources/single_release_callback.h",
"resources/single_release_callback_impl.cc",
"resources/single_release_callback_impl.h",
- "resources/skpicture_content_layer_updater.cc",
- "resources/skpicture_content_layer_updater.h",
"resources/texture_mailbox.cc",
"resources/texture_mailbox.h",
- "resources/texture_uploader.cc",
- "resources/texture_uploader.h",
"resources/transferable_resource.cc",
"resources/transferable_resource.h",
"resources/ui_resource_bitmap.cc",
@@ -446,7 +417,11 @@ component("cc") {
"resources/video_resource_updater.h",
"scheduler/begin_frame_source.cc",
"scheduler/begin_frame_source.h",
+ "scheduler/begin_frame_tracker.cc",
+ "scheduler/begin_frame_tracker.h",
"scheduler/commit_earlyout_reason.h",
+ "scheduler/compositor_timing_history.cc",
+ "scheduler/compositor_timing_history.h",
"scheduler/delay_based_time_source.cc",
"scheduler/delay_based_time_source.h",
"scheduler/draw_result.h",
@@ -459,8 +434,6 @@ component("cc") {
"scheduler/video_frame_controller.h",
"tiles/eviction_tile_priority_queue.cc",
"tiles/eviction_tile_priority_queue.h",
- "tiles/layer_tiling_data.cc",
- "tiles/layer_tiling_data.h",
"tiles/picture_layer_tiling.cc",
"tiles/picture_layer_tiling.h",
"tiles/picture_layer_tiling_set.cc",
@@ -507,6 +480,7 @@ component("cc") {
"trees/layer_tree_impl.h",
"trees/layer_tree_settings.cc",
"trees/layer_tree_settings.h",
+ "trees/mutator_host_client.h",
"trees/occlusion.cc",
"trees/occlusion.h",
"trees/occlusion_tracker.cc",
@@ -517,8 +491,6 @@ component("cc") {
"trees/property_tree_builder.h",
"trees/proxy.cc",
"trees/proxy.h",
- "trees/proxy_timing_history.cc",
- "trees/proxy_timing_history.h",
"trees/scoped_abort_remaining_swap_promises.h",
"trees/single_thread_proxy.cc",
"trees/single_thread_proxy.h",
@@ -530,8 +502,12 @@ component("cc") {
"trees/tree_synchronizer.h",
]
- # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
- configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
+ if (target_cpu == "x86" || target_cpu == "x64") {
+ sources += [
+ "raster/texture_compressor_etc1_sse.cc",
+ "raster/texture_compressor_etc1_sse.h",
+ ]
+ }
public_deps = [
"//cc/base",
@@ -540,7 +516,6 @@ component("cc") {
deps = [
"//base",
"//base/third_party/dynamic_annotations",
- "//cc:cc_opts",
"//cc/surfaces:surface_id",
"//gpu",
"//gpu/command_buffer/client:gles2_interface",
@@ -558,51 +533,19 @@ component("cc") {
}
}
-source_set("cc_opts") {
- public_deps = [
- "//cc:cc_opts_sse",
- ]
-}
-
-source_set("cc_opts_sse") {
- if (target_cpu == "x86" || target_cpu == "x64") {
- deps = [
- "//base",
- ]
-
- defines = [ "CC_IMPLEMENTATION=1" ]
-
- if (!is_debug && (is_win || is_android)) {
- configs -= [ "//build/config/compiler:optimize" ]
- configs += [ "//build/config/compiler:optimize_max" ]
- }
-
- sources = [
- "raster/texture_compressor.h",
- "raster/texture_compressor_etc1.h",
- "raster/texture_compressor_etc1_sse.cc",
- "raster/texture_compressor_etc1_sse.h",
- ]
-
- cflags = [ "-msse2" ]
- }
-}
-
source_set("test_support") {
testonly = true
sources = [
"test/animation_test_common.cc",
"test/animation_test_common.h",
+ "test/animation_timelines_test_common.cc",
+ "test/animation_timelines_test_common.h",
"test/begin_frame_args_test.cc",
"test/begin_frame_args_test.h",
"test/failure_output_surface.cc",
"test/failure_output_surface.h",
- "test/fake_content_layer.cc",
- "test/fake_content_layer.h",
"test/fake_content_layer_client.cc",
"test/fake_content_layer_client.h",
- "test/fake_content_layer_impl.cc",
- "test/fake_content_layer_impl.h",
"test/fake_delegated_renderer_layer.cc",
"test/fake_delegated_renderer_layer.h",
"test/fake_delegated_renderer_layer_impl.cc",
@@ -640,6 +583,7 @@ source_set("test_support") {
"test/fake_renderer_client.cc",
"test/fake_renderer_client.h",
"test/fake_rendering_stats_instrumentation.h",
+ "test/fake_resource_provider.h",
"test/fake_scoped_ui_resource.cc",
"test/fake_scoped_ui_resource.h",
"test/fake_scrollbar.cc",
@@ -654,7 +598,6 @@ source_set("test_support") {
"test/fake_video_frame_provider.h",
"test/geometry_test_utils.cc",
"test/geometry_test_utils.h",
- "test/impl_side_painting_settings.h",
"test/layer_test_common.cc",
"test/layer_test_common.h",
"test/layer_tree_host_common_test.cc",
@@ -706,8 +649,6 @@ source_set("test_support") {
"test/test_image_factory.h",
"test/test_in_process_context_provider.cc",
"test/test_in_process_context_provider.h",
- "test/test_now_source.cc",
- "test/test_now_source.h",
"test/test_occlusion_tracker.h",
"test/test_shared_bitmap_manager.cc",
"test/test_shared_bitmap_manager.h",
@@ -719,12 +660,8 @@ source_set("test_support") {
"test/test_tile_priorities.h",
"test/test_web_graphics_context_3d.cc",
"test/test_web_graphics_context_3d.h",
- "test/tiled_layer_test_common.cc",
- "test/tiled_layer_test_common.h",
]
- configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
-
include_dirs = [
".",
"test",
@@ -760,7 +697,11 @@ source_set("test_support") {
test("cc_unittests") {
sources = [
+ "animation/animation_host_unittest.cc",
+ "animation/animation_player_unittest.cc",
+ "animation/animation_timeline_unittest.cc",
"animation/animation_unittest.cc",
+ "animation/element_animations_unittest.cc",
"animation/keyframed_animation_curve_unittest.cc",
"animation/layer_animation_controller_unittest.cc",
"animation/scroll_offset_animation_curve_unittest.cc",
@@ -768,17 +709,18 @@ test("cc_unittests") {
"animation/scrollbar_animation_controller_thinning_unittest.cc",
"animation/transform_operations_unittest.cc",
"base/float_quad_unittest.cc",
+ "base/histograms_unittest.cc",
+ "base/list_container_unittest.cc",
"base/math_util_unittest.cc",
"base/region_unittest.cc",
"base/rolling_time_delta_history_unittest.cc",
"base/scoped_ptr_vector_unittest.cc",
+ "base/sidecar_list_container_unittest.cc",
"base/simple_enclosed_region_unittest.cc",
"base/tiling_data_unittest.cc",
- "base/util_unittest.cc",
"debug/frame_timing_tracker_unittest.cc",
"debug/micro_benchmark_controller_unittest.cc",
"input/top_controls_manager_unittest.cc",
- "layers/contents_scaling_layer_unittest.cc",
"layers/delegated_frame_provider_unittest.cc",
"layers/delegated_frame_resource_collection_unittest.cc",
"layers/delegated_renderer_layer_impl_unittest.cc",
@@ -807,10 +749,9 @@ test("cc_unittests") {
"layers/surface_layer_unittest.cc",
"layers/texture_layer_impl_unittest.cc",
"layers/texture_layer_unittest.cc",
- "layers/tiled_layer_impl_unittest.cc",
- "layers/tiled_layer_unittest.cc",
"layers/ui_resource_layer_impl_unittest.cc",
"layers/ui_resource_layer_unittest.cc",
+ "layers/video_frame_provider_client_impl_unittest.cc",
"layers/video_layer_impl_unittest.cc",
"output/begin_frame_args_unittest.cc",
"output/delegating_renderer_unittest.cc",
@@ -825,6 +766,7 @@ test("cc_unittests") {
"output/software_renderer_unittest.cc",
"output/texture_mailbox_deleter_unittest.cc",
"playback/display_item_list_unittest.cc",
+ "playback/display_list_raster_source_unittest.cc",
"playback/display_list_recording_source_unittest.cc",
"playback/picture_pile_impl_unittest.cc",
"playback/picture_pile_unittest.cc",
@@ -832,20 +774,18 @@ test("cc_unittests") {
"playback/pixel_ref_map_unittest.cc",
"playback/recording_source_unittest.cc",
"quads/draw_quad_unittest.cc",
- "quads/list_container_unittest.cc",
"quads/render_pass_unittest.cc",
"raster/scoped_gpu_raster_unittest.cc",
"raster/task_graph_runner_unittest.cc",
"raster/texture_compressor_etc1_unittest.cc",
"raster/tile_task_worker_pool_unittest.cc",
"resources/platform_color_unittest.cc",
- "resources/prioritized_resource_unittest.cc",
+ "resources/resource_pool_unittest.cc",
"resources/resource_provider_unittest.cc",
- "resources/resource_update_controller_unittest.cc",
"resources/scoped_resource_unittest.cc",
- "resources/texture_uploader_unittest.cc",
"resources/video_resource_updater_unittest.cc",
"scheduler/begin_frame_source_unittest.cc",
+ "scheduler/compositor_timing_history_unittest.cc",
"scheduler/delay_based_time_source_unittest.cc",
"scheduler/scheduler_state_machine_unittest.cc",
"scheduler/scheduler_unittest.cc",
@@ -864,13 +804,14 @@ test("cc_unittests") {
"trees/layer_tree_host_pixeltest_masks.cc",
"trees/layer_tree_host_pixeltest_readback.cc",
"trees/layer_tree_host_pixeltest_synchronous.cc",
+ "trees/layer_tree_host_pixeltest_tiles.cc",
"trees/layer_tree_host_unittest.cc",
"trees/layer_tree_host_unittest_animation.cc",
+ "trees/layer_tree_host_unittest_animation_timelines.cc",
"trees/layer_tree_host_unittest_context.cc",
"trees/layer_tree_host_unittest_copyrequest.cc",
"trees/layer_tree_host_unittest_damage.cc",
"trees/layer_tree_host_unittest_delegated.cc",
- "trees/layer_tree_host_unittest_no_message_loop.cc",
"trees/layer_tree_host_unittest_occlusion.cc",
"trees/layer_tree_host_unittest_picture.cc",
"trees/layer_tree_host_unittest_proxy.cc",
@@ -894,8 +835,6 @@ test("cc_unittests") {
"test/run_all_unittests.cc",
]
- configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
-
deps = [
":cc",
":test_support",
@@ -922,6 +861,7 @@ test("cc_perftests") {
"layers/layer_perftest.cc",
"layers/picture_layer_impl_perftest.cc",
"playback/picture_pile_impl_perftest.cc",
+ "quads/draw_quad_perftest.cc",
"raster/task_graph_runner_perftest.cc",
"raster/texture_compressor_perftest.cc",
"raster/tile_task_worker_pool_perftest.cc",
@@ -935,8 +875,6 @@ test("cc_perftests") {
"trees/occlusion_tracker_perftest.cc",
]
- configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
-
deps = [
":cc",
":test_support",
@@ -956,6 +894,10 @@ test("cc_perftests") {
"//ui/gfx/geometry",
"//ui/gl",
]
+
+ if (is_android) {
+ isolate_file = "cc_perftests.isolate"
+ }
}
# When adding support for isolates, please have a look at run-time dependencies
# in the cc_unittests_run target in cc_tests.gyp.
diff --git a/chromium/cc/OWNERS b/chromium/cc/OWNERS
index b0bce1de929..6cc39e71a21 100644
--- a/chromium/cc/OWNERS
+++ b/chromium/cc/OWNERS
@@ -47,5 +47,6 @@ vollick@chromium.org
vollick@chromium.org
ajuma@chromium.org
-per-file *.isolate=csharp@chromium.org
per-file *.isolate=maruel@chromium.org
+per-file *.isolate=tandrii@chromium.org
+per-file *.isolate=vadimsh@chromium.org
diff --git a/chromium/cc/PRESUBMIT.py b/chromium/cc/PRESUBMIT.py
index fa15632fd45..c8506182da1 100644
--- a/chromium/cc/PRESUBMIT.py
+++ b/chromium/cc/PRESUBMIT.py
@@ -333,3 +333,31 @@ def GetPreferredTryMasters(project, change):
'linux_blink_rel': set(['defaulttests']),
},
}
+
+def PostUploadHook(cl, change, output_api):
+ """git cl upload will call this hook after the issue is created/modified.
+
+ This hook adds extra try bots list to the CL description in order to run
+ Blink tests in addition to CQ try bots.
+ """
+ rietveld_obj = cl.RpcServer()
+ issue = cl.issue
+ description = rietveld_obj.get_description(issue)
+ if re.search(r'^CQ_INCLUDE_TRYBOTS=.*', description, re.M | re.I):
+ return []
+
+ bots = GetPreferredTryMasters(None, change)
+ bots_string_bits = []
+ for master in bots.keys():
+ bots_string_bits.append("%s:%s" % (master, ','.join(bots[master].keys())))
+
+ results = []
+ new_description = description
+ new_description += '\nCQ_INCLUDE_TRYBOTS=%s' % ';'.join(bots_string_bits)
+ results.append(output_api.PresubmitNotifyResult(
+ 'Automatically added Perf trybots to run Blink tests on CQ.'))
+
+ if new_description != description:
+ rietveld_obj.update_description(issue, new_description)
+
+ return results
diff --git a/chromium/cc/animation/animation.h b/chromium/cc/animation/animation.h
index 2677fdeff58..153e4ef7752 100644
--- a/chromium/cc/animation/animation.h
+++ b/chromium/cc/animation/animation.h
@@ -151,6 +151,9 @@ class CC_EXPORT Animation {
scoped_ptr<Animation> CloneAndInitialize(RunState initial_run_state) const;
+ void set_is_controlling_instance_for_test(bool is_controlling_instance) {
+ is_controlling_instance_ = is_controlling_instance;
+ }
bool is_controlling_instance() const { return is_controlling_instance_; }
void PushPropertiesTo(Animation* other) const;
diff --git a/chromium/cc/animation/animation_host.cc b/chromium/cc/animation/animation_host.cc
new file mode 100644
index 00000000000..e7f289fad9a
--- /dev/null
+++ b/chromium/cc/animation/animation_host.cc
@@ -0,0 +1,511 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/animation/animation_host.h"
+
+#include <algorithm>
+
+#include "cc/animation/animation_delegate.h"
+#include "cc/animation/animation_id_provider.h"
+#include "cc/animation/animation_player.h"
+#include "cc/animation/animation_registrar.h"
+#include "cc/animation/animation_timeline.h"
+#include "cc/animation/element_animations.h"
+#include "cc/animation/scroll_offset_animation_curve.h"
+#include "cc/animation/timing_function.h"
+#include "ui/gfx/geometry/box_f.h"
+#include "ui/gfx/geometry/scroll_offset.h"
+
+namespace cc {
+
+class AnimationHost::ScrollOffsetAnimations : public AnimationDelegate {
+ public:
+ explicit ScrollOffsetAnimations(AnimationHost* animation_host)
+ : animation_host_(animation_host),
+ scroll_offset_timeline_(
+ AnimationTimeline::Create(AnimationIdProvider::NextTimelineId())),
+ scroll_offset_animation_player_(
+ AnimationPlayer::Create(AnimationIdProvider::NextPlayerId())) {
+ scroll_offset_timeline_->set_is_impl_only(true);
+ scroll_offset_animation_player_->set_layer_animation_delegate(this);
+
+ animation_host_->AddAnimationTimeline(scroll_offset_timeline_.get());
+ scroll_offset_timeline_->AttachPlayer(
+ scroll_offset_animation_player_.get());
+ }
+
+ ~ScrollOffsetAnimations() override {
+ scroll_offset_timeline_->DetachPlayer(
+ scroll_offset_animation_player_.get());
+ animation_host_->RemoveAnimationTimeline(scroll_offset_timeline_.get());
+ }
+
+ void ScrollAnimationCreate(int layer_id,
+ const gfx::ScrollOffset& target_offset,
+ const gfx::ScrollOffset& current_offset) {
+ scoped_ptr<ScrollOffsetAnimationCurve> curve =
+ ScrollOffsetAnimationCurve::Create(target_offset,
+ EaseInOutTimingFunction::Create());
+ curve->SetInitialValue(current_offset);
+
+ scoped_ptr<Animation> animation = Animation::Create(
+ curve.Pass(), AnimationIdProvider::NextAnimationId(),
+ AnimationIdProvider::NextGroupId(), Animation::SCROLL_OFFSET);
+ animation->set_is_impl_only(true);
+
+ DCHECK(scroll_offset_animation_player_);
+ DCHECK(scroll_offset_animation_player_->animation_timeline());
+
+ if (scroll_offset_animation_player_->layer_id() != layer_id) {
+ if (scroll_offset_animation_player_->layer_id())
+ scroll_offset_animation_player_->DetachLayer();
+ scroll_offset_animation_player_->AttachLayer(layer_id);
+ }
+
+ scroll_offset_animation_player_->AddAnimation(animation.Pass());
+ }
+
+ bool ScrollAnimationUpdateTarget(int layer_id,
+ const gfx::Vector2dF& scroll_delta,
+ const gfx::ScrollOffset& max_scroll_offset,
+ base::TimeTicks frame_monotonic_time) {
+ DCHECK(scroll_offset_animation_player_);
+ DCHECK_EQ(layer_id, scroll_offset_animation_player_->layer_id());
+
+ Animation* animation = scroll_offset_animation_player_->element_animations()
+ ->layer_animation_controller()
+ ->GetAnimation(Animation::SCROLL_OFFSET);
+ if (!animation) {
+ scroll_offset_animation_player_->DetachLayer();
+ return false;
+ }
+
+ ScrollOffsetAnimationCurve* curve =
+ animation->curve()->ToScrollOffsetAnimationCurve();
+
+ gfx::ScrollOffset new_target =
+ gfx::ScrollOffsetWithDelta(curve->target_value(), scroll_delta);
+ new_target.SetToMax(gfx::ScrollOffset());
+ new_target.SetToMin(max_scroll_offset);
+
+ curve->UpdateTarget(animation->TrimTimeToCurrentIteration(
+ frame_monotonic_time).InSecondsF(),
+ new_target);
+
+ return true;
+ }
+
+ // AnimationDelegate implementation.
+ void NotifyAnimationStarted(base::TimeTicks monotonic_time,
+ Animation::TargetProperty target_property,
+ int group) override {}
+ void NotifyAnimationFinished(base::TimeTicks monotonic_time,
+ Animation::TargetProperty target_property,
+ int group) override {
+ DCHECK_EQ(target_property, Animation::SCROLL_OFFSET);
+ DCHECK(animation_host_->mutator_host_client());
+ animation_host_->mutator_host_client()->ScrollOffsetAnimationFinished();
+ }
+
+ private:
+ AnimationHost* animation_host_;
+ scoped_refptr<AnimationTimeline> scroll_offset_timeline_;
+
+ // We have just one player for impl-only scroll offset animations.
+ // I.e. only one layer can have an impl-only scroll offset animation at
+ // any given time.
+ scoped_refptr<AnimationPlayer> scroll_offset_animation_player_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScrollOffsetAnimations);
+};
+
+scoped_ptr<AnimationHost> AnimationHost::Create(
+ ThreadInstance thread_instance) {
+ return make_scoped_ptr(new AnimationHost(thread_instance));
+}
+
+AnimationHost::AnimationHost(ThreadInstance thread_instance)
+ : animation_registrar_(AnimationRegistrar::Create()),
+ mutator_host_client_(nullptr),
+ thread_instance_(thread_instance) {
+ if (thread_instance_ == ThreadInstance::IMPL)
+ scroll_offset_animations_ =
+ make_scoped_ptr(new ScrollOffsetAnimations(this));
+}
+
+AnimationHost::~AnimationHost() {
+ scroll_offset_animations_ = nullptr;
+
+ ClearTimelines();
+ DCHECK(!mutator_host_client());
+ DCHECK(layer_to_element_animations_map_.empty());
+}
+
+AnimationTimeline* AnimationHost::GetTimelineById(int timeline_id) const {
+ for (auto& timeline : timelines_)
+ if (timeline->id() == timeline_id)
+ return timeline.get();
+ return nullptr;
+}
+
+void AnimationHost::ClearTimelines() {
+ EraseTimelines(timelines_.begin(), timelines_.end());
+}
+
+void AnimationHost::EraseTimelines(AnimationTimelineList::iterator begin,
+ AnimationTimelineList::iterator end) {
+ for (auto i = begin; i != end; ++i) {
+ auto& timeline = *i;
+ timeline->ClearPlayers();
+ timeline->SetAnimationHost(nullptr);
+ }
+
+ timelines_.erase(begin, end);
+}
+
+void AnimationHost::AddAnimationTimeline(
+ scoped_refptr<AnimationTimeline> timeline) {
+ timeline->SetAnimationHost(this);
+ timelines_.push_back(timeline);
+}
+
+void AnimationHost::RemoveAnimationTimeline(
+ scoped_refptr<AnimationTimeline> timeline) {
+ for (auto iter = timelines_.begin(); iter != timelines_.end(); ++iter) {
+ if (iter->get() != timeline)
+ continue;
+
+ EraseTimelines(iter, iter + 1);
+ break;
+ }
+}
+
+void AnimationHost::RegisterLayer(int layer_id, LayerTreeType tree_type) {
+ ElementAnimations* element_animations =
+ GetElementAnimationsForLayerId(layer_id);
+ if (element_animations)
+ element_animations->LayerRegistered(layer_id, tree_type);
+}
+
+void AnimationHost::UnregisterLayer(int layer_id, LayerTreeType tree_type) {
+ ElementAnimations* element_animations =
+ GetElementAnimationsForLayerId(layer_id);
+ if (element_animations)
+ element_animations->LayerUnregistered(layer_id, tree_type);
+}
+
+void AnimationHost::RegisterPlayerForLayer(int layer_id,
+ AnimationPlayer* player) {
+ DCHECK(layer_id);
+ DCHECK(player);
+
+ ElementAnimations* element_animations =
+ GetElementAnimationsForLayerId(layer_id);
+ if (!element_animations) {
+ auto new_element_animations = ElementAnimations::Create(this);
+ element_animations = new_element_animations.get();
+
+ layer_to_element_animations_map_.add(layer_id,
+ new_element_animations.Pass());
+ element_animations->CreateLayerAnimationController(layer_id);
+ }
+
+ DCHECK(element_animations);
+ element_animations->AddPlayer(player);
+}
+
+void AnimationHost::UnregisterPlayerForLayer(int layer_id,
+ AnimationPlayer* player) {
+ DCHECK(layer_id);
+ DCHECK(player);
+
+ ElementAnimations* element_animations =
+ GetElementAnimationsForLayerId(layer_id);
+ DCHECK(element_animations);
+ element_animations->RemovePlayer(player);
+
+ if (element_animations->IsEmpty()) {
+ element_animations->DestroyLayerAnimationController();
+ layer_to_element_animations_map_.erase(layer_id);
+ element_animations = nullptr;
+ }
+}
+
+void AnimationHost::SetMutatorHostClient(MutatorHostClient* client) {
+ if (mutator_host_client_ == client)
+ return;
+
+ mutator_host_client_ = client;
+}
+
+void AnimationHost::SetNeedsCommit() {
+ DCHECK(mutator_host_client_);
+ mutator_host_client_->SetMutatorsNeedCommit();
+}
+
+void AnimationHost::PushPropertiesTo(AnimationHost* host_impl) {
+ PushTimelinesToImplThread(host_impl);
+ RemoveTimelinesFromImplThread(host_impl);
+ PushPropertiesToImplThread(host_impl);
+}
+
+void AnimationHost::PushTimelinesToImplThread(AnimationHost* host_impl) const {
+ for (auto& timeline : timelines_) {
+ AnimationTimeline* timeline_impl =
+ host_impl->GetTimelineById(timeline->id());
+ if (timeline_impl)
+ continue;
+
+ scoped_refptr<AnimationTimeline> to_add = timeline->CreateImplInstance();
+ host_impl->AddAnimationTimeline(to_add.get());
+ }
+}
+
+void AnimationHost::RemoveTimelinesFromImplThread(
+ AnimationHost* host_impl) const {
+ AnimationTimelineList& timelines_impl = host_impl->timelines_;
+
+ auto to_erase =
+ std::partition(timelines_impl.begin(), timelines_impl.end(),
+ [this](AnimationTimelineList::value_type timeline_impl) {
+ return timeline_impl->is_impl_only() ||
+ GetTimelineById(timeline_impl->id());
+ });
+
+ host_impl->EraseTimelines(to_erase, timelines_impl.end());
+}
+
+void AnimationHost::PushPropertiesToImplThread(AnimationHost* host_impl) {
+ // Firstly, sync all players with impl thread to create ElementAnimations and
+ // layer animation controllers.
+ for (auto& timeline : timelines_) {
+ AnimationTimeline* timeline_impl =
+ host_impl->GetTimelineById(timeline->id());
+ if (timeline_impl)
+ timeline->PushPropertiesTo(timeline_impl);
+ }
+
+ // Secondly, sync properties for created layer animation controllers.
+ for (auto& kv : layer_to_element_animations_map_) {
+ ElementAnimations* element_animations = kv.second;
+ ElementAnimations* element_animations_impl =
+ host_impl->GetElementAnimationsForLayerId(kv.first);
+ if (element_animations_impl)
+ element_animations->PushPropertiesTo(element_animations_impl);
+ }
+}
+
+LayerAnimationController* AnimationHost::GetControllerForLayerId(
+ int layer_id) const {
+ const ElementAnimations* element_animations =
+ GetElementAnimationsForLayerId(layer_id);
+ if (!element_animations)
+ return nullptr;
+
+ return element_animations->layer_animation_controller();
+}
+
+ElementAnimations* AnimationHost::GetElementAnimationsForLayerId(
+ int layer_id) const {
+ DCHECK(layer_id);
+ auto iter = layer_to_element_animations_map_.find(layer_id);
+ return iter == layer_to_element_animations_map_.end() ? nullptr
+ : iter->second;
+}
+
+void AnimationHost::SetSupportsScrollAnimations(
+ bool supports_scroll_animations) {
+ animation_registrar_->set_supports_scroll_animations(
+ supports_scroll_animations);
+}
+
+bool AnimationHost::SupportsScrollAnimations() const {
+ return animation_registrar_->supports_scroll_animations();
+}
+
+bool AnimationHost::NeedsAnimateLayers() const {
+ return animation_registrar_->needs_animate_layers();
+}
+
+bool AnimationHost::ActivateAnimations() {
+ return animation_registrar_->ActivateAnimations();
+}
+
+bool AnimationHost::AnimateLayers(base::TimeTicks monotonic_time) {
+ return animation_registrar_->AnimateLayers(monotonic_time);
+}
+
+bool AnimationHost::UpdateAnimationState(bool start_ready_animations,
+ AnimationEventsVector* events) {
+ return animation_registrar_->UpdateAnimationState(start_ready_animations,
+ events);
+}
+
+scoped_ptr<AnimationEventsVector> AnimationHost::CreateEvents() {
+ return animation_registrar_->CreateEvents();
+}
+
+void AnimationHost::SetAnimationEvents(
+ scoped_ptr<AnimationEventsVector> events) {
+ return animation_registrar_->SetAnimationEvents(events.Pass());
+}
+
+bool AnimationHost::ScrollOffsetAnimationWasInterrupted(int layer_id) const {
+ LayerAnimationController* controller = GetControllerForLayerId(layer_id);
+ return controller ? controller->scroll_offset_animation_was_interrupted()
+ : false;
+}
+
+bool AnimationHost::IsAnimatingFilterProperty(int layer_id) const {
+ LayerAnimationController* controller = GetControllerForLayerId(layer_id);
+ return controller ? controller->IsAnimatingProperty(Animation::FILTER)
+ : false;
+}
+
+bool AnimationHost::IsAnimatingOpacityProperty(int layer_id) const {
+ LayerAnimationController* controller = GetControllerForLayerId(layer_id);
+ return controller ? controller->IsAnimatingProperty(Animation::OPACITY)
+ : false;
+}
+
+bool AnimationHost::IsAnimatingTransformProperty(int layer_id) const {
+ LayerAnimationController* controller = GetControllerForLayerId(layer_id);
+ return controller ? controller->IsAnimatingProperty(Animation::TRANSFORM)
+ : false;
+}
+
+bool AnimationHost::HasPotentiallyRunningOpacityAnimation(int layer_id) const {
+ LayerAnimationController* controller = GetControllerForLayerId(layer_id);
+ if (!controller)
+ return false;
+
+ Animation* animation = controller->GetAnimation(Animation::OPACITY);
+ return animation && !animation->is_finished();
+}
+
+bool AnimationHost::HasPotentiallyRunningTransformAnimation(
+ int layer_id) const {
+ LayerAnimationController* controller = GetControllerForLayerId(layer_id);
+ if (!controller)
+ return false;
+
+ Animation* animation = controller->GetAnimation(Animation::TRANSFORM);
+ return animation && !animation->is_finished();
+}
+
+bool AnimationHost::FilterIsAnimatingOnImplOnly(int layer_id) const {
+ LayerAnimationController* controller = GetControllerForLayerId(layer_id);
+ if (!controller)
+ return false;
+
+ Animation* animation = controller->GetAnimation(Animation::FILTER);
+ return animation && animation->is_impl_only();
+}
+
+bool AnimationHost::OpacityIsAnimatingOnImplOnly(int layer_id) const {
+ LayerAnimationController* controller = GetControllerForLayerId(layer_id);
+ if (!controller)
+ return false;
+
+ Animation* animation = controller->GetAnimation(Animation::OPACITY);
+ return animation && animation->is_impl_only();
+}
+
+bool AnimationHost::TransformIsAnimatingOnImplOnly(int layer_id) const {
+ LayerAnimationController* controller = GetControllerForLayerId(layer_id);
+ if (!controller)
+ return false;
+
+ Animation* animation = controller->GetAnimation(Animation::TRANSFORM);
+ return animation && animation->is_impl_only();
+}
+
+bool AnimationHost::HasFilterAnimationThatInflatesBounds(int layer_id) const {
+ LayerAnimationController* controller = GetControllerForLayerId(layer_id);
+ return controller ? controller->HasFilterAnimationThatInflatesBounds()
+ : false;
+}
+
+bool AnimationHost::HasTransformAnimationThatInflatesBounds(
+ int layer_id) const {
+ LayerAnimationController* controller = GetControllerForLayerId(layer_id);
+ return controller ? controller->HasTransformAnimationThatInflatesBounds()
+ : false;
+}
+
+bool AnimationHost::HasAnimationThatInflatesBounds(int layer_id) const {
+ LayerAnimationController* controller = GetControllerForLayerId(layer_id);
+ return controller ? controller->HasAnimationThatInflatesBounds() : false;
+}
+
+bool AnimationHost::FilterAnimationBoundsForBox(int layer_id,
+ const gfx::BoxF& box,
+ gfx::BoxF* bounds) const {
+ LayerAnimationController* controller = GetControllerForLayerId(layer_id);
+ return controller ? controller->FilterAnimationBoundsForBox(box, bounds)
+ : false;
+}
+
+bool AnimationHost::TransformAnimationBoundsForBox(int layer_id,
+ const gfx::BoxF& box,
+ gfx::BoxF* bounds) const {
+ *bounds = gfx::BoxF();
+ LayerAnimationController* controller = GetControllerForLayerId(layer_id);
+ return controller ? controller->TransformAnimationBoundsForBox(box, bounds)
+ : true;
+}
+
+bool AnimationHost::HasOnlyTranslationTransforms(int layer_id) const {
+ LayerAnimationController* controller = GetControllerForLayerId(layer_id);
+ return controller ? controller->HasOnlyTranslationTransforms() : true;
+}
+
+bool AnimationHost::AnimationsPreserveAxisAlignment(int layer_id) const {
+ LayerAnimationController* controller = GetControllerForLayerId(layer_id);
+ return controller ? controller->AnimationsPreserveAxisAlignment() : true;
+}
+
+bool AnimationHost::MaximumTargetScale(int layer_id, float* max_scale) const {
+ *max_scale = 0.f;
+ LayerAnimationController* controller = GetControllerForLayerId(layer_id);
+ return controller ? controller->MaximumTargetScale(max_scale) : true;
+}
+
+bool AnimationHost::AnimationStartScale(int layer_id,
+ float* start_scale) const {
+ *start_scale = 0.f;
+ LayerAnimationController* controller = GetControllerForLayerId(layer_id);
+ return controller ? controller->AnimationStartScale(start_scale) : true;
+}
+
+bool AnimationHost::HasAnyAnimation(int layer_id) const {
+ LayerAnimationController* controller = GetControllerForLayerId(layer_id);
+ return controller ? controller->has_any_animation() : false;
+}
+
+bool AnimationHost::HasActiveAnimation(int layer_id) const {
+ LayerAnimationController* controller = GetControllerForLayerId(layer_id);
+ return controller ? controller->HasActiveAnimation() : false;
+}
+
+void AnimationHost::ImplOnlyScrollAnimationCreate(
+ int layer_id,
+ const gfx::ScrollOffset& target_offset,
+ const gfx::ScrollOffset& current_offset) {
+ DCHECK(scroll_offset_animations_);
+ scroll_offset_animations_->ScrollAnimationCreate(layer_id, target_offset,
+ current_offset);
+}
+
+bool AnimationHost::ImplOnlyScrollAnimationUpdateTarget(
+ int layer_id,
+ const gfx::Vector2dF& scroll_delta,
+ const gfx::ScrollOffset& max_scroll_offset,
+ base::TimeTicks frame_monotonic_time) {
+ DCHECK(scroll_offset_animations_);
+ return scroll_offset_animations_->ScrollAnimationUpdateTarget(
+ layer_id, scroll_delta, max_scroll_offset, frame_monotonic_time);
+}
+
+} // namespace cc
diff --git a/chromium/cc/animation/animation_host.h b/chromium/cc/animation/animation_host.h
new file mode 100644
index 00000000000..3f69a023379
--- /dev/null
+++ b/chromium/cc/animation/animation_host.h
@@ -0,0 +1,167 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_ANIMATION_ANIMATION_HOST_H_
+#define CC_ANIMATION_ANIMATION_HOST_H_
+
+#include <vector>
+
+#include "base/containers/scoped_ptr_hash_map.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/time/time.h"
+#include "cc/animation/animation_events.h"
+#include "cc/base/cc_export.h"
+#include "cc/trees/mutator_host_client.h"
+
+namespace gfx {
+class ScrollOffset;
+}
+
+namespace cc {
+
+class AnimationPlayer;
+class AnimationRegistrar;
+class AnimationTimeline;
+class ElementAnimations;
+class LayerAnimationController;
+class LayerTreeHost;
+
+enum class ThreadInstance { MAIN, IMPL };
+
+typedef std::vector<scoped_refptr<AnimationTimeline>> AnimationTimelineList;
+
+// An AnimationHost contains all the state required to play animations.
+// Specifically, it owns all the AnimationTimelines objects.
+// There is just one AnimationHost for LayerTreeHost on main renderer thread
+// and just one AnimationHost for LayerTreeHostImpl on impl thread.
+// We synchronize them during the commit process in a one-way data flow process
+// (PushPropertiesTo).
+// An AnimationHost talks to its correspondent LayerTreeHost via
+// LayerTreeMutatorsClient interface.
+// AnimationHost has it's own instance of AnimationRegistrar,
+// we want to merge AnimationRegistrar into AnimationHost.
+class CC_EXPORT AnimationHost {
+ public:
+ static scoped_ptr<AnimationHost> Create(ThreadInstance thread_instance);
+ virtual ~AnimationHost();
+
+ void AddAnimationTimeline(scoped_refptr<AnimationTimeline> timeline);
+ void RemoveAnimationTimeline(scoped_refptr<AnimationTimeline> timeline);
+ AnimationTimeline* GetTimelineById(int timeline_id) const;
+
+ void ClearTimelines();
+
+ void RegisterLayer(int layer_id, LayerTreeType tree_type);
+ void UnregisterLayer(int layer_id, LayerTreeType tree_type);
+
+ void RegisterPlayerForLayer(int layer_id, AnimationPlayer* player);
+ void UnregisterPlayerForLayer(int layer_id, AnimationPlayer* player);
+
+ ElementAnimations* GetElementAnimationsForLayerId(int layer_id) const;
+
+ // TODO(loyso): Get rid of LayerAnimationController.
+ LayerAnimationController* GetControllerForLayerId(int layer_id) const;
+
+ // Parent LayerTreeHost or LayerTreeHostImpl.
+ MutatorHostClient* mutator_host_client() { return mutator_host_client_; }
+ const MutatorHostClient* mutator_host_client() const {
+ return mutator_host_client_;
+ }
+ void SetMutatorHostClient(MutatorHostClient* client);
+
+ void SetNeedsCommit();
+
+ void PushPropertiesTo(AnimationHost* host_impl);
+
+ AnimationRegistrar* animation_registrar() const {
+ return animation_registrar_.get();
+ }
+
+ void SetSupportsScrollAnimations(bool supports_scroll_animations);
+ bool SupportsScrollAnimations() const;
+ bool NeedsAnimateLayers() const;
+
+ bool ActivateAnimations();
+ bool AnimateLayers(base::TimeTicks monotonic_time);
+ bool UpdateAnimationState(bool start_ready_animations,
+ AnimationEventsVector* events);
+
+ scoped_ptr<AnimationEventsVector> CreateEvents();
+ void SetAnimationEvents(scoped_ptr<AnimationEventsVector> events);
+
+ bool ScrollOffsetAnimationWasInterrupted(int layer_id) const;
+
+ bool IsAnimatingFilterProperty(int layer_id) const;
+ bool IsAnimatingOpacityProperty(int layer_id) const;
+ bool IsAnimatingTransformProperty(int layer_id) const;
+
+ bool HasPotentiallyRunningOpacityAnimation(int layer_id) const;
+ bool HasPotentiallyRunningTransformAnimation(int layer_id) const;
+
+ bool FilterIsAnimatingOnImplOnly(int layer_id) const;
+ bool OpacityIsAnimatingOnImplOnly(int layer_id) const;
+ bool TransformIsAnimatingOnImplOnly(int layer_id) const;
+
+ bool HasFilterAnimationThatInflatesBounds(int layer_id) const;
+ bool HasTransformAnimationThatInflatesBounds(int layer_id) const;
+ bool HasAnimationThatInflatesBounds(int layer_id) const;
+
+ bool FilterAnimationBoundsForBox(int layer_id,
+ const gfx::BoxF& box,
+ gfx::BoxF* bounds) const;
+ bool TransformAnimationBoundsForBox(int layer_id,
+ const gfx::BoxF& box,
+ gfx::BoxF* bounds) const;
+
+ bool HasOnlyTranslationTransforms(int layer_id) const;
+ bool AnimationsPreserveAxisAlignment(int layer_id) const;
+
+ bool MaximumTargetScale(int layer_id, float* max_scale) const;
+ bool AnimationStartScale(int layer_id, float* start_scale) const;
+
+ bool HasAnyAnimation(int layer_id) const;
+ bool HasActiveAnimation(int layer_id) const;
+
+ void ImplOnlyScrollAnimationCreate(int layer_id,
+ const gfx::ScrollOffset& target_offset,
+ const gfx::ScrollOffset& current_offset);
+ bool ImplOnlyScrollAnimationUpdateTarget(
+ int layer_id,
+ const gfx::Vector2dF& scroll_delta,
+ const gfx::ScrollOffset& max_scroll_offset,
+ base::TimeTicks frame_monotonic_time);
+
+ private:
+ explicit AnimationHost(ThreadInstance thread_instance);
+
+ void PushTimelinesToImplThread(AnimationHost* host_impl) const;
+ void RemoveTimelinesFromImplThread(AnimationHost* host_impl) const;
+ void PushPropertiesToImplThread(AnimationHost* host_impl);
+
+ void EraseTimelines(AnimationTimelineList::iterator begin,
+ AnimationTimelineList::iterator end);
+
+ // TODO(loyso): For now AnimationPlayers share LayerAnimationController object
+ // if they are attached to the same element(layer). Note that Element can
+ // contain many Layers.
+ typedef base::ScopedPtrHashMap<int, scoped_ptr<ElementAnimations>>
+ LayerToElementAnimationsMap;
+ LayerToElementAnimationsMap layer_to_element_animations_map_;
+
+ AnimationTimelineList timelines_;
+ scoped_ptr<AnimationRegistrar> animation_registrar_;
+ MutatorHostClient* mutator_host_client_;
+
+ class ScrollOffsetAnimations;
+ scoped_ptr<ScrollOffsetAnimations> scroll_offset_animations_;
+
+ const ThreadInstance thread_instance_;
+
+ DISALLOW_COPY_AND_ASSIGN(AnimationHost);
+};
+
+} // namespace cc
+
+#endif // CC_ANIMATION_ANIMATION_HOST_H_
diff --git a/chromium/cc/animation/animation_host_unittest.cc b/chromium/cc/animation/animation_host_unittest.cc
new file mode 100644
index 00000000000..18d6c9f66f5
--- /dev/null
+++ b/chromium/cc/animation/animation_host_unittest.cc
@@ -0,0 +1,75 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/animation/animation_host.h"
+
+#include "cc/animation/animation_id_provider.h"
+#include "cc/animation/animation_timeline.h"
+#include "cc/test/animation_test_common.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+namespace {
+
+// See AnimationPlayer tests on layer registration/unregistration in
+// animation_player_unittest.cc.
+
+TEST(AnimationHostTest, SyncTimelinesAddRemove) {
+ scoped_ptr<AnimationHost> host(AnimationHost::Create(ThreadInstance::MAIN));
+ scoped_ptr<AnimationHost> host_impl(
+ AnimationHost::Create(ThreadInstance::IMPL));
+
+ const int timeline_id = AnimationIdProvider::NextTimelineId();
+ scoped_refptr<AnimationTimeline> timeline(
+ AnimationTimeline::Create(timeline_id));
+ host->AddAnimationTimeline(timeline.get());
+ EXPECT_TRUE(timeline->animation_host());
+
+ EXPECT_FALSE(host_impl->GetTimelineById(timeline_id));
+
+ host->PushPropertiesTo(host_impl.get());
+
+ scoped_refptr<AnimationTimeline> timeline_impl =
+ host_impl->GetTimelineById(timeline_id);
+ EXPECT_TRUE(timeline_impl);
+ EXPECT_EQ(timeline_impl->id(), timeline_id);
+
+ host->PushPropertiesTo(host_impl.get());
+ EXPECT_EQ(timeline_impl, host_impl->GetTimelineById(timeline_id));
+
+ host->RemoveAnimationTimeline(timeline.get());
+ EXPECT_FALSE(timeline->animation_host());
+
+ host->PushPropertiesTo(host_impl.get());
+ EXPECT_FALSE(host_impl->GetTimelineById(timeline_id));
+
+ EXPECT_FALSE(timeline_impl->animation_host());
+}
+
+TEST(AnimationHostTest, ImplOnlyTimeline) {
+ scoped_ptr<AnimationHost> host(AnimationHost::Create(ThreadInstance::MAIN));
+ scoped_ptr<AnimationHost> host_impl(
+ AnimationHost::Create(ThreadInstance::IMPL));
+
+ const int timeline_id1 = AnimationIdProvider::NextTimelineId();
+ const int timeline_id2 = AnimationIdProvider::NextTimelineId();
+
+ scoped_refptr<AnimationTimeline> timeline(
+ AnimationTimeline::Create(timeline_id1));
+ scoped_refptr<AnimationTimeline> timeline_impl(
+ AnimationTimeline::Create(timeline_id2));
+ timeline_impl->set_is_impl_only(true);
+
+ host->AddAnimationTimeline(timeline.get());
+ host_impl->AddAnimationTimeline(timeline_impl.get());
+
+ host->PushPropertiesTo(host_impl.get());
+
+ EXPECT_TRUE(host->GetTimelineById(timeline_id1));
+ EXPECT_TRUE(host_impl->GetTimelineById(timeline_id2));
+}
+
+} // namespace
+} // namespace cc
diff --git a/chromium/cc/animation/animation_id_provider.cc b/chromium/cc/animation/animation_id_provider.cc
index caefdb8fee5..9c87d2049f4 100644
--- a/chromium/cc/animation/animation_id_provider.cc
+++ b/chromium/cc/animation/animation_id_provider.cc
@@ -9,6 +9,8 @@ namespace cc {
base::StaticAtomicSequenceNumber g_next_animation_id;
base::StaticAtomicSequenceNumber g_next_group_id;
+base::StaticAtomicSequenceNumber g_next_timeline_id;
+base::StaticAtomicSequenceNumber g_next_player_id;
int AnimationIdProvider::NextAnimationId() {
// Animation IDs start from 1.
@@ -20,4 +22,12 @@ int AnimationIdProvider::NextGroupId() {
return g_next_group_id.GetNext() + 1;
}
+int AnimationIdProvider::NextTimelineId() {
+ return g_next_timeline_id.GetNext() + 1;
+}
+
+int AnimationIdProvider::NextPlayerId() {
+ return g_next_player_id.GetNext() + 1;
+}
+
} // namespace cc
diff --git a/chromium/cc/animation/animation_id_provider.h b/chromium/cc/animation/animation_id_provider.h
index b403841315b..3b14801e7d3 100644
--- a/chromium/cc/animation/animation_id_provider.h
+++ b/chromium/cc/animation/animation_id_provider.h
@@ -15,6 +15,8 @@ class CC_EXPORT AnimationIdProvider {
// These functions each return monotonically increasing values.
static int NextAnimationId();
static int NextGroupId();
+ static int NextTimelineId();
+ static int NextPlayerId();
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(AnimationIdProvider);
diff --git a/chromium/cc/animation/animation_player.cc b/chromium/cc/animation/animation_player.cc
new file mode 100644
index 00000000000..e4febeb242a
--- /dev/null
+++ b/chromium/cc/animation/animation_player.cc
@@ -0,0 +1,189 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/animation/animation_player.h"
+
+#include "cc/animation/animation_delegate.h"
+#include "cc/animation/animation_host.h"
+#include "cc/animation/animation_timeline.h"
+#include "cc/animation/element_animations.h"
+#include "cc/animation/layer_animation_controller.h"
+
+namespace cc {
+
+scoped_refptr<AnimationPlayer> AnimationPlayer::Create(int id) {
+ return make_scoped_refptr(new AnimationPlayer(id));
+}
+
+AnimationPlayer::AnimationPlayer(int id)
+ : animation_host_(),
+ animation_timeline_(),
+ element_animations_(),
+ layer_animation_delegate_(),
+ id_(id),
+ layer_id_(0) {
+ DCHECK(id_);
+}
+
+AnimationPlayer::~AnimationPlayer() {
+ DCHECK(!animation_timeline_);
+ DCHECK(!element_animations_);
+ DCHECK(!layer_id_);
+}
+
+scoped_refptr<AnimationPlayer> AnimationPlayer::CreateImplInstance() const {
+ scoped_refptr<AnimationPlayer> player = AnimationPlayer::Create(id());
+ return player;
+}
+
+void AnimationPlayer::SetAnimationHost(AnimationHost* animation_host) {
+ animation_host_ = animation_host;
+}
+
+void AnimationPlayer::SetAnimationTimeline(AnimationTimeline* timeline) {
+ if (animation_timeline_ == timeline)
+ return;
+
+ // We need to unregister player to manage ElementAnimations and observers
+ // properly.
+ if (layer_id_ && element_animations_)
+ UnregisterPlayer();
+
+ animation_timeline_ = timeline;
+
+ // Register player only if layer AND host attached.
+ if (layer_id_ && animation_host_)
+ RegisterPlayer();
+}
+
+void AnimationPlayer::AttachLayer(int layer_id) {
+ DCHECK_EQ(layer_id_, 0);
+ DCHECK(layer_id);
+
+ layer_id_ = layer_id;
+
+ // Register player only if layer AND host attached.
+ if (animation_host_)
+ RegisterPlayer();
+}
+
+void AnimationPlayer::DetachLayer() {
+ DCHECK(layer_id_);
+
+ if (animation_host_)
+ UnregisterPlayer();
+
+ layer_id_ = 0;
+}
+
+void AnimationPlayer::RegisterPlayer() {
+ DCHECK(layer_id_);
+ DCHECK(animation_host_);
+ DCHECK(!element_animations_);
+
+ // Create LAC or re-use existing.
+ animation_host_->RegisterPlayerForLayer(layer_id_, this);
+ // Get local reference to shared LAC.
+ BindElementAnimations();
+}
+
+void AnimationPlayer::UnregisterPlayer() {
+ DCHECK(layer_id_);
+ DCHECK(animation_host_);
+ DCHECK(element_animations_);
+
+ UnbindElementAnimations();
+ // Destroy LAC or release it if it's still needed.
+ animation_host_->UnregisterPlayerForLayer(layer_id_, this);
+}
+
+void AnimationPlayer::BindElementAnimations() {
+ DCHECK(!element_animations_);
+ element_animations_ =
+ animation_host_->GetElementAnimationsForLayerId(layer_id_);
+ DCHECK(element_animations_);
+
+ // Pass all accumulated animations to LAC.
+ for (auto it = animations_.begin(); it != animations_.end(); ++it)
+ element_animations_->layer_animation_controller()->AddAnimation(
+ animations_.take(it));
+ if (!animations_.empty())
+ SetNeedsCommit();
+ animations_.clear();
+}
+
+void AnimationPlayer::UnbindElementAnimations() {
+ element_animations_ = nullptr;
+ DCHECK(animations_.empty());
+}
+
+void AnimationPlayer::AddAnimation(scoped_ptr<Animation> animation) {
+ DCHECK_IMPLIES(
+ animation->target_property() == Animation::SCROLL_OFFSET,
+ animation_host_ && animation_host_->SupportsScrollAnimations());
+
+ if (element_animations_) {
+ element_animations_->layer_animation_controller()->AddAnimation(
+ animation.Pass());
+ SetNeedsCommit();
+ } else {
+ animations_.push_back(animation.Pass());
+ }
+}
+
+void AnimationPlayer::PauseAnimation(int animation_id, double time_offset) {
+ DCHECK(element_animations_);
+ element_animations_->layer_animation_controller()->PauseAnimation(
+ animation_id, base::TimeDelta::FromSecondsD(time_offset));
+ SetNeedsCommit();
+}
+
+void AnimationPlayer::RemoveAnimation(int animation_id) {
+ if (element_animations_) {
+ element_animations_->layer_animation_controller()->RemoveAnimation(
+ animation_id);
+ SetNeedsCommit();
+ } else {
+ auto animations_to_remove = animations_.remove_if([animation_id](
+ Animation* animation) { return animation->id() == animation_id; });
+ animations_.erase(animations_to_remove, animations_.end());
+ }
+}
+
+void AnimationPlayer::PushPropertiesTo(AnimationPlayer* player_impl) {
+ if (!element_animations_) {
+ if (player_impl->element_animations())
+ player_impl->DetachLayer();
+ return;
+ }
+
+ DCHECK(layer_id_);
+ if (!player_impl->element_animations())
+ player_impl->AttachLayer(layer_id_);
+}
+
+void AnimationPlayer::NotifyAnimationStarted(
+ base::TimeTicks monotonic_time,
+ Animation::TargetProperty target_property,
+ int group) {
+ if (layer_animation_delegate_)
+ layer_animation_delegate_->NotifyAnimationStarted(monotonic_time,
+ target_property, group);
+}
+
+void AnimationPlayer::NotifyAnimationFinished(
+ base::TimeTicks monotonic_time,
+ Animation::TargetProperty target_property,
+ int group) {
+ if (layer_animation_delegate_)
+ layer_animation_delegate_->NotifyAnimationFinished(monotonic_time,
+ target_property, group);
+}
+
+void AnimationPlayer::SetNeedsCommit() {
+ DCHECK(animation_host_);
+ animation_host_->SetNeedsCommit();
+}
+
+} // namespace cc
diff --git a/chromium/cc/animation/animation_player.h b/chromium/cc/animation/animation_player.h
new file mode 100644
index 00000000000..afb819d5c5e
--- /dev/null
+++ b/chromium/cc/animation/animation_player.h
@@ -0,0 +1,114 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_ANIMATION_ANIMATION_PLAYER_H_
+#define CC_ANIMATION_ANIMATION_PLAYER_H_
+
+#include "base/containers/linked_list.h"
+#include "base/memory/ref_counted.h"
+#include "base/time/time.h"
+#include "cc/animation/animation.h"
+#include "cc/base/cc_export.h"
+#include "cc/base/scoped_ptr_vector.h"
+
+namespace cc {
+
+class AnimationDelegate;
+class AnimationHost;
+class AnimationTimeline;
+class ElementAnimations;
+class LayerAnimationController;
+enum class LayerTreeType;
+
+// An AnimationPlayer owns all animations to be run on particular CC Layer.
+// Multiple AnimationPlayers can be attached to one layer. In this case,
+// they share common LayerAnimationController (temp solution) so the
+// LayerAnimationController-to-Layer relationship stays the same (1:1, LACs
+// have same IDs as their respective Layers).
+// For now, the blink logic is responsible for handling of conflicting
+// same-property animations.
+// Each AnimationPlayer has its copy on the impl thread.
+// This is a CC counterpart for blink::AnimationPlayer (in 1:1 relationship).
+class CC_EXPORT AnimationPlayer : public base::RefCounted<AnimationPlayer>,
+ public base::LinkNode<AnimationPlayer> {
+ public:
+ static scoped_refptr<AnimationPlayer> Create(int id);
+ scoped_refptr<AnimationPlayer> CreateImplInstance() const;
+
+ int id() const { return id_; }
+ int layer_id() const { return layer_id_; }
+
+ // Parent AnimationHost. AnimationPlayer can be detached from
+ // AnimationTimeline.
+ AnimationHost* animation_host() { return animation_host_; }
+ const AnimationHost* animation_host() const { return animation_host_; }
+ void SetAnimationHost(AnimationHost* animation_host);
+
+ // Parent AnimationTimeline.
+ AnimationTimeline* animation_timeline() { return animation_timeline_; }
+ const AnimationTimeline* animation_timeline() const {
+ return animation_timeline_;
+ }
+ void SetAnimationTimeline(AnimationTimeline* timeline);
+
+ // ElementAnimations object where this player is listed.
+ // ElementAnimations has a reference to shared LayerAnimationController.
+ ElementAnimations* element_animations() const { return element_animations_; }
+
+ void set_layer_animation_delegate(AnimationDelegate* delegate) {
+ layer_animation_delegate_ = delegate;
+ }
+
+ void AttachLayer(int layer_id);
+ void DetachLayer();
+
+ void AddAnimation(scoped_ptr<Animation> animation);
+ void PauseAnimation(int animation_id, double time_offset);
+ void RemoveAnimation(int animation_id);
+
+ void PushPropertiesTo(AnimationPlayer* player_impl);
+
+ // AnimationDelegate routing.
+ void NotifyAnimationStarted(base::TimeTicks monotonic_time,
+ Animation::TargetProperty target_property,
+ int group);
+ void NotifyAnimationFinished(base::TimeTicks monotonic_time,
+ Animation::TargetProperty target_property,
+ int group);
+
+ private:
+ friend class base::RefCounted<AnimationPlayer>;
+
+ explicit AnimationPlayer(int id);
+ ~AnimationPlayer();
+
+ void SetNeedsCommit();
+
+ void RegisterPlayer();
+ void UnregisterPlayer();
+
+ void BindElementAnimations();
+ void UnbindElementAnimations();
+
+ // We accumulate added animations in animations_ container
+ // if element_animations_ is a nullptr. It allows us to add/remove animations
+ // to non-attached AnimationPlayers.
+ typedef ScopedPtrVector<Animation> AnimationList;
+ AnimationList animations_;
+
+ AnimationHost* animation_host_;
+ AnimationTimeline* animation_timeline_;
+ // element_animations isn't null if player attached to an element (layer).
+ ElementAnimations* element_animations_;
+ AnimationDelegate* layer_animation_delegate_;
+
+ int id_;
+ int layer_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(AnimationPlayer);
+};
+
+} // namespace cc
+
+#endif // CC_ANIMATION_ANIMATION_PLAYER_H_
diff --git a/chromium/cc/animation/animation_player_unittest.cc b/chromium/cc/animation/animation_player_unittest.cc
new file mode 100644
index 00000000000..466964f6d77
--- /dev/null
+++ b/chromium/cc/animation/animation_player_unittest.cc
@@ -0,0 +1,336 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/animation/animation_player.h"
+
+#include "cc/animation/animation_delegate.h"
+#include "cc/animation/animation_host.h"
+#include "cc/animation/animation_id_provider.h"
+#include "cc/animation/animation_registrar.h"
+#include "cc/animation/animation_timeline.h"
+#include "cc/animation/element_animations.h"
+#include "cc/test/animation_test_common.h"
+#include "cc/test/animation_timelines_test_common.h"
+
+namespace cc {
+namespace {
+
+class AnimationPlayerTest : public AnimationTimelinesTest {
+ public:
+ AnimationPlayerTest() {}
+ ~AnimationPlayerTest() override {}
+};
+
+// See element_animations_unittest.cc for active/pending observers tests.
+
+TEST_F(AnimationPlayerTest, AttachDetachLayerIfTimelineAttached) {
+ host_->AddAnimationTimeline(timeline_);
+ timeline_->AttachPlayer(player_);
+ EXPECT_FALSE(player_->element_animations());
+ EXPECT_FALSE(player_->layer_id());
+
+ host_->PushPropertiesTo(host_impl_);
+
+ EXPECT_FALSE(GetImplPlayerForLayerId(layer_id_));
+
+ GetImplTimelineAndPlayerByID();
+
+ EXPECT_FALSE(player_impl_->element_animations());
+ EXPECT_FALSE(player_impl_->layer_id());
+
+ player_->AttachLayer(layer_id_);
+ EXPECT_EQ(player_, GetPlayerForLayerId(layer_id_));
+ EXPECT_TRUE(player_->element_animations());
+ EXPECT_EQ(player_->layer_id(), layer_id_);
+
+ host_->PushPropertiesTo(host_impl_);
+
+ EXPECT_EQ(player_impl_, GetImplPlayerForLayerId(layer_id_));
+ EXPECT_TRUE(player_impl_->element_animations());
+ EXPECT_EQ(player_impl_->layer_id(), layer_id_);
+
+ player_->DetachLayer();
+ EXPECT_FALSE(GetPlayerForLayerId(layer_id_));
+ EXPECT_FALSE(player_->element_animations());
+ EXPECT_FALSE(player_->layer_id());
+
+ host_->PushPropertiesTo(host_impl_);
+
+ EXPECT_FALSE(GetImplPlayerForLayerId(layer_id_));
+ EXPECT_FALSE(player_impl_->element_animations());
+ EXPECT_FALSE(player_impl_->layer_id());
+
+ timeline_->DetachPlayer(player_);
+ EXPECT_FALSE(player_->animation_timeline());
+ EXPECT_FALSE(player_->element_animations());
+ EXPECT_FALSE(player_->layer_id());
+}
+
+TEST_F(AnimationPlayerTest, AttachDetachTimelineIfLayerAttached) {
+ host_->AddAnimationTimeline(timeline_);
+
+ EXPECT_FALSE(player_->element_animations());
+ EXPECT_FALSE(player_->layer_id());
+
+ player_->AttachLayer(layer_id_);
+ EXPECT_FALSE(player_->animation_timeline());
+ EXPECT_FALSE(GetPlayerForLayerId(layer_id_));
+ EXPECT_FALSE(player_->element_animations());
+ EXPECT_EQ(player_->layer_id(), layer_id_);
+
+ timeline_->AttachPlayer(player_);
+ EXPECT_EQ(timeline_, player_->animation_timeline());
+ EXPECT_EQ(player_, GetPlayerForLayerId(layer_id_));
+ EXPECT_TRUE(player_->element_animations());
+ EXPECT_EQ(player_->layer_id(), layer_id_);
+
+ // Removing player from timeline detaches layer.
+ timeline_->DetachPlayer(player_);
+ EXPECT_FALSE(player_->animation_timeline());
+ EXPECT_FALSE(GetPlayerForLayerId(layer_id_));
+ EXPECT_FALSE(player_->element_animations());
+ EXPECT_FALSE(player_->layer_id());
+}
+
+TEST_F(AnimationPlayerTest, PropertiesMutate) {
+ client_.RegisterLayer(layer_id_, LayerTreeType::ACTIVE);
+ client_impl_.RegisterLayer(layer_id_, LayerTreeType::PENDING);
+ client_impl_.RegisterLayer(layer_id_, LayerTreeType::ACTIVE);
+
+ host_->AddAnimationTimeline(timeline_);
+ timeline_->AttachPlayer(player_);
+ player_->AttachLayer(layer_id_);
+
+ const float start_opacity = .7f;
+ const float end_opacity = .3f;
+
+ const float start_brightness = .6f;
+ const float end_brightness = .4f;
+
+ const int transform_x = 10;
+ const int transform_y = 20;
+
+ const double duration = 1.;
+
+ AddOpacityTransitionToPlayer(player_.get(), duration, start_opacity,
+ end_opacity, false);
+ AddAnimatedTransformToPlayer(player_.get(), duration, transform_x,
+ transform_y);
+ AddAnimatedFilterToPlayer(player_.get(), duration, start_brightness,
+ end_brightness);
+
+ host_->PushPropertiesTo(host_impl_);
+
+ EXPECT_FALSE(client_.IsPropertyMutated(layer_id_, LayerTreeType::ACTIVE,
+ Animation::OPACITY));
+ EXPECT_FALSE(client_.IsPropertyMutated(layer_id_, LayerTreeType::ACTIVE,
+ Animation::TRANSFORM));
+ EXPECT_FALSE(client_.IsPropertyMutated(layer_id_, LayerTreeType::ACTIVE,
+ Animation::FILTER));
+
+ EXPECT_FALSE(client_impl_.IsPropertyMutated(layer_id_, LayerTreeType::ACTIVE,
+ Animation::OPACITY));
+ EXPECT_FALSE(client_impl_.IsPropertyMutated(layer_id_, LayerTreeType::ACTIVE,
+ Animation::TRANSFORM));
+ EXPECT_FALSE(client_impl_.IsPropertyMutated(layer_id_, LayerTreeType::ACTIVE,
+ Animation::FILTER));
+
+ host_impl_->animation_registrar()->ActivateAnimations();
+
+ base::TimeTicks time;
+ time += base::TimeDelta::FromSecondsD(0.1);
+ AnimateLayersTransferEvents(time, 3u);
+
+ time += base::TimeDelta::FromSecondsD(duration);
+ AnimateLayersTransferEvents(time, 3u);
+
+ client_.ExpectOpacityPropertyMutated(layer_id_, LayerTreeType::ACTIVE,
+ end_opacity);
+ client_.ExpectTransformPropertyMutated(layer_id_, LayerTreeType::ACTIVE,
+ transform_x, transform_y);
+ client_.ExpectFilterPropertyMutated(layer_id_, LayerTreeType::ACTIVE,
+ end_brightness);
+
+ client_impl_.ExpectOpacityPropertyMutated(layer_id_, LayerTreeType::ACTIVE,
+ end_opacity);
+ client_impl_.ExpectTransformPropertyMutated(layer_id_, LayerTreeType::ACTIVE,
+ transform_x, transform_y);
+ client_impl_.ExpectFilterPropertyMutated(layer_id_, LayerTreeType::ACTIVE,
+ end_brightness);
+
+ client_impl_.ExpectOpacityPropertyMutated(layer_id_, LayerTreeType::PENDING,
+ end_opacity);
+ client_impl_.ExpectTransformPropertyMutated(layer_id_, LayerTreeType::PENDING,
+ transform_x, transform_y);
+ client_impl_.ExpectFilterPropertyMutated(layer_id_, LayerTreeType::PENDING,
+ end_brightness);
+}
+
+TEST_F(AnimationPlayerTest, AttachTwoPlayersToOneLayer) {
+ TestAnimationDelegate delegate1;
+ TestAnimationDelegate delegate2;
+
+ client_.RegisterLayer(layer_id_, LayerTreeType::ACTIVE);
+ client_impl_.RegisterLayer(layer_id_, LayerTreeType::PENDING);
+ client_impl_.RegisterLayer(layer_id_, LayerTreeType::ACTIVE);
+
+ scoped_refptr<AnimationPlayer> player1 =
+ AnimationPlayer::Create(AnimationIdProvider::NextPlayerId());
+ scoped_refptr<AnimationPlayer> player2 =
+ AnimationPlayer::Create(AnimationIdProvider::NextPlayerId());
+
+ host_->AddAnimationTimeline(timeline_);
+ timeline_->AttachPlayer(player1);
+ timeline_->AttachPlayer(player2);
+
+ player1->set_layer_animation_delegate(&delegate1);
+ player2->set_layer_animation_delegate(&delegate2);
+
+ // Attach players to the same layer.
+ player1->AttachLayer(layer_id_);
+ player2->AttachLayer(layer_id_);
+
+ const float start_opacity = .7f;
+ const float end_opacity = .3f;
+
+ const int transform_x = 10;
+ const int transform_y = 20;
+
+ const double duration = 1.;
+
+ AddOpacityTransitionToPlayer(player1.get(), duration, start_opacity,
+ end_opacity, false);
+ AddAnimatedTransformToPlayer(player2.get(), duration, transform_x,
+ transform_y);
+
+ host_->PushPropertiesTo(host_impl_);
+ host_impl_->animation_registrar()->ActivateAnimations();
+
+ EXPECT_FALSE(delegate1.started_);
+ EXPECT_FALSE(delegate1.finished_);
+
+ EXPECT_FALSE(delegate2.started_);
+ EXPECT_FALSE(delegate2.finished_);
+
+ base::TimeTicks time;
+ time += base::TimeDelta::FromSecondsD(0.1);
+ AnimateLayersTransferEvents(time, 2u);
+
+ EXPECT_TRUE(delegate1.started_);
+ EXPECT_FALSE(delegate1.finished_);
+
+ EXPECT_TRUE(delegate2.started_);
+ EXPECT_FALSE(delegate2.finished_);
+
+ time += base::TimeDelta::FromSecondsD(duration);
+ AnimateLayersTransferEvents(time, 2u);
+
+ EXPECT_TRUE(delegate1.finished_);
+ EXPECT_TRUE(delegate2.finished_);
+
+ client_.ExpectOpacityPropertyMutated(layer_id_, LayerTreeType::ACTIVE,
+ end_opacity);
+ client_.ExpectTransformPropertyMutated(layer_id_, LayerTreeType::ACTIVE,
+ transform_x, transform_y);
+
+ client_impl_.ExpectOpacityPropertyMutated(layer_id_, LayerTreeType::ACTIVE,
+ end_opacity);
+ client_impl_.ExpectTransformPropertyMutated(layer_id_, LayerTreeType::ACTIVE,
+ transform_x, transform_y);
+
+ client_impl_.ExpectOpacityPropertyMutated(layer_id_, LayerTreeType::PENDING,
+ end_opacity);
+ client_impl_.ExpectTransformPropertyMutated(layer_id_, LayerTreeType::PENDING,
+ transform_x, transform_y);
+}
+
+TEST_F(AnimationPlayerTest, AddRemoveAnimationToNonAttachedPlayer) {
+ client_.RegisterLayer(layer_id_, LayerTreeType::ACTIVE);
+ client_impl_.RegisterLayer(layer_id_, LayerTreeType::PENDING);
+ client_impl_.RegisterLayer(layer_id_, LayerTreeType::ACTIVE);
+
+ const double duration = 1.;
+ const float start_opacity = .7f;
+ const float end_opacity = .3f;
+
+ const int filter_id =
+ AddAnimatedFilterToPlayer(player_.get(), duration, 0.1f, 0.9f);
+ const int opacity_id = AddOpacityTransitionToPlayer(
+ player_.get(), duration, start_opacity, end_opacity, false);
+
+ host_->AddAnimationTimeline(timeline_);
+ timeline_->AttachPlayer(player_);
+
+ EXPECT_FALSE(player_->element_animations());
+ player_->RemoveAnimation(filter_id);
+
+ player_->AttachLayer(layer_id_);
+
+ EXPECT_TRUE(player_->element_animations());
+ EXPECT_FALSE(player_->element_animations()
+ ->layer_animation_controller()
+ ->GetAnimationById(filter_id));
+ EXPECT_TRUE(player_->element_animations()
+ ->layer_animation_controller()
+ ->GetAnimationById(opacity_id));
+
+ host_->PushPropertiesTo(host_impl_);
+
+ EXPECT_FALSE(client_.IsPropertyMutated(layer_id_, LayerTreeType::ACTIVE,
+ Animation::OPACITY));
+ EXPECT_FALSE(client_impl_.IsPropertyMutated(layer_id_, LayerTreeType::ACTIVE,
+ Animation::OPACITY));
+
+ EXPECT_FALSE(client_.IsPropertyMutated(layer_id_, LayerTreeType::ACTIVE,
+ Animation::FILTER));
+ EXPECT_FALSE(client_impl_.IsPropertyMutated(layer_id_, LayerTreeType::ACTIVE,
+ Animation::FILTER));
+
+ host_impl_->animation_registrar()->ActivateAnimations();
+
+ base::TimeTicks time;
+ time += base::TimeDelta::FromSecondsD(0.1);
+ AnimateLayersTransferEvents(time, 1u);
+
+ time += base::TimeDelta::FromSecondsD(duration);
+ AnimateLayersTransferEvents(time, 1u);
+
+ client_.ExpectOpacityPropertyMutated(layer_id_, LayerTreeType::ACTIVE,
+ end_opacity);
+ client_impl_.ExpectOpacityPropertyMutated(layer_id_, LayerTreeType::ACTIVE,
+ end_opacity);
+ client_impl_.ExpectOpacityPropertyMutated(layer_id_, LayerTreeType::PENDING,
+ end_opacity);
+
+ EXPECT_FALSE(client_.IsPropertyMutated(layer_id_, LayerTreeType::ACTIVE,
+ Animation::FILTER));
+ EXPECT_FALSE(client_impl_.IsPropertyMutated(layer_id_, LayerTreeType::ACTIVE,
+ Animation::FILTER));
+}
+
+TEST_F(AnimationPlayerTest, AddRemoveAnimationCausesSetNeedsCommit) {
+ client_.RegisterLayer(layer_id_, LayerTreeType::ACTIVE);
+ host_->AddAnimationTimeline(timeline_);
+ timeline_->AttachPlayer(player_);
+ player_->AttachLayer(layer_id_);
+
+ EXPECT_FALSE(client_.mutators_need_commit());
+
+ const int animation_id =
+ AddOpacityTransitionToPlayer(player_.get(), 1., .7f, .3f, false);
+
+ EXPECT_TRUE(client_.mutators_need_commit());
+ client_.set_mutators_need_commit(false);
+
+ player_->PauseAnimation(animation_id, 1.);
+ EXPECT_TRUE(client_.mutators_need_commit());
+ client_.set_mutators_need_commit(false);
+
+ player_->RemoveAnimation(animation_id);
+ EXPECT_TRUE(client_.mutators_need_commit());
+ client_.set_mutators_need_commit(false);
+}
+
+} // namespace
+} // namespace cc
diff --git a/chromium/cc/animation/animation_timeline.cc b/chromium/cc/animation/animation_timeline.cc
new file mode 100644
index 00000000000..9d19f8fbe0b
--- /dev/null
+++ b/chromium/cc/animation/animation_timeline.cc
@@ -0,0 +1,120 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/animation/animation_timeline.h"
+
+#include <algorithm>
+
+#include "cc/animation/animation_player.h"
+
+namespace cc {
+
+scoped_refptr<AnimationTimeline> AnimationTimeline::Create(int id) {
+ return make_scoped_refptr(new AnimationTimeline(id));
+}
+
+AnimationTimeline::AnimationTimeline(int id)
+ : id_(id), animation_host_(), is_impl_only_(false) {
+}
+
+AnimationTimeline::~AnimationTimeline() {
+ for (auto& player : players_)
+ player->SetAnimationTimeline(nullptr);
+}
+
+scoped_refptr<AnimationTimeline> AnimationTimeline::CreateImplInstance() const {
+ scoped_refptr<AnimationTimeline> timeline = AnimationTimeline::Create(id());
+ return timeline;
+}
+
+void AnimationTimeline::SetAnimationHost(AnimationHost* animation_host) {
+ animation_host_ = animation_host;
+ for (auto& player : players_)
+ player->SetAnimationHost(animation_host);
+}
+
+void AnimationTimeline::AttachPlayer(scoped_refptr<AnimationPlayer> player) {
+ DCHECK(animation_host_);
+ player->SetAnimationHost(animation_host_);
+ player->SetAnimationTimeline(this);
+ players_.push_back(player);
+}
+
+void AnimationTimeline::DetachPlayer(scoped_refptr<AnimationPlayer> player) {
+ for (AnimationPlayerList::iterator iter = players_.begin();
+ iter != players_.end(); ++iter) {
+ if (iter->get() != player)
+ continue;
+
+ ErasePlayers(iter, iter + 1);
+ break;
+ }
+
+ player->SetAnimationHost(nullptr);
+}
+
+AnimationPlayer* AnimationTimeline::GetPlayerById(int player_id) const {
+ for (auto& player : players_)
+ if (player->id() == player_id)
+ return player.get();
+ return nullptr;
+}
+
+void AnimationTimeline::ClearPlayers() {
+ ErasePlayers(players_.begin(), players_.end());
+}
+
+void AnimationTimeline::PushPropertiesTo(AnimationTimeline* timeline_impl) {
+ PushAttachedPlayersToImplThread(timeline_impl);
+ RemoveDetachedPlayersFromImplThread(timeline_impl);
+ PushPropertiesToImplThread(timeline_impl);
+}
+
+void AnimationTimeline::PushAttachedPlayersToImplThread(
+ AnimationTimeline* timeline_impl) const {
+ for (auto& player : players_) {
+ AnimationPlayer* player_impl = timeline_impl->GetPlayerById(player->id());
+ if (player_impl)
+ continue;
+
+ scoped_refptr<AnimationPlayer> to_add = player->CreateImplInstance();
+ timeline_impl->AttachPlayer(to_add.get());
+ }
+}
+
+void AnimationTimeline::RemoveDetachedPlayersFromImplThread(
+ AnimationTimeline* timeline_impl) const {
+ AnimationPlayerList& players_impl = timeline_impl->players_;
+
+ auto to_erase =
+ std::partition(players_impl.begin(), players_impl.end(),
+ [this](AnimationPlayerList::value_type player_impl) {
+ return GetPlayerById(player_impl->id());
+ });
+
+ timeline_impl->ErasePlayers(to_erase, players_impl.end());
+}
+
+void AnimationTimeline::ErasePlayers(AnimationPlayerList::iterator begin,
+ AnimationPlayerList::iterator end) {
+ for (auto i = begin; i != end; ++i) {
+ auto& player = *i;
+ if (player->element_animations())
+ player->DetachLayer();
+ player->SetAnimationTimeline(nullptr);
+ }
+
+ players_.erase(begin, end);
+}
+
+void AnimationTimeline::PushPropertiesToImplThread(
+ AnimationTimeline* timeline_impl) {
+ for (auto& player : players_) {
+ AnimationPlayer* player_impl = timeline_impl->GetPlayerById(player->id());
+ if (player_impl)
+ player->PushPropertiesTo(player_impl);
+ }
+}
+
+} // namespace cc
diff --git a/chromium/cc/animation/animation_timeline.h b/chromium/cc/animation/animation_timeline.h
new file mode 100644
index 00000000000..4cb31f5c076
--- /dev/null
+++ b/chromium/cc/animation/animation_timeline.h
@@ -0,0 +1,77 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_ANIMATION_ANIMATION_TIMELINE_H_
+#define CC_ANIMATION_ANIMATION_TIMELINE_H_
+
+#include <vector>
+
+#include "base/containers/hash_tables.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "cc/base/cc_export.h"
+
+namespace cc {
+
+class AnimationHost;
+class AnimationPlayer;
+
+typedef std::vector<scoped_refptr<AnimationPlayer>> AnimationPlayerList;
+
+// An AnimationTimeline owns a group of AnimationPlayers.
+// This is a cc counterpart for blink::AnimationTimeline (in 1:1 relationship).
+// Each AnimationTimeline and its AnimationPlayers have their copies on
+// the impl thread. We synchronize main thread and impl thread instances
+// using integer IDs.
+class CC_EXPORT AnimationTimeline : public base::RefCounted<AnimationTimeline> {
+ public:
+ static scoped_refptr<AnimationTimeline> Create(int id);
+ scoped_refptr<AnimationTimeline> CreateImplInstance() const;
+
+ int id() const { return id_; }
+
+ // Parent AnimationHost.
+ AnimationHost* animation_host() { return animation_host_; }
+ const AnimationHost* animation_host() const { return animation_host_; }
+ void SetAnimationHost(AnimationHost* animation_host);
+
+ void set_is_impl_only(bool is_impl_only) { is_impl_only_ = is_impl_only; }
+ bool is_impl_only() const { return is_impl_only_; }
+
+ void AttachPlayer(scoped_refptr<AnimationPlayer> player);
+ void DetachPlayer(scoped_refptr<AnimationPlayer> player);
+
+ void ClearPlayers();
+
+ void PushPropertiesTo(AnimationTimeline* timeline_impl);
+
+ AnimationPlayer* GetPlayerById(int player_id) const;
+
+ private:
+ friend class base::RefCounted<AnimationTimeline>;
+
+ explicit AnimationTimeline(int id);
+ virtual ~AnimationTimeline();
+
+ void PushAttachedPlayersToImplThread(AnimationTimeline* timeline) const;
+ void RemoveDetachedPlayersFromImplThread(AnimationTimeline* timeline) const;
+ void PushPropertiesToImplThread(AnimationTimeline* timeline);
+
+ void ErasePlayers(AnimationPlayerList::iterator begin,
+ AnimationPlayerList::iterator end);
+
+ AnimationPlayerList players_;
+ int id_;
+ AnimationHost* animation_host_;
+
+ // Impl-only AnimationTimeline has no main thread instance and lives on
+ // it's own.
+ bool is_impl_only_;
+
+ DISALLOW_COPY_AND_ASSIGN(AnimationTimeline);
+};
+
+} // namespace cc
+
+#endif // CC_ANIMATION_ANIMATION_TIMELINE_H_
diff --git a/chromium/cc/animation/animation_timeline_unittest.cc b/chromium/cc/animation/animation_timeline_unittest.cc
new file mode 100644
index 00000000000..3b0bc5ab730
--- /dev/null
+++ b/chromium/cc/animation/animation_timeline_unittest.cc
@@ -0,0 +1,99 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/animation/animation_timeline.h"
+
+#include "cc/animation/animation_host.h"
+#include "cc/animation/animation_id_provider.h"
+#include "cc/animation/animation_player.h"
+#include "cc/test/animation_test_common.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+namespace {
+
+TEST(AnimationTimelineTest, SyncPlayersAttachDetach) {
+ scoped_ptr<AnimationHost> host(AnimationHost::Create(ThreadInstance::MAIN));
+ scoped_ptr<AnimationHost> host_impl(
+ AnimationHost::Create(ThreadInstance::IMPL));
+
+ const int timeline_id = AnimationIdProvider::NextTimelineId();
+ const int player_id = AnimationIdProvider::NextPlayerId();
+
+ scoped_refptr<AnimationTimeline> timeline_impl(
+ AnimationTimeline::Create(timeline_id));
+ scoped_refptr<AnimationTimeline> timeline(
+ AnimationTimeline::Create(timeline_id));
+
+ host->AddAnimationTimeline(timeline.get());
+ EXPECT_TRUE(timeline->animation_host());
+
+ host_impl->AddAnimationTimeline(timeline_impl.get());
+ EXPECT_TRUE(timeline_impl->animation_host());
+
+ scoped_refptr<AnimationPlayer> player(AnimationPlayer::Create(player_id));
+ timeline->AttachPlayer(player.get());
+ EXPECT_TRUE(player->animation_timeline());
+
+ EXPECT_FALSE(timeline_impl->GetPlayerById(player_id));
+
+ timeline->PushPropertiesTo(timeline_impl.get());
+
+ scoped_refptr<AnimationPlayer> player_impl =
+ timeline_impl->GetPlayerById(player_id);
+ EXPECT_TRUE(player_impl);
+ EXPECT_EQ(player_impl->id(), player_id);
+ EXPECT_TRUE(player_impl->animation_timeline());
+
+ timeline->PushPropertiesTo(timeline_impl.get());
+ EXPECT_EQ(player_impl, timeline_impl->GetPlayerById(player_id));
+
+ timeline->DetachPlayer(player.get());
+ EXPECT_FALSE(player->animation_timeline());
+
+ timeline->PushPropertiesTo(timeline_impl.get());
+ EXPECT_FALSE(timeline_impl->GetPlayerById(player_id));
+
+ EXPECT_FALSE(player_impl->animation_timeline());
+}
+
+TEST(AnimationTimelineTest, ClearPlayers) {
+ scoped_ptr<AnimationHost> host(AnimationHost::Create(ThreadInstance::MAIN));
+ scoped_ptr<AnimationHost> host_impl(
+ AnimationHost::Create(ThreadInstance::IMPL));
+
+ const int timeline_id = AnimationIdProvider::NextTimelineId();
+ const int player_id1 = AnimationIdProvider::NextPlayerId();
+ const int player_id2 = AnimationIdProvider::NextPlayerId();
+
+ scoped_refptr<AnimationTimeline> timeline_impl(
+ AnimationTimeline::Create(timeline_id));
+ scoped_refptr<AnimationTimeline> timeline(
+ AnimationTimeline::Create(timeline_id));
+
+ host->AddAnimationTimeline(timeline.get());
+ host_impl->AddAnimationTimeline(timeline_impl.get());
+
+ scoped_refptr<AnimationPlayer> player1(AnimationPlayer::Create(player_id1));
+ timeline->AttachPlayer(player1.get());
+ scoped_refptr<AnimationPlayer> player2(AnimationPlayer::Create(player_id2));
+ timeline->AttachPlayer(player2.get());
+
+ timeline->PushPropertiesTo(timeline_impl.get());
+
+ EXPECT_TRUE(timeline_impl->GetPlayerById(player_id1));
+ EXPECT_TRUE(timeline_impl->GetPlayerById(player_id2));
+
+ timeline->ClearPlayers();
+ EXPECT_FALSE(timeline->GetPlayerById(player_id1));
+ EXPECT_FALSE(timeline->GetPlayerById(player_id2));
+
+ timeline_impl->ClearPlayers();
+ EXPECT_FALSE(timeline_impl->GetPlayerById(player_id1));
+ EXPECT_FALSE(timeline_impl->GetPlayerById(player_id2));
+}
+
+} // namespace
+} // namespace cc
diff --git a/chromium/cc/animation/element_animations.cc b/chromium/cc/animation/element_animations.cc
new file mode 100644
index 00000000000..2974bff91a2
--- /dev/null
+++ b/chromium/cc/animation/element_animations.cc
@@ -0,0 +1,250 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/animation/element_animations.h"
+
+#include "cc/animation/animation_host.h"
+#include "cc/animation/animation_player.h"
+#include "cc/animation/animation_registrar.h"
+#include "cc/animation/layer_animation_value_observer.h"
+#include "cc/trees/mutator_host_client.h"
+
+namespace cc {
+
+class ElementAnimations::ValueObserver : public LayerAnimationValueObserver {
+ public:
+ ValueObserver(ElementAnimations* element_animation, LayerTreeType tree_type)
+ : element_animations_(element_animation), tree_type_(tree_type) {
+ DCHECK(element_animations_);
+ }
+
+ // LayerAnimationValueObserver implementation.
+ void OnFilterAnimated(const FilterOperations& filters) override {
+ element_animations_->SetFilterMutated(tree_type_, filters);
+ }
+
+ void OnOpacityAnimated(float opacity) override {
+ element_animations_->SetOpacityMutated(tree_type_, opacity);
+ }
+
+ void OnTransformAnimated(const gfx::Transform& transform) override {
+ element_animations_->SetTransformMutated(tree_type_, transform);
+ }
+
+ void OnScrollOffsetAnimated(const gfx::ScrollOffset& scroll_offset) override {
+ element_animations_->SetScrollOffsetMutated(tree_type_, scroll_offset);
+ }
+
+ void OnAnimationWaitingForDeletion() override {
+ // TODO(loyso): See Layer::OnAnimationWaitingForDeletion. But we always do
+ // PushProperties for AnimationTimelines for now.
+ }
+
+ bool IsActive() const override { return tree_type_ == LayerTreeType::ACTIVE; }
+
+ private:
+ ElementAnimations* element_animations_;
+ const LayerTreeType tree_type_;
+
+ DISALLOW_COPY_AND_ASSIGN(ValueObserver);
+};
+
+scoped_ptr<ElementAnimations> ElementAnimations::Create(AnimationHost* host) {
+ return make_scoped_ptr(new ElementAnimations(host));
+}
+
+ElementAnimations::ElementAnimations(AnimationHost* host)
+ : players_list_(make_scoped_ptr(new PlayersList())), animation_host_(host) {
+ DCHECK(animation_host_);
+}
+
+ElementAnimations::~ElementAnimations() {
+ DCHECK(!layer_animation_controller_);
+}
+
+void ElementAnimations::CreateLayerAnimationController(int layer_id) {
+ DCHECK(layer_id);
+ DCHECK(!layer_animation_controller_);
+ DCHECK(animation_host_);
+
+ AnimationRegistrar* registrar = animation_host_->animation_registrar();
+ DCHECK(registrar);
+
+ layer_animation_controller_ =
+ registrar->GetAnimationControllerForId(layer_id);
+ layer_animation_controller_->SetAnimationRegistrar(registrar);
+ layer_animation_controller_->set_layer_animation_delegate(this);
+ layer_animation_controller_->set_value_provider(this);
+
+ DCHECK(animation_host_->mutator_host_client());
+ if (animation_host_->mutator_host_client()->IsLayerInTree(
+ layer_id, LayerTreeType::ACTIVE))
+ CreateActiveValueObserver();
+ if (animation_host_->mutator_host_client()->IsLayerInTree(
+ layer_id, LayerTreeType::PENDING))
+ CreatePendingValueObserver();
+}
+
+void ElementAnimations::DestroyLayerAnimationController() {
+ DCHECK(animation_host_);
+
+ DestroyPendingValueObserver();
+ DestroyActiveValueObserver();
+
+ if (layer_animation_controller_) {
+ layer_animation_controller_->remove_value_provider(this);
+ layer_animation_controller_->remove_layer_animation_delegate(this);
+ layer_animation_controller_->SetAnimationRegistrar(nullptr);
+ layer_animation_controller_ = nullptr;
+ }
+}
+
+void ElementAnimations::LayerRegistered(int layer_id, LayerTreeType tree_type) {
+ DCHECK(layer_animation_controller_);
+ DCHECK_EQ(layer_animation_controller_->id(), layer_id);
+
+ if (tree_type == LayerTreeType::ACTIVE) {
+ if (!active_value_observer_)
+ CreateActiveValueObserver();
+ } else {
+ if (!pending_value_observer_)
+ CreatePendingValueObserver();
+ }
+}
+
+void ElementAnimations::LayerUnregistered(int layer_id,
+ LayerTreeType tree_type) {
+ DCHECK_EQ(this->layer_id(), layer_id);
+ tree_type == LayerTreeType::ACTIVE ? DestroyActiveValueObserver()
+ : DestroyPendingValueObserver();
+}
+
+void ElementAnimations::AddPlayer(AnimationPlayer* player) {
+ players_list_->Append(player);
+}
+
+void ElementAnimations::RemovePlayer(AnimationPlayer* player) {
+ for (PlayersListNode* node = players_list_->head();
+ node != players_list_->end(); node = node->next()) {
+ if (node->value() == player) {
+ node->RemoveFromList();
+ return;
+ }
+ }
+}
+
+bool ElementAnimations::IsEmpty() const {
+ return players_list_->empty();
+}
+
+void ElementAnimations::PushPropertiesTo(
+ ElementAnimations* element_animations_impl) {
+ DCHECK(layer_animation_controller_);
+ DCHECK(element_animations_impl->layer_animation_controller());
+
+ layer_animation_controller_->PushAnimationUpdatesTo(
+ element_animations_impl->layer_animation_controller());
+}
+
+void ElementAnimations::SetFilterMutated(LayerTreeType tree_type,
+ const FilterOperations& filters) {
+ DCHECK(layer_id());
+ DCHECK(animation_host());
+ DCHECK(animation_host()->mutator_host_client());
+ animation_host()->mutator_host_client()->SetLayerFilterMutated(
+ layer_id(), tree_type, filters);
+}
+
+void ElementAnimations::SetOpacityMutated(LayerTreeType tree_type,
+ float opacity) {
+ DCHECK(layer_id());
+ DCHECK(animation_host());
+ DCHECK(animation_host()->mutator_host_client());
+ animation_host()->mutator_host_client()->SetLayerOpacityMutated(
+ layer_id(), tree_type, opacity);
+}
+
+void ElementAnimations::SetTransformMutated(LayerTreeType tree_type,
+ const gfx::Transform& transform) {
+ DCHECK(layer_id());
+ DCHECK(animation_host());
+ DCHECK(animation_host()->mutator_host_client());
+ animation_host()->mutator_host_client()->SetLayerTransformMutated(
+ layer_id(), tree_type, transform);
+}
+
+void ElementAnimations::SetScrollOffsetMutated(
+ LayerTreeType tree_type,
+ const gfx::ScrollOffset& scroll_offset) {
+ DCHECK(layer_id());
+ DCHECK(animation_host());
+ DCHECK(animation_host()->mutator_host_client());
+ animation_host()->mutator_host_client()->SetLayerScrollOffsetMutated(
+ layer_id(), tree_type, scroll_offset);
+}
+
+void ElementAnimations::CreateActiveValueObserver() {
+ DCHECK(layer_animation_controller_);
+ DCHECK(!active_value_observer_);
+ active_value_observer_ =
+ make_scoped_ptr(new ValueObserver(this, LayerTreeType::ACTIVE));
+ layer_animation_controller_->AddValueObserver(active_value_observer_.get());
+}
+
+void ElementAnimations::DestroyActiveValueObserver() {
+ if (layer_animation_controller_ && active_value_observer_)
+ layer_animation_controller_->RemoveValueObserver(
+ active_value_observer_.get());
+ active_value_observer_ = nullptr;
+}
+
+void ElementAnimations::CreatePendingValueObserver() {
+ DCHECK(layer_animation_controller_);
+ DCHECK(!pending_value_observer_);
+ pending_value_observer_ =
+ make_scoped_ptr(new ValueObserver(this, LayerTreeType::PENDING));
+ layer_animation_controller_->AddValueObserver(pending_value_observer_.get());
+}
+
+void ElementAnimations::DestroyPendingValueObserver() {
+ if (layer_animation_controller_ && pending_value_observer_)
+ layer_animation_controller_->RemoveValueObserver(
+ pending_value_observer_.get());
+ pending_value_observer_ = nullptr;
+}
+
+void ElementAnimations::NotifyAnimationStarted(
+ base::TimeTicks monotonic_time,
+ Animation::TargetProperty target_property,
+ int group) {
+ for (PlayersListNode* node = players_list_->head();
+ node != players_list_->end(); node = node->next()) {
+ AnimationPlayer* player = node->value();
+ player->NotifyAnimationStarted(monotonic_time, target_property, group);
+ }
+}
+
+void ElementAnimations::NotifyAnimationFinished(
+ base::TimeTicks monotonic_time,
+ Animation::TargetProperty target_property,
+ int group) {
+ for (PlayersListNode* node = players_list_->head();
+ node != players_list_->end(); node = node->next()) {
+ AnimationPlayer* player = node->value();
+ player->NotifyAnimationFinished(monotonic_time, target_property, group);
+ }
+}
+
+gfx::ScrollOffset ElementAnimations::ScrollOffsetForAnimation() const {
+ DCHECK(layer_animation_controller_);
+ if (animation_host()) {
+ DCHECK(animation_host()->mutator_host_client());
+ return animation_host()->mutator_host_client()->GetScrollOffsetForAnimation(
+ layer_id());
+ }
+
+ return gfx::ScrollOffset();
+}
+
+} // namespace cc
diff --git a/chromium/cc/animation/element_animations.h b/chromium/cc/animation/element_animations.h
new file mode 100644
index 00000000000..6fb2a429d4a
--- /dev/null
+++ b/chromium/cc/animation/element_animations.h
@@ -0,0 +1,119 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_ANIMATION_ELEMENT_ANIMATIONS_H_
+#define CC_ANIMATION_ELEMENT_ANIMATIONS_H_
+
+#include "base/containers/linked_list.h"
+#include "base/memory/ref_counted.h"
+#include "cc/animation/animation_delegate.h"
+#include "cc/animation/layer_animation_controller.h"
+#include "cc/animation/layer_animation_value_provider.h"
+#include "cc/base/cc_export.h"
+
+namespace gfx {
+class ScrollOffset;
+class Transform;
+}
+
+namespace cc {
+
+class AnimationHost;
+class AnimationPlayer;
+class FilterOperations;
+class LayerAnimationController;
+enum class LayerTreeType;
+
+// An ElementAnimations owns a list of all AnimationPlayers, attached to
+// the layer. Also, it owns LayerAnimationController instance (1:1
+// relationship)
+// ElementAnimations object redirects all events from LAC to the list
+// of animation layers.
+// This is a CC counterpart for blink::ElementAnimations (in 1:1 relationship).
+// No pointer to/from respective blink::ElementAnimations object for now.
+class CC_EXPORT ElementAnimations : public AnimationDelegate,
+ public LayerAnimationValueProvider {
+ public:
+ static scoped_ptr<ElementAnimations> Create(AnimationHost* host);
+ ~ElementAnimations() override;
+
+ int layer_id() const {
+ return layer_animation_controller_ ? layer_animation_controller_->id() : 0;
+ }
+
+ // Parent AnimationHost.
+ AnimationHost* animation_host() { return animation_host_; }
+ const AnimationHost* animation_host() const { return animation_host_; }
+
+ LayerAnimationController* layer_animation_controller() const {
+ return layer_animation_controller_.get();
+ }
+
+ void CreateLayerAnimationController(int layer_id);
+ void DestroyLayerAnimationController();
+
+ void LayerRegistered(int layer_id, LayerTreeType tree_type);
+ void LayerUnregistered(int layer_id, LayerTreeType tree_type);
+
+ bool has_active_value_observer_for_testing() const {
+ return active_value_observer_;
+ }
+ bool has_pending_value_observer_for_testing() const {
+ return pending_value_observer_;
+ }
+
+ void AddPlayer(AnimationPlayer* player);
+ void RemovePlayer(AnimationPlayer* player);
+ bool IsEmpty() const;
+
+ typedef base::LinkedList<AnimationPlayer> PlayersList;
+ typedef base::LinkNode<AnimationPlayer> PlayersListNode;
+ const PlayersList& players_list() const { return *players_list_.get(); }
+
+ void PushPropertiesTo(ElementAnimations* element_animations_impl);
+
+ private:
+ explicit ElementAnimations(AnimationHost* host);
+
+ void SetFilterMutated(LayerTreeType tree_type,
+ const FilterOperations& filters);
+ void SetOpacityMutated(LayerTreeType tree_type, float opacity);
+ void SetTransformMutated(LayerTreeType tree_type,
+ const gfx::Transform& transform);
+ void SetScrollOffsetMutated(LayerTreeType tree_type,
+ const gfx::ScrollOffset& scroll_offset);
+
+ void CreateActiveValueObserver();
+ void DestroyActiveValueObserver();
+
+ void CreatePendingValueObserver();
+ void DestroyPendingValueObserver();
+
+ // AnimationDelegate implementation
+ void NotifyAnimationStarted(base::TimeTicks monotonic_time,
+ Animation::TargetProperty target_property,
+ int group) override;
+ void NotifyAnimationFinished(base::TimeTicks monotonic_time,
+ Animation::TargetProperty target_property,
+ int group) override;
+
+ // LayerAnimationValueProvider implementation.
+ gfx::ScrollOffset ScrollOffsetForAnimation() const override;
+
+ scoped_ptr<PlayersList> players_list_;
+
+ class ValueObserver;
+ scoped_ptr<ValueObserver> active_value_observer_;
+ scoped_ptr<ValueObserver> pending_value_observer_;
+
+ // LAC is owned by ElementAnimations (1:1 relationship).
+ scoped_refptr<LayerAnimationController> layer_animation_controller_;
+ AnimationHost* animation_host_;
+
+ DISALLOW_COPY_AND_ASSIGN(ElementAnimations);
+};
+
+} // namespace cc
+
+#endif // CC_ANIMATION_ELEMENT_ANIMATIONS_H_
diff --git a/chromium/cc/animation/element_animations_unittest.cc b/chromium/cc/animation/element_animations_unittest.cc
new file mode 100644
index 00000000000..b676906c3c8
--- /dev/null
+++ b/chromium/cc/animation/element_animations_unittest.cc
@@ -0,0 +1,218 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/animation/element_animations.h"
+
+#include "cc/animation/animation_delegate.h"
+#include "cc/animation/animation_host.h"
+#include "cc/animation/animation_id_provider.h"
+#include "cc/animation/animation_player.h"
+#include "cc/animation/animation_registrar.h"
+#include "cc/animation/animation_timeline.h"
+#include "cc/test/animation_test_common.h"
+#include "cc/test/animation_timelines_test_common.h"
+
+namespace cc {
+namespace {
+
+class ElementAnimationsTest : public AnimationTimelinesTest {
+ public:
+ ElementAnimationsTest() {}
+ ~ElementAnimationsTest() override {}
+};
+
+// See animation_player_unittest.cc for integration with AnimationPlayer.
+
+TEST_F(ElementAnimationsTest, AttachToLayerInActiveTree) {
+ // Set up the layer which is in active tree for main thread and not
+ // yet passed onto the impl thread.
+ client_.RegisterLayer(layer_id_, LayerTreeType::ACTIVE);
+ client_impl_.RegisterLayer(layer_id_, LayerTreeType::PENDING);
+
+ EXPECT_TRUE(client_.IsLayerInTree(layer_id_, LayerTreeType::ACTIVE));
+ EXPECT_FALSE(client_.IsLayerInTree(layer_id_, LayerTreeType::PENDING));
+
+ host_->AddAnimationTimeline(timeline_);
+
+ timeline_->AttachPlayer(player_);
+ player_->AttachLayer(layer_id_);
+
+ ElementAnimations* element_animations = player_->element_animations();
+ EXPECT_TRUE(element_animations);
+
+ EXPECT_TRUE(element_animations->has_active_value_observer_for_testing());
+ EXPECT_FALSE(element_animations->has_pending_value_observer_for_testing());
+
+ host_->PushPropertiesTo(host_impl_);
+
+ GetImplTimelineAndPlayerByID();
+
+ ElementAnimations* element_animations_impl =
+ player_impl_->element_animations();
+ EXPECT_TRUE(element_animations_impl);
+
+ EXPECT_FALSE(
+ element_animations_impl->has_active_value_observer_for_testing());
+ EXPECT_TRUE(
+ element_animations_impl->has_pending_value_observer_for_testing());
+
+ // Create the layer in the impl active tree.
+ client_impl_.RegisterLayer(layer_id_, LayerTreeType::ACTIVE);
+ EXPECT_TRUE(element_animations_impl->has_active_value_observer_for_testing());
+ EXPECT_TRUE(
+ element_animations_impl->has_pending_value_observer_for_testing());
+
+ EXPECT_TRUE(client_impl_.IsLayerInTree(layer_id_, LayerTreeType::ACTIVE));
+ EXPECT_TRUE(client_impl_.IsLayerInTree(layer_id_, LayerTreeType::PENDING));
+
+ // kill layer on main thread.
+ client_.UnregisterLayer(layer_id_, LayerTreeType::ACTIVE);
+ EXPECT_EQ(element_animations, player_->element_animations());
+ EXPECT_FALSE(element_animations->has_active_value_observer_for_testing());
+ EXPECT_FALSE(element_animations->has_pending_value_observer_for_testing());
+
+ // Sync doesn't detach LayerImpl.
+ host_->PushPropertiesTo(host_impl_);
+ EXPECT_EQ(element_animations_impl, player_impl_->element_animations());
+ EXPECT_TRUE(element_animations_impl->has_active_value_observer_for_testing());
+ EXPECT_TRUE(
+ element_animations_impl->has_pending_value_observer_for_testing());
+
+ // Kill layer on impl thread in pending tree.
+ client_impl_.UnregisterLayer(layer_id_, LayerTreeType::PENDING);
+ EXPECT_EQ(element_animations_impl, player_impl_->element_animations());
+ EXPECT_TRUE(element_animations_impl->has_active_value_observer_for_testing());
+ EXPECT_FALSE(
+ element_animations_impl->has_pending_value_observer_for_testing());
+
+ // Kill layer on impl thread in active tree.
+ client_impl_.UnregisterLayer(layer_id_, LayerTreeType::ACTIVE);
+ EXPECT_EQ(element_animations_impl, player_impl_->element_animations());
+ EXPECT_FALSE(
+ element_animations_impl->has_active_value_observer_for_testing());
+ EXPECT_FALSE(
+ element_animations_impl->has_pending_value_observer_for_testing());
+
+ // Sync doesn't change anything.
+ host_->PushPropertiesTo(host_impl_);
+ EXPECT_EQ(element_animations_impl, player_impl_->element_animations());
+ EXPECT_FALSE(
+ element_animations_impl->has_active_value_observer_for_testing());
+ EXPECT_FALSE(
+ element_animations_impl->has_pending_value_observer_for_testing());
+
+ player_->DetachLayer();
+ EXPECT_FALSE(player_->element_animations());
+
+ // Release ptrs now to test the order of destruction.
+ ReleaseRefPtrs();
+}
+
+TEST_F(ElementAnimationsTest, AttachToNotYetCreatedLayer) {
+ host_->AddAnimationTimeline(timeline_);
+ timeline_->AttachPlayer(player_);
+
+ host_->PushPropertiesTo(host_impl_);
+
+ GetImplTimelineAndPlayerByID();
+
+ player_->AttachLayer(layer_id_);
+
+ ElementAnimations* element_animations = player_->element_animations();
+ EXPECT_TRUE(element_animations);
+
+ EXPECT_FALSE(element_animations->has_active_value_observer_for_testing());
+ EXPECT_FALSE(element_animations->has_pending_value_observer_for_testing());
+
+ host_->PushPropertiesTo(host_impl_);
+
+ ElementAnimations* element_animations_impl =
+ player_impl_->element_animations();
+ EXPECT_TRUE(element_animations_impl);
+
+ EXPECT_FALSE(
+ element_animations_impl->has_active_value_observer_for_testing());
+ EXPECT_FALSE(
+ element_animations_impl->has_pending_value_observer_for_testing());
+
+ // Create layer.
+ client_.RegisterLayer(layer_id_, LayerTreeType::ACTIVE);
+ EXPECT_TRUE(element_animations->has_active_value_observer_for_testing());
+ EXPECT_FALSE(element_animations->has_pending_value_observer_for_testing());
+
+ client_impl_.RegisterLayer(layer_id_, LayerTreeType::PENDING);
+ EXPECT_FALSE(
+ element_animations_impl->has_active_value_observer_for_testing());
+ EXPECT_TRUE(
+ element_animations_impl->has_pending_value_observer_for_testing());
+
+ client_impl_.RegisterLayer(layer_id_, LayerTreeType::ACTIVE);
+ EXPECT_TRUE(element_animations_impl->has_active_value_observer_for_testing());
+ EXPECT_TRUE(
+ element_animations_impl->has_pending_value_observer_for_testing());
+}
+
+TEST_F(ElementAnimationsTest, AddRemovePlayers) {
+ host_->AddAnimationTimeline(timeline_);
+ timeline_->AttachPlayer(player_);
+ player_->AttachLayer(layer_id_);
+
+ ElementAnimations* element_animations = player_->element_animations();
+ EXPECT_TRUE(element_animations);
+
+ scoped_refptr<AnimationPlayer> player1 =
+ AnimationPlayer::Create(AnimationIdProvider::NextPlayerId());
+ scoped_refptr<AnimationPlayer> player2 =
+ AnimationPlayer::Create(AnimationIdProvider::NextPlayerId());
+
+ timeline_->AttachPlayer(player1);
+ timeline_->AttachPlayer(player2);
+
+ // Attach players to the same layer.
+ player1->AttachLayer(layer_id_);
+ player2->AttachLayer(layer_id_);
+
+ EXPECT_EQ(element_animations, player1->element_animations());
+ EXPECT_EQ(element_animations, player2->element_animations());
+
+ host_->PushPropertiesTo(host_impl_);
+ GetImplTimelineAndPlayerByID();
+
+ ElementAnimations* element_animations_impl =
+ player_impl_->element_animations();
+ EXPECT_TRUE(element_animations_impl);
+
+ int list_size_before = 0;
+ for (const ElementAnimations::PlayersListNode* node =
+ element_animations_impl->players_list().head();
+ node != element_animations_impl->players_list().end();
+ node = node->next()) {
+ const AnimationPlayer* player_impl = node->value();
+ EXPECT_TRUE(timeline_->GetPlayerById(player_impl->id()));
+ ++list_size_before;
+ }
+ EXPECT_EQ(3, list_size_before);
+
+ player2->DetachLayer();
+ EXPECT_FALSE(player2->element_animations());
+ EXPECT_EQ(element_animations, player_->element_animations());
+ EXPECT_EQ(element_animations, player1->element_animations());
+
+ host_->PushPropertiesTo(host_impl_);
+ EXPECT_EQ(element_animations_impl, player_impl_->element_animations());
+
+ int list_size_after = 0;
+ for (const ElementAnimations::PlayersListNode* node =
+ element_animations_impl->players_list().head();
+ node != element_animations_impl->players_list().end();
+ node = node->next()) {
+ const AnimationPlayer* player_impl = node->value();
+ EXPECT_TRUE(timeline_->GetPlayerById(player_impl->id()));
+ ++list_size_after;
+ }
+ EXPECT_EQ(2, list_size_after);
+}
+
+} // namespace
+} // namespace cc
diff --git a/chromium/cc/animation/layer_animation_controller.cc b/chromium/cc/animation/layer_animation_controller.cc
index 91bfe54e159..54b1a717f78 100644
--- a/chromium/cc/animation/layer_animation_controller.cc
+++ b/chromium/cc/animation/layer_animation_controller.cc
@@ -584,15 +584,6 @@ void LayerAnimationController::PushNewAnimationsToImplThread(
if (controller_impl->GetAnimationById(animations_[i]->id()))
continue;
- // If the animation is not running on the impl thread, it does not
- // necessarily mean that it needs to be copied over and started; it may
- // have already finished. In this case, the impl thread animation will
- // have already notified that it has started and the main thread animation
- // will no longer need
- // a synchronized start time.
- if (!animations_[i]->needs_synchronized_start_time())
- continue;
-
// Scroll animations always start at the current scroll offset.
if (animations_[i]->target_property() == Animation::SCROLL_OFFSET) {
gfx::ScrollOffset current_scroll_offset;
@@ -764,9 +755,14 @@ void LayerAnimationController::PromoteStartedAnimations(
!animations_[i]->needs_synchronized_start_time())
animations_[i]->set_start_time(monotonic_time);
if (events) {
+ base::TimeTicks start_time;
+ if (animations_[i]->has_set_start_time())
+ start_time = animations_[i]->start_time();
+ else
+ start_time = monotonic_time;
AnimationEvent started_event(
AnimationEvent::STARTED, id_, animations_[i]->group(),
- animations_[i]->target_property(), monotonic_time);
+ animations_[i]->target_property(), start_time);
started_event.is_impl_only = animations_[i]->is_impl_only();
if (started_event.is_impl_only)
NotifyAnimationStarted(started_event);
@@ -819,7 +815,9 @@ void LayerAnimationController::MarkAnimationsForDeletion(
// on the impl thread, we only mark a FINISHED main thread animation for
// deletion once it has received a FINISHED event from the impl thread.
bool animation_i_will_send_or_has_received_finish_event =
- events || animations_[i]->received_finished_event();
+ animations_[i]->is_controlling_instance() ||
+ animations_[i]->is_impl_only() ||
+ animations_[i]->received_finished_event();
// If an animation is finished, and not already marked for deletion,
// find out if all other animations in the same group are also finished.
if (animations_[i]->run_state() == Animation::FINISHED &&
@@ -831,7 +829,9 @@ void LayerAnimationController::MarkAnimationsForDeletion(
all_anims_with_same_id_are_finished = true;
for (size_t j = 0; j < animations_.size(); ++j) {
bool animation_j_will_send_or_has_received_finish_event =
- events || animations_[j]->received_finished_event();
+ animations_[j]->is_controlling_instance() ||
+ animations_[j]->is_impl_only() ||
+ animations_[j]->received_finished_event();
if (group_id == animations_[j]->group()) {
if (!animations_[j]->is_finished() ||
(animations_[j]->run_state() == Animation::FINISHED &&
@@ -984,7 +984,7 @@ void LayerAnimationController::NotifyObserversOpacityAnimated(
bool notify_active_observers,
bool notify_pending_observers) {
if (value_observers_.might_have_observers()) {
- ObserverListBase<LayerAnimationValueObserver>::Iterator it(
+ base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
&value_observers_);
LayerAnimationValueObserver* obs;
while ((obs = it.GetNext()) != nullptr) {
@@ -1001,7 +1001,7 @@ void LayerAnimationController::NotifyObserversTransformAnimated(
bool notify_active_observers,
bool notify_pending_observers) {
if (value_observers_.might_have_observers()) {
- ObserverListBase<LayerAnimationValueObserver>::Iterator it(
+ base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
&value_observers_);
LayerAnimationValueObserver* obs;
while ((obs = it.GetNext()) != nullptr) {
@@ -1018,7 +1018,7 @@ void LayerAnimationController::NotifyObserversFilterAnimated(
bool notify_active_observers,
bool notify_pending_observers) {
if (value_observers_.might_have_observers()) {
- ObserverListBase<LayerAnimationValueObserver>::Iterator it(
+ base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
&value_observers_);
LayerAnimationValueObserver* obs;
while ((obs = it.GetNext()) != nullptr) {
@@ -1035,7 +1035,7 @@ void LayerAnimationController::NotifyObserversScrollOffsetAnimated(
bool notify_active_observers,
bool notify_pending_observers) {
if (value_observers_.might_have_observers()) {
- ObserverListBase<LayerAnimationValueObserver>::Iterator it(
+ base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
&value_observers_);
LayerAnimationValueObserver* obs;
while ((obs = it.GetNext()) != nullptr) {
@@ -1055,7 +1055,7 @@ void LayerAnimationController::NotifyObserversAnimationWaitingForDeletion() {
bool LayerAnimationController::HasValueObserver() {
if (value_observers_.might_have_observers()) {
- ObserverListBase<LayerAnimationValueObserver>::Iterator it(
+ base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
&value_observers_);
return it.GetNext() != nullptr;
}
@@ -1064,7 +1064,7 @@ bool LayerAnimationController::HasValueObserver() {
bool LayerAnimationController::HasActiveValueObserver() {
if (value_observers_.might_have_observers()) {
- ObserverListBase<LayerAnimationValueObserver>::Iterator it(
+ base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
&value_observers_);
LayerAnimationValueObserver* obs;
while ((obs = it.GetNext()) != nullptr)
diff --git a/chromium/cc/animation/layer_animation_controller.h b/chromium/cc/animation/layer_animation_controller.h
index 1ac76fa393e..4b37ad44930 100644
--- a/chromium/cc/animation/layer_animation_controller.h
+++ b/chromium/cc/animation/layer_animation_controller.h
@@ -215,8 +215,8 @@ class CC_EXPORT LayerAnimationController
base::TimeTicks last_tick_time_;
- ObserverList<LayerAnimationValueObserver> value_observers_;
- ObserverList<LayerAnimationEventObserver> event_observers_;
+ base::ObserverList<LayerAnimationValueObserver> value_observers_;
+ base::ObserverList<LayerAnimationEventObserver> event_observers_;
LayerAnimationValueProvider* value_provider_;
diff --git a/chromium/cc/animation/layer_animation_controller_unittest.cc b/chromium/cc/animation/layer_animation_controller_unittest.cc
index ad1d4c9eece..e267eea1288 100644
--- a/chromium/cc/animation/layer_animation_controller_unittest.cc
+++ b/chromium/cc/animation/layer_animation_controller_unittest.cc
@@ -298,12 +298,13 @@ TEST(LayerAnimationControllerTest, DoNotSyncFinishedAnimation) {
scoped_refptr<LayerAnimationController> controller(
LayerAnimationController::Create(0));
controller->AddValueObserver(&dummy);
+ scoped_ptr<AnimationEventsVector> events(
+ make_scoped_ptr(new AnimationEventsVector));
EXPECT_FALSE(controller_impl->GetAnimation(Animation::OPACITY));
int animation_id =
AddOpacityTransitionToController(controller.get(), 1, 0, 1, false);
- int group_id = controller->GetAnimationById(animation_id)->group();
controller->PushAnimationUpdatesTo(controller_impl.get());
controller_impl->ActivateAnimations();
@@ -312,21 +313,30 @@ TEST(LayerAnimationControllerTest, DoNotSyncFinishedAnimation) {
EXPECT_EQ(Animation::WAITING_FOR_TARGET_AVAILABILITY,
controller_impl->GetAnimationById(animation_id)->run_state());
+ events.reset(new AnimationEventsVector);
+ controller_impl->Animate(kInitialTickTime);
+ controller_impl->UpdateState(true, events.get());
+ EXPECT_EQ(1u, events->size());
+ EXPECT_EQ(AnimationEvent::STARTED, (*events)[0].type);
+
// Notify main thread controller that the animation has started.
- AnimationEvent animation_started_event(AnimationEvent::STARTED, 0, group_id,
- Animation::OPACITY, kInitialTickTime);
- controller->NotifyAnimationStarted(animation_started_event);
+ controller->NotifyAnimationStarted((*events)[0]);
- // Force animation to complete on impl thread.
- controller_impl->RemoveAnimation(animation_id);
+ // Complete animation on impl thread.
+ events.reset(new AnimationEventsVector);
+ controller_impl->Animate(kInitialTickTime + TimeDelta::FromSeconds(1));
+ controller_impl->UpdateState(true, events.get());
+ EXPECT_EQ(1u, events->size());
+ EXPECT_EQ(AnimationEvent::FINISHED, (*events)[0].type);
- EXPECT_FALSE(controller_impl->GetAnimationById(animation_id));
+ controller->NotifyAnimationFinished((*events)[0]);
+
+ controller->Animate(kInitialTickTime + TimeDelta::FromSeconds(2));
+ controller->UpdateState(true, nullptr);
controller->PushAnimationUpdatesTo(controller_impl.get());
controller_impl->ActivateAnimations();
-
- // Even though the main thread has a 'new' animation, it should not be pushed
- // because the animation has already completed on the impl thread.
+ EXPECT_FALSE(controller->GetAnimationById(animation_id));
EXPECT_FALSE(controller_impl->GetAnimationById(animation_id));
}
@@ -936,13 +946,13 @@ TEST(LayerAnimationControllerTest, ScrollOffsetRemovalClearsScrollDelta) {
class FakeAnimationDelegate : public AnimationDelegate {
public:
FakeAnimationDelegate()
- : started_(false),
- finished_(false) {}
+ : started_(false), finished_(false), start_time_(base::TimeTicks()) {}
void NotifyAnimationStarted(TimeTicks monotonic_time,
Animation::TargetProperty target_property,
int group) override {
started_ = true;
+ start_time_ = monotonic_time;
}
void NotifyAnimationFinished(TimeTicks monotonic_time,
@@ -955,9 +965,12 @@ class FakeAnimationDelegate : public AnimationDelegate {
bool finished() { return finished_; }
+ TimeTicks start_time() { return start_time_; }
+
private:
bool started_;
bool finished_;
+ TimeTicks start_time_;
};
// Tests that impl-only animations lead to start and finished notifications
@@ -997,6 +1010,97 @@ TEST(LayerAnimationControllerTest,
EXPECT_TRUE(delegate.finished());
}
+// Tests that specified start times are sent to the main thread delegate
+TEST(LayerAnimationControllerTest,
+ SpecifiedStartTimesAreSentToMainThreadDelegate) {
+ FakeLayerAnimationValueObserver dummy_impl;
+ scoped_refptr<LayerAnimationController> controller_impl(
+ LayerAnimationController::Create(0));
+ controller_impl->AddValueObserver(&dummy_impl);
+ FakeLayerAnimationValueObserver dummy;
+ scoped_refptr<LayerAnimationController> controller(
+ LayerAnimationController::Create(0));
+ controller->AddValueObserver(&dummy);
+ FakeAnimationDelegate delegate;
+ controller->set_layer_animation_delegate(&delegate);
+
+ int animation_id =
+ AddOpacityTransitionToController(controller.get(), 1, 0, 1, false);
+
+ const TimeTicks start_time = TicksFromSecondsF(123);
+ controller->GetAnimation(Animation::OPACITY)->set_start_time(start_time);
+
+ controller->PushAnimationUpdatesTo(controller_impl.get());
+ controller_impl->ActivateAnimations();
+
+ EXPECT_TRUE(controller_impl->GetAnimationById(animation_id));
+ EXPECT_EQ(Animation::WAITING_FOR_TARGET_AVAILABILITY,
+ controller_impl->GetAnimationById(animation_id)->run_state());
+
+ AnimationEventsVector events;
+ controller_impl->Animate(kInitialTickTime);
+ controller_impl->UpdateState(true, &events);
+
+ // Synchronize the start times.
+ EXPECT_EQ(1u, events.size());
+ controller->NotifyAnimationStarted(events[0]);
+
+ // Validate start time on the main thread delegate.
+ EXPECT_EQ(start_time, delegate.start_time());
+}
+
+class FakeLayerAnimationEventObserver : public LayerAnimationEventObserver {
+ public:
+ FakeLayerAnimationEventObserver() : start_time_(base::TimeTicks()) {}
+
+ void OnAnimationStarted(const AnimationEvent& event) override {
+ start_time_ = event.monotonic_time;
+ }
+
+ TimeTicks start_time() { return start_time_; }
+
+ private:
+ TimeTicks start_time_;
+};
+
+// Tests that specified start times are sent to the event observers
+TEST(LayerAnimationControllerTest, SpecifiedStartTimesAreSentToEventObservers) {
+ FakeLayerAnimationValueObserver dummy_impl;
+ scoped_refptr<LayerAnimationController> controller_impl(
+ LayerAnimationController::Create(0));
+ controller_impl->AddValueObserver(&dummy_impl);
+ FakeLayerAnimationValueObserver dummy;
+ scoped_refptr<LayerAnimationController> controller(
+ LayerAnimationController::Create(0));
+ controller->AddValueObserver(&dummy);
+ FakeLayerAnimationEventObserver observer;
+ controller->AddEventObserver(&observer);
+
+ int animation_id =
+ AddOpacityTransitionToController(controller.get(), 1, 0, 1, false);
+
+ const TimeTicks start_time = TicksFromSecondsF(123);
+ controller->GetAnimation(Animation::OPACITY)->set_start_time(start_time);
+
+ controller->PushAnimationUpdatesTo(controller_impl.get());
+ controller_impl->ActivateAnimations();
+
+ EXPECT_TRUE(controller_impl->GetAnimationById(animation_id));
+ EXPECT_EQ(Animation::WAITING_FOR_TARGET_AVAILABILITY,
+ controller_impl->GetAnimationById(animation_id)->run_state());
+
+ AnimationEventsVector events;
+ controller_impl->Animate(kInitialTickTime);
+ controller_impl->UpdateState(true, &events);
+
+ // Synchronize the start times.
+ EXPECT_EQ(1u, events.size());
+ controller->NotifyAnimationStarted(events[0]);
+
+ // Validate start time on the event observer.
+ EXPECT_EQ(start_time, observer.start_time());
+}
+
// Tests animations that are waiting for a synchronized start time do not
// finish.
TEST(LayerAnimationControllerTest,
@@ -1423,16 +1527,20 @@ TEST(LayerAnimationControllerTest, SkipUpdateState) {
LayerAnimationController::Create(0));
controller->AddValueObserver(&dummy);
- controller->AddAnimation(CreateAnimation(
+ scoped_ptr<Animation> first_animation(CreateAnimation(
scoped_ptr<AnimationCurve>(new FakeTransformTransition(1)).Pass(), 1,
Animation::TRANSFORM));
+ first_animation->set_is_controlling_instance_for_test(true);
+ controller->AddAnimation(first_animation.Pass());
controller->Animate(kInitialTickTime);
controller->UpdateState(true, events.get());
- controller->AddAnimation(CreateAnimation(
+ scoped_ptr<Animation> second_animation(CreateAnimation(
scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
2, Animation::OPACITY));
+ second_animation->set_is_controlling_instance_for_test(true);
+ controller->AddAnimation(second_animation.Pass());
// Animate but don't UpdateState.
controller->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000));
@@ -1734,12 +1842,17 @@ TEST(LayerAnimationControllerTest, FinishedEventsForGroup) {
const int group_id = 1;
// Add two animations with the same group id but different durations.
- controller_impl->AddAnimation(Animation::Create(
+ scoped_ptr<Animation> first_animation(Animation::Create(
scoped_ptr<AnimationCurve>(new FakeTransformTransition(2.0)).Pass(), 1,
group_id, Animation::TRANSFORM));
- controller_impl->AddAnimation(Animation::Create(
+ first_animation->set_is_controlling_instance_for_test(true);
+ controller_impl->AddAnimation(first_animation.Pass());
+
+ scoped_ptr<Animation> second_animation(Animation::Create(
scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
2, group_id, Animation::OPACITY));
+ second_animation->set_is_controlling_instance_for_test(true);
+ controller_impl->AddAnimation(second_animation.Pass());
controller_impl->Animate(kInitialTickTime);
controller_impl->UpdateState(true, events.get());
@@ -1784,12 +1897,17 @@ TEST(LayerAnimationControllerTest, FinishedAndAbortedEventsForGroup) {
controller_impl->AddValueObserver(&dummy_impl);
// Add two animations with the same group id.
- controller_impl->AddAnimation(CreateAnimation(
+ scoped_ptr<Animation> first_animation(CreateAnimation(
scoped_ptr<AnimationCurve>(new FakeTransformTransition(1.0)).Pass(), 1,
Animation::TRANSFORM));
- controller_impl->AddAnimation(CreateAnimation(
+ first_animation->set_is_controlling_instance_for_test(true);
+ controller_impl->AddAnimation(first_animation.Pass());
+
+ scoped_ptr<Animation> second_animation(CreateAnimation(
scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
1, Animation::OPACITY));
+ second_animation->set_is_controlling_instance_for_test(true);
+ controller_impl->AddAnimation(second_animation.Pass());
controller_impl->Animate(kInitialTickTime);
controller_impl->UpdateState(true, events.get());
diff --git a/chromium/cc/animation/scroll_offset_animation_curve.cc b/chromium/cc/animation/scroll_offset_animation_curve.cc
index 68761fbf8d1..17dff26b9ce 100644
--- a/chromium/cc/animation/scroll_offset_animation_curve.cc
+++ b/chromium/cc/animation/scroll_offset_animation_curve.cc
@@ -35,11 +35,18 @@ static base::TimeDelta DurationFromDelta(const gfx::Vector2dF& delta) {
static scoped_ptr<TimingFunction> EaseOutWithInitialVelocity(double velocity) {
// Based on EaseInOutTimingFunction::Create with first control point rotated.
- const double r2 = 0.42 * 0.42;
- const double v2 = velocity * velocity;
- const double x1 = std::sqrt(r2 / (v2 + 1));
- const double y1 = std::sqrt(r2 * v2 / (v2 + 1));
- return CubicBezierTimingFunction::Create(x1, y1, 0.58, 1);
+ if (std::abs(velocity) < 1000.0) {
+ const double r2 = 0.42 * 0.42;
+ const double v2 = velocity * velocity;
+ const double x1 = std::sqrt(r2 / (v2 + 1));
+ const double y1 = std::sqrt(r2 * v2 / (v2 + 1));
+ return CubicBezierTimingFunction::Create(x1, y1, 0.58, 1);
+ }
+
+ // For large |velocity|, x1 approaches 0 and y1 approaches 0.42. To avoid the
+ // risk of floating point arithmetic involving infinity and NaN, use those
+ // values directly rather than computing them above.
+ return CubicBezierTimingFunction::Create(0, 0.42, 0.58, 1);
}
} // namespace
diff --git a/chromium/cc/animation/scroll_offset_animation_curve_unittest.cc b/chromium/cc/animation/scroll_offset_animation_curve_unittest.cc
index 8aea905dfc2..58875136406 100644
--- a/chromium/cc/animation/scroll_offset_animation_curve_unittest.cc
+++ b/chromium/cc/animation/scroll_offset_animation_curve_unittest.cc
@@ -154,5 +154,28 @@ TEST(ScrollOffsetAnimationCurveTest, UpdateTarget) {
EXPECT_EQ(7200.0, curve->GetValue(base::TimeDelta::FromSecondsD(1.674)).y());
}
+TEST(ScrollOffsetAnimationCurveTest, UpdateTargetWithLargeVelocity) {
+ gfx::ScrollOffset initial_value(0.f, 0.f);
+ gfx::ScrollOffset target_value(0.f, 900.f);
+ scoped_ptr<ScrollOffsetAnimationCurve> curve(
+ ScrollOffsetAnimationCurve::Create(
+ target_value, EaseInOutTimingFunction::Create().Pass()));
+ curve->SetInitialValue(initial_value);
+ EXPECT_EQ(0.5, curve->Duration().InSecondsF());
+
+ EXPECT_EQ(450.0, curve->GetValue(base::TimeDelta::FromSecondsD(0.25)).y());
+
+ // This leads to a new computed velocity larger than 5000.
+ curve->UpdateTarget(0.25, gfx::ScrollOffset(0.0, 450.0001));
+
+ EXPECT_NEAR(0.25015, curve->Duration().InSecondsF(), 0.0001);
+ EXPECT_NEAR(450.0,
+ curve->GetValue(base::TimeDelta::FromSecondsD(0.22501)).y(),
+ 0.001);
+ EXPECT_NEAR(450.0,
+ curve->GetValue(base::TimeDelta::FromSecondsD(0.225015)).y(),
+ 0.001);
+}
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/animation/transform_operation.cc b/chromium/cc/animation/transform_operation.cc
index 7421924aedc..e487921cdb4 100644
--- a/chromium/cc/animation/transform_operation.cc
+++ b/chromium/cc/animation/transform_operation.cc
@@ -41,7 +41,7 @@ static bool ShareSameAxis(const TransformOperation* from,
if (IsOperationIdentity(from) && IsOperationIdentity(to))
return false;
- if (IsOperationIdentity(from) && !IsOperationIdentity(to)) {
+ if (!from && !IsOperationIdentity(to)) {
*axis_x = to->rotate.axis.x;
*axis_y = to->rotate.axis.y;
*axis_z = to->rotate.axis.z;
@@ -49,7 +49,7 @@ static bool ShareSameAxis(const TransformOperation* from,
return true;
}
- if (!IsOperationIdentity(from) && IsOperationIdentity(to)) {
+ if (!IsOperationIdentity(from) && !to) {
*axis_x = from->rotate.axis.x;
*axis_y = from->rotate.axis.y;
*axis_z = from->rotate.axis.z;
diff --git a/chromium/cc/animation/transform_operations.cc b/chromium/cc/animation/transform_operations.cc
index 20e8c6a6587..6631a2a980b 100644
--- a/chromium/cc/animation/transform_operations.cc
+++ b/chromium/cc/animation/transform_operations.cc
@@ -58,25 +58,24 @@ bool TransformOperations::BlendedBoundsForBox(const gfx::BoxF& box,
if (!MatchesTypes(from))
return false;
- size_t num_operations =
- std::max(from_identity ? 0 : from.operations_.size(),
- to_identity ? 0 : operations_.size());
+ size_t num_operations = std::max(from_identity ? 0 : from.operations_.size(),
+ to_identity ? 0 : operations_.size());
// Because we are squashing all of the matrices together when applying
// them to the animation, we must apply them in reverse order when
// not squashing them.
- for (int i = num_operations - 1; i >= 0; --i) {
+ for (size_t i = 0; i < num_operations; ++i) {
+ size_t operation_index = num_operations - 1 - i;
gfx::BoxF bounds_for_operation;
const TransformOperation* from_op =
- from_identity ? nullptr : &from.operations_[i];
- const TransformOperation* to_op = to_identity ? nullptr : &operations_[i];
- if (!TransformOperation::BlendedBoundsForBox(*bounds,
- from_op,
- to_op,
- min_progress,
- max_progress,
- &bounds_for_operation))
+ from_identity ? nullptr : &from.operations_[operation_index];
+ const TransformOperation* to_op =
+ to_identity ? nullptr : &operations_[operation_index];
+ if (!TransformOperation::BlendedBoundsForBox(*bounds, from_op, to_op,
+ min_progress, max_progress,
+ &bounds_for_operation)) {
return false;
+ }
*bounds = bounds_for_operation;
}
@@ -164,16 +163,14 @@ bool TransformOperations::ScaleComponent(gfx::Vector3dF* scale) const {
}
bool TransformOperations::MatchesTypes(const TransformOperations& other) const {
- if (IsIdentity() || other.IsIdentity())
+ if (operations_.size() == 0 || other.operations_.size() == 0)
return true;
if (operations_.size() != other.operations_.size())
return false;
for (size_t i = 0; i < operations_.size(); ++i) {
- if (operations_[i].type != other.operations_[i].type
- && !operations_[i].IsIdentity()
- && !other.operations_[i].IsIdentity())
+ if (operations_[i].type != other.operations_[i].type)
return false;
}
@@ -280,10 +277,9 @@ bool TransformOperations::BlendInternal(const TransformOperations& from,
for (size_t i = 0; i < num_operations; ++i) {
gfx::Transform blended;
if (!TransformOperation::BlendTransformOperations(
- from_identity ? 0 : &from.operations_[i],
- to_identity ? 0 : &operations_[i],
- progress,
- &blended))
+ from.operations_.size() <= i ? 0 : &from.operations_[i],
+ operations_.size() <= i ? 0 : &operations_[i], progress,
+ &blended))
return false;
result->PreconcatTransform(blended);
}
diff --git a/chromium/cc/animation/transform_operations_unittest.cc b/chromium/cc/animation/transform_operations_unittest.cc
index 7aae696db4c..a5cf7ec9619 100644
--- a/chromium/cc/animation/transform_operations_unittest.cc
+++ b/chromium/cc/animation/transform_operations_unittest.cc
@@ -139,14 +139,34 @@ void GetIdentityOperations(ScopedVector<TransformOperations>* operations) {
operations->push_back(to_add);
}
-TEST(TransformOperationTest, IdentityAlwaysMatches) {
+TEST(TransformOperationTest, MatchTypesOrder) {
+ TransformOperations mix_order_identity;
+ mix_order_identity.AppendTranslate(0, 0, 0);
+ mix_order_identity.AppendScale(1, 1, 1);
+ mix_order_identity.AppendTranslate(0, 0, 0);
+
+ TransformOperations mix_order_one;
+ mix_order_one.AppendTranslate(0, 1, 0);
+ mix_order_one.AppendScale(2, 1, 3);
+ mix_order_one.AppendTranslate(1, 0, 0);
+
+ TransformOperations mix_order_two;
+ mix_order_two.AppendTranslate(0, 1, 0);
+ mix_order_two.AppendTranslate(1, 0, 0);
+ mix_order_two.AppendScale(2, 1, 3);
+
+ EXPECT_TRUE(mix_order_identity.MatchesTypes(mix_order_one));
+ EXPECT_FALSE(mix_order_identity.MatchesTypes(mix_order_two));
+ EXPECT_FALSE(mix_order_one.MatchesTypes(mix_order_two));
+}
+
+TEST(TransformOperationTest, NoneAlwaysMatches) {
ScopedVector<TransformOperations> operations;
GetIdentityOperations(&operations);
- for (size_t i = 0; i < operations.size(); ++i) {
- for (size_t j = 0; j < operations.size(); ++j)
- EXPECT_TRUE(operations[i]->MatchesTypes(*operations[j]));
- }
+ TransformOperations none_operation;
+ for (size_t i = 0; i < operations.size(); ++i)
+ EXPECT_TRUE(operations[i]->MatchesTypes(none_operation));
}
TEST(TransformOperationTest, ApplyTranslate) {
@@ -421,18 +441,54 @@ TEST(TransformOperationTest, LargeRotationsWithDifferentAxes) {
expected, operations_to.Blend(operations_from, progress));
}
+TEST(TransformOperationTest, RotationWithSlerpFromZeroDeg) {
+ TransformOperations operations_from;
+ operations_from.AppendRotate(0, 0, 1, 0);
+
+ TransformOperations operations_to;
+ operations_to.AppendRotate(0, 1, 0, 450);
+
+ SkMScalar progress = 0.5f;
+ gfx::Transform matrix_from;
+ matrix_from.RotateAbout(gfx::Vector3dF(0, 0, 1), 0);
+
+ gfx::Transform matrix_to;
+ matrix_to.RotateAbout(gfx::Vector3dF(0, 1, 0), 90);
+
+ gfx::Transform expected = matrix_to;
+ expected.Blend(matrix_from, progress);
+
+ EXPECT_TRANSFORMATION_MATRIX_EQ(
+ expected, operations_to.Blend(operations_from, progress));
+}
+
+TEST(TransformOperationTest, RotationWithoutSlerpFromZeroDeg) {
+ TransformOperations operations_from;
+ operations_from.AppendRotate(0, 0, 1, 0);
+
+ TransformOperations operations_to;
+ operations_to.AppendRotate(0, 0, 1, 450);
+
+ SkMScalar progress = 0.5f;
+ gfx::Transform expected;
+ expected.RotateAbout(gfx::Vector3dF(0, 0, 1), 225);
+
+ EXPECT_TRANSFORMATION_MATRIX_EQ(
+ expected, operations_to.Blend(operations_from, progress));
+}
+
TEST(TransformOperationTest, BlendRotationFromIdentity) {
ScopedVector<TransformOperations> identity_operations;
GetIdentityOperations(&identity_operations);
for (size_t i = 0; i < identity_operations.size(); ++i) {
TransformOperations operations;
- operations.AppendRotate(0, 0, 1, 360);
+ operations.AppendRotate(0, 0, 1, 90);
SkMScalar progress = 0.5f;
gfx::Transform expected;
- expected.RotateAbout(gfx::Vector3dF(0, 0, 1), 180);
+ expected.RotateAbout(gfx::Vector3dF(0, 0, 1), 45);
EXPECT_TRANSFORMATION_MATRIX_EQ(
expected, operations.Blend(*identity_operations[i], progress));
@@ -440,7 +496,7 @@ TEST(TransformOperationTest, BlendRotationFromIdentity) {
progress = -0.5f;
expected.MakeIdentity();
- expected.RotateAbout(gfx::Vector3dF(0, 0, 1), -180);
+ expected.RotateAbout(gfx::Vector3dF(0, 0, 1), -45);
EXPECT_TRANSFORMATION_MATRIX_EQ(
expected, operations.Blend(*identity_operations[i], progress));
@@ -448,7 +504,7 @@ TEST(TransformOperationTest, BlendRotationFromIdentity) {
progress = 1.5f;
expected.MakeIdentity();
- expected.RotateAbout(gfx::Vector3dF(0, 0, 1), 540);
+ expected.RotateAbout(gfx::Vector3dF(0, 0, 1), 135);
EXPECT_TRANSFORMATION_MATRIX_EQ(
expected, operations.Blend(*identity_operations[i], progress));
@@ -523,41 +579,38 @@ TEST(TransformOperationTest, BlendScaleFromIdentity) {
}
}
-TEST(TransformOperationTest, BlendSkewFromIdentity) {
- ScopedVector<TransformOperations> identity_operations;
- GetIdentityOperations(&identity_operations);
+TEST(TransformOperationTest, BlendSkewFromEmpty) {
+ TransformOperations empty_operation;
- for (size_t i = 0; i < identity_operations.size(); ++i) {
- TransformOperations operations;
- operations.AppendSkew(2, 2);
+ TransformOperations operations;
+ operations.AppendSkew(2, 2);
- SkMScalar progress = 0.5f;
+ SkMScalar progress = 0.5f;
- gfx::Transform expected;
- expected.SkewX(1);
- expected.SkewY(1);
+ gfx::Transform expected;
+ expected.SkewX(1);
+ expected.SkewY(1);
- EXPECT_TRANSFORMATION_MATRIX_EQ(
- expected, operations.Blend(*identity_operations[i], progress));
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expected,
+ operations.Blend(empty_operation, progress));
- progress = -0.5f;
+ progress = -0.5f;
- expected.MakeIdentity();
- expected.SkewX(-1);
- expected.SkewY(-1);
+ expected.MakeIdentity();
+ expected.SkewX(-1);
+ expected.SkewY(-1);
- EXPECT_TRANSFORMATION_MATRIX_EQ(
- expected, operations.Blend(*identity_operations[i], progress));
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expected,
+ operations.Blend(empty_operation, progress));
- progress = 1.5f;
+ progress = 1.5f;
- expected.MakeIdentity();
- expected.SkewX(3);
- expected.SkewY(3);
+ expected.MakeIdentity();
+ expected.SkewX(3);
+ expected.SkewY(3);
- EXPECT_TRANSFORMATION_MATRIX_EQ(
- expected, operations.Blend(*identity_operations[i], progress));
- }
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expected,
+ operations.Blend(empty_operation, progress));
}
TEST(TransformOperationTest, BlendPerspectiveFromIdentity) {
@@ -584,12 +637,12 @@ TEST(TransformOperationTest, BlendRotationToIdentity) {
for (size_t i = 0; i < identity_operations.size(); ++i) {
TransformOperations operations;
- operations.AppendRotate(0, 0, 1, 360);
+ operations.AppendRotate(0, 0, 1, 90);
SkMScalar progress = 0.5f;
gfx::Transform expected;
- expected.RotateAbout(gfx::Vector3dF(0, 0, 1), 180);
+ expected.RotateAbout(gfx::Vector3dF(0, 0, 1), 45);
EXPECT_TRANSFORMATION_MATRIX_EQ(
expected, identity_operations[i]->Blend(operations, progress));
@@ -632,23 +685,20 @@ TEST(TransformOperationTest, BlendScaleToIdentity) {
}
}
-TEST(TransformOperationTest, BlendSkewToIdentity) {
- ScopedVector<TransformOperations> identity_operations;
- GetIdentityOperations(&identity_operations);
+TEST(TransformOperationTest, BlendSkewToEmpty) {
+ TransformOperations empty_operation;
- for (size_t i = 0; i < identity_operations.size(); ++i) {
- TransformOperations operations;
- operations.AppendSkew(2, 2);
+ TransformOperations operations;
+ operations.AppendSkew(2, 2);
- SkMScalar progress = 0.5f;
+ SkMScalar progress = 0.5f;
- gfx::Transform expected;
- expected.SkewX(1);
- expected.SkewY(1);
+ gfx::Transform expected;
+ expected.SkewX(1);
+ expected.SkewY(1);
- EXPECT_TRANSFORMATION_MATRIX_EQ(
- expected, identity_operations[i]->Blend(operations, progress));
- }
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expected,
+ empty_operation.Blend(operations, progress));
}
TEST(TransformOperationTest, BlendPerspectiveToIdentity) {
diff --git a/chromium/cc/base/BUILD.gn b/chromium/cc/base/BUILD.gn
index e41c74f1586..98a5d4ad1e6 100644
--- a/chromium/cc/base/BUILD.gn
+++ b/chromium/cc/base/BUILD.gn
@@ -9,17 +9,23 @@ source_set("base") {
"completion_event.h",
"delayed_unique_notifier.cc",
"delayed_unique_notifier.h",
+ "histograms.cc",
+ "histograms.h",
"invalidation_region.cc",
"invalidation_region.h",
+ "list_container.cc",
+ "list_container.h",
"math_util.cc",
"math_util.h",
"region.cc",
"region.h",
+ "resource_id.h",
"rolling_time_delta_history.cc",
"rolling_time_delta_history.h",
"scoped_ptr_algorithm.h",
"scoped_ptr_deque.h",
"scoped_ptr_vector.h",
+ "sidecar_list_container.h",
"simple_enclosed_region.cc",
"simple_enclosed_region.h",
"switches.cc",
@@ -30,7 +36,6 @@ source_set("base") {
"time_util.h",
"unique_notifier.cc",
"unique_notifier.h",
- "util.h",
]
deps = [
diff --git a/chromium/cc/base/histograms.cc b/chromium/cc/base/histograms.cc
new file mode 100644
index 00000000000..9fe1515bc2a
--- /dev/null
+++ b/chromium/cc/base/histograms.cc
@@ -0,0 +1,50 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/base/histograms.h"
+
+#include <algorithm>
+#include <cmath>
+#include <limits>
+
+#include "base/numerics/safe_conversions.h"
+
+namespace cc {
+
+// Minimum elapsed time of 1us to limit weighting of fast calls.
+static const int64 kMinimumTimeMicroseconds = 1;
+
+ScopedUMAHistogramAreaTimerBase::ScopedUMAHistogramAreaTimerBase() : area_(0) {
+}
+
+ScopedUMAHistogramAreaTimerBase::~ScopedUMAHistogramAreaTimerBase() {
+}
+
+bool ScopedUMAHistogramAreaTimerBase::GetHistogramValues(
+ Sample* time_microseconds,
+ Sample* pixels_per_ms) const {
+ return GetHistogramValues(
+ timer_.Elapsed(), area_.ValueOrDefault(std::numeric_limits<int>::max()),
+ time_microseconds, pixels_per_ms);
+}
+
+// static
+bool ScopedUMAHistogramAreaTimerBase::GetHistogramValues(
+ base::TimeDelta elapsed,
+ int area,
+ Sample* time_microseconds,
+ Sample* pixels_per_ms) {
+ elapsed = std::max(
+ elapsed, base::TimeDelta::FromMicroseconds(kMinimumTimeMicroseconds));
+ double area_per_time = area / elapsed.InMillisecondsF();
+ // It is not clear how NaN can get here, but we've gotten crashes from
+ // saturated_cast. http://crbug.com/486214
+ if (std::isnan(area_per_time))
+ return false;
+ *time_microseconds = base::saturated_cast<Sample>(elapsed.InMicroseconds());
+ *pixels_per_ms = base::saturated_cast<Sample>(area_per_time);
+ return true;
+}
+
+} // namespace cc
diff --git a/chromium/cc/base/histograms.h b/chromium/cc/base/histograms.h
new file mode 100644
index 00000000000..0c8a2bc8532
--- /dev/null
+++ b/chromium/cc/base/histograms.h
@@ -0,0 +1,76 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_BASE_HISTOGRAMS_H_
+#define CC_BASE_HISTOGRAMS_H_
+
+#include "base/compiler_specific.h"
+#include "base/metrics/histogram_base.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/numerics/safe_math.h"
+#include "base/time/time.h"
+#include "base/timer/elapsed_timer.h"
+#include "cc/base/cc_export.h"
+
+namespace cc {
+
+// Emits UMA histogram trackers for time spent as well as area (in pixels)
+// processed per unit time. Time is measured in microseconds, and work in
+// pixels per millisecond.
+//
+// Usage:
+// // Outside of a method, perhaps in a namespace.
+// DEFINE_SCOPED_UMA_HISTOGRAM_AREA_TIMER(ScopedReticulateSplinesTimer,
+// "ReticulateSplinesUs",
+// "ReticulateSplinesPixelsPerMs");
+//
+// // Inside a method.
+// ScopedReticulateSplinesTimer timer;
+// timer.AddArea(some_rect.size().GetArea());
+#define DEFINE_SCOPED_UMA_HISTOGRAM_AREA_TIMER(class_name, time_histogram, \
+ area_histogram) \
+ class class_name : public ::cc::ScopedUMAHistogramAreaTimerBase { \
+ public: \
+ ~class_name(); \
+ }; \
+ class_name::~class_name() { \
+ Sample time_sample; \
+ Sample area_sample; \
+ if (GetHistogramValues(&time_sample, &area_sample)) { \
+ UMA_HISTOGRAM_COUNTS(time_histogram, time_sample); \
+ UMA_HISTOGRAM_COUNTS(area_histogram, area_sample); \
+ } \
+ }
+
+class CC_EXPORT ScopedUMAHistogramAreaTimerBase {
+ public:
+ void AddArea(int area) { area_ += area; }
+ void SetArea(int area) { area_ = area; }
+
+ protected:
+ using Sample = base::HistogramBase::Sample;
+
+ ScopedUMAHistogramAreaTimerBase();
+ ~ScopedUMAHistogramAreaTimerBase();
+
+ // Returns true if histograms should be recorded (i.e. values are valid).
+ bool GetHistogramValues(Sample* time_microseconds,
+ Sample* pixels_per_ms) const;
+
+ private:
+ static bool GetHistogramValues(base::TimeDelta elapsed,
+ int area,
+ Sample* time_microseconds,
+ Sample* pixels_per_ms);
+
+ base::ElapsedTimer timer_;
+ base::CheckedNumeric<int> area_;
+
+ friend class ScopedUMAHistogramAreaTimerBaseTest;
+ DISALLOW_COPY_AND_ASSIGN(ScopedUMAHistogramAreaTimerBase);
+};
+
+} // namespace cc
+
+#endif // CC_BASE_HISTOGRAMS_H_
diff --git a/chromium/cc/base/histograms_unittest.cc b/chromium/cc/base/histograms_unittest.cc
new file mode 100644
index 00000000000..19bdb09bd7b
--- /dev/null
+++ b/chromium/cc/base/histograms_unittest.cc
@@ -0,0 +1,65 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/base/histograms.h"
+
+#include <limits>
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+using base::TimeDelta;
+using Sample = base::HistogramBase::Sample;
+
+namespace cc {
+
+class ScopedUMAHistogramAreaTimerBaseTest : public ::testing::Test {
+ protected:
+ void ExpectValidHistogramValues(base::TimeDelta elapsed,
+ int area,
+ Sample expected_time_microseconds,
+ Sample expected_pixels_per_ms) {
+ Sample time_microseconds;
+ Sample pixels_per_ms;
+ ScopedUMAHistogramAreaTimerBase::GetHistogramValues(
+ elapsed, area, &time_microseconds, &pixels_per_ms);
+ EXPECT_EQ(expected_time_microseconds, time_microseconds);
+ EXPECT_EQ(expected_pixels_per_ms, pixels_per_ms);
+ }
+};
+
+namespace {
+
+TEST_F(ScopedUMAHistogramAreaTimerBaseTest, CommonCase) {
+ ExpectValidHistogramValues(TimeDelta::FromMicroseconds(500), 1000, 500, 2000);
+ ExpectValidHistogramValues(TimeDelta::FromMicroseconds(300), 1000, 300, 3333);
+}
+
+TEST_F(ScopedUMAHistogramAreaTimerBaseTest, ZeroArea) {
+ ExpectValidHistogramValues(TimeDelta::FromMicroseconds(500), 0, 500, 0);
+}
+
+TEST_F(ScopedUMAHistogramAreaTimerBaseTest, ZeroTime) {
+ // 1M pixels/ms, since the time is limited to at least 1us.
+ ExpectValidHistogramValues(TimeDelta(), 1000, 1, 1000000);
+}
+
+TEST_F(ScopedUMAHistogramAreaTimerBaseTest, ZeroTimeAndArea) {
+ ExpectValidHistogramValues(TimeDelta(), 0, 1, 0);
+}
+
+TEST_F(ScopedUMAHistogramAreaTimerBaseTest, VeryLargeTime) {
+ ExpectValidHistogramValues(TimeDelta::FromHours(24), 1000,
+ std::numeric_limits<Sample>::max(), 0);
+}
+
+TEST_F(ScopedUMAHistogramAreaTimerBaseTest, VeryLargeArea) {
+ ExpectValidHistogramValues(TimeDelta::FromMicroseconds(500), 1000000000, 500,
+ 2000000000);
+ ExpectValidHistogramValues(TimeDelta::FromMicroseconds(1000),
+ std::numeric_limits<int>::max(), 1000,
+ std::numeric_limits<Sample>::max());
+}
+
+} // namespace
+} // namespace cc
diff --git a/chromium/cc/base/list_container.cc b/chromium/cc/base/list_container.cc
new file mode 100644
index 00000000000..d5cb4f03260
--- /dev/null
+++ b/chromium/cc/base/list_container.cc
@@ -0,0 +1,520 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/base/list_container.h"
+
+#include <algorithm>
+#include <vector>
+
+#include "cc/base/scoped_ptr_vector.h"
+
+namespace {
+const size_t kDefaultNumElementTypesToReserve = 32;
+} // namespace
+
+namespace cc {
+
+// ListContainerCharAllocator
+////////////////////////////////////////////////////
+// This class deals only with char* and void*. It does allocation and passing
+// out raw pointers, as well as memory deallocation when being destroyed.
+class ListContainerBase::ListContainerCharAllocator {
+ public:
+ // ListContainerCharAllocator::InnerList
+ /////////////////////////////////////////////
+ // This class holds the raw memory chunk, as well as information about its
+ // size and availability.
+ struct InnerList {
+ scoped_ptr<char[]> data;
+ // The number of elements in total the memory can hold. The difference
+ // between capacity and size is the how many more elements this list can
+ // hold.
+ size_t capacity;
+ // The number of elements have been put into this list.
+ size_t size;
+ // The size of each element is in bytes. This is used to move from between
+ // elements' memory locations.
+ size_t step;
+
+ InnerList() : capacity(0), size(0), step(0) {}
+
+ void Erase(char* position) {
+ // Confident that destructor is called by caller of this function. Since
+ // ListContainerCharAllocator does not handle construction after
+ // allocation, it doesn't handle desctrution before deallocation.
+ DCHECK_LE(position, LastElement());
+ DCHECK_GE(position, Begin());
+ char* start = position + step;
+ std::copy(start, End(), position);
+
+ --size;
+ // Decrease capacity to avoid creating not full not last InnerList.
+ --capacity;
+ }
+
+ bool IsEmpty() const { return !size; }
+ bool IsFull() { return capacity == size; }
+ size_t NumElementsAvailable() const { return capacity - size; }
+
+ void* AddElement() {
+ DCHECK_LT(size, capacity);
+ ++size;
+ return LastElement();
+ }
+
+ void RemoveLast() {
+ DCHECK(!IsEmpty());
+ --size;
+ }
+
+ char* Begin() const { return data.get(); }
+ char* End() const { return data.get() + size * step; }
+ char* LastElement() const { return data.get() + (size - 1) * step; }
+ char* ElementAt(size_t index) const { return data.get() + index * step; }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(InnerList);
+ };
+
+ explicit ListContainerCharAllocator(size_t element_size)
+ : element_size_(element_size),
+ size_(0),
+ last_list_index_(0),
+ last_list_(NULL) {
+ AllocateNewList(kDefaultNumElementTypesToReserve);
+ last_list_ = storage_[last_list_index_];
+ }
+
+ ListContainerCharAllocator(size_t element_size, size_t element_count)
+ : element_size_(element_size),
+ size_(0),
+ last_list_index_(0),
+ last_list_(NULL) {
+ AllocateNewList(element_count > 0 ? element_count
+ : kDefaultNumElementTypesToReserve);
+ last_list_ = storage_[last_list_index_];
+ }
+
+ ~ListContainerCharAllocator() {}
+
+ void* Allocate() {
+ if (last_list_->IsFull()) {
+ // Only allocate a new list if there isn't a spare one still there from
+ // previous usage.
+ if (last_list_index_ + 1 >= storage_.size())
+ AllocateNewList(last_list_->capacity * 2);
+
+ ++last_list_index_;
+ last_list_ = storage_[last_list_index_];
+ }
+
+ ++size_;
+ return last_list_->AddElement();
+ }
+
+ size_t element_size() const { return element_size_; }
+ size_t list_count() const { return storage_.size(); }
+ size_t size() const { return size_; }
+ bool IsEmpty() const { return size() == 0; }
+
+ size_t Capacity() const {
+ size_t capacity_sum = 0;
+ for (const auto& inner_list : storage_)
+ capacity_sum += inner_list->capacity;
+ return capacity_sum;
+ }
+
+ void Clear() {
+ // Remove all except for the first InnerList.
+ DCHECK(!storage_.empty());
+ storage_.erase(storage_.begin() + 1, storage_.end());
+ last_list_index_ = 0;
+ last_list_ = storage_[0];
+ last_list_->size = 0;
+ size_ = 0;
+ }
+
+ void RemoveLast() {
+ DCHECK(!IsEmpty());
+ last_list_->RemoveLast();
+ if (last_list_->IsEmpty() && last_list_index_ > 0) {
+ --last_list_index_;
+ last_list_ = storage_[last_list_index_];
+
+ // If there are now two empty inner lists, free one of them.
+ if (last_list_index_ + 2 < storage_.size())
+ storage_.pop_back();
+ }
+ --size_;
+ }
+
+ void Erase(PositionInListContainerCharAllocator position) {
+ DCHECK_EQ(this, position.ptr_to_container);
+ storage_[position.vector_index]->Erase(position.item_iterator);
+ // TODO(weiliangc): Free the InnerList if it is empty.
+ --size_;
+ }
+
+ InnerList* InnerListById(size_t id) const {
+ DCHECK_LT(id, storage_.size());
+ return storage_[id];
+ }
+
+ size_t FirstInnerListId() const {
+ // |size_| > 0 means that at least one vector in |storage_| will be
+ // non-empty.
+ DCHECK_GT(size_, 0u);
+ size_t id = 0;
+ while (storage_[id]->size == 0)
+ ++id;
+ return id;
+ }
+
+ size_t LastInnerListId() const {
+ // |size_| > 0 means that at least one vector in |storage_| will be
+ // non-empty.
+ DCHECK_GT(size_, 0u);
+ size_t id = storage_.size() - 1;
+ while (storage_[id]->size == 0)
+ --id;
+ return id;
+ }
+
+ size_t NumAvailableElementsInLastList() const {
+ return last_list_->NumElementsAvailable();
+ }
+
+ private:
+ void AllocateNewList(size_t list_size) {
+ scoped_ptr<InnerList> new_list(new InnerList);
+ new_list->capacity = list_size;
+ new_list->size = 0;
+ new_list->step = element_size_;
+ new_list->data.reset(new char[list_size * element_size_]);
+ storage_.push_back(new_list.Pass());
+ }
+
+ ScopedPtrVector<InnerList> storage_;
+ const size_t element_size_;
+
+ // The number of elements in the list.
+ size_t size_;
+
+ // The index of the last list to have had elements added to it, or the only
+ // list if the container has not had elements added since being cleared.
+ size_t last_list_index_;
+
+ // This is equivalent to |storage_[last_list_index_]|.
+ InnerList* last_list_;
+
+ DISALLOW_COPY_AND_ASSIGN(ListContainerCharAllocator);
+};
+
+// PositionInListContainerCharAllocator
+//////////////////////////////////////////////////////
+ListContainerBase::PositionInListContainerCharAllocator::
+ PositionInListContainerCharAllocator(
+ const ListContainerBase::PositionInListContainerCharAllocator& other)
+ : ptr_to_container(other.ptr_to_container),
+ vector_index(other.vector_index),
+ item_iterator(other.item_iterator) {
+}
+
+ListContainerBase::PositionInListContainerCharAllocator::
+ PositionInListContainerCharAllocator(
+ ListContainerBase::ListContainerCharAllocator* container,
+ size_t vector_ind,
+ char* item_iter)
+ : ptr_to_container(container),
+ vector_index(vector_ind),
+ item_iterator(item_iter) {
+}
+
+bool ListContainerBase::PositionInListContainerCharAllocator::operator==(
+ const ListContainerBase::PositionInListContainerCharAllocator& other)
+ const {
+ DCHECK_EQ(ptr_to_container, other.ptr_to_container);
+ return vector_index == other.vector_index &&
+ item_iterator == other.item_iterator;
+}
+
+bool ListContainerBase::PositionInListContainerCharAllocator::operator!=(
+ const ListContainerBase::PositionInListContainerCharAllocator& other)
+ const {
+ return !(*this == other);
+}
+
+ListContainerBase::PositionInListContainerCharAllocator
+ListContainerBase::PositionInListContainerCharAllocator::Increment() {
+ ListContainerCharAllocator::InnerList* list =
+ ptr_to_container->InnerListById(vector_index);
+ if (item_iterator == list->LastElement()) {
+ ++vector_index;
+ while (vector_index < ptr_to_container->list_count()) {
+ if (ptr_to_container->InnerListById(vector_index)->size != 0)
+ break;
+ ++vector_index;
+ }
+ if (vector_index < ptr_to_container->list_count())
+ item_iterator = ptr_to_container->InnerListById(vector_index)->Begin();
+ else
+ item_iterator = NULL;
+ } else {
+ item_iterator += list->step;
+ }
+ return *this;
+}
+
+ListContainerBase::PositionInListContainerCharAllocator
+ListContainerBase::PositionInListContainerCharAllocator::ReverseIncrement() {
+ ListContainerCharAllocator::InnerList* list =
+ ptr_to_container->InnerListById(vector_index);
+ if (item_iterator == list->Begin()) {
+ --vector_index;
+ // Since |vector_index| is unsigned, we compare < list_count() instead of
+ // comparing >= 0, as the variable will wrap around when it goes out of
+ // range (below 0).
+ while (vector_index < ptr_to_container->list_count()) {
+ if (ptr_to_container->InnerListById(vector_index)->size != 0)
+ break;
+ --vector_index;
+ }
+ if (vector_index < ptr_to_container->list_count()) {
+ item_iterator =
+ ptr_to_container->InnerListById(vector_index)->LastElement();
+ } else {
+ item_iterator = NULL;
+ }
+ } else {
+ item_iterator -= list->step;
+ }
+ return *this;
+}
+
+// ListContainerBase
+////////////////////////////////////////////
+ListContainerBase::ListContainerBase(size_t max_size_for_derived_class)
+ : data_(new ListContainerCharAllocator(max_size_for_derived_class)) {
+}
+
+ListContainerBase::ListContainerBase(size_t max_size_for_derived_class,
+ size_t num_of_elements_to_reserve_for)
+ : data_(new ListContainerCharAllocator(max_size_for_derived_class,
+ num_of_elements_to_reserve_for)) {
+}
+
+ListContainerBase::~ListContainerBase() {
+}
+
+void ListContainerBase::RemoveLast() {
+ data_->RemoveLast();
+}
+
+void ListContainerBase::EraseAndInvalidateAllPointers(
+ ListContainerBase::Iterator position) {
+ data_->Erase(position);
+}
+
+ListContainerBase::ConstReverseIterator ListContainerBase::crbegin() const {
+ if (data_->IsEmpty())
+ return crend();
+
+ size_t id = data_->LastInnerListId();
+ return ConstReverseIterator(data_.get(), id,
+ data_->InnerListById(id)->LastElement(), 0);
+}
+
+ListContainerBase::ConstReverseIterator ListContainerBase::crend() const {
+ return ConstReverseIterator(data_.get(), static_cast<size_t>(-1), NULL,
+ size());
+}
+
+ListContainerBase::ReverseIterator ListContainerBase::rbegin() {
+ if (data_->IsEmpty())
+ return rend();
+
+ size_t id = data_->LastInnerListId();
+ return ReverseIterator(data_.get(), id,
+ data_->InnerListById(id)->LastElement(), 0);
+}
+
+ListContainerBase::ReverseIterator ListContainerBase::rend() {
+ return ReverseIterator(data_.get(), static_cast<size_t>(-1), NULL, size());
+}
+
+ListContainerBase::ConstIterator ListContainerBase::cbegin() const {
+ if (data_->IsEmpty())
+ return cend();
+
+ size_t id = data_->FirstInnerListId();
+ return ConstIterator(data_.get(), id, data_->InnerListById(id)->Begin(), 0);
+}
+
+ListContainerBase::ConstIterator ListContainerBase::cend() const {
+ if (data_->IsEmpty())
+ return ConstIterator(data_.get(), 0, NULL, size());
+
+ size_t id = data_->list_count();
+ return ConstIterator(data_.get(), id, NULL, size());
+}
+
+ListContainerBase::Iterator ListContainerBase::begin() {
+ if (data_->IsEmpty())
+ return end();
+
+ size_t id = data_->FirstInnerListId();
+ return Iterator(data_.get(), id, data_->InnerListById(id)->Begin(), 0);
+}
+
+ListContainerBase::Iterator ListContainerBase::end() {
+ if (data_->IsEmpty())
+ return Iterator(data_.get(), 0, NULL, size());
+
+ size_t id = data_->list_count();
+ return Iterator(data_.get(), id, NULL, size());
+}
+
+ListContainerBase::ConstIterator ListContainerBase::IteratorAt(
+ size_t index) const {
+ DCHECK_LT(index, size());
+ size_t original_index = index;
+ size_t list_index;
+ for (list_index = 0; list_index < data_->list_count(); ++list_index) {
+ size_t current_size = data_->InnerListById(list_index)->size;
+ if (index < current_size)
+ break;
+ index -= current_size;
+ }
+ return ConstIterator(data_.get(), list_index,
+ data_->InnerListById(list_index)->ElementAt(index),
+ original_index);
+}
+
+ListContainerBase::Iterator ListContainerBase::IteratorAt(size_t index) {
+ DCHECK_LT(index, size());
+ size_t original_index = index;
+ size_t list_index;
+ for (list_index = 0; list_index < data_->list_count(); ++list_index) {
+ size_t current_size = data_->InnerListById(list_index)->size;
+ if (index < current_size)
+ break;
+ index -= current_size;
+ }
+ return Iterator(data_.get(), list_index,
+ data_->InnerListById(list_index)->ElementAt(index),
+ original_index);
+}
+
+void* ListContainerBase::Allocate(size_t size_of_actual_element_in_bytes) {
+ DCHECK_LE(size_of_actual_element_in_bytes, data_->element_size());
+ return data_->Allocate();
+}
+
+size_t ListContainerBase::size() const {
+ return data_->size();
+}
+
+bool ListContainerBase::empty() const {
+ return data_->IsEmpty();
+}
+
+size_t ListContainerBase::MaxSizeForDerivedClass() const {
+ return data_->element_size();
+}
+
+size_t ListContainerBase::GetCapacityInBytes() const {
+ return data_->Capacity() * data_->element_size();
+}
+
+void ListContainerBase::clear() {
+ data_->Clear();
+}
+
+size_t ListContainerBase::AvailableSizeWithoutAnotherAllocationForTesting()
+ const {
+ return data_->NumAvailableElementsInLastList();
+}
+
+// ListContainerBase::Iterator
+/////////////////////////////////////////////////
+ListContainerBase::Iterator::Iterator(ListContainerCharAllocator* container,
+ size_t vector_ind,
+ char* item_iter,
+ size_t index)
+ : PositionInListContainerCharAllocator(container, vector_ind, item_iter),
+ index_(index) {
+}
+
+ListContainerBase::Iterator::~Iterator() {
+}
+
+size_t ListContainerBase::Iterator::index() const {
+ return index_;
+}
+
+// ListContainerBase::ConstIterator
+/////////////////////////////////////////////////
+ListContainerBase::ConstIterator::ConstIterator(
+ const ListContainerBase::Iterator& other)
+ : PositionInListContainerCharAllocator(other), index_(other.index()) {
+}
+
+ListContainerBase::ConstIterator::ConstIterator(
+ ListContainerCharAllocator* container,
+ size_t vector_ind,
+ char* item_iter,
+ size_t index)
+ : PositionInListContainerCharAllocator(container, vector_ind, item_iter),
+ index_(index) {
+}
+
+ListContainerBase::ConstIterator::~ConstIterator() {
+}
+
+size_t ListContainerBase::ConstIterator::index() const {
+ return index_;
+}
+
+// ListContainerBase::ReverseIterator
+/////////////////////////////////////////////////
+ListContainerBase::ReverseIterator::ReverseIterator(
+ ListContainerCharAllocator* container,
+ size_t vector_ind,
+ char* item_iter,
+ size_t index)
+ : PositionInListContainerCharAllocator(container, vector_ind, item_iter),
+ index_(index) {
+}
+
+ListContainerBase::ReverseIterator::~ReverseIterator() {
+}
+
+size_t ListContainerBase::ReverseIterator::index() const {
+ return index_;
+}
+
+// ListContainerBase::ConstReverseIterator
+/////////////////////////////////////////////////
+ListContainerBase::ConstReverseIterator::ConstReverseIterator(
+ const ListContainerBase::ReverseIterator& other)
+ : PositionInListContainerCharAllocator(other), index_(other.index()) {
+}
+
+ListContainerBase::ConstReverseIterator::ConstReverseIterator(
+ ListContainerCharAllocator* container,
+ size_t vector_ind,
+ char* item_iter,
+ size_t index)
+ : PositionInListContainerCharAllocator(container, vector_ind, item_iter),
+ index_(index) {
+}
+
+ListContainerBase::ConstReverseIterator::~ConstReverseIterator() {
+}
+
+size_t ListContainerBase::ConstReverseIterator::index() const {
+ return index_;
+}
+
+} // namespace cc
diff --git a/chromium/cc/base/list_container.h b/chromium/cc/base/list_container.h
new file mode 100644
index 00000000000..ae7afa92e5b
--- /dev/null
+++ b/chromium/cc/base/list_container.h
@@ -0,0 +1,483 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_BASE_LIST_CONTAINER_H_
+#define CC_BASE_LIST_CONTAINER_H_
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "cc/base/cc_export.h"
+
+namespace cc {
+
+// ListContainer is a container type that handles allocating contiguous memory
+// for new elements and traversing through elements with either iterator or
+// reverse iterator. Since this container hands out raw pointers of its
+// elements, it is very important that this container never reallocate its
+// memory so those raw pointer will continue to be valid. This class is used to
+// contain SharedQuadState or DrawQuad. Since the size of each DrawQuad varies,
+// to hold DrawQuads, the allocations size of each element in this class is
+// LargestDrawQuadSize while BaseElementType is DrawQuad.
+
+// Base class for non-templated logic. All methods are protected, and only
+// exposed by ListContainer<BaseElementType>.
+// For usage, see comments in ListContainer.
+class CC_EXPORT ListContainerBase {
+ protected:
+ explicit ListContainerBase(size_t max_size_for_derived_class);
+ ListContainerBase(size_t max_size_for_derived_class,
+ size_t num_of_elements_to_reserve_for);
+ ~ListContainerBase();
+
+ // This class deals only with char* and void*. It does allocation and passing
+ // out raw pointers, as well as memory deallocation when being destroyed.
+ class ListContainerCharAllocator;
+
+ // This class points to a certain position inside memory of
+ // ListContainerCharAllocator. It is a base class for ListContainer iterators.
+ struct CC_EXPORT PositionInListContainerCharAllocator {
+ ListContainerCharAllocator* ptr_to_container;
+ size_t vector_index;
+ char* item_iterator;
+
+ PositionInListContainerCharAllocator(
+ const PositionInListContainerCharAllocator& other);
+
+ PositionInListContainerCharAllocator(ListContainerCharAllocator* container,
+ size_t vector_ind,
+ char* item_iter);
+
+ bool operator==(const PositionInListContainerCharAllocator& other) const;
+ bool operator!=(const PositionInListContainerCharAllocator& other) const;
+
+ PositionInListContainerCharAllocator Increment();
+ PositionInListContainerCharAllocator ReverseIncrement();
+ };
+
+ // Iterator classes that can be used to access data.
+ /////////////////////////////////////////////////////////////////
+ class CC_EXPORT Iterator : public PositionInListContainerCharAllocator {
+ // This class is only defined to forward iterate through
+ // ListContainerCharAllocator.
+ public:
+ Iterator(ListContainerCharAllocator* container,
+ size_t vector_ind,
+ char* item_iter,
+ size_t index);
+ ~Iterator();
+
+ size_t index() const;
+
+ protected:
+ // This is used to track how many increment has happened since begin(). It
+ // is used to avoid double increment at places an index reference is
+ // needed. For iterator this means begin() corresponds to index 0 and end()
+ // corresponds to index |size|.
+ size_t index_;
+ };
+
+ class CC_EXPORT ConstIterator : public PositionInListContainerCharAllocator {
+ // This class is only defined to forward iterate through
+ // ListContainerCharAllocator.
+ public:
+ ConstIterator(ListContainerCharAllocator* container,
+ size_t vector_ind,
+ char* item_iter,
+ size_t index);
+ ConstIterator(const Iterator& other); // NOLINT
+ ~ConstIterator();
+
+ size_t index() const;
+
+ protected:
+ // This is used to track how many increment has happened since begin(). It
+ // is used to avoid double increment at places an index reference is
+ // needed. For iterator this means begin() corresponds to index 0 and end()
+ // corresponds to index |size|.
+ size_t index_;
+ };
+
+ class CC_EXPORT ReverseIterator
+ : public PositionInListContainerCharAllocator {
+ // This class is only defined to reverse iterate through
+ // ListContainerCharAllocator.
+ public:
+ ReverseIterator(ListContainerCharAllocator* container,
+ size_t vector_ind,
+ char* item_iter,
+ size_t index);
+ ~ReverseIterator();
+
+ size_t index() const;
+
+ protected:
+ // This is used to track how many increment has happened since rbegin(). It
+ // is used to avoid double increment at places an index reference is
+ // needed. For reverse iterator this means rbegin() corresponds to index 0
+ // and rend() corresponds to index |size|.
+ size_t index_;
+ };
+
+ class CC_EXPORT ConstReverseIterator
+ : public PositionInListContainerCharAllocator {
+ // This class is only defined to reverse iterate through
+ // ListContainerCharAllocator.
+ public:
+ ConstReverseIterator(ListContainerCharAllocator* container,
+ size_t vector_ind,
+ char* item_iter,
+ size_t index);
+ ConstReverseIterator(const ReverseIterator& other); // NOLINT
+ ~ConstReverseIterator();
+
+ size_t index() const;
+
+ protected:
+ // This is used to track how many increment has happened since rbegin(). It
+ // is used to avoid double increment at places an index reference is
+ // needed. For reverse iterator this means rbegin() corresponds to index 0
+ // and rend() corresponds to index |size|.
+ size_t index_;
+ };
+
+ // Unlike the ListContainer methods, these do not invoke element destructors.
+ void RemoveLast();
+ void EraseAndInvalidateAllPointers(Iterator position);
+
+ ConstReverseIterator crbegin() const;
+ ConstReverseIterator crend() const;
+ ReverseIterator rbegin();
+ ReverseIterator rend();
+ ConstIterator cbegin() const;
+ ConstIterator cend() const;
+ Iterator begin();
+ Iterator end();
+
+ Iterator IteratorAt(size_t index);
+ ConstIterator IteratorAt(size_t index) const;
+
+ size_t size() const;
+ bool empty() const;
+
+ size_t MaxSizeForDerivedClass() const;
+
+ size_t GetCapacityInBytes() const;
+
+ // Unlike the ListContainer method, this one does not invoke element
+ // destructors.
+ void clear();
+
+ size_t AvailableSizeWithoutAnotherAllocationForTesting() const;
+
+ // Hands out memory location for an element at the end of data structure.
+ void* Allocate(size_t size_of_actual_element_in_bytes);
+
+ scoped_ptr<ListContainerCharAllocator> data_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ListContainerBase);
+};
+
+template <class BaseElementType>
+class ListContainer : public ListContainerBase {
+ public:
+ // BaseElementType is the type of raw pointers this class hands out; however,
+ // its derived classes might require different memory sizes.
+ // max_size_for_derived_class the largest memory size required for all the
+ // derived classes to use for allocation.
+ explicit ListContainer(size_t max_size_for_derived_class)
+ : ListContainerBase(max_size_for_derived_class) {}
+
+ // This constructor omits input variable for max_size_for_derived_class. This
+ // is used when there is no derived classes from BaseElementType we need to
+ // worry about, and allocation size is just sizeof(BaseElementType).
+ ListContainer() : ListContainerBase(sizeof(BaseElementType)) {}
+
+ // This constructor reserves the requested memory up front so only single
+ // allocation is needed. When num_of_elements_to_reserve_for is zero, use the
+ // default size.
+ ListContainer(size_t max_size_for_derived_class,
+ size_t num_of_elements_to_reserve_for)
+ : ListContainerBase(max_size_for_derived_class,
+ num_of_elements_to_reserve_for) {}
+
+ ~ListContainer() {
+ for (Iterator i = begin(); i != end(); ++i) {
+ i->~BaseElementType();
+ }
+ }
+
+ class Iterator;
+ class ConstIterator;
+ class ReverseIterator;
+ class ConstReverseIterator;
+
+ // Removes the last element of the list and makes its space available for
+ // allocation.
+ void RemoveLast() {
+ DCHECK(!empty());
+ back()->~BaseElementType();
+ ListContainerBase::RemoveLast();
+ }
+
+ // When called, all raw pointers that have been handed out are no longer
+ // valid. Use with caution.
+ // This function does not deallocate memory.
+ void EraseAndInvalidateAllPointers(Iterator position) {
+ BaseElementType* item = *position;
+ item->~BaseElementType();
+ ListContainerBase::EraseAndInvalidateAllPointers(position);
+ }
+
+ ConstReverseIterator crbegin() const {
+ return ConstReverseIterator(ListContainerBase::crbegin());
+ }
+ ConstReverseIterator crend() const {
+ return ConstReverseIterator(ListContainerBase::crend());
+ }
+ ConstReverseIterator rbegin() const { return crbegin(); }
+ ConstReverseIterator rend() const { return crend(); }
+ ReverseIterator rbegin() {
+ return ReverseIterator(ListContainerBase::rbegin());
+ }
+ ReverseIterator rend() { return ReverseIterator(ListContainerBase::rend()); }
+ ConstIterator cbegin() const {
+ return ConstIterator(ListContainerBase::cbegin());
+ }
+ ConstIterator cend() const {
+ return ConstIterator(ListContainerBase::cend());
+ }
+ ConstIterator begin() const { return cbegin(); }
+ ConstIterator end() const { return cend(); }
+ Iterator begin() { return Iterator(ListContainerBase::begin()); }
+ Iterator end() { return Iterator(ListContainerBase::end()); }
+
+ // TODO(weiliangc): front(), back() and ElementAt() function should return
+ // reference, consistent with container-of-object.
+ BaseElementType* front() { return *begin(); }
+ BaseElementType* back() { return *rbegin(); }
+ const BaseElementType* front() const { return *begin(); }
+ const BaseElementType* back() const { return *rbegin(); }
+
+ BaseElementType* ElementAt(size_t index) {
+ return *Iterator(IteratorAt(index));
+ }
+ const BaseElementType* ElementAt(size_t index) const {
+ return *ConstIterator(IteratorAt(index));
+ }
+
+ // Take in derived element type and construct it at location generated by
+ // Allocate().
+ template <typename DerivedElementType>
+ DerivedElementType* AllocateAndConstruct() {
+ return new (Allocate(sizeof(DerivedElementType))) DerivedElementType;
+ }
+
+ // Take in derived element type and copy construct it at location generated by
+ // Allocate().
+ template <typename DerivedElementType>
+ DerivedElementType* AllocateAndCopyFrom(const DerivedElementType* source) {
+ return new (Allocate(sizeof(DerivedElementType)))
+ DerivedElementType(*source);
+ }
+
+ // Construct a new element on top of an existing one.
+ template <typename DerivedElementType>
+ DerivedElementType* ReplaceExistingElement(Iterator at) {
+ at->~BaseElementType();
+ return new (*at) DerivedElementType();
+ }
+
+ template <typename DerivedElementType>
+ void swap(ListContainer<DerivedElementType>& other) {
+ data_.swap(other.data_);
+ }
+
+ // Appends a new item without copying. The original item will not be
+ // destructed and will be replaced with a new DerivedElementType. The
+ // DerivedElementType does not have to match the moved type as a full block
+ // of memory will be moved (up to MaxSizeForDerivedClass()). A pointer to
+ // the moved element is returned.
+ template <typename DerivedElementType>
+ DerivedElementType* AppendByMoving(DerivedElementType* item) {
+ size_t max_size_for_derived_class = MaxSizeForDerivedClass();
+ void* new_item = Allocate(max_size_for_derived_class);
+ memcpy(new_item, static_cast<void*>(item), max_size_for_derived_class);
+ // Construct a new element in-place so it can be destructed safely.
+ new (item) DerivedElementType;
+ return static_cast<DerivedElementType*>(new_item);
+ }
+
+ using ListContainerBase::size;
+ using ListContainerBase::empty;
+ using ListContainerBase::GetCapacityInBytes;
+
+ void clear() {
+ for (Iterator i = begin(); i != end(); ++i) {
+ i->~BaseElementType();
+ }
+ ListContainerBase::clear();
+ }
+
+ using ListContainerBase::AvailableSizeWithoutAnotherAllocationForTesting;
+
+ // Iterator classes that can be used to access data.
+ /////////////////////////////////////////////////////////////////
+ class Iterator : public ListContainerBase::Iterator {
+ // This class is only defined to forward iterate through
+ // ListContainerCharAllocator.
+ public:
+ Iterator(ListContainerCharAllocator* container,
+ size_t vector_ind,
+ char* item_iter,
+ size_t index)
+ : ListContainerBase::Iterator(container, vector_ind, item_iter, index) {
+ }
+ BaseElementType* operator->() const {
+ return reinterpret_cast<BaseElementType*>(item_iterator);
+ }
+ BaseElementType* operator*() const {
+ return reinterpret_cast<BaseElementType*>(item_iterator);
+ }
+ Iterator operator++(int unused_post_increment) {
+ Iterator tmp = *this;
+ operator++();
+ return tmp;
+ }
+ Iterator& operator++() {
+ Increment();
+ ++index_;
+ return *this;
+ }
+
+ private:
+ explicit Iterator(const ListContainerBase::Iterator& base_iterator)
+ : ListContainerBase::Iterator(base_iterator) {}
+ friend Iterator ListContainer<BaseElementType>::begin();
+ friend Iterator ListContainer<BaseElementType>::end();
+ friend BaseElementType* ListContainer<BaseElementType>::ElementAt(
+ size_t index);
+ };
+
+ class ConstIterator : public ListContainerBase::ConstIterator {
+ // This class is only defined to forward iterate through
+ // ListContainerCharAllocator.
+ public:
+ ConstIterator(ListContainerCharAllocator* container,
+ size_t vector_ind,
+ char* item_iter,
+ size_t index)
+ : ListContainerBase::ConstIterator(container,
+ vector_ind,
+ item_iter,
+ index) {}
+ ConstIterator(const Iterator& other) // NOLINT
+ : ListContainerBase::ConstIterator(other) {}
+ const BaseElementType* operator->() const {
+ return reinterpret_cast<const BaseElementType*>(item_iterator);
+ }
+ const BaseElementType* operator*() const {
+ return reinterpret_cast<const BaseElementType*>(item_iterator);
+ }
+ ConstIterator operator++(int unused_post_increment) {
+ ConstIterator tmp = *this;
+ operator++();
+ return tmp;
+ }
+ ConstIterator& operator++() {
+ Increment();
+ ++index_;
+ return *this;
+ }
+
+ private:
+ explicit ConstIterator(
+ const ListContainerBase::ConstIterator& base_iterator)
+ : ListContainerBase::ConstIterator(base_iterator) {}
+ friend ConstIterator ListContainer<BaseElementType>::cbegin() const;
+ friend ConstIterator ListContainer<BaseElementType>::cend() const;
+ friend const BaseElementType* ListContainer<BaseElementType>::ElementAt(
+ size_t index) const;
+ };
+
+ class ReverseIterator : public ListContainerBase::ReverseIterator {
+ // This class is only defined to reverse iterate through
+ // ListContainerCharAllocator.
+ public:
+ ReverseIterator(ListContainerCharAllocator* container,
+ size_t vector_ind,
+ char* item_iter,
+ size_t index)
+ : ListContainerBase::ReverseIterator(container,
+ vector_ind,
+ item_iter,
+ index) {}
+ BaseElementType* operator->() const {
+ return reinterpret_cast<BaseElementType*>(item_iterator);
+ }
+ BaseElementType* operator*() const {
+ return reinterpret_cast<BaseElementType*>(item_iterator);
+ }
+ ReverseIterator operator++(int unused_post_increment) {
+ ReverseIterator tmp = *this;
+ operator++();
+ return tmp;
+ }
+ ReverseIterator& operator++() {
+ ReverseIncrement();
+ ++index_;
+ return *this;
+ }
+
+ private:
+ explicit ReverseIterator(ListContainerBase::ReverseIterator base_iterator)
+ : ListContainerBase::ReverseIterator(base_iterator) {}
+ friend ReverseIterator ListContainer<BaseElementType>::rbegin();
+ friend ReverseIterator ListContainer<BaseElementType>::rend();
+ };
+
+ class ConstReverseIterator : public ListContainerBase::ConstReverseIterator {
+ // This class is only defined to reverse iterate through
+ // ListContainerCharAllocator.
+ public:
+ ConstReverseIterator(ListContainerCharAllocator* container,
+ size_t vector_ind,
+ char* item_iter,
+ size_t index)
+ : ListContainerBase::ConstReverseIterator(container,
+ vector_ind,
+ item_iter,
+ index) {}
+ ConstReverseIterator(const ReverseIterator& other) // NOLINT
+ : ListContainerBase::ConstReverseIterator(other) {}
+ const BaseElementType* operator->() const {
+ return reinterpret_cast<const BaseElementType*>(item_iterator);
+ }
+ const BaseElementType* operator*() const {
+ return reinterpret_cast<const BaseElementType*>(item_iterator);
+ }
+ ConstReverseIterator operator++(int unused_post_increment) {
+ ConstReverseIterator tmp = *this;
+ operator++();
+ return tmp;
+ }
+ ConstReverseIterator& operator++() {
+ ReverseIncrement();
+ ++index_;
+ return *this;
+ }
+
+ private:
+ explicit ConstReverseIterator(
+ ListContainerBase::ConstReverseIterator base_iterator)
+ : ListContainerBase::ConstReverseIterator(base_iterator) {}
+ friend ConstReverseIterator ListContainer<BaseElementType>::crbegin() const;
+ friend ConstReverseIterator ListContainer<BaseElementType>::crend() const;
+ };
+};
+
+} // namespace cc
+
+#endif // CC_BASE_LIST_CONTAINER_H_
diff --git a/chromium/cc/base/list_container_unittest.cc b/chromium/cc/base/list_container_unittest.cc
new file mode 100644
index 00000000000..d1fb3fb9490
--- /dev/null
+++ b/chromium/cc/base/list_container_unittest.cc
@@ -0,0 +1,1081 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/base/list_container.h"
+
+#include <algorithm>
+#include <vector>
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+namespace {
+
+// Element class having derived classes.
+class DerivedElement {
+ public:
+ virtual ~DerivedElement() {}
+
+ protected:
+ bool bool_values[1];
+ char char_values[1];
+ int int_values[1];
+ long long_values[1];
+};
+
+class DerivedElement1 : public DerivedElement {
+ protected:
+ bool bool_values1[1];
+ char char_values1[1];
+ int int_values1[1];
+ long long_values1[1];
+};
+
+class DerivedElement2 : public DerivedElement {
+ protected:
+ bool bool_values2[2];
+ char char_values2[2];
+ int int_values2[2];
+ long long_values2[2];
+};
+
+class DerivedElement3 : public DerivedElement {
+ protected:
+ bool bool_values3[3];
+ char char_values3[3];
+ int int_values3[3];
+ long long_values3[3];
+};
+
+const size_t kLargestDerivedElementSize = sizeof(DerivedElement3);
+
+size_t LargestDerivedElementSize() {
+ static_assert(sizeof(DerivedElement1) <= kLargestDerivedElementSize,
+ "Largest Derived Element size needs update. DerivedElement1 is "
+ "currently largest.");
+ static_assert(sizeof(DerivedElement2) <= kLargestDerivedElementSize,
+ "Largest Derived Element size needs update. DerivedElement2 is "
+ "currently largest.");
+
+ return kLargestDerivedElementSize;
+}
+
+// Element class having no derived classes.
+class NonDerivedElement {
+ public:
+ NonDerivedElement() {}
+ ~NonDerivedElement() {}
+
+ int int_values[1];
+};
+
+bool isConstNonDerivedElementPointer(const NonDerivedElement* ptr) {
+ return true;
+}
+
+bool isConstNonDerivedElementPointer(NonDerivedElement* ptr) {
+ return false;
+}
+
+const int kMagicNumberToUseForSimpleDerivedElementOne = 42;
+const int kMagicNumberToUseForSimpleDerivedElementTwo = 314;
+const int kMagicNumberToUseForSimpleDerivedElementThree = 1618;
+
+class SimpleDerivedElement : public DerivedElement {
+ public:
+ ~SimpleDerivedElement() override {}
+ void set_value(int val) { value = val; }
+ int get_value() { return value; }
+
+ private:
+ int value;
+};
+
+class SimpleDerivedElementConstructMagicNumberOne
+ : public SimpleDerivedElement {
+ public:
+ SimpleDerivedElementConstructMagicNumberOne() {
+ set_value(kMagicNumberToUseForSimpleDerivedElementOne);
+ }
+};
+
+class SimpleDerivedElementConstructMagicNumberTwo
+ : public SimpleDerivedElement {
+ public:
+ SimpleDerivedElementConstructMagicNumberTwo() {
+ set_value(kMagicNumberToUseForSimpleDerivedElementTwo);
+ }
+};
+
+class SimpleDerivedElementConstructMagicNumberThree
+ : public SimpleDerivedElement {
+ public:
+ SimpleDerivedElementConstructMagicNumberThree() {
+ set_value(kMagicNumberToUseForSimpleDerivedElementThree);
+ }
+};
+
+class MockDerivedElement : public SimpleDerivedElementConstructMagicNumberOne {
+ public:
+ ~MockDerivedElement() override { Destruct(); }
+ MOCK_METHOD0(Destruct, void());
+};
+
+class MockDerivedElementSubclass : public MockDerivedElement {
+ public:
+ MockDerivedElementSubclass() {
+ set_value(kMagicNumberToUseForSimpleDerivedElementTwo);
+ }
+};
+
+const size_t kCurrentLargestDerivedElementSize =
+ std::max(LargestDerivedElementSize(), sizeof(MockDerivedElementSubclass));
+
+TEST(ListContainerTest, ConstructorCalledInAllocateAndConstruct) {
+ ListContainer<DerivedElement> list(kCurrentLargestDerivedElementSize);
+
+ size_t size = 2;
+ SimpleDerivedElementConstructMagicNumberOne* de_1 =
+ list.AllocateAndConstruct<SimpleDerivedElementConstructMagicNumberOne>();
+ SimpleDerivedElementConstructMagicNumberTwo* de_2 =
+ list.AllocateAndConstruct<SimpleDerivedElementConstructMagicNumberTwo>();
+
+ EXPECT_EQ(size, list.size());
+ EXPECT_EQ(de_1, list.front());
+ EXPECT_EQ(de_2, list.back());
+
+ EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne, de_1->get_value());
+ EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementTwo, de_2->get_value());
+}
+
+TEST(ListContainerTest, DestructorCalled) {
+ ListContainer<DerivedElement> list(kCurrentLargestDerivedElementSize);
+
+ size_t size = 1;
+ MockDerivedElement* de_1 = list.AllocateAndConstruct<MockDerivedElement>();
+
+ EXPECT_CALL(*de_1, Destruct());
+ EXPECT_EQ(size, list.size());
+ EXPECT_EQ(de_1, list.front());
+}
+
+TEST(ListContainerTest, DestructorCalledOnceWhenClear) {
+ ListContainer<DerivedElement> list(kCurrentLargestDerivedElementSize);
+ size_t size = 1;
+ MockDerivedElement* de_1 = list.AllocateAndConstruct<MockDerivedElement>();
+
+ EXPECT_EQ(size, list.size());
+ EXPECT_EQ(de_1, list.front());
+
+ // Make sure destructor is called once during clear, and won't be called
+ // again.
+ testing::MockFunction<void()> separator;
+ {
+ testing::InSequence s;
+ EXPECT_CALL(*de_1, Destruct());
+ EXPECT_CALL(separator, Call());
+ EXPECT_CALL(*de_1, Destruct()).Times(0);
+ }
+
+ list.clear();
+ separator.Call();
+}
+
+TEST(ListContainerTest, ClearDoesNotMalloc) {
+ const size_t reserve = 10;
+ ListContainer<DerivedElement> list(kCurrentLargestDerivedElementSize,
+ reserve);
+
+ // Memory from the initial inner list that should be re-used after clear().
+ std::vector<DerivedElement*> reserved_element_pointers;
+ for (size_t i = 0; i < reserve; i++) {
+ DerivedElement* element = list.AllocateAndConstruct<DerivedElement>();
+ reserved_element_pointers.push_back(element);
+ }
+ EXPECT_EQ(0u, list.AvailableSizeWithoutAnotherAllocationForTesting());
+
+ // Allocate more than the reserve count, forcing new capacity to be added.
+ list.AllocateAndConstruct<DerivedElement>();
+ EXPECT_NE(0u, list.AvailableSizeWithoutAnotherAllocationForTesting());
+
+ // Clear should free all memory except the first |reserve| elements.
+ list.clear();
+ EXPECT_EQ(reserve, list.AvailableSizeWithoutAnotherAllocationForTesting());
+
+ // Verify the first |reserve| elements are re-used after clear().
+ for (size_t i = 0; i < reserve; i++) {
+ DerivedElement* element = list.AllocateAndConstruct<DerivedElement>();
+ EXPECT_EQ(element, reserved_element_pointers[i]);
+ }
+ EXPECT_EQ(0u, list.AvailableSizeWithoutAnotherAllocationForTesting());
+
+ // Verify that capacity can still grow properly.
+ list.AllocateAndConstruct<DerivedElement>();
+ EXPECT_NE(0u, list.AvailableSizeWithoutAnotherAllocationForTesting());
+}
+
+TEST(ListContainerTest, ReplaceExistingElement) {
+ ListContainer<DerivedElement> list(kCurrentLargestDerivedElementSize);
+ size_t size = 1;
+ MockDerivedElement* de_1 = list.AllocateAndConstruct<MockDerivedElement>();
+
+ EXPECT_EQ(size, list.size());
+ EXPECT_EQ(de_1, list.front());
+
+ // Make sure destructor is called once during clear, and won't be called
+ // again.
+ testing::MockFunction<void()> separator;
+ {
+ testing::InSequence s;
+ EXPECT_CALL(*de_1, Destruct());
+ EXPECT_CALL(separator, Call());
+ EXPECT_CALL(*de_1, Destruct()).Times(0);
+ }
+
+ list.ReplaceExistingElement<MockDerivedElementSubclass>(list.begin());
+ EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementTwo, de_1->get_value());
+ separator.Call();
+
+ EXPECT_CALL(*de_1, Destruct());
+ list.clear();
+}
+
+TEST(ListContainerTest, DestructorCalledOnceWhenErase) {
+ ListContainer<DerivedElement> list(kCurrentLargestDerivedElementSize);
+ size_t size = 1;
+ MockDerivedElement* de_1 = list.AllocateAndConstruct<MockDerivedElement>();
+
+ EXPECT_EQ(size, list.size());
+ EXPECT_EQ(de_1, list.front());
+
+ // Make sure destructor is called once during clear, and won't be called
+ // again.
+ testing::MockFunction<void()> separator;
+ {
+ testing::InSequence s;
+ EXPECT_CALL(*de_1, Destruct());
+ EXPECT_CALL(separator, Call());
+ EXPECT_CALL(*de_1, Destruct()).Times(0);
+ }
+
+ list.EraseAndInvalidateAllPointers(list.begin());
+ separator.Call();
+}
+
+TEST(ListContainerTest, SimpleIndexAccessNonDerivedElement) {
+ ListContainer<NonDerivedElement> list;
+
+ size_t size = 3;
+ NonDerivedElement* nde_1 = list.AllocateAndConstruct<NonDerivedElement>();
+ NonDerivedElement* nde_2 = list.AllocateAndConstruct<NonDerivedElement>();
+ NonDerivedElement* nde_3 = list.AllocateAndConstruct<NonDerivedElement>();
+
+ EXPECT_EQ(size, list.size());
+ EXPECT_EQ(nde_1, list.front());
+ EXPECT_EQ(nde_3, list.back());
+ EXPECT_EQ(list.front(), list.ElementAt(0));
+ EXPECT_EQ(nde_2, list.ElementAt(1));
+ EXPECT_EQ(list.back(), list.ElementAt(2));
+}
+
+TEST(ListContainerTest, SimpleInsertionNonDerivedElement) {
+ ListContainer<NonDerivedElement> list;
+
+ size_t size = 3;
+ NonDerivedElement* nde_1 = list.AllocateAndConstruct<NonDerivedElement>();
+ list.AllocateAndConstruct<NonDerivedElement>();
+ NonDerivedElement* nde_3 = list.AllocateAndConstruct<NonDerivedElement>();
+
+ EXPECT_EQ(size, list.size());
+ EXPECT_EQ(nde_1, list.front());
+ EXPECT_EQ(nde_3, list.back());
+}
+
+TEST(ListContainerTest, SimpleInsertionAndClearNonDerivedElement) {
+ ListContainer<NonDerivedElement> list;
+ EXPECT_TRUE(list.empty());
+ EXPECT_EQ(0u, list.size());
+
+ size_t size = 3;
+ NonDerivedElement* nde_1 = list.AllocateAndConstruct<NonDerivedElement>();
+ list.AllocateAndConstruct<NonDerivedElement>();
+ NonDerivedElement* nde_3 = list.AllocateAndConstruct<NonDerivedElement>();
+
+ EXPECT_EQ(size, list.size());
+ EXPECT_EQ(nde_1, list.front());
+ EXPECT_EQ(nde_3, list.back());
+ EXPECT_FALSE(list.empty());
+
+ list.clear();
+ EXPECT_TRUE(list.empty());
+ EXPECT_EQ(0u, list.size());
+}
+
+TEST(ListContainerTest, SimpleInsertionClearAndInsertAgainNonDerivedElement) {
+ ListContainer<NonDerivedElement> list;
+ EXPECT_TRUE(list.empty());
+ EXPECT_EQ(0u, list.size());
+
+ size_t size = 2;
+ NonDerivedElement* nde_front = list.AllocateAndConstruct<NonDerivedElement>();
+ NonDerivedElement* nde_back = list.AllocateAndConstruct<NonDerivedElement>();
+
+ EXPECT_EQ(size, list.size());
+ EXPECT_EQ(nde_front, list.front());
+ EXPECT_EQ(nde_back, list.back());
+ EXPECT_FALSE(list.empty());
+
+ list.clear();
+ EXPECT_TRUE(list.empty());
+ EXPECT_EQ(0u, list.size());
+
+ size = 3;
+ nde_front = list.AllocateAndConstruct<NonDerivedElement>();
+ list.AllocateAndConstruct<NonDerivedElement>();
+ nde_back = list.AllocateAndConstruct<NonDerivedElement>();
+
+ EXPECT_EQ(size, list.size());
+ EXPECT_EQ(nde_front, list.front());
+ EXPECT_EQ(nde_back, list.back());
+ EXPECT_FALSE(list.empty());
+}
+
+// This test is used to test when there is more than one allocation needed
+// for, ListContainer can still perform like normal vector.
+TEST(ListContainerTest,
+ SimpleInsertionTriggerMoreThanOneAllocationNonDerivedElement) {
+ ListContainer<NonDerivedElement> list(sizeof(NonDerivedElement), 2);
+ std::vector<NonDerivedElement*> nde_list;
+ size_t size = 10;
+ for (size_t i = 0; i < size; ++i) {
+ nde_list.push_back(list.AllocateAndConstruct<NonDerivedElement>());
+ }
+ EXPECT_EQ(size, list.size());
+
+ ListContainer<NonDerivedElement>::Iterator iter = list.begin();
+ for (std::vector<NonDerivedElement*>::const_iterator nde_iter =
+ nde_list.begin();
+ nde_iter != nde_list.end(); ++nde_iter) {
+ EXPECT_EQ(*nde_iter, *iter);
+ ++iter;
+ }
+}
+
+TEST(ListContainerTest,
+ CorrectAllocationSizeForMoreThanOneAllocationNonDerivedElement) {
+ // Constructor sets the allocation size to 2. Every time ListContainer needs
+ // to allocate again, it doubles allocation size. In this test, 10 elements is
+ // needed, thus ListContainerShould allocate spaces 2, 4 and 8 elements.
+ ListContainer<NonDerivedElement> list(sizeof(NonDerivedElement), 2);
+ std::vector<NonDerivedElement*> nde_list;
+ size_t size = 10;
+ for (size_t i = 0; i < size; ++i) {
+ // Before asking for a new element, space available without another
+ // allocation follows.
+ switch (i) {
+ case 2:
+ case 6:
+ EXPECT_EQ(0u, list.AvailableSizeWithoutAnotherAllocationForTesting());
+ break;
+ case 1:
+ case 5:
+ EXPECT_EQ(1u, list.AvailableSizeWithoutAnotherAllocationForTesting());
+ break;
+ case 0:
+ case 4:
+ EXPECT_EQ(2u, list.AvailableSizeWithoutAnotherAllocationForTesting());
+ break;
+ case 3:
+ EXPECT_EQ(3u, list.AvailableSizeWithoutAnotherAllocationForTesting());
+ break;
+ case 9:
+ EXPECT_EQ(5u, list.AvailableSizeWithoutAnotherAllocationForTesting());
+ break;
+ case 8:
+ EXPECT_EQ(6u, list.AvailableSizeWithoutAnotherAllocationForTesting());
+ break;
+ case 7:
+ EXPECT_EQ(7u, list.AvailableSizeWithoutAnotherAllocationForTesting());
+ break;
+ default:
+ break;
+ }
+ nde_list.push_back(list.AllocateAndConstruct<NonDerivedElement>());
+ // After asking for a new element, space available without another
+ // allocation follows.
+ switch (i) {
+ case 1:
+ case 5:
+ EXPECT_EQ(0u, list.AvailableSizeWithoutAnotherAllocationForTesting());
+ break;
+ case 0:
+ case 4:
+ EXPECT_EQ(1u, list.AvailableSizeWithoutAnotherAllocationForTesting());
+ break;
+ case 3:
+ EXPECT_EQ(2u, list.AvailableSizeWithoutAnotherAllocationForTesting());
+ break;
+ case 2:
+ EXPECT_EQ(3u, list.AvailableSizeWithoutAnotherAllocationForTesting());
+ break;
+ case 9:
+ EXPECT_EQ(4u, list.AvailableSizeWithoutAnotherAllocationForTesting());
+ break;
+ case 8:
+ EXPECT_EQ(5u, list.AvailableSizeWithoutAnotherAllocationForTesting());
+ break;
+ case 7:
+ EXPECT_EQ(6u, list.AvailableSizeWithoutAnotherAllocationForTesting());
+ break;
+ case 6:
+ EXPECT_EQ(7u, list.AvailableSizeWithoutAnotherAllocationForTesting());
+ break;
+ default:
+ break;
+ }
+ }
+ EXPECT_EQ(size, list.size());
+
+ ListContainer<NonDerivedElement>::Iterator iter = list.begin();
+ for (std::vector<NonDerivedElement*>::const_iterator nde_iter =
+ nde_list.begin();
+ nde_iter != nde_list.end(); ++nde_iter) {
+ EXPECT_EQ(*nde_iter, *iter);
+ ++iter;
+ }
+}
+
+TEST(ListContainerTest, SimpleIterationNonDerivedElement) {
+ ListContainer<NonDerivedElement> list;
+ std::vector<NonDerivedElement*> nde_list;
+ size_t size = 10;
+ for (size_t i = 0; i < size; ++i) {
+ nde_list.push_back(list.AllocateAndConstruct<NonDerivedElement>());
+ }
+ EXPECT_EQ(size, list.size());
+
+ size_t num_iters_in_list = 0;
+ {
+ std::vector<NonDerivedElement*>::const_iterator nde_iter = nde_list.begin();
+ for (ListContainer<NonDerivedElement>::Iterator iter = list.begin();
+ iter != list.end(); ++iter) {
+ EXPECT_EQ(*nde_iter, *iter);
+ ++num_iters_in_list;
+ ++nde_iter;
+ }
+ }
+
+ size_t num_iters_in_vector = 0;
+ {
+ ListContainer<NonDerivedElement>::Iterator iter = list.begin();
+ for (std::vector<NonDerivedElement*>::const_iterator nde_iter =
+ nde_list.begin();
+ nde_iter != nde_list.end(); ++nde_iter) {
+ EXPECT_EQ(*nde_iter, *iter);
+ ++num_iters_in_vector;
+ ++iter;
+ }
+ }
+
+ EXPECT_EQ(num_iters_in_vector, num_iters_in_list);
+}
+
+TEST(ListContainerTest, SimpleConstIteratorIterationNonDerivedElement) {
+ ListContainer<NonDerivedElement> list;
+ std::vector<const NonDerivedElement*> nde_list;
+ size_t size = 10;
+ for (size_t i = 0; i < size; ++i) {
+ nde_list.push_back(list.AllocateAndConstruct<NonDerivedElement>());
+ }
+ EXPECT_EQ(size, list.size());
+
+ {
+ std::vector<const NonDerivedElement*>::const_iterator nde_iter =
+ nde_list.begin();
+ for (ListContainer<NonDerivedElement>::ConstIterator iter = list.begin();
+ iter != list.end(); ++iter) {
+ EXPECT_TRUE(isConstNonDerivedElementPointer(*iter));
+ EXPECT_EQ(*nde_iter, *iter);
+ ++nde_iter;
+ }
+ }
+
+ {
+ std::vector<const NonDerivedElement*>::const_iterator nde_iter =
+ nde_list.begin();
+ for (ListContainer<NonDerivedElement>::Iterator iter = list.begin();
+ iter != list.end(); ++iter) {
+ EXPECT_FALSE(isConstNonDerivedElementPointer(*iter));
+ EXPECT_EQ(*nde_iter, *iter);
+ ++nde_iter;
+ }
+ }
+
+ {
+ ListContainer<NonDerivedElement>::ConstIterator iter = list.begin();
+ for (std::vector<const NonDerivedElement*>::const_iterator nde_iter =
+ nde_list.begin();
+ nde_iter != nde_list.end(); ++nde_iter) {
+ EXPECT_EQ(*nde_iter, *iter);
+ ++iter;
+ }
+ }
+}
+
+TEST(ListContainerTest, SimpleReverseInsertionNonDerivedElement) {
+ ListContainer<NonDerivedElement> list;
+ std::vector<NonDerivedElement*> nde_list;
+ size_t size = 10;
+ for (size_t i = 0; i < size; ++i) {
+ nde_list.push_back(list.AllocateAndConstruct<NonDerivedElement>());
+ }
+ EXPECT_EQ(size, list.size());
+
+ {
+ std::vector<NonDerivedElement*>::const_reverse_iterator nde_iter =
+ nde_list.rbegin();
+ for (ListContainer<NonDerivedElement>::ReverseIterator iter = list.rbegin();
+ iter != list.rend(); ++iter) {
+ EXPECT_EQ(*nde_iter, *iter);
+ ++nde_iter;
+ }
+ }
+
+ {
+ ListContainer<NonDerivedElement>::ReverseIterator iter = list.rbegin();
+ for (std::vector<NonDerivedElement*>::reverse_iterator nde_iter =
+ nde_list.rbegin();
+ nde_iter != nde_list.rend(); ++nde_iter) {
+ EXPECT_EQ(*nde_iter, *iter);
+ ++iter;
+ }
+ }
+}
+
+TEST(ListContainerTest, SimpleDeletion) {
+ ListContainer<DerivedElement> list(kCurrentLargestDerivedElementSize);
+ std::vector<SimpleDerivedElement*> sde_list;
+ int size = 10;
+ for (int i = 0; i < size; ++i) {
+ sde_list.push_back(list.AllocateAndConstruct<SimpleDerivedElement>());
+ sde_list.back()->set_value(i);
+ }
+ EXPECT_EQ(static_cast<size_t>(size), list.size());
+
+ list.EraseAndInvalidateAllPointers(list.begin());
+ --size;
+ EXPECT_EQ(static_cast<size_t>(size), list.size());
+ int i = 1;
+ for (ListContainer<DerivedElement>::Iterator iter = list.begin();
+ iter != list.end(); ++iter) {
+ EXPECT_EQ(i, static_cast<SimpleDerivedElement*>(*iter)->get_value());
+ ++i;
+ }
+}
+
+TEST(ListContainerTest, DeletionAllInAllocation) {
+ const size_t kReserve = 10;
+ ListContainer<DerivedElement> list(kCurrentLargestDerivedElementSize,
+ kReserve);
+ std::vector<SimpleDerivedElement*> sde_list;
+ // Add enough elements to cause another allocation.
+ for (size_t i = 0; i < kReserve + 1; ++i) {
+ sde_list.push_back(list.AllocateAndConstruct<SimpleDerivedElement>());
+ sde_list.back()->set_value(static_cast<int>(i));
+ }
+ EXPECT_EQ(kReserve + 1, list.size());
+
+ // Remove everything in the first allocation.
+ for (size_t i = 0; i < kReserve; ++i)
+ list.EraseAndInvalidateAllPointers(list.begin());
+ EXPECT_EQ(1u, list.size());
+
+ // The last element is left.
+ SimpleDerivedElement* de = static_cast<SimpleDerivedElement*>(*list.begin());
+ EXPECT_EQ(static_cast<int>(kReserve), de->get_value());
+
+ // Remove the element from the 2nd allocation.
+ list.EraseAndInvalidateAllPointers(list.begin());
+ EXPECT_EQ(0u, list.size());
+}
+
+TEST(ListContainerTest, DeletionAllInAllocationReversed) {
+ const size_t kReserve = 10;
+ ListContainer<DerivedElement> list(kCurrentLargestDerivedElementSize,
+ kReserve);
+ std::vector<SimpleDerivedElement*> sde_list;
+ // Add enough elements to cause another allocation.
+ for (size_t i = 0; i < kReserve + 1; ++i) {
+ sde_list.push_back(list.AllocateAndConstruct<SimpleDerivedElement>());
+ sde_list.back()->set_value(static_cast<int>(i));
+ }
+ EXPECT_EQ(kReserve + 1, list.size());
+
+ // Remove everything in the 2nd allocation.
+ auto it = list.begin();
+ for (size_t i = 0; i < kReserve; ++i)
+ ++it;
+ list.EraseAndInvalidateAllPointers(it);
+
+ // The 2nd-last element is next, and the rest of the elements exist.
+ size_t i = kReserve - 1;
+ for (auto it = list.rbegin(); it != list.rend(); ++it) {
+ SimpleDerivedElement* de = static_cast<SimpleDerivedElement*>(*it);
+ EXPECT_EQ(static_cast<int>(i), de->get_value());
+ --i;
+ }
+
+ // Can forward iterate too.
+ i = 0;
+ for (auto it = list.begin(); it != list.end(); ++it) {
+ SimpleDerivedElement* de = static_cast<SimpleDerivedElement*>(*it);
+ EXPECT_EQ(static_cast<int>(i), de->get_value());
+ ++i;
+ }
+
+ // Remove the last thing from the 1st allocation.
+ it = list.begin();
+ for (size_t i = 0; i < kReserve - 1; ++i)
+ ++it;
+ list.EraseAndInvalidateAllPointers(it);
+
+ // The 2nd-last element is next, and the rest of the elements exist.
+ i = kReserve - 2;
+ for (auto it = list.rbegin(); it != list.rend(); ++it) {
+ SimpleDerivedElement* de = static_cast<SimpleDerivedElement*>(*it);
+ EXPECT_EQ(static_cast<int>(i), de->get_value());
+ --i;
+ }
+
+ // Can forward iterate too.
+ i = 0;
+ for (auto it = list.begin(); it != list.end(); ++it) {
+ SimpleDerivedElement* de = static_cast<SimpleDerivedElement*>(*it);
+ EXPECT_EQ(static_cast<int>(i), de->get_value());
+ ++i;
+ }
+}
+
+TEST(ListContainerTest, SimpleIterationAndManipulation) {
+ ListContainer<DerivedElement> list(kCurrentLargestDerivedElementSize);
+ std::vector<SimpleDerivedElement*> sde_list;
+ size_t size = 10;
+ for (size_t i = 0; i < size; ++i) {
+ SimpleDerivedElement* simple_dq =
+ list.AllocateAndConstruct<SimpleDerivedElement>();
+ sde_list.push_back(simple_dq);
+ }
+ EXPECT_EQ(size, list.size());
+
+ ListContainer<DerivedElement>::Iterator iter = list.begin();
+ for (int i = 0; i < 10; ++i) {
+ static_cast<SimpleDerivedElement*>(*iter)->set_value(i);
+ ++iter;
+ }
+
+ int i = 0;
+ for (std::vector<SimpleDerivedElement*>::const_iterator sde_iter =
+ sde_list.begin();
+ sde_iter < sde_list.end(); ++sde_iter) {
+ EXPECT_EQ(i, (*sde_iter)->get_value());
+ ++i;
+ }
+}
+
+TEST(ListContainerTest, SimpleManipulationWithIndexSimpleDerivedElement) {
+ ListContainer<DerivedElement> list(kCurrentLargestDerivedElementSize);
+ std::vector<SimpleDerivedElement*> de_list;
+ int size = 10;
+ for (int i = 0; i < size; ++i) {
+ de_list.push_back(list.AllocateAndConstruct<SimpleDerivedElement>());
+ }
+ EXPECT_EQ(static_cast<size_t>(size), list.size());
+
+ for (int i = 0; i < size; ++i) {
+ static_cast<SimpleDerivedElement*>(list.ElementAt(i))->set_value(i);
+ }
+
+ int i = 0;
+ for (std::vector<SimpleDerivedElement*>::const_iterator
+ de_iter = de_list.begin();
+ de_iter != de_list.end(); ++de_iter, ++i) {
+ EXPECT_EQ(i, (*de_iter)->get_value());
+ }
+}
+
+TEST(ListContainerTest,
+ SimpleManipulationWithIndexMoreThanOneAllocationSimpleDerivedElement) {
+ ListContainer<DerivedElement> list(LargestDerivedElementSize(), 2);
+ std::vector<SimpleDerivedElement*> de_list;
+ int size = 10;
+ for (int i = 0; i < size; ++i) {
+ de_list.push_back(list.AllocateAndConstruct<SimpleDerivedElement>());
+ }
+ EXPECT_EQ(static_cast<size_t>(size), list.size());
+
+ for (int i = 0; i < size; ++i) {
+ static_cast<SimpleDerivedElement*>(list.ElementAt(i))->set_value(i);
+ }
+
+ int i = 0;
+ for (std::vector<SimpleDerivedElement*>::const_iterator
+ de_iter = de_list.begin();
+ de_iter != de_list.end(); ++de_iter, ++i) {
+ EXPECT_EQ(i, (*de_iter)->get_value());
+ }
+}
+
+TEST(ListContainerTest,
+ SimpleIterationAndReverseIterationWithIndexNonDerivedElement) {
+ ListContainer<NonDerivedElement> list;
+ std::vector<NonDerivedElement*> nde_list;
+ size_t size = 10;
+ for (size_t i = 0; i < size; ++i) {
+ nde_list.push_back(list.AllocateAndConstruct<NonDerivedElement>());
+ }
+ EXPECT_EQ(size, list.size());
+
+ size_t i = 0;
+ for (ListContainer<NonDerivedElement>::Iterator iter = list.begin();
+ iter != list.end(); ++iter) {
+ EXPECT_EQ(i, iter.index());
+ ++i;
+ }
+
+ i = 0;
+ for (ListContainer<NonDerivedElement>::ReverseIterator iter = list.rbegin();
+ iter != list.rend(); ++iter) {
+ EXPECT_EQ(i, iter.index());
+ ++i;
+ }
+}
+
+// Increments an int when constructed (or the counter pointer is supplied) and
+// decrements when destructed.
+class InstanceCounter {
+ public:
+ InstanceCounter() : counter_(nullptr) {}
+ explicit InstanceCounter(int* counter) { SetCounter(counter); }
+ ~InstanceCounter() {
+ if (counter_)
+ --*counter_;
+ }
+ void SetCounter(int* counter) {
+ counter_ = counter;
+ ++*counter_;
+ }
+
+ private:
+ int* counter_;
+};
+
+TEST(ListContainerTest, RemoveLastDestruction) {
+ // We keep an explicit instance count to make sure that the destructors are
+ // indeed getting called.
+ int counter = 0;
+ ListContainer<InstanceCounter> list(sizeof(InstanceCounter), 1);
+ EXPECT_EQ(0, counter);
+ EXPECT_EQ(0u, list.size());
+
+ // We should be okay to add one and then go back to zero.
+ list.AllocateAndConstruct<InstanceCounter>()->SetCounter(&counter);
+ EXPECT_EQ(1, counter);
+ EXPECT_EQ(1u, list.size());
+ list.RemoveLast();
+ EXPECT_EQ(0, counter);
+ EXPECT_EQ(0u, list.size());
+
+ // We should also be okay to remove the last multiple times, as long as there
+ // are enough elements in the first place.
+ list.AllocateAndConstruct<InstanceCounter>()->SetCounter(&counter);
+ list.AllocateAndConstruct<InstanceCounter>()->SetCounter(&counter);
+ list.AllocateAndConstruct<InstanceCounter>()->SetCounter(&counter);
+ list.AllocateAndConstruct<InstanceCounter>()->SetCounter(&counter);
+ list.AllocateAndConstruct<InstanceCounter>()->SetCounter(&counter);
+ list.AllocateAndConstruct<InstanceCounter>()->SetCounter(&counter);
+ list.RemoveLast();
+ list.RemoveLast();
+ EXPECT_EQ(4, counter); // Leaves one in the last list.
+ EXPECT_EQ(4u, list.size());
+ list.RemoveLast();
+ EXPECT_EQ(3, counter); // Removes an inner list from before.
+ EXPECT_EQ(3u, list.size());
+}
+
+// TODO(jbroman): std::equal would work if ListContainer iterators satisfied the
+// usual STL iterator constraints. We should fix that.
+template <typename It1, typename It2>
+bool Equal(It1 it1, const It1& end1, It2 it2) {
+ for (; it1 != end1; ++it1, ++it2) {
+ if (!(*it1 == *it2))
+ return false;
+ }
+ return true;
+}
+
+TEST(ListContainerTest, RemoveLastIteration) {
+ struct SmallStruct {
+ char dummy[16];
+ };
+ ListContainer<SmallStruct> list(sizeof(SmallStruct), 1);
+ std::vector<SmallStruct*> pointers;
+
+ // Utilities which keep these two lists in sync and check that their iteration
+ // order matches.
+ auto push = [&list, &pointers]() {
+ pointers.push_back(list.AllocateAndConstruct<SmallStruct>());
+ };
+ auto pop = [&list, &pointers]() {
+ pointers.pop_back();
+ list.RemoveLast();
+ };
+ auto check_equal = [&list, &pointers]() {
+ // They should be of the same size, and compare equal with all four kinds of
+ // iteration.
+ // Apparently Mac doesn't have vector::cbegin and vector::crbegin?
+ const auto& const_pointers = pointers;
+ ASSERT_EQ(list.size(), pointers.size());
+ ASSERT_TRUE(Equal(list.begin(), list.end(), pointers.begin()));
+ ASSERT_TRUE(Equal(list.cbegin(), list.cend(), const_pointers.begin()));
+ ASSERT_TRUE(Equal(list.rbegin(), list.rend(), pointers.rbegin()));
+ ASSERT_TRUE(Equal(list.crbegin(), list.crend(), const_pointers.rbegin()));
+ };
+
+ check_equal(); // Initially empty.
+ push();
+ check_equal(); // One full inner list.
+ push();
+ check_equal(); // One full, one partially full.
+ push();
+ push();
+ check_equal(); // Two full, one partially full.
+ pop();
+ check_equal(); // Two full, one empty.
+ pop();
+ check_equal(); // One full, one partially full, one empty.
+ pop();
+ check_equal(); // One full, one empty.
+ push();
+ pop();
+ pop();
+ ASSERT_TRUE(list.empty());
+ check_equal(); // Empty.
+}
+
+TEST(ListContainerTest, AppendByMovingSameList) {
+ ListContainer<SimpleDerivedElement> list(kCurrentLargestDerivedElementSize);
+ list.AllocateAndConstruct<SimpleDerivedElementConstructMagicNumberOne>();
+
+ list.AppendByMoving(list.front());
+ EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne,
+ list.back()->get_value());
+ EXPECT_EQ(2u, list.size());
+
+ list.front()->set_value(kMagicNumberToUseForSimpleDerivedElementTwo);
+ EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementTwo,
+ list.front()->get_value());
+ list.AppendByMoving(list.front());
+ EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementTwo,
+ list.back()->get_value());
+ EXPECT_EQ(3u, list.size());
+}
+
+TEST(ListContainerTest, AppendByMovingDoesNotDestruct) {
+ ListContainer<DerivedElement> list_1(kCurrentLargestDerivedElementSize);
+ ListContainer<DerivedElement> list_2(kCurrentLargestDerivedElementSize);
+ MockDerivedElement* mde_1 = list_1.AllocateAndConstruct<MockDerivedElement>();
+
+ // Make sure destructor isn't called during AppendByMoving.
+ list_2.AppendByMoving(mde_1);
+ EXPECT_CALL(*mde_1, Destruct()).Times(0);
+ testing::Mock::VerifyAndClearExpectations(mde_1);
+ mde_1 = static_cast<MockDerivedElement*>(list_2.back());
+ EXPECT_CALL(*mde_1, Destruct());
+}
+
+TEST(ListContainerTest, AppendByMovingReturnsMovedPointer) {
+ ListContainer<SimpleDerivedElement> list_1(kCurrentLargestDerivedElementSize);
+ ListContainer<SimpleDerivedElement> list_2(kCurrentLargestDerivedElementSize);
+ SimpleDerivedElement* simple_element =
+ list_1.AllocateAndConstruct<SimpleDerivedElement>();
+
+ SimpleDerivedElement* moved_1 = list_2.AppendByMoving(simple_element);
+ EXPECT_EQ(list_2.back(), moved_1);
+
+ SimpleDerivedElement* moved_2 = list_1.AppendByMoving(moved_1);
+ EXPECT_EQ(list_1.back(), moved_2);
+ EXPECT_NE(moved_1, moved_2);
+}
+
+TEST(ListContainerTest, AppendByMovingReplacesSourceWithNewDerivedElement) {
+ ListContainer<SimpleDerivedElementConstructMagicNumberOne> list_1(
+ kCurrentLargestDerivedElementSize);
+ ListContainer<SimpleDerivedElementConstructMagicNumberTwo> list_2(
+ kCurrentLargestDerivedElementSize);
+
+ list_1.AllocateAndConstruct<SimpleDerivedElementConstructMagicNumberOne>();
+ EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne,
+ list_1.front()->get_value());
+
+ list_2.AppendByMoving(list_1.front());
+ EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne,
+ list_1.front()->get_value());
+ EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne,
+ list_2.front()->get_value());
+
+ // Change the value of list_2.front() to ensure the value is actually moved.
+ list_2.back()->set_value(kMagicNumberToUseForSimpleDerivedElementThree);
+
+ list_1.AppendByMoving(list_2.back());
+ EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne,
+ list_1.front()->get_value());
+ EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementThree,
+ list_1.back()->get_value());
+ EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementTwo,
+ list_2.back()->get_value());
+
+ // AppendByMoving replaces the source element with a new derived element so
+ // we do not expect sizes to shrink after AppendByMoving is called.
+ EXPECT_EQ(2u, list_1.size()); // One direct allocation, one AppendByMoving.
+ EXPECT_EQ(1u, list_2.size()); // One AppendByMoving.
+}
+
+const size_t kLongCountForLongSimpleDerivedElement = 5;
+
+class LongSimpleDerivedElement : public SimpleDerivedElement {
+ public:
+ ~LongSimpleDerivedElement() override {}
+ void SetAllValues(unsigned long value) {
+ for (size_t i = 0; i < kLongCountForLongSimpleDerivedElement; i++)
+ values[i] = value;
+ }
+ bool AreAllValuesEqualTo(size_t value) const {
+ for (size_t i = 1; i < kLongCountForLongSimpleDerivedElement; i++) {
+ if (values[i] != values[0])
+ return false;
+ }
+ return true;
+ }
+
+ private:
+ unsigned long values[kLongCountForLongSimpleDerivedElement];
+};
+
+const unsigned long kMagicNumberToUseForLongSimpleDerivedElement = 2718ul;
+
+class LongSimpleDerivedElementConstructMagicNumber
+ : public LongSimpleDerivedElement {
+ public:
+ LongSimpleDerivedElementConstructMagicNumber() {
+ SetAllValues(kMagicNumberToUseForLongSimpleDerivedElement);
+ }
+};
+
+TEST(ListContainerTest, AppendByMovingLongAndSimpleDerivedElements) {
+ static_assert(sizeof(LongSimpleDerivedElement) > sizeof(SimpleDerivedElement),
+ "LongSimpleDerivedElement should be larger than "
+ "SimpleDerivedElement's size.");
+ static_assert(sizeof(LongSimpleDerivedElement) <= kLargestDerivedElementSize,
+ "LongSimpleDerivedElement should be smaller than the maximum "
+ "DerivedElement size.");
+
+ ListContainer<SimpleDerivedElement> list(kCurrentLargestDerivedElementSize);
+ list.AllocateAndConstruct<LongSimpleDerivedElementConstructMagicNumber>();
+ list.AllocateAndConstruct<SimpleDerivedElementConstructMagicNumberOne>();
+
+ EXPECT_TRUE(
+ static_cast<LongSimpleDerivedElement*>(list.front())
+ ->AreAllValuesEqualTo(kMagicNumberToUseForLongSimpleDerivedElement));
+ EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne,
+ list.back()->get_value());
+
+ // Test that moving a simple derived element actually moves enough data so
+ // that the LongSimpleDerivedElement at this location is entirely moved.
+ SimpleDerivedElement* simple_element = list.back();
+ list.AppendByMoving(list.front());
+ EXPECT_TRUE(
+ static_cast<LongSimpleDerivedElement*>(list.back())
+ ->AreAllValuesEqualTo(kMagicNumberToUseForLongSimpleDerivedElement));
+ EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne,
+ simple_element->get_value());
+
+ LongSimpleDerivedElement* long_element =
+ static_cast<LongSimpleDerivedElement*>(list.back());
+ list.AppendByMoving(simple_element);
+ EXPECT_TRUE(long_element->AreAllValuesEqualTo(
+ kMagicNumberToUseForLongSimpleDerivedElement));
+ EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne,
+ list.back()->get_value());
+}
+
+TEST(ListContainerTest, Swap) {
+ ListContainer<SimpleDerivedElement> list_1(kCurrentLargestDerivedElementSize);
+ list_1.AllocateAndConstruct<SimpleDerivedElementConstructMagicNumberOne>();
+ ListContainer<SimpleDerivedElement> list_2(kCurrentLargestDerivedElementSize);
+ list_2.AllocateAndConstruct<SimpleDerivedElementConstructMagicNumberTwo>();
+ list_2.AllocateAndConstruct<SimpleDerivedElementConstructMagicNumberThree>();
+
+ SimpleDerivedElement* pre_swap_list_1_front = list_1.front();
+
+ EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne,
+ list_1.front()->get_value());
+ EXPECT_EQ(1u, list_1.size());
+
+ EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementTwo,
+ list_2.front()->get_value());
+ EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementThree,
+ list_2.back()->get_value());
+ EXPECT_EQ(2u, list_2.size());
+
+ list_2.swap(list_1);
+
+ EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementTwo,
+ list_1.front()->get_value());
+ EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementThree,
+ list_1.back()->get_value());
+ EXPECT_EQ(2u, list_1.size());
+
+ EXPECT_EQ(kMagicNumberToUseForSimpleDerivedElementOne,
+ list_2.front()->get_value());
+ EXPECT_EQ(1u, list_2.size());
+
+ // Ensure pointers are still valid after swapping.
+ EXPECT_EQ(pre_swap_list_1_front, list_2.front());
+}
+
+TEST(ListContainerTest, GetCapacityInBytes) {
+ const int iterations = 500;
+ const size_t initial_capacity = 10;
+ const size_t upper_bound_on_min_capacity = initial_capacity;
+
+ // At time of writing, removing elements from the end can cause up to 7x the
+ // memory required to be consumed, in the worst case, since we can have up to
+ // two trailing inner lists that are empty (for 2*size + 4*size in unused
+ // memory, due to the exponential growth strategy).
+ const size_t max_waste_factor = 8;
+
+ ListContainer<DerivedElement> list(LargestDerivedElementSize(),
+ initial_capacity);
+
+ // The capacity should grow with the list.
+ for (int i = 0; i < iterations; i++) {
+ size_t capacity = list.GetCapacityInBytes();
+ ASSERT_GE(capacity, list.size() * LargestDerivedElementSize());
+ ASSERT_LE(capacity, std::max(list.size(), upper_bound_on_min_capacity) *
+ max_waste_factor * LargestDerivedElementSize());
+ list.AllocateAndConstruct<DerivedElement1>();
+ }
+
+ // The capacity should shrink with the list.
+ for (int i = 0; i < iterations; i++) {
+ size_t capacity = list.GetCapacityInBytes();
+ ASSERT_GE(capacity, list.size() * LargestDerivedElementSize());
+ ASSERT_LE(capacity, std::max(list.size(), upper_bound_on_min_capacity) *
+ max_waste_factor * LargestDerivedElementSize());
+ list.RemoveLast();
+ }
+}
+
+} // namespace
+} // namespace cc
diff --git a/chromium/cc/base/math_util.h b/chromium/cc/base/math_util.h
index 749b9bdbae1..4c40e8ef9a4 100644
--- a/chromium/cc/base/math_util.h
+++ b/chromium/cc/base/math_util.h
@@ -96,6 +96,29 @@ class CC_EXPORT MathUtil {
return (d > 0.0) ? std::floor(d + 0.5) : std::ceil(d - 0.5);
}
+ // RoundUp rounds up a given |n| to be a multiple of |mul|.
+ // Examples:
+ // - RoundUp(123, 50) returns 150.
+ // - RoundUp(-123, 50) returns -100.
+ template <typename T>
+ static T RoundUp(T n, T mul) {
+ static_assert(std::numeric_limits<T>::is_integer,
+ "T must be an integer type");
+ return (n > 0) ? ((n + mul - 1) / mul) * mul : (n / mul) * mul;
+ }
+
+ // RoundDown rounds down a given |n| to be a multiple of |mul|.
+ // Examples:
+ // - RoundDown(123, 50) returns 100.
+ // - RoundDown(-123, 50) returns -150.
+ template <typename T>
+ static T RoundDown(T n, T mul) {
+ static_assert(std::numeric_limits<T>::is_integer,
+ "T must be an integer type");
+ return (n > 0) ? (n / mul) * mul : (n == 0) ? 0
+ : ((n - mul + 1) / mul) * mul;
+ }
+
template <typename T> static T ClampToRange(T value, T min, T max) {
return std::min(std::max(value, min), max);
}
diff --git a/chromium/cc/base/math_util_unittest.cc b/chromium/cc/base/math_util_unittest.cc
index 325870dc1f6..1d43e0f2129 100644
--- a/chromium/cc/base/math_util_unittest.cc
+++ b/chromium/cc/base/math_util_unittest.cc
@@ -193,5 +193,59 @@ TEST(MathUtilTest, MapEnclosedRectWith2dAxisAlignedTransform) {
EXPECT_EQ(gfx::Rect(2, 4, 6, 8), output);
}
+TEST(MathUtilTest, RoundUp) {
+ for (int multiplier = 1; multiplier <= 10; ++multiplier) {
+ // Try attempts in descending order, so that we can
+ // determine the correct value before it's needed.
+ int correct;
+ for (int attempt = 5 * multiplier; attempt >= -5 * multiplier; --attempt) {
+ if ((attempt % multiplier) == 0)
+ correct = attempt;
+ EXPECT_EQ(correct, MathUtil::RoundUp(attempt, multiplier))
+ << "attempt=" << attempt << " multiplier=" << multiplier;
+ }
+ }
+
+ for (unsigned multiplier = 1; multiplier <= 10; ++multiplier) {
+ // Try attempts in descending order, so that we can
+ // determine the correct value before it's needed.
+ unsigned correct;
+ for (unsigned attempt = 5 * multiplier; attempt > 0; --attempt) {
+ if ((attempt % multiplier) == 0)
+ correct = attempt;
+ EXPECT_EQ(correct, MathUtil::RoundUp(attempt, multiplier))
+ << "attempt=" << attempt << " multiplier=" << multiplier;
+ }
+ EXPECT_EQ(0u, MathUtil::RoundUp(0u, multiplier))
+ << "attempt=0 multiplier=" << multiplier;
+ }
+}
+
+TEST(MathUtilTest, RoundDown) {
+ for (int multiplier = 1; multiplier <= 10; ++multiplier) {
+ // Try attempts in ascending order, so that we can
+ // determine the correct value before it's needed.
+ int correct;
+ for (int attempt = -5 * multiplier; attempt <= 5 * multiplier; ++attempt) {
+ if ((attempt % multiplier) == 0)
+ correct = attempt;
+ EXPECT_EQ(correct, MathUtil::RoundDown(attempt, multiplier))
+ << "attempt=" << attempt << " multiplier=" << multiplier;
+ }
+ }
+
+ for (unsigned multiplier = 1; multiplier <= 10; ++multiplier) {
+ // Try attempts in ascending order, so that we can
+ // determine the correct value before it's needed.
+ unsigned correct;
+ for (unsigned attempt = 0; attempt <= 5 * multiplier; ++attempt) {
+ if ((attempt % multiplier) == 0)
+ correct = attempt;
+ EXPECT_EQ(correct, MathUtil::RoundDown(attempt, multiplier))
+ << "attempt=" << attempt << " multiplier=" << multiplier;
+ }
+ }
+}
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/base/resource_id.h b/chromium/cc/base/resource_id.h
new file mode 100644
index 00000000000..84d00ad8e59
--- /dev/null
+++ b/chromium/cc/base/resource_id.h
@@ -0,0 +1,16 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_BASE_RESOURCE_ID_H_
+#define CC_BASE_RESOURCE_ID_H_
+
+#include <stdint.h>
+
+namespace cc {
+
+using ResourceId = uint32_t;
+
+} // namespace cc
+
+#endif // CC_BASE_RESOURCE_ID_H_
diff --git a/chromium/cc/base/sidecar_list_container.h b/chromium/cc/base/sidecar_list_container.h
new file mode 100644
index 00000000000..5135ab1d7d2
--- /dev/null
+++ b/chromium/cc/base/sidecar_list_container.h
@@ -0,0 +1,97 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_BASE_SIDECAR_LIST_CONTAINER_H_
+#define CC_BASE_SIDECAR_LIST_CONTAINER_H_
+
+#include "base/logging.h"
+#include "cc/base/list_container.h"
+
+namespace cc {
+
+// This is a container, based on ListContainer, which allocates space in a
+// contiguous block for objects subclassing BaseElementType, as well as an
+// additional "sidecar" of opaque type.
+//
+// It takes a pointer to a function for tearing down sidecar objects, which must
+// free any resources held by it as its memory will be deallocated by the
+// container afterwards. When an element is constructed, callers are expected to
+// immediately construct the sidecar as well (such that the sidecar destroyer
+// will run safely and successfully).
+//
+// TODO(jbroman): It would be nice to be clear about the memory alignment
+// constraints here, but that probably requires closer inspection of
+// ListContainer first.
+template <class BaseElementType>
+class SidecarListContainer {
+ public:
+ using SidecarDestroyer = void (*)(void* sidecar);
+ using Iterator = typename ListContainer<BaseElementType>::Iterator;
+ using ConstIterator = typename ListContainer<BaseElementType>::ConstIterator;
+ using ReverseIterator =
+ typename ListContainer<BaseElementType>::ReverseIterator;
+ using ConstReverseIterator =
+ typename ListContainer<BaseElementType>::ConstReverseIterator;
+
+ explicit SidecarListContainer(size_t max_size_for_derived_class,
+ size_t max_size_for_sidecar,
+ size_t num_of_elements_to_reserve_for,
+ SidecarDestroyer destroyer)
+ : list_(max_size_for_derived_class + max_size_for_sidecar,
+ num_of_elements_to_reserve_for),
+ destroyer_(destroyer),
+ sidecar_offset_(max_size_for_derived_class) {}
+ ~SidecarListContainer() { DestroyAllSidecars(); }
+
+ // Forward most of the reading logic to ListContainer.
+ bool empty() const { return list_.empty(); }
+ size_t size() const { return list_.size(); }
+ size_t GetCapacityInBytes() const { return list_.GetCapacityInBytes(); }
+ ConstIterator begin() const { return list_.begin(); }
+ ConstIterator end() const { return list_.end(); }
+
+ template <typename DerivedElementType>
+ DerivedElementType* AllocateAndConstruct() {
+ return list_.template AllocateAndConstruct<DerivedElementType>();
+ }
+ template <typename DerivedElementType>
+ DerivedElementType* AllocateAndCopyFrom(const DerivedElementType* source) {
+ return list_.template AllocateAndCopyFrom<DerivedElementType>(source);
+ }
+
+ void clear() {
+ DestroyAllSidecars();
+ list_.clear();
+ }
+
+ void RemoveLast() {
+ destroyer_(GetSidecar(*list_.rbegin()));
+ list_.RemoveLast();
+ }
+
+ // This permits a client to exchange a pointer to an element to a pointer to
+ // its corresponding sidecar.
+ void* GetSidecar(BaseElementType* element) {
+ DCHECK_GT(sidecar_offset_, 0u);
+ return reinterpret_cast<char*>(element) + sidecar_offset_;
+ }
+ const void* GetSidecar(const BaseElementType* element) {
+ DCHECK_GT(sidecar_offset_, 0u);
+ return reinterpret_cast<const char*>(element) + sidecar_offset_;
+ }
+
+ private:
+ void DestroyAllSidecars() {
+ for (auto* element : list_)
+ destroyer_(GetSidecar(element));
+ }
+
+ ListContainer<BaseElementType> list_;
+ SidecarDestroyer destroyer_;
+ size_t sidecar_offset_;
+};
+
+} // namespace cc
+
+#endif // CC_BASE_SIDECAR_LIST_CONTAINER_H_
diff --git a/chromium/cc/base/sidecar_list_container_unittest.cc b/chromium/cc/base/sidecar_list_container_unittest.cc
new file mode 100644
index 00000000000..0012014df8f
--- /dev/null
+++ b/chromium/cc/base/sidecar_list_container_unittest.cc
@@ -0,0 +1,198 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/base/sidecar_list_container.h"
+
+#include <algorithm>
+
+#include "base/logging.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+namespace {
+
+const size_t kNumInitiallyReservedElements = 2;
+const size_t kNumElementsForTest = 100;
+
+class DestructionNotifier {
+ public:
+ DestructionNotifier() : flag_(nullptr) {}
+ explicit DestructionNotifier(bool* flag) { set_flag(flag); }
+ ~DestructionNotifier() {
+ if (flag_)
+ *flag_ = true;
+ }
+ void set_flag(bool* flag) {
+ if (flag)
+ DCHECK(!*flag);
+ flag_ = flag;
+ }
+
+ private:
+ bool* flag_;
+};
+
+class TestElement {
+ public:
+ TestElement() {}
+ virtual ~TestElement() {}
+ void set_destruction_flag(bool* flag) { notifier_.set_flag(flag); }
+
+ private:
+ DestructionNotifier notifier_;
+};
+
+class DerivedTestElement : public TestElement {
+ public:
+ int additional_field = 0;
+};
+
+class TestSidecar {
+ public:
+ TestSidecar() {}
+ explicit TestSidecar(bool* destruction_flag) : notifier_(destruction_flag) {}
+
+ static void Destroy(void* sidecar) {
+ static_cast<TestSidecar*>(sidecar)->~TestSidecar();
+ }
+
+ protected:
+ virtual ~TestSidecar() {}
+
+ private:
+ DestructionNotifier notifier_;
+};
+
+class DerivedTestSidecar : public TestSidecar {
+ public:
+ DerivedTestSidecar() {}
+ explicit DerivedTestSidecar(bool* destruction_flag)
+ : TestSidecar(destruction_flag) {}
+ int additional_field = 0;
+
+ private:
+ ~DerivedTestSidecar() override {}
+};
+
+class TestContainer : public SidecarListContainer<TestElement> {
+ public:
+ TestContainer()
+ : SidecarListContainer(
+ std::max(sizeof(TestElement), sizeof(DerivedTestElement)),
+ std::max(sizeof(TestSidecar), sizeof(DerivedTestSidecar)),
+ kNumInitiallyReservedElements,
+ &TestSidecar::Destroy) {}
+};
+
+TEST(SidecarListContainerTest, Destructor) {
+ bool element_destroyed = false;
+ bool sidecar_destroyed = false;
+
+ {
+ TestContainer container;
+
+ TestElement* element = container.AllocateAndConstruct<TestElement>();
+ TestSidecar* sidecar =
+ new (container.GetSidecar(element)) TestSidecar(&sidecar_destroyed);
+ element->set_destruction_flag(&element_destroyed);
+
+ // They shouldn't be destroyed yet. And they shouldn't overlap in memory.
+ ASSERT_FALSE(element_destroyed);
+ ASSERT_FALSE(sidecar_destroyed);
+ ASSERT_GE(reinterpret_cast<char*>(sidecar),
+ reinterpret_cast<char*>(element) + sizeof(TestElement));
+ }
+
+ // They should, however, be destroyed when going out of scope.
+ ASSERT_TRUE(element_destroyed);
+ ASSERT_TRUE(sidecar_destroyed);
+}
+
+TEST(SidecarListContainerTest, Clear) {
+ bool element_destroyed = false;
+ bool sidecar_destroyed = false;
+
+ TestContainer container;
+
+ TestElement* element = container.AllocateAndConstruct<TestElement>();
+ new (container.GetSidecar(element)) TestSidecar(&sidecar_destroyed);
+ element->set_destruction_flag(&element_destroyed);
+
+ // They shouldn't be destroyed yet.
+ ASSERT_FALSE(element_destroyed);
+ ASSERT_FALSE(sidecar_destroyed);
+
+ // They should, however, be destroyed after clearing.
+ container.clear();
+ EXPECT_TRUE(element_destroyed);
+ EXPECT_TRUE(sidecar_destroyed);
+}
+
+TEST(SidecarListContainerTest, DerivedTypes) {
+ bool element_destroyed = false;
+ bool sidecar_destroyed = false;
+
+ {
+ TestContainer container;
+
+ DerivedTestElement* element =
+ container.AllocateAndConstruct<DerivedTestElement>();
+ DerivedTestSidecar* sidecar = new (container.GetSidecar(element))
+ DerivedTestSidecar(&sidecar_destroyed);
+ element->set_destruction_flag(&element_destroyed);
+ element->additional_field = 12;
+ sidecar->additional_field = 13;
+
+ // They shouldn't be destroyed yet.
+ ASSERT_FALSE(element_destroyed);
+ ASSERT_FALSE(sidecar_destroyed);
+ }
+
+ // They should, however, be destroyed when going out of scope.
+ EXPECT_TRUE(element_destroyed);
+ EXPECT_TRUE(sidecar_destroyed);
+}
+
+TEST(SidecarListContainerTest, AddingAndRemovingElements) {
+ TestContainer container;
+ EXPECT_TRUE(container.empty());
+ EXPECT_EQ(0u, container.size());
+ EXPECT_EQ(container.end(), container.begin());
+
+ for (size_t i = 1; i <= kNumElementsForTest; i++) {
+ TestElement* element = container.AllocateAndConstruct<TestElement>();
+ new (container.GetSidecar(element)) TestSidecar();
+
+ ASSERT_FALSE(container.empty());
+ ASSERT_EQ(i, container.size());
+ ASSERT_NE(container.end(), container.begin());
+ }
+
+ size_t num_elements = 0;
+ for (const auto* element : container) {
+ (void)element;
+ num_elements++;
+ }
+ EXPECT_EQ(kNumElementsForTest, num_elements);
+
+ container.clear();
+ EXPECT_TRUE(container.empty());
+ EXPECT_EQ(0u, container.size());
+ EXPECT_EQ(container.end(), container.begin());
+}
+
+TEST(SidecarListContainerTest, RemoveLast) {
+ // We need only ensure that the sidecar is also destroyed on RemoveLast.
+ // The rest is logic already present in ListContainer.
+ bool sidecar_destroyed = false;
+ TestContainer container;
+ TestElement* element = container.AllocateAndConstruct<TestElement>();
+ new (container.GetSidecar(element)) TestSidecar(&sidecar_destroyed);
+ ASSERT_FALSE(sidecar_destroyed);
+ container.RemoveLast();
+ ASSERT_TRUE(sidecar_destroyed);
+}
+
+} // namespace
+} // namespace cc
diff --git a/chromium/cc/base/switches.cc b/chromium/cc/base/switches.cc
index ae424824611..0a27205d9d3 100644
--- a/chromium/cc/base/switches.cc
+++ b/chromium/cc/base/switches.cc
@@ -51,10 +51,6 @@ const char kCompositeToMailbox[] = "composite-to-mailbox";
const char kStrictLayerPropertyChangeChecking[] =
"strict-layer-property-change-checking";
-// Virtual viewport for fixed-position elements, scrollbars during pinch.
-const char kEnablePinchVirtualViewport[] = "enable-pinch-virtual-viewport";
-const char kDisablePinchVirtualViewport[] = "disable-pinch-virtual-viewport";
-
// Ensures that the draw properties computed via the property trees match those
// computed by CalcDrawProperties.
const char kEnablePropertyTreeVerification[] =
@@ -63,6 +59,9 @@ const char kEnablePropertyTreeVerification[] =
// Disable partial swap which is needed for some OpenGL drivers / emulators.
const char kUIDisablePartialSwap[] = "ui-disable-partial-swap";
+// Use a BeginFrame signal from browser to renderer to schedule rendering.
+const char kEnableBeginFrameScheduling[] = "enable-begin-frame-scheduling";
+
// Enables the GPU benchmarking extension
const char kEnableGpuBenchmarking[] = "enable-gpu-benchmarking";
diff --git a/chromium/cc/base/switches.h b/chromium/cc/base/switches.h
index 46fe922ea7e..cd5e3678824 100644
--- a/chromium/cc/base/switches.h
+++ b/chromium/cc/base/switches.h
@@ -27,13 +27,12 @@ CC_EXPORT extern const char kSlowDownRasterScaleFactor[];
CC_EXPORT extern const char kCompositeToMailbox[];
CC_EXPORT extern const char kMaxTilesForInterestArea[];
CC_EXPORT extern const char kMaxUnusedResourceMemoryUsagePercentage[];
-CC_EXPORT extern const char kEnablePinchVirtualViewport[];
-CC_EXPORT extern const char kDisablePinchVirtualViewport[];
CC_EXPORT extern const char kStrictLayerPropertyChangeChecking[];
CC_EXPORT extern const char kEnablePropertyTreeVerification[];
// Switches for both the renderer and ui compositors.
CC_EXPORT extern const char kUIDisablePartialSwap[];
+CC_EXPORT extern const char kEnableBeginFrameScheduling[];
CC_EXPORT extern const char kEnableGpuBenchmarking[];
// Debug visualizations.
diff --git a/chromium/cc/base/unique_notifier.cc b/chromium/cc/base/unique_notifier.cc
index 0656c6d747b..eb0b09af36e 100644
--- a/chromium/cc/base/unique_notifier.cc
+++ b/chromium/cc/base/unique_notifier.cc
@@ -22,6 +22,10 @@ UniqueNotifier::UniqueNotifier(base::SequencedTaskRunner* task_runner,
UniqueNotifier::~UniqueNotifier() {
}
+void UniqueNotifier::Cancel() {
+ notification_pending_ = false;
+}
+
void UniqueNotifier::Schedule() {
if (notification_pending_)
return;
@@ -33,6 +37,9 @@ void UniqueNotifier::Schedule() {
}
void UniqueNotifier::Notify() {
+ if (!notification_pending_)
+ return;
+
// Note that the order here is important in case closure schedules another
// run.
notification_pending_ = false;
diff --git a/chromium/cc/base/unique_notifier.h b/chromium/cc/base/unique_notifier.h
index 9a4a02cd62c..3cbc22a0a79 100644
--- a/chromium/cc/base/unique_notifier.h
+++ b/chromium/cc/base/unique_notifier.h
@@ -29,6 +29,9 @@ class CC_EXPORT UniqueNotifier {
// pending, then only one notification will take place.
void Schedule();
+ // Cancel a pending notification, if one was scheduled.
+ void Cancel();
+
private:
void Notify();
diff --git a/chromium/cc/base/unique_notifier_unittest.cc b/chromium/cc/base/unique_notifier_unittest.cc
index 7b52512d6c7..b53b52a76fd 100644
--- a/chromium/cc/base/unique_notifier_unittest.cc
+++ b/chromium/cc/base/unique_notifier_unittest.cc
@@ -50,12 +50,26 @@ TEST_F(UniqueNotifierTest, Schedule) {
base::RunLoop().RunUntilIdle();
EXPECT_EQ(2, NotificationCount());
+ // Schedule and cancel.
+ notifier.Schedule();
+ notifier.Cancel();
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(2, NotificationCount());
+
+ notifier.Schedule();
+ notifier.Cancel();
+ notifier.Schedule();
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(3, NotificationCount());
+
notifier.Schedule();
}
// Notifier went out of scope, so we don't expect to get a notification.
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(2, NotificationCount());
+ EXPECT_EQ(3, NotificationCount());
}
} // namespace
diff --git a/chromium/cc/base/util.h b/chromium/cc/base/util.h
deleted file mode 100644
index a16d4855283..00000000000
--- a/chromium/cc/base/util.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_BASE_UTIL_H_
-#define CC_BASE_UTIL_H_
-
-#include <limits>
-
-#include "base/basictypes.h"
-
-namespace cc {
-
-template <typename T> T RoundUp(T n, T mul) {
- static_assert(std::numeric_limits<T>::is_integer,
- "T must be an integer type");
- return (n > 0) ? ((n + mul - 1) / mul) * mul
- : (n / mul) * mul;
-}
-
-template <typename T> T RoundDown(T n, T mul) {
- static_assert(std::numeric_limits<T>::is_integer,
- "T must be an integer type");
- return (n > 0) ? (n / mul) * mul
- : (n == 0) ? 0
- : ((n - mul + 1) / mul) * mul;
-}
-
-} // namespace cc
-
-#endif // CC_BASE_UTIL_H_
diff --git a/chromium/cc/base/util_unittest.cc b/chromium/cc/base/util_unittest.cc
deleted file mode 100644
index 6665a6a458d..00000000000
--- a/chromium/cc/base/util_unittest.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/base/util.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-namespace {
-
-TEST(UtilTest, RoundUp) {
- for (int multiplier = 1; multiplier <= 10; ++multiplier) {
- // Try attempts in descending order, so that we can
- // determine the correct value before it's needed.
- int correct;
- for (int attempt = 5 * multiplier; attempt >= -5 * multiplier; --attempt) {
- if ((attempt % multiplier) == 0)
- correct = attempt;
- EXPECT_EQ(correct, RoundUp(attempt, multiplier))
- << "attempt=" << attempt << " multiplier=" << multiplier;
- }
- }
-
- for (unsigned multiplier = 1; multiplier <= 10; ++multiplier) {
- // Try attempts in descending order, so that we can
- // determine the correct value before it's needed.
- unsigned correct;
- for (unsigned attempt = 5 * multiplier; attempt > 0; --attempt) {
- if ((attempt % multiplier) == 0)
- correct = attempt;
- EXPECT_EQ(correct, RoundUp(attempt, multiplier))
- << "attempt=" << attempt << " multiplier=" << multiplier;
- }
- EXPECT_EQ(0u, RoundUp(0u, multiplier))
- << "attempt=0 multiplier=" << multiplier;
- }
-}
-
-TEST(UtilTest, RoundDown) {
- for (int multiplier = 1; multiplier <= 10; ++multiplier) {
- // Try attempts in ascending order, so that we can
- // determine the correct value before it's needed.
- int correct;
- for (int attempt = -5 * multiplier; attempt <= 5 * multiplier; ++attempt) {
- if ((attempt % multiplier) == 0)
- correct = attempt;
- EXPECT_EQ(correct, RoundDown(attempt, multiplier))
- << "attempt=" << attempt << " multiplier=" << multiplier;
- }
- }
-
- for (unsigned multiplier = 1; multiplier <= 10; ++multiplier) {
- // Try attempts in ascending order, so that we can
- // determine the correct value before it's needed.
- unsigned correct;
- for (unsigned attempt = 0; attempt <= 5 * multiplier; ++attempt) {
- if ((attempt % multiplier) == 0)
- correct = attempt;
- EXPECT_EQ(correct, RoundDown(attempt, multiplier))
- << "attempt=" << attempt << " multiplier=" << multiplier;
- }
- }
-}
-
-} // namespace
-} // namespace cc
diff --git a/chromium/cc/blink/BUILD.gn b/chromium/cc/blink/BUILD.gn
index 4854ead1ce8..c39498fe73a 100644
--- a/chromium/cc/blink/BUILD.gn
+++ b/chromium/cc/blink/BUILD.gn
@@ -17,6 +17,10 @@ component("blink") {
"web_animation_curve_common.h",
"web_animation_impl.cc",
"web_animation_impl.h",
+ "web_compositor_animation_player_impl.cc",
+ "web_compositor_animation_player_impl.h",
+ "web_compositor_animation_timeline_impl.cc",
+ "web_compositor_animation_timeline_impl.h",
"web_compositor_support_impl.cc",
"web_compositor_support_impl.h",
"web_content_layer_impl.cc",
@@ -90,6 +94,7 @@ if (!is_mac) {
"//base/third_party/dynamic_annotations",
"//skia",
"//testing/gtest",
+ "//third_party/WebKit/public:blink",
"//ui/gfx/geometry",
"//ui/gfx:test_support",
"//cc",
diff --git a/chromium/cc/blink/cc_blink.gyp b/chromium/cc/blink/cc_blink.gyp
index e9934bf9653..c55213c5444 100644
--- a/chromium/cc/blink/cc_blink.gyp
+++ b/chromium/cc/blink/cc_blink.gyp
@@ -33,6 +33,10 @@
'web_animation_curve_common.h',
'web_animation_impl.cc',
'web_animation_impl.h',
+ 'web_compositor_animation_player_impl.cc',
+ 'web_compositor_animation_player_impl.h',
+ 'web_compositor_animation_timeline_impl.cc',
+ 'web_compositor_animation_timeline_impl.h',
'web_compositor_support_impl.cc',
'web_compositor_support_impl.h',
'web_content_layer_impl.cc',
diff --git a/chromium/cc/blink/web_compositor_animation_player_impl.cc b/chromium/cc/blink/web_compositor_animation_player_impl.cc
new file mode 100644
index 00000000000..fd146de856f
--- /dev/null
+++ b/chromium/cc/blink/web_compositor_animation_player_impl.cc
@@ -0,0 +1,66 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/blink/web_compositor_animation_player_impl.h"
+
+#include "cc/animation/animation_id_provider.h"
+#include "cc/animation/animation_player.h"
+#include "cc/blink/web_animation_impl.h"
+#include "cc/blink/web_to_cc_animation_delegate_adapter.h"
+#include "third_party/WebKit/public/platform/WebLayer.h"
+
+using cc::AnimationPlayer;
+
+namespace cc_blink {
+
+WebCompositorAnimationPlayerImpl::WebCompositorAnimationPlayerImpl()
+ : animation_player_(
+ AnimationPlayer::Create(cc::AnimationIdProvider::NextPlayerId())) {
+}
+
+WebCompositorAnimationPlayerImpl::~WebCompositorAnimationPlayerImpl() {
+}
+
+CC_BLINK_EXPORT cc::AnimationPlayer*
+WebCompositorAnimationPlayerImpl::animation_player() const {
+ return animation_player_.get();
+}
+
+void WebCompositorAnimationPlayerImpl::setAnimationDelegate(
+ blink::WebCompositorAnimationDelegate* delegate) {
+ animation_delegate_adapter_.reset(
+ new WebToCCAnimationDelegateAdapter(delegate));
+ animation_player_->set_layer_animation_delegate(
+ animation_delegate_adapter_.get());
+}
+
+void WebCompositorAnimationPlayerImpl::attachLayer(blink::WebLayer* web_layer) {
+ animation_player_->AttachLayer(web_layer->id());
+}
+
+void WebCompositorAnimationPlayerImpl::detachLayer() {
+ animation_player_->DetachLayer();
+}
+
+bool WebCompositorAnimationPlayerImpl::isLayerAttached() const {
+ return animation_player_->layer_id() != 0;
+}
+
+void WebCompositorAnimationPlayerImpl::addAnimation(
+ blink::WebCompositorAnimation* animation) {
+ animation_player_->AddAnimation(
+ static_cast<WebCompositorAnimationImpl*>(animation)->PassAnimation());
+ delete animation;
+}
+
+void WebCompositorAnimationPlayerImpl::removeAnimation(int animation_id) {
+ animation_player_->RemoveAnimation(animation_id);
+}
+
+void WebCompositorAnimationPlayerImpl::pauseAnimation(int animation_id,
+ double time_offset) {
+ animation_player_->PauseAnimation(animation_id, time_offset);
+}
+
+} // namespace cc_blink
diff --git a/chromium/cc/blink/web_compositor_animation_player_impl.h b/chromium/cc/blink/web_compositor_animation_player_impl.h
new file mode 100644
index 00000000000..9b5ea4475e7
--- /dev/null
+++ b/chromium/cc/blink/web_compositor_animation_player_impl.h
@@ -0,0 +1,48 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_BLINK_WEB_COMPOSITOR_ANIMATION_PLAYER_IMPL_H_
+#define CC_BLINK_WEB_COMPOSITOR_ANIMATION_PLAYER_IMPL_H_
+
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "cc/blink/cc_blink_export.h"
+#include "third_party/WebKit/public/platform/WebCompositorAnimationPlayer.h"
+
+namespace cc {
+class AnimationPlayer;
+}
+
+namespace cc_blink {
+
+class WebToCCAnimationDelegateAdapter;
+
+class WebCompositorAnimationPlayerImpl
+ : public blink::WebCompositorAnimationPlayer {
+ public:
+ CC_BLINK_EXPORT WebCompositorAnimationPlayerImpl();
+ virtual ~WebCompositorAnimationPlayerImpl();
+
+ CC_BLINK_EXPORT cc::AnimationPlayer* animation_player() const;
+
+ // blink::WebCompositorAnimationPlayer implementation
+ virtual void setAnimationDelegate(
+ blink::WebCompositorAnimationDelegate* delegate);
+ virtual void attachLayer(blink::WebLayer* web_layer);
+ virtual void detachLayer();
+ virtual bool isLayerAttached() const;
+ virtual void addAnimation(blink::WebCompositorAnimation* animation);
+ virtual void removeAnimation(int animation_id);
+ virtual void pauseAnimation(int animation_id, double time_offset);
+
+ private:
+ scoped_refptr<cc::AnimationPlayer> animation_player_;
+ scoped_ptr<WebToCCAnimationDelegateAdapter> animation_delegate_adapter_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebCompositorAnimationPlayerImpl);
+};
+
+} // namespace cc_blink
+
+#endif // CC_BLINK_WEB_COMPOSITOR_ANIMATION_PLAYER_IMPL_H_
diff --git a/chromium/cc/blink/web_compositor_animation_timeline_impl.cc b/chromium/cc/blink/web_compositor_animation_timeline_impl.cc
new file mode 100644
index 00000000000..a87778331bb
--- /dev/null
+++ b/chromium/cc/blink/web_compositor_animation_timeline_impl.cc
@@ -0,0 +1,46 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/blink/web_compositor_animation_timeline_impl.h"
+
+#include "cc/animation/animation_id_provider.h"
+#include "cc/animation/animation_player.h"
+#include "cc/animation/animation_timeline.h"
+#include "cc/blink/web_compositor_animation_player_impl.h"
+#include "third_party/WebKit/public/platform/WebCompositorAnimationPlayerClient.h"
+
+using cc::AnimationTimeline;
+
+namespace cc_blink {
+
+WebCompositorAnimationTimelineImpl::WebCompositorAnimationTimelineImpl()
+ : animation_timeline_(AnimationTimeline::Create(
+ cc::AnimationIdProvider::NextTimelineId())) {
+}
+
+WebCompositorAnimationTimelineImpl::~WebCompositorAnimationTimelineImpl() {
+}
+
+cc::AnimationTimeline* WebCompositorAnimationTimelineImpl::animation_timeline()
+ const {
+ return animation_timeline_.get();
+}
+
+void WebCompositorAnimationTimelineImpl::playerAttached(
+ const blink::WebCompositorAnimationPlayerClient& client) {
+ if (client.compositorPlayer())
+ animation_timeline_->AttachPlayer(
+ static_cast<WebCompositorAnimationPlayerImpl*>(
+ client.compositorPlayer())->animation_player());
+}
+
+void WebCompositorAnimationTimelineImpl::playerDestroyed(
+ const blink::WebCompositorAnimationPlayerClient& client) {
+ if (client.compositorPlayer())
+ animation_timeline_->DetachPlayer(
+ static_cast<WebCompositorAnimationPlayerImpl*>(
+ client.compositorPlayer())->animation_player());
+}
+
+} // namespace cc_blink
diff --git a/chromium/cc/blink/web_compositor_animation_timeline_impl.h b/chromium/cc/blink/web_compositor_animation_timeline_impl.h
new file mode 100644
index 00000000000..65d05d83157
--- /dev/null
+++ b/chromium/cc/blink/web_compositor_animation_timeline_impl.h
@@ -0,0 +1,45 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_BLINK_WEB_COMPOSITOR_ANIMATION_TIMELINE_IMPL_H_
+#define CC_BLINK_WEB_COMPOSITOR_ANIMATION_TIMELINE_IMPL_H_
+
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "cc/blink/cc_blink_export.h"
+#include "third_party/WebKit/public/platform/WebCompositorAnimationTimeline.h"
+
+namespace blink {
+class WebCompositorAnimationPlayerClient;
+}
+
+namespace cc {
+class AnimationTimeline;
+}
+
+namespace cc_blink {
+
+class WebCompositorAnimationTimelineImpl
+ : public blink::WebCompositorAnimationTimeline {
+ public:
+ CC_BLINK_EXPORT explicit WebCompositorAnimationTimelineImpl();
+ virtual ~WebCompositorAnimationTimelineImpl();
+
+ CC_BLINK_EXPORT cc::AnimationTimeline* animation_timeline() const;
+
+ // blink::WebCompositorAnimationTimeline implementation
+ virtual void playerAttached(
+ const blink::WebCompositorAnimationPlayerClient& client);
+ virtual void playerDestroyed(
+ const blink::WebCompositorAnimationPlayerClient& client);
+
+ private:
+ scoped_refptr<cc::AnimationTimeline> animation_timeline_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebCompositorAnimationTimelineImpl);
+};
+
+} // namespace cc_blink
+
+#endif // CC_BLINK_WEB_COMPOSITOR_ANIMATION_TIMELINE_IMPL_H_
diff --git a/chromium/cc/blink/web_compositor_support_impl.cc b/chromium/cc/blink/web_compositor_support_impl.cc
index e69abf69239..13a868d7ebf 100644
--- a/chromium/cc/blink/web_compositor_support_impl.cc
+++ b/chromium/cc/blink/web_compositor_support_impl.cc
@@ -5,9 +5,10 @@
#include "cc/blink/web_compositor_support_impl.h"
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop/message_loop_proxy.h"
#include "cc/animation/transform_operations.h"
#include "cc/blink/web_animation_impl.h"
+#include "cc/blink/web_compositor_animation_player_impl.h"
+#include "cc/blink/web_compositor_animation_timeline_impl.h"
#include "cc/blink/web_content_layer_impl.h"
#include "cc/blink/web_display_item_list_impl.h"
#include "cc/blink/web_external_texture_layer_impl.h"
@@ -26,6 +27,8 @@
using blink::WebCompositorAnimation;
using blink::WebCompositorAnimationCurve;
+using blink::WebCompositorAnimationPlayer;
+using blink::WebCompositorAnimationTimeline;
using blink::WebContentLayer;
using blink::WebContentLayerClient;
using blink::WebDisplayItemList;
@@ -96,15 +99,9 @@ WebScrollbarLayer* WebCompositorSupportImpl::createSolidColorScrollbarLayer(
WebCompositorAnimation* WebCompositorSupportImpl::createAnimation(
const blink::WebCompositorAnimationCurve& curve,
blink::WebCompositorAnimation::TargetProperty target,
-#ifdef WEB_COMPOSITOR_SUPPORT_CREATE_ANIMATION_SUPPORTS_GROUP
int group_id,
-#endif
int animation_id) {
-#ifdef WEB_COMPOSITOR_SUPPORT_CREATE_ANIMATION_SUPPORTS_GROUP
return new WebCompositorAnimationImpl(curve, target, animation_id, group_id);
-#else
- return new WebCompositorAnimationImpl(curve, target, animation_id, 0);
-#endif
}
WebFilterAnimationCurve*
@@ -136,4 +133,18 @@ WebFilterOperations* WebCompositorSupportImpl::createFilterOperations() {
return new WebFilterOperationsImpl();
}
+WebDisplayItemList* WebCompositorSupportImpl::createDisplayItemList() {
+ return new WebDisplayItemListImpl();
+}
+
+WebCompositorAnimationPlayer*
+WebCompositorSupportImpl::createAnimationPlayer() {
+ return new WebCompositorAnimationPlayerImpl();
+}
+
+WebCompositorAnimationTimeline*
+WebCompositorSupportImpl::createAnimationTimeline() {
+ return new WebCompositorAnimationTimelineImpl();
+}
+
} // namespace cc_blink
diff --git a/chromium/cc/blink/web_compositor_support_impl.h b/chromium/cc/blink/web_compositor_support_impl.h
index b924be9cc09..989966989e6 100644
--- a/chromium/cc/blink/web_compositor_support_impl.h
+++ b/chromium/cc/blink/web_compositor_support_impl.h
@@ -6,7 +6,6 @@
#define CC_BLINK_WEB_COMPOSITOR_SUPPORT_IMPL_H_
#include "base/memory/ref_counted.h"
-#include "base/message_loop/message_loop_proxy.h"
#include "cc/blink/cc_blink_export.h"
#include "third_party/WebKit/public/platform/WebCompositorAnimationCurve.h"
#include "third_party/WebKit/public/platform/WebCompositorSupport.h"
@@ -45,9 +44,7 @@ class CC_BLINK_EXPORT WebCompositorSupportImpl
virtual blink::WebCompositorAnimation* createAnimation(
const blink::WebCompositorAnimationCurve& curve,
blink::WebCompositorAnimation::TargetProperty target,
-#ifdef WEB_COMPOSITOR_SUPPORT_CREATE_ANIMATION_SUPPORTS_GROUP
int group_id,
-#endif
int animation_id);
virtual blink::WebFilterAnimationCurve* createFilterAnimationCurve();
virtual blink::WebFloatAnimationCurve* createFloatAnimationCurve();
@@ -59,6 +56,10 @@ class CC_BLINK_EXPORT WebCompositorSupportImpl
virtual blink::WebTransformAnimationCurve* createTransformAnimationCurve();
virtual blink::WebTransformOperations* createTransformOperations();
virtual blink::WebFilterOperations* createFilterOperations();
+ virtual blink::WebDisplayItemList* createDisplayItemList();
+
+ virtual blink::WebCompositorAnimationPlayer* createAnimationPlayer();
+ virtual blink::WebCompositorAnimationTimeline* createAnimationTimeline();
private:
DISALLOW_COPY_AND_ASSIGN(WebCompositorSupportImpl);
diff --git a/chromium/cc/blink/web_content_layer_impl.cc b/chromium/cc/blink/web_content_layer_impl.cc
index a480a06614c..c9ca473cf8e 100644
--- a/chromium/cc/blink/web_content_layer_impl.cc
+++ b/chromium/cc/blink/web_content_layer_impl.cc
@@ -5,8 +5,8 @@
#include "cc/blink/web_content_layer_impl.h"
#include "cc/blink/web_display_item_list_impl.h"
-#include "cc/layers/content_layer.h"
#include "cc/layers/picture_layer.h"
+#include "cc/playback/display_item_list_settings.h"
#include "third_party/WebKit/public/platform/WebContentLayerClient.h"
#include "third_party/WebKit/public/platform/WebFloatPoint.h"
#include "third_party/WebKit/public/platform/WebFloatRect.h"
@@ -14,7 +14,6 @@
#include "third_party/WebKit/public/platform/WebSize.h"
#include "third_party/skia/include/utils/SkMatrix44.h"
-using cc::ContentLayer;
using cc::PictureLayer;
namespace cc_blink {
@@ -38,18 +37,13 @@ PaintingControlToWeb(
WebContentLayerImpl::WebContentLayerImpl(blink::WebContentLayerClient* client)
: client_(client) {
- if (WebLayerImpl::UsingPictureLayer())
- layer_ = make_scoped_ptr(new WebLayerImpl(PictureLayer::Create(this)));
- else
- layer_ = make_scoped_ptr(new WebLayerImpl(ContentLayer::Create(this)));
+ layer_ = make_scoped_ptr(new WebLayerImpl(
+ PictureLayer::Create(WebLayerImpl::LayerSettings(), this)));
layer_->layer()->SetIsDrawable(true);
}
WebContentLayerImpl::~WebContentLayerImpl() {
- if (WebLayerImpl::UsingPictureLayer())
- static_cast<PictureLayer*>(layer_->layer())->ClearClient();
- else
- static_cast<ContentLayer*>(layer_->layer())->ClearClient();
+ static_cast<PictureLayer*>(layer_->layer())->ClearClient();
}
blink::WebLayer* WebContentLayerImpl::layer() {
@@ -74,15 +68,21 @@ void WebContentLayerImpl::PaintContents(
client_->paintContents(canvas, clip, PaintingControlToWeb(painting_control));
}
-void WebContentLayerImpl::PaintContentsToDisplayList(
- cc::DisplayItemList* display_list,
+scoped_refptr<cc::DisplayItemList>
+WebContentLayerImpl::PaintContentsToDisplayList(
const gfx::Rect& clip,
cc::ContentLayerClient::PaintingControlSetting painting_control) {
- if (!client_)
- return;
-
- WebDisplayItemListImpl list(display_list);
- client_->paintContents(&list, clip, PaintingControlToWeb(painting_control));
+ cc::DisplayItemListSettings settings;
+ settings.use_cached_picture = true;
+
+ scoped_refptr<cc::DisplayItemList> display_list =
+ cc::DisplayItemList::Create(clip, settings);
+ if (client_) {
+ WebDisplayItemListImpl list(display_list.get());
+ client_->paintContents(&list, clip, PaintingControlToWeb(painting_control));
+ }
+ display_list->Finalize();
+ return display_list;
}
bool WebContentLayerImpl::FillsBoundsCompletely() const {
diff --git a/chromium/cc/blink/web_content_layer_impl.h b/chromium/cc/blink/web_content_layer_impl.h
index e7b04b02abc..3e7b55c59a4 100644
--- a/chromium/cc/blink/web_content_layer_impl.h
+++ b/chromium/cc/blink/web_content_layer_impl.h
@@ -39,8 +39,7 @@ class WebContentLayerImpl : public blink::WebContentLayer,
void PaintContents(SkCanvas* canvas,
const gfx::Rect& clip,
PaintingControlSetting painting_control) override;
- void PaintContentsToDisplayList(
- cc::DisplayItemList* display_list,
+ scoped_refptr<cc::DisplayItemList> PaintContentsToDisplayList(
const gfx::Rect& clip,
PaintingControlSetting painting_control) override;
bool FillsBoundsCompletely() const override;
diff --git a/chromium/cc/blink/web_display_item_list_impl.cc b/chromium/cc/blink/web_display_item_list_impl.cc
index 3782358da33..ffcd5e35df7 100644
--- a/chromium/cc/blink/web_display_item_list_impl.cc
+++ b/chromium/cc/blink/web_display_item_list_impl.cc
@@ -10,6 +10,7 @@
#include "cc/playback/clip_display_item.h"
#include "cc/playback/clip_path_display_item.h"
#include "cc/playback/compositing_display_item.h"
+#include "cc/playback/display_item_list_settings.h"
#include "cc/playback/drawing_display_item.h"
#include "cc/playback/filter_display_item.h"
#include "cc/playback/float_clip_display_item.h"
@@ -25,15 +26,35 @@
namespace cc_blink {
+namespace {
+
+scoped_refptr<cc::DisplayItemList> CreateUncachedDisplayItemListForBlink() {
+ cc::DisplayItemListSettings settings;
+ settings.use_cached_picture = false;
+ return cc::DisplayItemList::CreateWithoutCachedPicture(settings);
+}
+
+} // namespace
+
+WebDisplayItemListImpl::WebDisplayItemListImpl()
+ : display_item_list_(CreateUncachedDisplayItemListForBlink()) {
+}
+
WebDisplayItemListImpl::WebDisplayItemListImpl(
cc::DisplayItemList* display_list)
: display_item_list_(display_list) {
}
void WebDisplayItemListImpl::appendDrawingItem(const SkPicture* picture) {
- auto* item =
- display_item_list_->CreateAndAppendItem<cc::DrawingDisplayItem>();
- item->SetNew(skia::SharePtr(const_cast<SkPicture*>(picture)));
+ if (display_item_list_->RetainsIndividualDisplayItems()) {
+ auto* item =
+ display_item_list_->CreateAndAppendItem<cc::DrawingDisplayItem>();
+ item->SetNew(skia::SharePtr(const_cast<SkPicture*>(picture)));
+ } else {
+ cc::DrawingDisplayItem item;
+ item.SetNew(skia::SharePtr(const_cast<SkPicture*>(picture)));
+ display_item_list_->RasterIntoCanvas(item);
+ }
}
void WebDisplayItemListImpl::appendClipItem(
@@ -43,47 +64,88 @@ void WebDisplayItemListImpl::appendClipItem(
for (size_t i = 0; i < rounded_clip_rects.size(); ++i) {
rounded_rects.push_back(rounded_clip_rects[i]);
}
- auto* item = display_item_list_->CreateAndAppendItem<cc::ClipDisplayItem>();
- item->SetNew(clip_rect, rounded_rects);
+ if (display_item_list_->RetainsIndividualDisplayItems()) {
+ auto* item = display_item_list_->CreateAndAppendItem<cc::ClipDisplayItem>();
+ item->SetNew(clip_rect, rounded_rects);
+ } else {
+ cc::ClipDisplayItem item;
+ item.SetNew(clip_rect, rounded_rects);
+ display_item_list_->RasterIntoCanvas(item);
+ }
}
void WebDisplayItemListImpl::appendEndClipItem() {
- display_item_list_->CreateAndAppendItem<cc::EndClipDisplayItem>();
+ if (display_item_list_->RetainsIndividualDisplayItems()) {
+ display_item_list_->CreateAndAppendItem<cc::EndClipDisplayItem>();
+ } else {
+ display_item_list_->RasterIntoCanvas(cc::EndClipDisplayItem());
+ }
}
void WebDisplayItemListImpl::appendClipPathItem(const SkPath& clip_path,
SkRegion::Op clip_op,
bool antialias) {
- auto* item =
- display_item_list_->CreateAndAppendItem<cc::ClipPathDisplayItem>();
- item->SetNew(clip_path, clip_op, antialias);
+ if (display_item_list_->RetainsIndividualDisplayItems()) {
+ auto* item =
+ display_item_list_->CreateAndAppendItem<cc::ClipPathDisplayItem>();
+ item->SetNew(clip_path, clip_op, antialias);
+ } else {
+ cc::ClipPathDisplayItem item;
+ item.SetNew(clip_path, clip_op, antialias);
+ display_item_list_->RasterIntoCanvas(item);
+ }
}
void WebDisplayItemListImpl::appendEndClipPathItem() {
- display_item_list_->CreateAndAppendItem<cc::EndClipPathDisplayItem>();
+ if (display_item_list_->RetainsIndividualDisplayItems()) {
+ display_item_list_->CreateAndAppendItem<cc::EndClipPathDisplayItem>();
+ } else {
+ display_item_list_->RasterIntoCanvas(cc::EndClipPathDisplayItem());
+ }
}
void WebDisplayItemListImpl::appendFloatClipItem(
const blink::WebFloatRect& clip_rect) {
- auto* item =
- display_item_list_->CreateAndAppendItem<cc::FloatClipDisplayItem>();
- item->SetNew(clip_rect);
+ if (display_item_list_->RetainsIndividualDisplayItems()) {
+ auto* item =
+ display_item_list_->CreateAndAppendItem<cc::FloatClipDisplayItem>();
+ item->SetNew(clip_rect);
+ } else {
+ cc::FloatClipDisplayItem item;
+ item.SetNew(clip_rect);
+ display_item_list_->RasterIntoCanvas(item);
+ }
}
void WebDisplayItemListImpl::appendEndFloatClipItem() {
- display_item_list_->CreateAndAppendItem<cc::EndFloatClipDisplayItem>();
+ if (display_item_list_->RetainsIndividualDisplayItems()) {
+ display_item_list_->CreateAndAppendItem<cc::EndFloatClipDisplayItem>();
+ } else {
+ display_item_list_->RasterIntoCanvas(cc::EndFloatClipDisplayItem());
+ }
}
void WebDisplayItemListImpl::appendTransformItem(const SkMatrix44& matrix) {
gfx::Transform transform;
transform.matrix() = matrix;
- auto* item =
- display_item_list_->CreateAndAppendItem<cc::TransformDisplayItem>();
- item->SetNew(transform);
+
+ if (display_item_list_->RetainsIndividualDisplayItems()) {
+ auto* item =
+ display_item_list_->CreateAndAppendItem<cc::TransformDisplayItem>();
+ item->SetNew(transform);
+ } else {
+ cc::TransformDisplayItem item;
+ item.SetNew(transform);
+ display_item_list_->RasterIntoCanvas(item);
+ }
}
void WebDisplayItemListImpl::appendEndTransformItem() {
- display_item_list_->CreateAndAppendItem<cc::EndTransformDisplayItem>();
+ if (display_item_list_->RetainsIndividualDisplayItems()) {
+ display_item_list_->CreateAndAppendItem<cc::EndTransformDisplayItem>();
+ } else {
+ display_item_list_->RasterIntoCanvas(cc::EndTransformDisplayItem());
+ }
}
void WebDisplayItemListImpl::appendCompositingItem(
@@ -95,14 +157,26 @@ void WebDisplayItemListImpl::appendCompositingItem(
DCHECK_LE(opacity, 1.f);
// TODO(ajuma): This should really be rounding instead of flooring the alpha
// value, but that breaks slimming paint reftests.
- auto* item =
- display_item_list_->CreateAndAppendItem<cc::CompositingDisplayItem>();
- item->SetNew(static_cast<uint8_t>(gfx::ToFlooredInt(255 * opacity)), xfermode,
- bounds, skia::SharePtr(color_filter));
+
+ if (display_item_list_->RetainsIndividualDisplayItems()) {
+ auto* item =
+ display_item_list_->CreateAndAppendItem<cc::CompositingDisplayItem>();
+ item->SetNew(static_cast<uint8_t>(gfx::ToFlooredInt(255 * opacity)),
+ xfermode, bounds, skia::SharePtr(color_filter));
+ } else {
+ cc::CompositingDisplayItem item;
+ item.SetNew(static_cast<uint8_t>(gfx::ToFlooredInt(255 * opacity)),
+ xfermode, bounds, skia::SharePtr(color_filter));
+ display_item_list_->RasterIntoCanvas(item);
+ }
}
void WebDisplayItemListImpl::appendEndCompositingItem() {
- display_item_list_->CreateAndAppendItem<cc::EndCompositingDisplayItem>();
+ if (display_item_list_->RetainsIndividualDisplayItems()) {
+ display_item_list_->CreateAndAppendItem<cc::EndCompositingDisplayItem>();
+ } else {
+ display_item_list_->RasterIntoCanvas(cc::EndCompositingDisplayItem());
+ }
}
void WebDisplayItemListImpl::appendFilterItem(
@@ -110,12 +184,24 @@ void WebDisplayItemListImpl::appendFilterItem(
const blink::WebFloatRect& bounds) {
const WebFilterOperationsImpl& filters_impl =
static_cast<const WebFilterOperationsImpl&>(filters);
- auto* item = display_item_list_->CreateAndAppendItem<cc::FilterDisplayItem>();
- item->SetNew(filters_impl.AsFilterOperations(), bounds);
+
+ if (display_item_list_->RetainsIndividualDisplayItems()) {
+ auto* item =
+ display_item_list_->CreateAndAppendItem<cc::FilterDisplayItem>();
+ item->SetNew(filters_impl.AsFilterOperations(), bounds);
+ } else {
+ cc::FilterDisplayItem item;
+ item.SetNew(filters_impl.AsFilterOperations(), bounds);
+ display_item_list_->RasterIntoCanvas(item);
+ }
}
void WebDisplayItemListImpl::appendEndFilterItem() {
- display_item_list_->CreateAndAppendItem<cc::EndFilterDisplayItem>();
+ if (display_item_list_->RetainsIndividualDisplayItems()) {
+ display_item_list_->CreateAndAppendItem<cc::EndFilterDisplayItem>();
+ } else {
+ display_item_list_->RasterIntoCanvas(cc::EndFilterDisplayItem());
+ }
}
void WebDisplayItemListImpl::appendScrollItem(
diff --git a/chromium/cc/blink/web_display_item_list_impl.h b/chromium/cc/blink/web_display_item_list_impl.h
index 6b5d147b5d1..d45d7d36d48 100644
--- a/chromium/cc/blink/web_display_item_list_impl.h
+++ b/chromium/cc/blink/web_display_item_list_impl.h
@@ -27,11 +27,17 @@ struct WebFloatRect;
struct WebRect;
}
+namespace cc {
+class DisplayItemListSettings;
+}
+
namespace cc_blink {
class WebDisplayItemListImpl : public blink::WebDisplayItemList {
public:
- CC_BLINK_EXPORT WebDisplayItemListImpl(cc::DisplayItemList* display_list);
+ CC_BLINK_EXPORT WebDisplayItemListImpl();
+ CC_BLINK_EXPORT explicit WebDisplayItemListImpl(
+ cc::DisplayItemList* display_list);
virtual ~WebDisplayItemListImpl();
// blink::WebDisplayItemList implementation.
@@ -61,7 +67,7 @@ class WebDisplayItemListImpl : public blink::WebDisplayItemList {
virtual void appendEndScrollItem();
private:
- cc::DisplayItemList* display_item_list_;
+ scoped_refptr<cc::DisplayItemList> display_item_list_;
DISALLOW_COPY_AND_ASSIGN(WebDisplayItemListImpl);
};
diff --git a/chromium/cc/blink/web_external_texture_layer_impl.cc b/chromium/cc/blink/web_external_texture_layer_impl.cc
index 8d29aa172dd..e9700c6c6d9 100644
--- a/chromium/cc/blink/web_external_texture_layer_impl.cc
+++ b/chromium/cc/blink/web_external_texture_layer_impl.cc
@@ -7,7 +7,6 @@
#include "cc/blink/web_external_bitmap_impl.h"
#include "cc/blink/web_layer_impl.h"
#include "cc/layers/texture_layer.h"
-#include "cc/resources/resource_update_queue.h"
#include "cc/resources/single_release_callback.h"
#include "cc/resources/texture_mailbox.h"
#include "third_party/WebKit/public/platform/WebExternalTextureLayerClient.h"
@@ -18,7 +17,6 @@
#include "third_party/khronos/GLES2/gl2.h"
using cc::TextureLayer;
-using cc::ResourceUpdateQueue;
namespace cc_blink {
@@ -26,7 +24,8 @@ WebExternalTextureLayerImpl::WebExternalTextureLayerImpl(
blink::WebExternalTextureLayerClient* client)
: client_(client) {
cc::TextureLayerClient* cc_client = client_ ? this : nullptr;
- scoped_refptr<TextureLayer> layer = TextureLayer::CreateForMailbox(cc_client);
+ scoped_refptr<TextureLayer> layer =
+ TextureLayer::CreateForMailbox(WebLayerImpl::LayerSettings(), cc_client);
layer->SetIsDrawable(true);
layer_.reset(new WebLayerImpl(layer));
}
@@ -86,10 +85,10 @@ bool WebExternalTextureLayerImpl::PrepareTextureMailbox(
if (bitmap) {
*mailbox = cc::TextureMailbox(bitmap->shared_bitmap(), bitmap->size());
} else {
- *mailbox =
- cc::TextureMailbox(name, GL_TEXTURE_2D, client_mailbox.syncPoint);
+ // TODO(achaulk): pass a valid size here if allowOverlay is set.
+ *mailbox = cc::TextureMailbox(name, GL_TEXTURE_2D, client_mailbox.syncPoint,
+ gfx::Size(), client_mailbox.allowOverlay);
}
- mailbox->set_allow_overlay(client_mailbox.allowOverlay);
mailbox->set_nearest_neighbor(client_mailbox.nearestNeighbor);
if (mailbox->IsValid()) {
diff --git a/chromium/cc/blink/web_filter_operations_impl.cc b/chromium/cc/blink/web_filter_operations_impl.cc
index acabe0f7a15..e896c6adede 100644
--- a/chromium/cc/blink/web_filter_operations_impl.cc
+++ b/chromium/cc/blink/web_filter_operations_impl.cc
@@ -92,4 +92,8 @@ void WebFilterOperationsImpl::clear() {
filter_operations_.Clear();
}
+bool WebFilterOperationsImpl::isEmpty() const {
+ return filter_operations_.IsEmpty();
+}
+
} // namespace cc_blink
diff --git a/chromium/cc/blink/web_filter_operations_impl.h b/chromium/cc/blink/web_filter_operations_impl.h
index 7a9dcf33c88..36c3b4565cf 100644
--- a/chromium/cc/blink/web_filter_operations_impl.h
+++ b/chromium/cc/blink/web_filter_operations_impl.h
@@ -37,6 +37,7 @@ class WebFilterOperationsImpl : public blink::WebFilterOperations {
virtual void appendReferenceFilter(SkImageFilter* image_filter);
virtual void clear();
+ virtual bool isEmpty() const;
private:
cc::FilterOperations filter_operations_;
diff --git a/chromium/cc/blink/web_image_layer_impl.cc b/chromium/cc/blink/web_image_layer_impl.cc
index afd551a3102..55e28ef8152 100644
--- a/chromium/cc/blink/web_image_layer_impl.cc
+++ b/chromium/cc/blink/web_image_layer_impl.cc
@@ -6,16 +6,13 @@
#include "cc/blink/web_layer_impl.h"
#include "cc/blink/web_layer_impl_fixed_bounds.h"
-#include "cc/layers/image_layer.h"
#include "cc/layers/picture_image_layer.h"
namespace cc_blink {
WebImageLayerImpl::WebImageLayerImpl() {
- if (WebLayerImpl::UsingPictureLayer())
- layer_.reset(new WebLayerImplFixedBounds(cc::PictureImageLayer::Create()));
- else
- layer_.reset(new WebLayerImpl(cc::ImageLayer::Create()));
+ layer_.reset(new WebLayerImplFixedBounds(
+ cc::PictureImageLayer::Create(WebLayerImpl::LayerSettings())));
}
WebImageLayerImpl::~WebImageLayerImpl() {
@@ -26,20 +23,14 @@ blink::WebLayer* WebImageLayerImpl::layer() {
}
void WebImageLayerImpl::setImageBitmap(const SkBitmap& bitmap) {
- if (WebLayerImpl::UsingPictureLayer()) {
- static_cast<cc::PictureImageLayer*>(layer_->layer())->SetBitmap(bitmap);
- static_cast<WebLayerImplFixedBounds*>(layer_.get())
- ->SetFixedBounds(gfx::Size(bitmap.width(), bitmap.height()));
- } else {
- static_cast<cc::ImageLayer*>(layer_->layer())->SetBitmap(bitmap);
- }
+ static_cast<cc::PictureImageLayer*>(layer_->layer())->SetBitmap(bitmap);
+ static_cast<WebLayerImplFixedBounds*>(layer_.get())
+ ->SetFixedBounds(gfx::Size(bitmap.width(), bitmap.height()));
}
void WebImageLayerImpl::setNearestNeighbor(bool nearest_neighbor) {
- if (WebLayerImpl::UsingPictureLayer()) {
- static_cast<cc::PictureImageLayer*>(layer_->layer())
- ->SetNearestNeighbor(nearest_neighbor);
- }
+ static_cast<cc::PictureImageLayer*>(layer_->layer())
+ ->SetNearestNeighbor(nearest_neighbor);
}
} // namespace cc_blink
diff --git a/chromium/cc/blink/web_layer_impl.cc b/chromium/cc/blink/web_layer_impl.cc
index 8bad92a002e..3ba9431171d 100644
--- a/chromium/cc/blink/web_layer_impl.cc
+++ b/chromium/cc/blink/web_layer_impl.cc
@@ -46,11 +46,12 @@ using blink::WebFilterOperations;
namespace cc_blink {
namespace {
-bool g_impl_side_painting_enabled = false;
+base::LazyInstance<cc::LayerSettings> g_layer_settings =
+ LAZY_INSTANCE_INITIALIZER;
} // namespace
-WebLayerImpl::WebLayerImpl() : layer_(Layer::Create()) {
+WebLayerImpl::WebLayerImpl() : layer_(Layer::Create(LayerSettings())) {
web_layer_client_ = nullptr;
layer_->SetLayerClient(this);
}
@@ -62,18 +63,19 @@ WebLayerImpl::WebLayerImpl(scoped_refptr<Layer> layer) : layer_(layer) {
WebLayerImpl::~WebLayerImpl() {
layer_->ClearRenderSurface();
- layer_->set_layer_animation_delegate(nullptr);
+ if (animation_delegate_adapter_.get())
+ layer_->set_layer_animation_delegate(nullptr);
web_layer_client_ = nullptr;
}
// static
-bool WebLayerImpl::UsingPictureLayer() {
- return g_impl_side_painting_enabled;
+void WebLayerImpl::SetLayerSettings(const cc::LayerSettings& settings) {
+ g_layer_settings.Get() = settings;
}
// static
-void WebLayerImpl::SetImplSidePaintingEnabled(bool enabled) {
- g_impl_side_painting_enabled = enabled;
+const cc::LayerSettings& WebLayerImpl::LayerSettings() {
+ return g_layer_settings.Get();
}
int WebLayerImpl::id() const {
diff --git a/chromium/cc/blink/web_layer_impl.h b/chromium/cc/blink/web_layer_impl.h
index beaf3b51679..eb049b8e711 100644
--- a/chromium/cc/blink/web_layer_impl.h
+++ b/chromium/cc/blink/web_layer_impl.h
@@ -39,6 +39,7 @@ class ConvertableToTraceFormat;
namespace cc {
class Layer;
+class LayerSettings;
}
namespace cc_blink {
@@ -51,8 +52,9 @@ class WebLayerImpl : public blink::WebLayer, public cc::LayerClient {
CC_BLINK_EXPORT explicit WebLayerImpl(scoped_refptr<cc::Layer>);
virtual ~WebLayerImpl();
- static bool UsingPictureLayer();
- CC_BLINK_EXPORT static void SetImplSidePaintingEnabled(bool enabled);
+ CC_BLINK_EXPORT static void SetLayerSettings(
+ const cc::LayerSettings& settings);
+ CC_BLINK_EXPORT static const cc::LayerSettings& LayerSettings();
CC_BLINK_EXPORT cc::Layer* layer() const;
diff --git a/chromium/cc/blink/web_layer_impl_fixed_bounds_unittest.cc b/chromium/cc/blink/web_layer_impl_fixed_bounds_unittest.cc
index c9fd4fad6dc..26f445ae072 100644
--- a/chromium/cc/blink/web_layer_impl_fixed_bounds_unittest.cc
+++ b/chromium/cc/blink/web_layer_impl_fixed_bounds_unittest.cc
@@ -7,6 +7,7 @@
#include "cc/layers/picture_image_layer.h"
#include "cc/test/fake_layer_tree_host.h"
#include "cc/test/geometry_test_utils.h"
+#include "cc/test/test_task_graph_runner.h"
#include "cc/trees/layer_tree_host_common.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebFloatPoint.h"
@@ -67,10 +68,10 @@ TEST(WebLayerImplFixedBoundsTest, BoundsScaleSimple) {
}
void ExpectEqualLayerRectsInTarget(cc::Layer* layer1, cc::Layer* layer2) {
- gfx::RectF layer1_rect_in_target(layer1->content_bounds());
+ gfx::RectF layer1_rect_in_target(layer1->bounds());
layer1->draw_transform().TransformRect(&layer1_rect_in_target);
- gfx::RectF layer2_rect_in_target(layer2->content_bounds());
+ gfx::RectF layer2_rect_in_target(layer2->bounds());
layer2->draw_transform().TransformRect(&layer2_rect_in_target);
EXPECT_FLOAT_RECT_EQ(layer1_rect_in_target, layer2_rect_in_target);
@@ -88,15 +89,16 @@ void CompareFixedBoundsLayerAndNormalLayer(const WebFloatPoint& anchor_point,
scoped_ptr<WebLayerImplFixedBounds> root_layer(new WebLayerImplFixedBounds());
- WebLayerImplFixedBounds* fixed_bounds_layer =
- new WebLayerImplFixedBounds(cc::PictureImageLayer::Create());
+ WebLayerImplFixedBounds* fixed_bounds_layer = new WebLayerImplFixedBounds(
+ cc::PictureImageLayer::Create(WebLayerImpl::LayerSettings()));
fixed_bounds_layer->setBounds(bounds);
fixed_bounds_layer->SetFixedBounds(fixed_bounds);
fixed_bounds_layer->setTransform(transform.matrix());
fixed_bounds_layer->setPosition(position);
root_layer->addChild(fixed_bounds_layer);
- WebLayerImpl* normal_layer(new WebLayerImpl(cc::PictureImageLayer::Create()));
+ WebLayerImpl* normal_layer(
+ new WebLayerImpl(cc::PictureImageLayer::Create(cc::LayerSettings())));
normal_layer->setBounds(bounds);
normal_layer->setTransform(transform.matrix());
@@ -104,8 +106,9 @@ void CompareFixedBoundsLayerAndNormalLayer(const WebFloatPoint& anchor_point,
root_layer->addChild(normal_layer);
cc::FakeLayerTreeHostClient client(cc::FakeLayerTreeHostClient::DIRECT_3D);
+ cc::TestTaskGraphRunner task_graph_runner;
scoped_ptr<cc::FakeLayerTreeHost> host =
- cc::FakeLayerTreeHost::Create(&client);
+ cc::FakeLayerTreeHost::Create(&client, &task_graph_runner);
host->SetRootLayer(root_layer->layer());
{
@@ -114,7 +117,7 @@ void CompareFixedBoundsLayerAndNormalLayer(const WebFloatPoint& anchor_point,
root_layer->layer(), kDeviceViewportSize, &render_surface_layer_list);
inputs.device_scale_factor = kDeviceScaleFactor;
inputs.page_scale_factor = kPageScaleFactor;
- inputs.page_scale_application_layer = root_layer->layer(),
+ inputs.page_scale_layer = root_layer->layer(),
cc::LayerTreeHostCommon::CalculateDrawProperties(&inputs);
ExpectEqualLayerRectsInTarget(normal_layer->layer(),
@@ -131,7 +134,7 @@ void CompareFixedBoundsLayerAndNormalLayer(const WebFloatPoint& anchor_point,
root_layer->layer(), kDeviceViewportSize, &render_surface_layer_list);
inputs.device_scale_factor = kDeviceScaleFactor;
inputs.page_scale_factor = kPageScaleFactor;
- inputs.page_scale_application_layer = root_layer->layer(),
+ inputs.page_scale_layer = root_layer->layer(),
cc::LayerTreeHostCommon::CalculateDrawProperties(&inputs);
ExpectEqualLayerRectsInTarget(normal_layer->layer(),
diff --git a/chromium/cc/blink/web_nine_patch_layer_impl.cc b/chromium/cc/blink/web_nine_patch_layer_impl.cc
index 094349182fa..8dd9980f331 100644
--- a/chromium/cc/blink/web_nine_patch_layer_impl.cc
+++ b/chromium/cc/blink/web_nine_patch_layer_impl.cc
@@ -14,7 +14,8 @@
namespace cc_blink {
WebNinePatchLayerImpl::WebNinePatchLayerImpl() {
- layer_.reset(new WebLayerImpl(cc::NinePatchLayer::Create()));
+ layer_.reset(new WebLayerImpl(
+ cc::NinePatchLayer::Create(WebLayerImpl::LayerSettings())));
}
WebNinePatchLayerImpl::~WebNinePatchLayerImpl() {
diff --git a/chromium/cc/blink/web_scrollbar_layer_impl.cc b/chromium/cc/blink/web_scrollbar_layer_impl.cc
index c94f2c5a9cc..a6813cb98e2 100644
--- a/chromium/cc/blink/web_scrollbar_layer_impl.cc
+++ b/chromium/cc/blink/web_scrollbar_layer_impl.cc
@@ -31,6 +31,7 @@ WebScrollbarLayerImpl::WebScrollbarLayerImpl(
blink::WebScrollbarThemePainter painter,
blink::WebScrollbarThemeGeometry* geometry)
: layer_(new WebLayerImpl(PaintedScrollbarLayer::Create(
+ WebLayerImpl::LayerSettings(),
scoped_ptr<cc::Scrollbar>(
new ScrollbarImpl(make_scoped_ptr(scrollbar),
painter,
@@ -44,7 +45,8 @@ WebScrollbarLayerImpl::WebScrollbarLayerImpl(
int track_start,
bool is_left_side_vertical_scrollbar)
: layer_(new WebLayerImpl(
- SolidColorScrollbarLayer::Create(ConvertOrientation(orientation),
+ SolidColorScrollbarLayer::Create(WebLayerImpl::LayerSettings(),
+ ConvertOrientation(orientation),
thumb_thickness,
track_start,
is_left_side_vertical_scrollbar,
diff --git a/chromium/cc/cc.gyp b/chromium/cc/cc.gyp
index 2a4d66a267e..d4a2ea02fe7 100644
--- a/chromium/cc/cc.gyp
+++ b/chromium/cc/cc.gyp
@@ -20,7 +20,6 @@
'<(DEPTH)/ui/events/events.gyp:events_base',
'<(DEPTH)/ui/gfx/gfx.gyp:gfx',
'<(DEPTH)/ui/gfx/gfx.gyp:gfx_geometry',
- 'cc_opts',
],
'variables': {
'optimize': 'max',
@@ -40,10 +39,18 @@
'animation/animation_delegate.h',
'animation/animation_events.cc',
'animation/animation_events.h',
+ 'animation/animation_host.cc',
+ 'animation/animation_host.h',
'animation/animation_id_provider.cc',
'animation/animation_id_provider.h',
+ 'animation/animation_player.cc',
+ 'animation/animation_player.h',
'animation/animation_registrar.cc',
'animation/animation_registrar.h',
+ 'animation/animation_timeline.cc',
+ 'animation/animation_timeline.h',
+ 'animation/element_animations.cc',
+ 'animation/element_animations.h',
'animation/keyframed_animation_curve.cc',
'animation/keyframed_animation_curve.h',
'animation/layer_animation_controller.cc',
@@ -68,17 +75,23 @@
'base/completion_event.h',
'base/delayed_unique_notifier.cc',
'base/delayed_unique_notifier.h',
+ 'base/histograms.cc',
+ 'base/histograms.h',
'base/invalidation_region.cc',
'base/invalidation_region.h',
+ 'base/list_container.cc',
+ 'base/list_container.h',
'base/math_util.cc',
'base/math_util.h',
'base/region.cc',
'base/region.h',
+ 'base/resource_id.h',
'base/rolling_time_delta_history.cc',
'base/rolling_time_delta_history.h',
'base/scoped_ptr_algorithm.h',
'base/scoped_ptr_deque.h',
'base/scoped_ptr_vector.h',
+ 'base/sidecar_list_container.h',
'base/simple_enclosed_region.cc',
'base/simple_enclosed_region.h',
'base/switches.cc',
@@ -89,7 +102,6 @@
'base/time_util.h',
'base/unique_notifier.cc',
'base/unique_notifier.h',
- 'base/util.h',
'debug/benchmark_instrumentation.cc',
'debug/benchmark_instrumentation.h',
'debug/debug_colors.cc',
@@ -134,6 +146,8 @@
'debug/rendering_stats_instrumentation.cc',
'debug/rendering_stats_instrumentation.h',
'debug/ring_buffer.h',
+ 'debug/traced_display_item_list.cc',
+ 'debug/traced_display_item_list.h',
'debug/traced_picture.cc',
'debug/traced_picture.h',
'debug/traced_value.cc',
@@ -156,11 +170,7 @@
'input/top_controls_manager.h',
'input/top_controls_manager_client.h',
'layers/append_quads_data.h',
- 'layers/content_layer.cc',
- 'layers/content_layer.h',
'layers/content_layer_client.h',
- 'layers/contents_scaling_layer.cc',
- 'layers/contents_scaling_layer.h',
'layers/delegated_frame_provider.cc',
'layers/delegated_frame_provider.h',
'layers/delegated_frame_resource_collection.cc',
@@ -174,8 +184,6 @@
'layers/heads_up_display_layer.h',
'layers/heads_up_display_layer_impl.cc',
'layers/heads_up_display_layer_impl.h',
- 'layers/image_layer.cc',
- 'layers/image_layer.h',
'layers/io_surface_layer.cc',
'layers/io_surface_layer.h',
'layers/io_surface_layer_impl.cc',
@@ -234,10 +242,6 @@
'layers/texture_layer_client.h',
'layers/texture_layer_impl.cc',
'layers/texture_layer_impl.h',
- 'layers/tiled_layer.cc',
- 'layers/tiled_layer.h',
- 'layers/tiled_layer_impl.cc',
- 'layers/tiled_layer_impl.h',
'layers/ui_resource_layer.cc',
'layers/ui_resource_layer.h',
'layers/ui_resource_layer_impl.cc',
@@ -334,7 +338,6 @@
'output/texture_mailbox_deleter.h',
'output/viewport_selection_bound.cc',
'output/viewport_selection_bound.h',
- 'output/vsync_parameter_observer.h',
'playback/clip_display_item.cc',
'playback/clip_display_item.h',
'playback/clip_path_display_item.cc',
@@ -345,6 +348,8 @@
'playback/display_item.h',
'playback/display_item_list.cc',
'playback/display_item_list.h',
+ 'playback/display_item_list_settings.cc',
+ 'playback/display_item_list_settings.h',
'playback/display_list_raster_source.cc',
'playback/display_list_raster_source.h',
'playback/display_list_recording_source.cc',
@@ -385,8 +390,6 @@
'quads/io_surface_draw_quad.h',
'quads/largest_draw_quad.cc',
'quads/largest_draw_quad.h',
- 'quads/list_container.cc',
- 'quads/list_container.h',
'quads/picture_draw_quad.cc',
'quads/picture_draw_quad.h',
'quads/render_pass.cc',
@@ -435,28 +438,10 @@
'raster/tile_task_worker_pool.h',
'raster/zero_copy_tile_task_worker_pool.cc',
'raster/zero_copy_tile_task_worker_pool.h',
- 'resources/bitmap_content_layer_updater.cc',
- 'resources/bitmap_content_layer_updater.h',
- 'resources/bitmap_skpicture_content_layer_updater.cc',
- 'resources/bitmap_skpicture_content_layer_updater.h',
- 'resources/content_layer_updater.cc',
- 'resources/content_layer_updater.h',
- 'resources/image_layer_updater.cc',
- 'resources/image_layer_updater.h',
- 'resources/layer_painter.h',
- 'resources/layer_updater.cc',
- 'resources/layer_updater.h',
'resources/memory_history.cc',
'resources/memory_history.h',
'resources/platform_color.h',
- 'resources/prioritized_resource.cc',
- 'resources/prioritized_resource.h',
- 'resources/prioritized_resource_manager.cc',
- 'resources/prioritized_resource_manager.h',
- 'resources/priority_calculator.cc',
- 'resources/priority_calculator.h',
'resources/release_callback.h',
- 'resources/resource.cc',
'resources/resource.h',
'resources/resource_format.cc',
'resources/resource_format.h',
@@ -464,12 +449,6 @@
'resources/resource_pool.h',
'resources/resource_provider.cc',
'resources/resource_provider.h',
- 'resources/resource_update.cc',
- 'resources/resource_update.h',
- 'resources/resource_update_controller.cc',
- 'resources/resource_update_controller.h',
- 'resources/resource_update_queue.cc',
- 'resources/resource_update_queue.h',
'resources/returned_resource.h',
'resources/scoped_resource.cc',
'resources/scoped_resource.h',
@@ -482,12 +461,8 @@
'resources/single_release_callback.h',
'resources/single_release_callback_impl.cc',
'resources/single_release_callback_impl.h',
- 'resources/skpicture_content_layer_updater.cc',
- 'resources/skpicture_content_layer_updater.h',
'resources/texture_mailbox.cc',
'resources/texture_mailbox.h',
- 'resources/texture_uploader.cc',
- 'resources/texture_uploader.h',
'resources/transferable_resource.cc',
'resources/transferable_resource.h',
'resources/ui_resource_bitmap.cc',
@@ -499,7 +474,11 @@
'resources/video_resource_updater.h',
'scheduler/begin_frame_source.cc',
'scheduler/begin_frame_source.h',
+ 'scheduler/begin_frame_tracker.cc',
+ 'scheduler/begin_frame_tracker.h',
'scheduler/commit_earlyout_reason.h',
+ 'scheduler/compositor_timing_history.cc',
+ 'scheduler/compositor_timing_history.h',
'scheduler/delay_based_time_source.cc',
'scheduler/delay_based_time_source.h',
'scheduler/draw_result.h',
@@ -512,8 +491,6 @@
'scheduler/video_frame_controller.h',
'tiles/eviction_tile_priority_queue.cc',
'tiles/eviction_tile_priority_queue.h',
- 'tiles/layer_tiling_data.cc',
- 'tiles/layer_tiling_data.h',
'tiles/picture_layer_tiling.cc',
'tiles/picture_layer_tiling.h',
'tiles/picture_layer_tiling_set.cc',
@@ -560,6 +537,7 @@
'trees/layer_tree_impl.h',
'trees/layer_tree_settings.cc',
'trees/layer_tree_settings.h',
+ 'trees/mutator_host_client.h',
'trees/occlusion.cc',
'trees/occlusion.h',
'trees/occlusion_tracker.cc',
@@ -570,8 +548,6 @@
'trees/property_tree_builder.h',
'trees/proxy.cc',
'trees/proxy.h',
- 'trees/proxy_timing_history.cc',
- 'trees/proxy_timing_history.h',
'trees/scoped_abort_remaining_swap_promises.h',
'trees/single_thread_proxy.cc',
'trees/single_thread_proxy.h',
@@ -585,8 +561,14 @@
'includes': [
'../build/android/increase_size_for_speed.gypi',
],
- # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
- 'msvs_disabled_warnings': [ 4267, ],
+ 'conditions': [
+ ['target_arch == "ia32" or target_arch == "x64"', {
+ 'sources': [
+ 'raster/texture_compressor_etc1_sse.cc',
+ 'raster/texture_compressor_etc1_sse.h',
+ ],
+ }],
+ ],
},
{
# GN version: //cc/surfaces
@@ -596,6 +578,7 @@
'cc',
'<(DEPTH)/base/base.gyp:base',
'<(DEPTH)/base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
+ '<(DEPTH)/gpu/gpu.gyp:gpu',
'<(DEPTH)/skia/skia.gyp:skia',
'<(DEPTH)/ui/events/events.gyp:events_base',
'<(DEPTH)/ui/gfx/gfx.gyp:gfx',
@@ -609,6 +592,8 @@
'surfaces/display.cc',
'surfaces/display.h',
'surfaces/display_client.h',
+ 'surfaces/display_scheduler.cc',
+ 'surfaces/display_scheduler.h',
'surfaces/onscreen_display_client.cc',
'surfaces/onscreen_display_client.h',
'surfaces/surface.cc',
@@ -633,41 +618,5 @@
'../build/android/increase_size_for_speed.gypi',
],
},
- {
- 'target_name': 'cc_opts',
- 'type': 'static_library',
- 'conditions': [
- ['target_arch == "ia32" or target_arch == "x64"', {
- 'defines': [
- 'CC_IMPLEMENTATION=1',
- ],
- 'dependencies': [
- 'cc_opts_sse',
- ]
- }],
- ],
- },
- {
- 'target_name': 'cc_opts_sse',
- 'type': 'static_library',
- 'dependencies': [
- '<(DEPTH)/base/base.gyp:base',
- ],
- 'conditions': [
- ['target_arch == "ia32" or target_arch == "x64"', {
- 'defines': [
- 'CC_IMPLEMENTATION=1',
- ],
- 'sources': [
- # Conditional compilation for SSE2 code on x86 and x64 machines
- 'raster/texture_compressor_etc1_sse.cc',
- 'raster/texture_compressor_etc1_sse.h',
- ],
- 'cflags': [
- '-msse2',
- ],
- }],
- ],
- },
],
}
diff --git a/chromium/cc/cc_tests.gyp b/chromium/cc/cc_tests.gyp
index 5ded2b81fc5..5f5f4e418aa 100644
--- a/chromium/cc/cc_tests.gyp
+++ b/chromium/cc/cc_tests.gyp
@@ -6,7 +6,11 @@
'variables': {
'chromium_code': 1,
'cc_unit_tests_source_files': [
+ 'animation/animation_host_unittest.cc',
+ 'animation/animation_player_unittest.cc',
+ 'animation/animation_timeline_unittest.cc',
'animation/animation_unittest.cc',
+ 'animation/element_animations_unittest.cc',
'animation/keyframed_animation_curve_unittest.cc',
'animation/layer_animation_controller_unittest.cc',
'animation/scroll_offset_animation_curve_unittest.cc',
@@ -15,19 +19,20 @@
'animation/transform_operations_unittest.cc',
'base/delayed_unique_notifier_unittest.cc',
'base/float_quad_unittest.cc',
+ 'base/histograms_unittest.cc',
+ 'base/list_container_unittest.cc',
'base/math_util_unittest.cc',
'base/region_unittest.cc',
'base/rolling_time_delta_history_unittest.cc',
'base/scoped_ptr_vector_unittest.cc',
+ 'base/sidecar_list_container_unittest.cc',
'base/simple_enclosed_region_unittest.cc',
'base/tiling_data_unittest.cc',
'base/unique_notifier_unittest.cc',
- 'base/util_unittest.cc',
'debug/frame_timing_tracker_unittest.cc',
'debug/micro_benchmark_controller_unittest.cc',
'debug/rendering_stats_unittest.cc',
'input/top_controls_manager_unittest.cc',
- 'layers/contents_scaling_layer_unittest.cc',
'layers/delegated_frame_provider_unittest.cc',
'layers/delegated_frame_resource_collection_unittest.cc',
'layers/delegated_renderer_layer_impl_unittest.cc',
@@ -56,10 +61,9 @@
'layers/surface_layer_unittest.cc',
'layers/texture_layer_impl_unittest.cc',
'layers/texture_layer_unittest.cc',
- 'layers/tiled_layer_impl_unittest.cc',
- 'layers/tiled_layer_unittest.cc',
'layers/ui_resource_layer_impl_unittest.cc',
'layers/ui_resource_layer_unittest.cc',
+ 'layers/video_frame_provider_client_impl_unittest.cc',
'layers/video_layer_impl_unittest.cc',
'output/begin_frame_args_unittest.cc',
'output/bsp_tree_unittest.cc',
@@ -75,6 +79,7 @@
'output/software_renderer_unittest.cc',
'output/texture_mailbox_deleter_unittest.cc',
'playback/display_item_list_unittest.cc',
+ 'playback/display_list_raster_source_unittest.cc',
'playback/display_list_recording_source_unittest.cc',
'playback/picture_pile_impl_unittest.cc',
'playback/picture_pile_unittest.cc',
@@ -83,20 +88,18 @@
'playback/recording_source_unittest.cc',
'quads/draw_polygon_unittest.cc',
'quads/draw_quad_unittest.cc',
- 'quads/list_container_unittest.cc',
'quads/render_pass_unittest.cc',
'raster/scoped_gpu_raster_unittest.cc',
'raster/task_graph_runner_unittest.cc',
'raster/texture_compressor_etc1_unittest.cc',
'raster/tile_task_worker_pool_unittest.cc',
'resources/platform_color_unittest.cc',
- 'resources/prioritized_resource_unittest.cc',
+ 'resources/resource_pool_unittest.cc',
'resources/resource_provider_unittest.cc',
- 'resources/resource_update_controller_unittest.cc',
'resources/scoped_resource_unittest.cc',
- 'resources/texture_uploader_unittest.cc',
'resources/video_resource_updater_unittest.cc',
'scheduler/begin_frame_source_unittest.cc',
+ 'scheduler/compositor_timing_history_unittest.cc',
'scheduler/delay_based_time_source_unittest.cc',
'scheduler/scheduler_state_machine_unittest.cc',
'scheduler/scheduler_unittest.cc',
@@ -116,13 +119,14 @@
'trees/layer_tree_host_pixeltest_masks.cc',
'trees/layer_tree_host_pixeltest_readback.cc',
'trees/layer_tree_host_pixeltest_synchronous.cc',
+ 'trees/layer_tree_host_pixeltest_tiles.cc',
'trees/layer_tree_host_unittest.cc',
'trees/layer_tree_host_unittest_animation.cc',
+ 'trees/layer_tree_host_unittest_animation_timelines.cc',
'trees/layer_tree_host_unittest_context.cc',
'trees/layer_tree_host_unittest_copyrequest.cc',
'trees/layer_tree_host_unittest_damage.cc',
'trees/layer_tree_host_unittest_delegated.cc',
- 'trees/layer_tree_host_unittest_no_message_loop.cc',
'trees/layer_tree_host_unittest_occlusion.cc',
'trees/layer_tree_host_unittest_picture.cc',
'trees/layer_tree_host_unittest_proxy.cc',
@@ -136,6 +140,7 @@
],
'cc_surfaces_unit_tests_source_files': [
'surfaces/display_unittest.cc',
+ 'surfaces/display_scheduler_unittest.cc',
'surfaces/surface_aggregator_test_helpers.cc',
'surfaces/surface_aggregator_test_helpers.h',
'surfaces/surface_aggregator_unittest.cc',
@@ -147,16 +152,14 @@
'cc_tests_support_files': [
'test/animation_test_common.cc',
'test/animation_test_common.h',
+ 'test/animation_timelines_test_common.cc',
+ 'test/animation_timelines_test_common.h',
'test/begin_frame_args_test.cc',
'test/begin_frame_args_test.h',
'test/failure_output_surface.cc',
'test/failure_output_surface.h',
- 'test/fake_content_layer.cc',
- 'test/fake_content_layer.h',
'test/fake_content_layer_client.cc',
'test/fake_content_layer_client.h',
- 'test/fake_content_layer_impl.cc',
- 'test/fake_content_layer_impl.h',
'test/fake_delegated_renderer_layer.cc',
'test/fake_delegated_renderer_layer.h',
'test/fake_delegated_renderer_layer_impl.cc',
@@ -194,6 +197,7 @@
'test/fake_renderer_client.cc',
'test/fake_renderer_client.h',
'test/fake_rendering_stats_instrumentation.h',
+ 'test/fake_resource_provider.h',
'test/fake_scoped_ui_resource.cc',
'test/fake_scoped_ui_resource.h',
'test/fake_scrollbar.cc',
@@ -208,7 +212,6 @@
'test/fake_video_frame_provider.h',
'test/geometry_test_utils.cc',
'test/geometry_test_utils.h',
- 'test/impl_side_painting_settings.h',
'test/layer_test_common.cc',
'test/layer_test_common.h',
'test/layer_tree_host_common_test.cc',
@@ -260,8 +263,6 @@
'test/test_image_factory.h',
'test/test_in_process_context_provider.cc',
'test/test_in_process_context_provider.h',
- 'test/test_now_source.cc',
- 'test/test_now_source.h',
'test/test_occlusion_tracker.h',
'test/test_shared_bitmap_manager.cc',
'test/test_shared_bitmap_manager.h',
@@ -273,8 +274,6 @@
'test/test_tile_priorities.h',
'test/test_web_graphics_context_3d.cc',
'test/test_web_graphics_context_3d.h',
- 'test/tiled_layer_test_common.cc',
- 'test/tiled_layer_test_common.h',
],
},
'targets': [
@@ -329,8 +328,6 @@
}
],
],
- # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
- 'msvs_disabled_warnings': [ 4267, ],
},
{
# GN version: //cc/cc_perftests
@@ -357,6 +354,7 @@
'layers/layer_perftest.cc',
'layers/picture_layer_impl_perftest.cc',
'playback/picture_pile_impl_perftest.cc',
+ 'quads/draw_quad_perftest.cc',
'raster/task_graph_runner_perftest.cc',
'raster/texture_compressor_perftest.cc',
'raster/tile_task_worker_pool_perftest.cc',
@@ -390,8 +388,6 @@
}
],
],
- # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
- 'msvs_disabled_warnings': [ 4267, ],
},
{
'target_name': 'cc_test_support',
@@ -423,8 +419,6 @@
'sources': [
'<@(cc_tests_support_files)',
],
- # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
- 'msvs_disabled_warnings': [ 4267, ],
},
],
'conditions': [
diff --git a/chromium/cc/debug/debug_rect_history.cc b/chromium/cc/debug/debug_rect_history.cc
index c257c60c5cf..9fa90a5bd36 100644
--- a/chromium/cc/debug/debug_rect_history.cc
+++ b/chromium/cc/debug/debug_rect_history.cc
@@ -70,18 +70,10 @@ void DebugRectHistory::SavePaintRects(LayerImpl* layer) {
Region invalidation_region = layer->GetInvalidationRegion();
if (!invalidation_region.IsEmpty() && layer->DrawsContent()) {
- float width_scale = layer->content_bounds().width() /
- static_cast<float>(layer->bounds().width());
- float height_scale = layer->content_bounds().height() /
- static_cast<float>(layer->bounds().height());
-
for (Region::Iterator it(invalidation_region); it.has_rect(); it.next()) {
- gfx::Rect update_content_rect =
- gfx::ScaleToEnclosingRect(it.rect(), width_scale, height_scale);
- debug_rects_.push_back(
- DebugRect(PAINT_RECT_TYPE,
- MathUtil::MapEnclosingClippedRect(
- layer->screen_space_transform(), update_content_rect)));
+ debug_rects_.push_back(DebugRect(
+ PAINT_RECT_TYPE, MathUtil::MapEnclosingClippedRect(
+ layer->screen_space_transform(), it.rect())));
}
}
@@ -92,9 +84,8 @@ void DebugRectHistory::SavePaintRects(LayerImpl* layer) {
void DebugRectHistory::SavePropertyChangedRects(
const LayerImplList& render_surface_layer_list,
LayerImpl* hud_layer) {
- for (int surface_index = render_surface_layer_list.size() - 1;
- surface_index >= 0;
- --surface_index) {
+ for (size_t i = 0; i < render_surface_layer_list.size(); ++i) {
+ size_t surface_index = render_surface_layer_list.size() - 1 - i;
LayerImpl* render_surface_layer = render_surface_layer_list[surface_index];
RenderSurfaceImpl* render_surface = render_surface_layer->render_surface();
DCHECK(render_surface);
@@ -115,20 +106,18 @@ void DebugRectHistory::SavePropertyChangedRects(
if (!layer->LayerPropertyChanged())
continue;
- debug_rects_.push_back(
- DebugRect(PROPERTY_CHANGED_RECT_TYPE,
- MathUtil::MapEnclosingClippedRect(
- layer->screen_space_transform(),
- gfx::Rect(layer->content_bounds()))));
+ debug_rects_.push_back(DebugRect(
+ PROPERTY_CHANGED_RECT_TYPE,
+ MathUtil::MapEnclosingClippedRect(layer->screen_space_transform(),
+ gfx::Rect(layer->bounds()))));
}
}
}
void DebugRectHistory::SaveSurfaceDamageRects(
const LayerImplList& render_surface_layer_list) {
- for (int surface_index = render_surface_layer_list.size() - 1;
- surface_index >= 0;
- --surface_index) {
+ for (size_t i = 0; i < render_surface_layer_list.size(); ++i) {
+ size_t surface_index = render_surface_layer_list.size() - 1 - i;
LayerImpl* render_surface_layer = render_surface_layer_list[surface_index];
RenderSurfaceImpl* render_surface = render_surface_layer->render_surface();
DCHECK(render_surface);
@@ -143,9 +132,8 @@ void DebugRectHistory::SaveSurfaceDamageRects(
void DebugRectHistory::SaveScreenSpaceRects(
const LayerImplList& render_surface_layer_list) {
- for (int surface_index = render_surface_layer_list.size() - 1;
- surface_index >= 0;
- --surface_index) {
+ for (size_t i = 0; i < render_surface_layer_list.size(); ++i) {
+ size_t surface_index = render_surface_layer_list.size() - 1 - i;
LayerImpl* render_surface_layer = render_surface_layer_list[surface_index];
RenderSurfaceImpl* render_surface = render_surface_layer->render_surface();
DCHECK(render_surface);
@@ -176,12 +164,10 @@ void DebugRectHistory::SaveTouchEventHandlerRectsCallback(LayerImpl* layer) {
for (Region::Iterator iter(layer->touch_event_handler_region());
iter.has_rect();
iter.next()) {
- gfx::Rect touch_rect = gfx::ScaleToEnclosingRect(
- iter.rect(), layer->contents_scale_x(), layer->contents_scale_y());
debug_rects_.push_back(
DebugRect(TOUCH_EVENT_HANDLER_RECT_TYPE,
MathUtil::MapEnclosingClippedRect(
- layer->screen_space_transform(), touch_rect)));
+ layer->screen_space_transform(), iter.rect())));
}
}
@@ -195,14 +181,10 @@ void DebugRectHistory::SaveWheelEventHandlerRectsCallback(LayerImpl* layer) {
if (!layer->have_wheel_event_handlers())
return;
- gfx::Rect wheel_rect =
- gfx::ScaleToEnclosingRect(gfx::Rect(layer->content_bounds()),
- layer->contents_scale_x(),
- layer->contents_scale_y());
- debug_rects_.push_back(
- DebugRect(WHEEL_EVENT_HANDLER_RECT_TYPE,
- MathUtil::MapEnclosingClippedRect(
- layer->screen_space_transform(), wheel_rect)));
+ debug_rects_.push_back(DebugRect(
+ WHEEL_EVENT_HANDLER_RECT_TYPE,
+ MathUtil::MapEnclosingClippedRect(layer->screen_space_transform(),
+ gfx::Rect(layer->bounds()))));
}
void DebugRectHistory::SaveScrollEventHandlerRects(LayerImpl* layer) {
@@ -215,14 +197,10 @@ void DebugRectHistory::SaveScrollEventHandlerRectsCallback(LayerImpl* layer) {
if (!layer->have_scroll_event_handlers())
return;
- gfx::Rect scroll_rect =
- gfx::ScaleToEnclosingRect(gfx::Rect(layer->content_bounds()),
- layer->contents_scale_x(),
- layer->contents_scale_y());
- debug_rects_.push_back(
- DebugRect(SCROLL_EVENT_HANDLER_RECT_TYPE,
- MathUtil::MapEnclosingClippedRect(
- layer->screen_space_transform(), scroll_rect)));
+ debug_rects_.push_back(DebugRect(
+ SCROLL_EVENT_HANDLER_RECT_TYPE,
+ MathUtil::MapEnclosingClippedRect(layer->screen_space_transform(),
+ gfx::Rect(layer->bounds()))));
}
void DebugRectHistory::SaveNonFastScrollableRects(LayerImpl* layer) {
@@ -235,21 +213,17 @@ void DebugRectHistory::SaveNonFastScrollableRectsCallback(LayerImpl* layer) {
for (Region::Iterator iter(layer->non_fast_scrollable_region());
iter.has_rect();
iter.next()) {
- gfx::Rect scroll_rect = gfx::ScaleToEnclosingRect(
- iter.rect(), layer->contents_scale_x(), layer->contents_scale_y());
debug_rects_.push_back(
DebugRect(NON_FAST_SCROLLABLE_RECT_TYPE,
MathUtil::MapEnclosingClippedRect(
- layer->screen_space_transform(), scroll_rect)));
+ layer->screen_space_transform(), iter.rect())));
}
}
void DebugRectHistory::SaveLayerAnimationBoundsRects(
const LayerImplList& render_surface_layer_list) {
- typedef LayerIterator<LayerImpl> LayerIteratorType;
- LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list);
- for (LayerIteratorType it =
- LayerIteratorType::Begin(&render_surface_layer_list);
+ LayerIterator end = LayerIterator::End(&render_surface_layer_list);
+ for (LayerIterator it = LayerIterator::Begin(&render_surface_layer_list);
it != end; ++it) {
if (!it.represents_itself())
continue;
diff --git a/chromium/cc/debug/devtools_instrumentation.h b/chromium/cc/debug/devtools_instrumentation.h
index f1faf6ff424..8f03f8c76fc 100644
--- a/chromium/cc/debug/devtools_instrumentation.h
+++ b/chromium/cc/debug/devtools_instrumentation.h
@@ -23,6 +23,7 @@ const char kPixelRefId[] = "pixelRefId";
const char kImageDecodeTask[] = "ImageDecodeTask";
const char kBeginFrame[] = "BeginFrame";
+const char kNeedsBeginFrameChanged[] = "NeedsBeginFrameChanged";
const char kActivateLayerTree[] = "ActivateLayerTree";
const char kRequestMainThreadFrame[] = "RequestMainThreadFrame";
const char kBeginMainThreadFrame[] = "BeginMainThreadFrame";
@@ -157,6 +158,21 @@ inline void WillBeginMainThreadFrame(int layer_tree_host_id, int frame_id) {
internal::kData, BeginMainThreadFrameData(frame_id));
}
+inline scoped_refptr<base::trace_event::ConvertableToTraceFormat>
+NeedsBeginFrameData(bool needs_begin_frame) {
+ scoped_refptr<base::trace_event::TracedValue> value =
+ new base::trace_event::TracedValue();
+ value->SetInteger("needsBeginFrame", needs_begin_frame);
+ return value;
+}
+
+inline void NeedsBeginFrameChanged(int layer_tree_host_id, bool new_value) {
+ TRACE_EVENT_INSTANT2(
+ internal::kCategoryFrame, internal::kNeedsBeginFrameChanged,
+ TRACE_EVENT_SCOPE_THREAD, internal::kLayerTreeId, layer_tree_host_id,
+ internal::kData, NeedsBeginFrameData(new_value));
+}
+
} // namespace devtools_instrumentation
} // namespace cc
diff --git a/chromium/cc/debug/frame_rate_counter.h b/chromium/cc/debug/frame_rate_counter.h
index 0b69b29aea5..c50d7e22237 100644
--- a/chromium/cc/debug/frame_rate_counter.h
+++ b/chromium/cc/debug/frame_rate_counter.h
@@ -18,7 +18,7 @@ class FrameRateCounter {
public:
static scoped_ptr<FrameRateCounter> Create(bool has_impl_thread);
- int current_frame_number() const { return ring_buffer_.CurrentIndex(); }
+ size_t current_frame_number() const { return ring_buffer_.CurrentIndex(); }
int dropped_frame_count() const { return dropped_frame_count_; }
size_t time_stamp_history_size() const { return ring_buffer_.BufferSize(); }
diff --git a/chromium/cc/debug/frame_timing_request.h b/chromium/cc/debug/frame_timing_request.h
index 09379980fa0..aedd7205298 100644
--- a/chromium/cc/debug/frame_timing_request.h
+++ b/chromium/cc/debug/frame_timing_request.h
@@ -25,6 +25,10 @@ class CC_EXPORT FrameTimingRequest {
// Return the layer space rect for this request.
const gfx::Rect& rect() const { return rect_; }
+ bool operator==(const FrameTimingRequest& other) const {
+ return (id_ == other.id_) && (rect_ == other.rect_);
+ }
+
private:
int64_t id_;
gfx::Rect rect_;
diff --git a/chromium/cc/debug/frame_timing_tracker.cc b/chromium/cc/debug/frame_timing_tracker.cc
index 50aa92be5aa..38977ee6f32 100644
--- a/chromium/cc/debug/frame_timing_tracker.cc
+++ b/chromium/cc/debug/frame_timing_tracker.cc
@@ -8,9 +8,13 @@
#include <limits>
#include "base/metrics/histogram.h"
+#include "cc/trees/layer_tree_host_impl.h"
#include "cc/trees/proxy.h"
namespace cc {
+namespace {
+int kSendTimingIntervalMS = 200;
+}
FrameTimingTracker::CompositeTimingEvent::CompositeTimingEvent(
int _frame_id,
@@ -32,11 +36,19 @@ FrameTimingTracker::MainFrameTimingEvent::~MainFrameTimingEvent() {
}
// static
-scoped_ptr<FrameTimingTracker> FrameTimingTracker::Create() {
- return make_scoped_ptr(new FrameTimingTracker);
+scoped_ptr<FrameTimingTracker> FrameTimingTracker::Create(
+ LayerTreeHostImpl* layer_tree_host_impl) {
+ return make_scoped_ptr(new FrameTimingTracker(layer_tree_host_impl));
}
-FrameTimingTracker::FrameTimingTracker() {
+FrameTimingTracker::FrameTimingTracker(LayerTreeHostImpl* layer_tree_host_impl)
+ : layer_tree_host_impl_(layer_tree_host_impl),
+ post_events_notifier_(
+ layer_tree_host_impl_->proxy()->HasImplThread()
+ ? layer_tree_host_impl_->proxy()->ImplThreadTaskRunner()
+ : layer_tree_host_impl_->proxy()->MainThreadTaskRunner(),
+ base::Bind(&FrameTimingTracker::PostEvents, base::Unretained(this)),
+ base::TimeDelta::FromMilliseconds(kSendTimingIntervalMS)) {
}
FrameTimingTracker::~FrameTimingTracker() {
@@ -51,6 +63,8 @@ void FrameTimingTracker::SaveTimeStamps(
(*composite_events_)[pair.second].push_back(
CompositeTimingEvent(pair.first, timestamp));
}
+ if (!post_events_notifier_.HasPendingNotification())
+ post_events_notifier_.Schedule();
}
void FrameTimingTracker::SaveMainFrameTimeStamps(
@@ -65,6 +79,8 @@ void FrameTimingTracker::SaveMainFrameTimeStamps(
events.push_back(
MainFrameTimingEvent(source_frame_number, main_frame_time, end_time));
}
+ if (!post_events_notifier_.HasPendingNotification())
+ post_events_notifier_.Schedule();
}
scoped_ptr<FrameTimingTracker::CompositeTimingSet>
@@ -95,4 +111,9 @@ FrameTimingTracker::GroupMainFrameCountsByRectId() {
return main_frame_events_.Pass();
}
+void FrameTimingTracker::PostEvents() {
+ layer_tree_host_impl_->PostFrameTimingEvents(GroupCompositeCountsByRectId(),
+ GroupMainFrameCountsByRectId());
+}
+
} // namespace cc
diff --git a/chromium/cc/debug/frame_timing_tracker.h b/chromium/cc/debug/frame_timing_tracker.h
index 33649931973..7b638d7f8ac 100644
--- a/chromium/cc/debug/frame_timing_tracker.h
+++ b/chromium/cc/debug/frame_timing_tracker.h
@@ -13,9 +13,12 @@
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "cc/base/cc_export.h"
+#include "cc/base/delayed_unique_notifier.h"
namespace cc {
+class LayerTreeHostImpl;
+
// This class maintains a history of timestamps and rect IDs to communicate
// frame events back to Blink
// TODO(mpb): Start using this. crbug.com/442554
@@ -30,7 +33,7 @@ class CC_EXPORT FrameTimingTracker {
};
using CompositeTimingSet =
- base::hash_map<int, std::vector<CompositeTimingEvent>>;
+ base::hash_map<int64_t, std::vector<CompositeTimingEvent>>;
struct CC_EXPORT MainFrameTimingEvent {
MainFrameTimingEvent(int frame_id,
@@ -44,9 +47,10 @@ class CC_EXPORT FrameTimingTracker {
};
using MainFrameTimingSet =
- base::hash_map<int, std::vector<MainFrameTimingEvent>>;
+ base::hash_map<int64_t, std::vector<MainFrameTimingEvent>>;
- static scoped_ptr<FrameTimingTracker> Create();
+ static scoped_ptr<FrameTimingTracker> Create(
+ LayerTreeHostImpl* layer_tree_host_impl);
~FrameTimingTracker();
@@ -74,11 +78,16 @@ class CC_EXPORT FrameTimingTracker {
int source_frame_number);
private:
- FrameTimingTracker();
+ explicit FrameTimingTracker(LayerTreeHostImpl* layer_tree_host_impl);
+
+ void PostEvents();
scoped_ptr<CompositeTimingSet> composite_events_;
scoped_ptr<MainFrameTimingSet> main_frame_events_;
+ LayerTreeHostImpl* layer_tree_host_impl_;
+ DelayedUniqueNotifier post_events_notifier_;
+
DISALLOW_COPY_AND_ASSIGN(FrameTimingTracker);
};
diff --git a/chromium/cc/debug/frame_timing_tracker_unittest.cc b/chromium/cc/debug/frame_timing_tracker_unittest.cc
index b5574435fbc..218927cf26a 100644
--- a/chromium/cc/debug/frame_timing_tracker_unittest.cc
+++ b/chromium/cc/debug/frame_timing_tracker_unittest.cc
@@ -9,6 +9,10 @@
#include "base/trace_event/trace_event_argument.h"
#include "base/values.h"
#include "cc/debug/frame_timing_tracker.h"
+#include "cc/test/fake_impl_proxy.h"
+#include "cc/test/fake_layer_tree_host_impl.h"
+#include "cc/test/test_shared_bitmap_manager.h"
+#include "cc/test/test_task_graph_runner.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cc {
@@ -70,7 +74,14 @@ std::string MainFrameToString(
}
TEST(FrameTimingTrackerTest, DefaultTrackerIsEmpty) {
- scoped_ptr<FrameTimingTracker> tracker(FrameTimingTracker::Create());
+ FakeImplProxy proxy;
+ TestSharedBitmapManager shared_bitmap_manager;
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
+
+ scoped_ptr<FrameTimingTracker> tracker(
+ FrameTimingTracker::Create(&host_impl));
EXPECT_EQ("{\"values\":[]}",
CompositeToString(tracker->GroupCompositeCountsByRectId()));
EXPECT_EQ("{\"values\":[]}",
@@ -78,7 +89,14 @@ TEST(FrameTimingTrackerTest, DefaultTrackerIsEmpty) {
}
TEST(FrameTimingTrackerTest, NoFrameIdsIsEmpty) {
- scoped_ptr<FrameTimingTracker> tracker(FrameTimingTracker::Create());
+ FakeImplProxy proxy;
+ TestSharedBitmapManager shared_bitmap_manager;
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
+
+ scoped_ptr<FrameTimingTracker> tracker(
+ FrameTimingTracker::Create(&host_impl));
std::vector<std::pair<int, int64_t>> ids;
tracker->SaveTimeStamps(base::TimeTicks::FromInternalValue(100), ids);
EXPECT_EQ("{\"values\":[]}",
@@ -86,7 +104,14 @@ TEST(FrameTimingTrackerTest, NoFrameIdsIsEmpty) {
}
TEST(FrameTimingTrackerTest, NoRectIdsYieldsNoMainFrameEvents) {
- scoped_ptr<FrameTimingTracker> tracker(FrameTimingTracker::Create());
+ FakeImplProxy proxy;
+ TestSharedBitmapManager shared_bitmap_manager;
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
+
+ scoped_ptr<FrameTimingTracker> tracker(
+ FrameTimingTracker::Create(&host_impl));
tracker->SaveMainFrameTimeStamps(std::vector<int64_t>(),
base::TimeTicks::FromInternalValue(100),
base::TimeTicks::FromInternalValue(110), 1);
@@ -95,7 +120,14 @@ TEST(FrameTimingTrackerTest, NoRectIdsYieldsNoMainFrameEvents) {
}
TEST(FrameTimingTrackerTest, OneFrameId) {
- scoped_ptr<FrameTimingTracker> tracker(FrameTimingTracker::Create());
+ FakeImplProxy proxy;
+ TestSharedBitmapManager shared_bitmap_manager;
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
+
+ scoped_ptr<FrameTimingTracker> tracker(
+ FrameTimingTracker::Create(&host_impl));
std::vector<std::pair<int, int64_t>> ids;
ids.push_back(std::make_pair(1, 2));
tracker->SaveTimeStamps(base::TimeTicks::FromInternalValue(100), ids);
@@ -106,7 +138,14 @@ TEST(FrameTimingTrackerTest, OneFrameId) {
}
TEST(FrameTimingTrackerTest, OneMainFrameRect) {
- scoped_ptr<FrameTimingTracker> tracker(FrameTimingTracker::Create());
+ FakeImplProxy proxy;
+ TestSharedBitmapManager shared_bitmap_manager;
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
+
+ scoped_ptr<FrameTimingTracker> tracker(
+ FrameTimingTracker::Create(&host_impl));
std::vector<int64_t> rect_ids;
rect_ids.push_back(1);
tracker->SaveMainFrameTimeStamps(rect_ids,
@@ -119,7 +158,14 @@ TEST(FrameTimingTrackerTest, OneMainFrameRect) {
}
TEST(FrameTimingTrackerTest, UnsortedTimestampsIds) {
- scoped_ptr<FrameTimingTracker> tracker(FrameTimingTracker::Create());
+ FakeImplProxy proxy;
+ TestSharedBitmapManager shared_bitmap_manager;
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
+
+ scoped_ptr<FrameTimingTracker> tracker(
+ FrameTimingTracker::Create(&host_impl));
std::vector<std::pair<int, int64_t>> ids;
ids.push_back(std::make_pair(1, 2));
tracker->SaveTimeStamps(base::TimeTicks::FromInternalValue(200), ids);
@@ -134,7 +180,14 @@ TEST(FrameTimingTrackerTest, UnsortedTimestampsIds) {
}
TEST(FrameTimingTrackerTest, MainFrameUnsortedTimestamps) {
- scoped_ptr<FrameTimingTracker> tracker(FrameTimingTracker::Create());
+ FakeImplProxy proxy;
+ TestSharedBitmapManager shared_bitmap_manager;
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
+
+ scoped_ptr<FrameTimingTracker> tracker(
+ FrameTimingTracker::Create(&host_impl));
std::vector<int64_t> rect_ids;
rect_ids.push_back(2);
tracker->SaveMainFrameTimeStamps(rect_ids,
@@ -155,7 +208,14 @@ TEST(FrameTimingTrackerTest, MainFrameUnsortedTimestamps) {
}
TEST(FrameTimingTrackerTest, MultipleFrameIds) {
- scoped_ptr<FrameTimingTracker> tracker(FrameTimingTracker::Create());
+ FakeImplProxy proxy;
+ TestSharedBitmapManager shared_bitmap_manager;
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
+
+ scoped_ptr<FrameTimingTracker> tracker(
+ FrameTimingTracker::Create(&host_impl));
std::vector<std::pair<int, int64_t>> ids200;
ids200.push_back(std::make_pair(1, 2));
@@ -187,7 +247,14 @@ TEST(FrameTimingTrackerTest, MultipleFrameIds) {
}
TEST(FrameTimingTrackerTest, MultipleMainFrameEvents) {
- scoped_ptr<FrameTimingTracker> tracker(FrameTimingTracker::Create());
+ FakeImplProxy proxy;
+ TestSharedBitmapManager shared_bitmap_manager;
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
+
+ scoped_ptr<FrameTimingTracker> tracker(
+ FrameTimingTracker::Create(&host_impl));
std::vector<int64_t> rect_ids200;
rect_ids200.push_back(2);
diff --git a/chromium/cc/debug/invalidation_benchmark.cc b/chromium/cc/debug/invalidation_benchmark.cc
index 6fd3d3e2fb6..8a9fc883224 100644
--- a/chromium/cc/debug/invalidation_benchmark.cc
+++ b/chromium/cc/debug/invalidation_benchmark.cc
@@ -71,9 +71,9 @@ void InvalidationBenchmark::RunOnLayer(PictureLayer* layer) {
switch (mode_) {
case FIXED_SIZE: {
// Invalidation with a random position and fixed size.
- gfx::Rect visible_content_rect = layer->visible_content_rect();
- int x = LCGRandom() * (visible_content_rect.width() - width_);
- int y = LCGRandom() * (visible_content_rect.height() - height_);
+ gfx::Rect visible_layer_rect = layer->visible_layer_rect();
+ int x = LCGRandom() * (visible_layer_rect.width() - width_);
+ int y = LCGRandom() * (visible_layer_rect.height() - height_);
gfx::Rect invalidation_rect(x, y, width_, height_);
layer->SetNeedsDisplayRect(invalidation_rect);
break;
@@ -85,11 +85,11 @@ void InvalidationBenchmark::RunOnLayer(PictureLayer* layer) {
}
case RANDOM: {
// Random invalidation inside the viewport.
- gfx::Rect visible_content_rect = layer->visible_content_rect();
- int x_min = LCGRandom() * visible_content_rect.width();
- int x_max = LCGRandom() * visible_content_rect.width();
- int y_min = LCGRandom() * visible_content_rect.height();
- int y_max = LCGRandom() * visible_content_rect.height();
+ gfx::Rect visible_layer_rect = layer->visible_layer_rect();
+ int x_min = LCGRandom() * visible_layer_rect.width();
+ int x_max = LCGRandom() * visible_layer_rect.width();
+ int y_min = LCGRandom() * visible_layer_rect.height();
+ int y_max = LCGRandom() * visible_layer_rect.height();
if (x_min > x_max)
std::swap(x_min, x_max);
if (y_min > y_max)
@@ -100,7 +100,7 @@ void InvalidationBenchmark::RunOnLayer(PictureLayer* layer) {
}
case VIEWPORT: {
// Invalidate entire viewport.
- layer->SetNeedsDisplayRect(layer->visible_content_rect());
+ layer->SetNeedsDisplayRect(layer->visible_layer_rect());
break;
}
}
diff --git a/chromium/cc/debug/lap_timer.cc b/chromium/cc/debug/lap_timer.cc
index 17bca3d313f..eb6900c460a 100644
--- a/chromium/cc/debug/lap_timer.cc
+++ b/chromium/cc/debug/lap_timer.cc
@@ -10,9 +10,13 @@ namespace cc {
namespace {
-base::TimeTicks Now() {
- return base::TimeTicks::IsThreadNowSupported() ? base::TimeTicks::ThreadNow()
- : base::TimeTicks::Now();
+// Returns the offset from the origin from the ThreadTicks time source.
+// TimeTicks is used as a fallback if ThreadTicks is not available on the
+// current platform.
+base::TimeDelta Now() {
+ return base::ThreadTicks::IsSupported()
+ ? base::ThreadTicks::Now() - base::ThreadTicks()
+ : base::TimeTicks::Now() - base::TimeTicks();
}
// Default values.
@@ -65,7 +69,7 @@ void LapTimer::NextLap() {
++num_laps_;
--remaining_no_check_laps_;
if (!remaining_no_check_laps_) {
- base::TimeTicks now = Now();
+ base::TimeDelta now = Now();
accumulator_ += now - start_time_;
start_time_ = now;
remaining_no_check_laps_ = check_interval_;
diff --git a/chromium/cc/debug/lap_timer.h b/chromium/cc/debug/lap_timer.h
index 7662e2adb5f..48f99172040 100644
--- a/chromium/cc/debug/lap_timer.h
+++ b/chromium/cc/debug/lap_timer.h
@@ -49,7 +49,7 @@ class CC_EXPORT LapTimer {
int NumLaps();
private:
- base::TimeTicks start_time_;
+ base::TimeDelta start_time_;
base::TimeDelta accumulator_;
int num_laps_;
int warmup_laps_;
diff --git a/chromium/cc/debug/micro_benchmark_controller_unittest.cc b/chromium/cc/debug/micro_benchmark_controller_unittest.cc
index 2a8dce45246..61f34f4b77e 100644
--- a/chromium/cc/debug/micro_benchmark_controller_unittest.cc
+++ b/chromium/cc/debug/micro_benchmark_controller_unittest.cc
@@ -7,10 +7,10 @@
#include "cc/debug/micro_benchmark.h"
#include "cc/debug/micro_benchmark_controller.h"
#include "cc/layers/layer.h"
-#include "cc/resources/resource_update_queue.h"
#include "cc/test/fake_layer_tree_host.h"
#include "cc/test/fake_layer_tree_host_impl.h"
#include "cc/test/fake_proxy.h"
+#include "cc/test/test_task_graph_runner.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cc {
@@ -23,12 +23,12 @@ class MicroBenchmarkControllerTest : public testing::Test {
void SetUp() override {
impl_proxy_ = make_scoped_ptr(new FakeImplProxy);
- shared_bitmap_manager_.reset(new TestSharedBitmapManager());
layer_tree_host_impl_ = make_scoped_ptr(new FakeLayerTreeHostImpl(
- impl_proxy_.get(), shared_bitmap_manager_.get(), nullptr));
+ impl_proxy_.get(), &shared_bitmap_manager_, &task_graph_runner_));
- layer_tree_host_ = FakeLayerTreeHost::Create(&layer_tree_host_client_);
- layer_tree_host_->SetRootLayer(Layer::Create());
+ layer_tree_host_ = FakeLayerTreeHost::Create(&layer_tree_host_client_,
+ &task_graph_runner_);
+ layer_tree_host_->SetRootLayer(Layer::Create(LayerSettings()));
layer_tree_host_->InitializeForTesting(scoped_ptr<Proxy>(new FakeProxy));
}
@@ -39,8 +39,9 @@ class MicroBenchmarkControllerTest : public testing::Test {
}
FakeLayerTreeHostClient layer_tree_host_client_;
+ TestTaskGraphRunner task_graph_runner_;
+ TestSharedBitmapManager shared_bitmap_manager_;
scoped_ptr<FakeLayerTreeHost> layer_tree_host_;
- scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
scoped_ptr<FakeLayerTreeHostImpl> layer_tree_host_impl_;
scoped_ptr<FakeImplProxy> impl_proxy_;
};
@@ -74,9 +75,8 @@ TEST_F(MicroBenchmarkControllerTest, BenchmarkRan) {
base::Bind(&IncrementCallCount, base::Unretained(&run_count)));
EXPECT_GT(id, 0);
- scoped_ptr<ResourceUpdateQueue> queue(new ResourceUpdateQueue);
layer_tree_host_->SetOutputSurfaceLostForTesting(false);
- layer_tree_host_->UpdateLayers(queue.get());
+ layer_tree_host_->UpdateLayers();
EXPECT_EQ(1, run_count);
}
@@ -94,9 +94,8 @@ TEST_F(MicroBenchmarkControllerTest, MultipleBenchmarkRan) {
base::Bind(&IncrementCallCount, base::Unretained(&run_count)));
EXPECT_GT(id, 0);
- scoped_ptr<ResourceUpdateQueue> queue(new ResourceUpdateQueue);
layer_tree_host_->SetOutputSurfaceLostForTesting(false);
- layer_tree_host_->UpdateLayers(queue.get());
+ layer_tree_host_->UpdateLayers();
EXPECT_EQ(2, run_count);
@@ -111,10 +110,10 @@ TEST_F(MicroBenchmarkControllerTest, MultipleBenchmarkRan) {
base::Bind(&IncrementCallCount, base::Unretained(&run_count)));
EXPECT_GT(id, 0);
- layer_tree_host_->UpdateLayers(queue.get());
+ layer_tree_host_->UpdateLayers();
EXPECT_EQ(4, run_count);
- layer_tree_host_->UpdateLayers(queue.get());
+ layer_tree_host_->UpdateLayers();
EXPECT_EQ(4, run_count);
}
diff --git a/chromium/cc/debug/picture_debug_util.cc b/chromium/cc/debug/picture_debug_util.cc
index e653b78e235..2b1f7734b9e 100644
--- a/chromium/cc/debug/picture_debug_util.cc
+++ b/chromium/cc/debug/picture_debug_util.cc
@@ -7,6 +7,7 @@
#include <vector>
#include "base/base64.h"
+#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkData.h"
@@ -33,10 +34,12 @@ class BitmapSerializer : public SkPixelSerializer {
// Otherwise encode as PNG.
bool encoding_succeeded = false;
if (info.isOpaque()) {
- encoding_succeeded =
- gfx::JPEGCodec::Encode(reinterpret_cast<const unsigned char*>(pixels),
- gfx::JPEGCodec::FORMAT_SkBitmap, info.width(),
- info.height(), row_bytes, kJpegQuality, &data);
+ DCHECK_LE(row_bytes,
+ static_cast<size_t>(std::numeric_limits<int>::max()));
+ encoding_succeeded = gfx::JPEGCodec::Encode(
+ reinterpret_cast<const unsigned char*>(pixels),
+ gfx::JPEGCodec::FORMAT_SkBitmap, info.width(), info.height(),
+ static_cast<int>(row_bytes), kJpegQuality, &data);
} else {
SkBitmap bm;
// The cast is ok, since we only read the bm.
diff --git a/chromium/cc/debug/picture_record_benchmark.cc b/chromium/cc/debug/picture_record_benchmark.cc
index d8608c538ff..0f093ce1ecc 100644
--- a/chromium/cc/debug/picture_record_benchmark.cc
+++ b/chromium/cc/debug/picture_record_benchmark.cc
@@ -85,7 +85,7 @@ void PictureRecordBenchmark::DidUpdateLayers(LayerTreeHost* host) {
void PictureRecordBenchmark::RunOnLayer(PictureLayer* layer) {
ContentLayerClient* painter = layer->client();
- gfx::Size content_bounds = layer->content_bounds();
+ gfx::Size bounds = layer->bounds();
gfx::Size tile_grid_size(kTileGridSize, kTileGridSize);
@@ -94,8 +94,8 @@ void PictureRecordBenchmark::RunOnLayer(PictureLayer* layer) {
int width = dimensions.first;
int height = dimensions.second;
- int y_limit = std::max(1, content_bounds.height() - height);
- int x_limit = std::max(1, content_bounds.width() - width);
+ int y_limit = std::max(1, bounds.height() - height);
+ int x_limit = std::max(1, bounds.width() - width);
for (int y = 0; y < y_limit; y += kPositionIncrement) {
for (int x = 0; x < x_limit; x += kPositionIncrement) {
gfx::Rect rect = gfx::Rect(x, y, width, height);
diff --git a/chromium/cc/debug/rasterize_and_record_benchmark.cc b/chromium/cc/debug/rasterize_and_record_benchmark.cc
index c8439856043..b474e431fd2 100644
--- a/chromium/cc/debug/rasterize_and_record_benchmark.cc
+++ b/chromium/cc/debug/rasterize_and_record_benchmark.cc
@@ -74,7 +74,8 @@ void RasterizeAndRecordBenchmark::DidUpdateLayers(LayerTreeHost* host) {
DCHECK(!results_.get());
results_ = make_scoped_ptr(new base::DictionaryValue);
results_->SetInteger("pixels_recorded", record_results_.pixels_recorded);
- results_->SetInteger("picture_memory_usage", record_results_.bytes_used);
+ results_->SetInteger("picture_memory_usage",
+ static_cast<int>(record_results_.bytes_used));
for (int i = 0; i < RecordingSource::RECORDING_MODE_COUNT; i++) {
std::string name = base::StringPrintf("record_time%s_ms", kModeSuffixes[i]);
@@ -108,8 +109,7 @@ scoped_ptr<MicroBenchmarkImpl> RasterizeAndRecordBenchmark::CreateBenchmarkImpl(
void RasterizeAndRecordBenchmark::RunOnLayer(PictureLayer* layer) {
DCHECK(host_);
- gfx::Rect visible_layer_rect = gfx::ScaleToEnclosingRect(
- layer->visible_content_rect(), 1.f / layer->contents_scale_x());
+ gfx::Rect visible_layer_rect = layer->visible_layer_rect();
if (visible_layer_rect.IsEmpty())
return;
@@ -218,18 +218,14 @@ void RasterizeAndRecordBenchmark::RunOnDisplayListLayer(
kTimeCheckInterval);
do {
- const bool use_cached_picture = true;
- display_list =
- DisplayItemList::Create(visible_layer_rect, use_cached_picture);
- painter->PaintContentsToDisplayList(
- display_list.get(), visible_layer_rect, painting_control);
- display_list->CreateAndCacheSkPicture();
+ display_list = painter->PaintContentsToDisplayList(visible_layer_rect,
+ painting_control);
if (memory_used) {
// Verify we are recording the same thing each time.
- DCHECK(memory_used == display_list->PictureMemoryUsage());
+ DCHECK_EQ(memory_used, display_list->ApproximateMemoryUsage());
} else {
- memory_used = display_list->PictureMemoryUsage();
+ memory_used = display_list->ApproximateMemoryUsage();
}
timer.NextLap();
diff --git a/chromium/cc/debug/rasterize_and_record_benchmark_impl.cc b/chromium/cc/debug/rasterize_and_record_benchmark_impl.cc
index 1f9a36b871f..1dc110b4fac 100644
--- a/chromium/cc/debug/rasterize_and_record_benchmark_impl.cc
+++ b/chromium/cc/debug/rasterize_and_record_benchmark_impl.cc
@@ -51,7 +51,8 @@ void RunBenchmark(RasterSource* raster_source,
raster_source->PerformSolidColorAnalysis(content_rect, contents_scale,
&analysis);
- raster_source->PlaybackToCanvas(&canvas, content_rect, contents_scale);
+ raster_source->PlaybackToCanvas(&canvas, content_rect, content_rect,
+ contents_scale);
*is_solid_color = analysis.is_solid_color;
@@ -90,8 +91,8 @@ class FixedInvalidationPictureLayerTilingClient
return base_client_->GetPendingOrActiveTwinTiling(tiling);
}
- TilePriority::PriorityBin GetMaxTilePriorityBin() const override {
- return base_client_->GetMaxTilePriorityBin();
+ bool HasValidTilePriorities() const override {
+ return base_client_->HasValidTilePriorities();
}
bool RequiresHighResToDraw() const override {
@@ -134,7 +135,7 @@ void RasterizeAndRecordBenchmarkImpl::DidCompleteCommit(
result->SetDouble("rasterize_time_ms",
rasterize_results_.total_best_time.InMillisecondsF());
result->SetDouble("total_pictures_in_pile_size",
- rasterize_results_.total_memory_usage);
+ static_cast<int>(rasterize_results_.total_memory_usage));
result->SetInteger("pixels_rasterized", rasterize_results_.pixels_rasterized);
result->SetInteger("pixels_rasterized_with_non_solid_color",
rasterize_results_.pixels_rasterized_with_non_solid_color);
@@ -157,13 +158,13 @@ void RasterizeAndRecordBenchmarkImpl::RunOnLayer(PictureLayerImpl* layer) {
rasterize_results_.total_picture_layers_with_no_content++;
return;
}
- if (layer->visible_content_rect().IsEmpty()) {
+ if (layer->visible_layer_rect().IsEmpty()) {
rasterize_results_.total_picture_layers_off_screen++;
return;
}
- FixedInvalidationPictureLayerTilingClient client(
- layer, gfx::Rect(layer->content_bounds()));
+ FixedInvalidationPictureLayerTilingClient client(layer,
+ gfx::Rect(layer->bounds()));
// In this benchmark, we will create a local tiling set and measure how long
// it takes to rasterize content. As such, the actual settings used here don't
@@ -174,14 +175,13 @@ void RasterizeAndRecordBenchmarkImpl::RunOnLayer(PictureLayerImpl* layer) {
settings.skewport_target_time_in_seconds,
settings.skewport_extrapolation_limit_in_content_pixels);
- PictureLayerTiling* tiling = tiling_set->AddTiling(layer->contents_scale_x(),
- layer->GetRasterSource());
+ PictureLayerTiling* tiling =
+ tiling_set->AddTiling(1.f, layer->GetRasterSource());
tiling->CreateAllTilesForTesting();
RasterSource* raster_source = tiling->raster_source();
- for (PictureLayerTiling::CoverageIterator it(
- tiling, layer->contents_scale_x(), layer->visible_content_rect());
- it;
- ++it) {
+ for (PictureLayerTiling::CoverageIterator it(tiling, 1.f,
+ layer->visible_layer_rect());
+ it; ++it) {
DCHECK(*it);
gfx::Rect content_rect = (*it)->content_rect();
diff --git a/chromium/cc/debug/rasterize_and_record_benchmark_impl.h b/chromium/cc/debug/rasterize_and_record_benchmark_impl.h
index 0ab95438256..99b22f154e7 100644
--- a/chromium/cc/debug/rasterize_and_record_benchmark_impl.h
+++ b/chromium/cc/debug/rasterize_and_record_benchmark_impl.h
@@ -40,7 +40,7 @@ class RasterizeAndRecordBenchmarkImpl : public MicroBenchmarkImpl {
int pixels_rasterized_with_non_solid_color;
int pixels_rasterized_as_opaque;
base::TimeDelta total_best_time;
- int total_memory_usage;
+ size_t total_memory_usage;
int total_layers;
int total_picture_layers;
int total_picture_layers_with_no_content;
diff --git a/chromium/cc/debug/rendering_stats_instrumentation.cc b/chromium/cc/debug/rendering_stats_instrumentation.cc
index 7497c628ed1..315743b8ffc 100644
--- a/chromium/cc/debug/rendering_stats_instrumentation.cc
+++ b/chromium/cc/debug/rendering_stats_instrumentation.cc
@@ -37,21 +37,21 @@ void RenderingStatsInstrumentation::AccumulateAndClearImplThreadStats() {
impl_thread_rendering_stats_ = RenderingStats();
}
-base::TimeTicks RenderingStatsInstrumentation::StartRecording() const {
+base::TimeDelta RenderingStatsInstrumentation::StartRecording() const {
if (record_rendering_stats_) {
- if (base::TimeTicks::IsThreadNowSupported())
- return base::TimeTicks::ThreadNow();
- return base::TimeTicks::Now();
+ if (base::ThreadTicks::IsSupported())
+ return base::ThreadTicks::Now() - base::ThreadTicks();
+ return base::TimeTicks::Now() - base::TimeTicks();
}
- return base::TimeTicks();
+ return base::TimeDelta();
}
base::TimeDelta RenderingStatsInstrumentation::EndRecording(
- base::TimeTicks start_time) const {
- if (!start_time.is_null()) {
- if (base::TimeTicks::IsThreadNowSupported())
- return base::TimeTicks::ThreadNow() - start_time;
- return base::TimeTicks::Now() - start_time;
+ base::TimeDelta start_time) const {
+ if (start_time != base::TimeDelta()) {
+ if (base::ThreadTicks::IsSupported())
+ return (base::ThreadTicks::Now() - base::ThreadTicks()) - start_time;
+ return (base::TimeTicks::Now() - base::TimeTicks()) - start_time;
}
return base::TimeDelta();
}
diff --git a/chromium/cc/debug/rendering_stats_instrumentation.h b/chromium/cc/debug/rendering_stats_instrumentation.h
index 2a6e3b7eb6e..47796887788 100644
--- a/chromium/cc/debug/rendering_stats_instrumentation.h
+++ b/chromium/cc/debug/rendering_stats_instrumentation.h
@@ -37,8 +37,8 @@ class CC_EXPORT RenderingStatsInstrumentation {
record_rendering_stats_ = record_rendering_stats;
}
- base::TimeTicks StartRecording() const;
- base::TimeDelta EndRecording(base::TimeTicks start_time) const;
+ base::TimeDelta StartRecording() const;
+ base::TimeDelta EndRecording(base::TimeDelta start_time) const;
void IncrementFrameCount(int64 count);
void AddVisibleContentArea(int64 area);
diff --git a/chromium/cc/debug/traced_display_item_list.cc b/chromium/cc/debug/traced_display_item_list.cc
new file mode 100644
index 00000000000..1b45a593f2a
--- /dev/null
+++ b/chromium/cc/debug/traced_display_item_list.cc
@@ -0,0 +1,27 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#include "cc/debug/traced_display_item_list.h"
+
+#include "base/json/json_writer.h"
+#include "cc/debug/traced_value.h"
+#include "cc/playback/display_item_list.h"
+
+namespace cc {
+
+TracedDisplayItemList::TracedDisplayItemList(
+ scoped_refptr<const DisplayItemList> list,
+ bool include_items)
+ : display_item_list_(list), include_items_(include_items) {
+}
+
+TracedDisplayItemList::~TracedDisplayItemList() {
+}
+
+void TracedDisplayItemList::AppendAsTraceFormat(std::string* out) const {
+ scoped_refptr<base::trace_event::ConvertableToTraceFormat> convertable =
+ display_item_list_->AsValue(include_items_);
+ convertable->AppendAsTraceFormat(out);
+}
+
+} // namespace cc
diff --git a/chromium/cc/debug/traced_display_item_list.h b/chromium/cc/debug/traced_display_item_list.h
new file mode 100644
index 00000000000..f7caa04b49e
--- /dev/null
+++ b/chromium/cc/debug/traced_display_item_list.h
@@ -0,0 +1,42 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_DEBUG_TRACED_DISPLAY_ITEM_LIST_H_
+#define CC_DEBUG_TRACED_DISPLAY_ITEM_LIST_H_
+
+#include <string>
+
+#include "base/memory/ref_counted.h"
+#include "base/trace_event/trace_event.h"
+#include "cc/debug/traced_value.h"
+
+namespace cc {
+
+class DisplayItemList;
+
+class TracedDisplayItemList
+ : public base::trace_event::ConvertableToTraceFormat {
+ public:
+ static scoped_refptr<ConvertableToTraceFormat> AsTraceableDisplayItemList(
+ scoped_refptr<const DisplayItemList> list,
+ bool include_items) {
+ return scoped_refptr<ConvertableToTraceFormat>(
+ new TracedDisplayItemList(list, include_items));
+ }
+ void AppendAsTraceFormat(std::string* out) const override;
+
+ private:
+ explicit TracedDisplayItemList(scoped_refptr<const DisplayItemList> list,
+ bool include_items);
+ ~TracedDisplayItemList() override;
+
+ scoped_refptr<const DisplayItemList> display_item_list_;
+ bool include_items_;
+
+ DISALLOW_COPY_AND_ASSIGN(TracedDisplayItemList);
+};
+
+} // namespace cc
+
+#endif // CC_DEBUG_TRACED_DISPLAY_ITEM_LIST_H_
diff --git a/chromium/cc/debug/traced_picture.cc b/chromium/cc/debug/traced_picture.cc
index 2c7622b66d5..3241871d8ee 100644
--- a/chromium/cc/debug/traced_picture.cc
+++ b/chromium/cc/debug/traced_picture.cc
@@ -40,18 +40,16 @@ void TracedPicture::AppendPictureAlias(std::string* out) const {
scoped_ptr<base::DictionaryValue> alias(new base::DictionaryValue());
alias->SetString("id_ref", base::StringPrintf("%p", picture_.get()));
- scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue());
- res->Set("alias", alias.release());
-
+ base::DictionaryValue res;
+ res.Set("alias", alias.release());
std::string tmp;
- base::JSONWriter::Write(res.get(), &tmp);
+ base::JSONWriter::Write(res, &tmp);
out->append(tmp);
}
void TracedPicture::AppendPicture(std::string* out) const {
- scoped_ptr<base::Value> value = picture_->AsValue();
std::string tmp;
- base::JSONWriter::Write(value.get(), &tmp);
+ base::JSONWriter::Write(*picture_->AsValue(), &tmp);
out->append(tmp);
}
diff --git a/chromium/cc/input/input_handler.h b/chromium/cc/input/input_handler.h
index 81d91b87143..3401eceb553 100644
--- a/chromium/cc/input/input_handler.h
+++ b/chromium/cc/input/input_handler.h
@@ -88,6 +88,9 @@ class CC_EXPORT InputHandler {
virtual ScrollStatus ScrollBegin(const gfx::Point& viewport_point,
ScrollInputType type) = 0;
+ // Similar to ScrollBegin, except the hit test is skipped and scroll always
+ // targets at the root layer.
+ virtual ScrollStatus RootScrollBegin(ScrollInputType type) = 0;
virtual ScrollStatus ScrollAnimated(const gfx::Point& viewport_point,
const gfx::Vector2dF& scroll_delta) = 0;
@@ -136,7 +139,7 @@ class CC_EXPORT InputHandler {
virtual void PinchGestureEnd() = 0;
// Request another callback to InputHandlerClient::Animate().
- virtual void SetNeedsAnimate() = 0;
+ virtual void SetNeedsAnimateInput() = 0;
// Whether the layer under |viewport_point| is the currently scrolling layer.
virtual bool IsCurrentlyScrollingLayerAt(const gfx::Point& viewport_point,
diff --git a/chromium/cc/input/layer_scroll_offset_delegate.h b/chromium/cc/input/layer_scroll_offset_delegate.h
index 02ba011118d..0afc4db89e3 100644
--- a/chromium/cc/input/layer_scroll_offset_delegate.h
+++ b/chromium/cc/input/layer_scroll_offset_delegate.h
@@ -6,6 +6,8 @@
#define CC_INPUT_LAYER_SCROLL_OFFSET_DELEGATE_H_
#include "base/basictypes.h"
+#include "base/callback_forward.h"
+#include "base/time/time.h"
#include "ui/gfx/geometry/scroll_offset.h"
#include "ui/gfx/geometry/size_f.h"
@@ -44,7 +46,14 @@ class LayerScrollOffsetDelegate {
// This is called by the compositor to check whether a delegate-managed fling
// is active or not.
- virtual bool IsExternalFlingActive() const = 0;
+ // TODO(hush): Remove after WebView's smooth scrolling path is unified with
+ // Chrome's.
+ virtual bool IsExternalScrollActive() const = 0;
+
+ // This is called by the compositor when a fling hitting the root layer
+ // requires a scheduled animation update.
+ typedef base::Callback<void(base::TimeTicks)> AnimationCallback;
+ virtual void SetNeedsAnimate(const AnimationCallback& animation) = 0;
protected:
LayerScrollOffsetDelegate() {}
diff --git a/chromium/cc/input/top_controls_manager.cc b/chromium/cc/input/top_controls_manager.cc
index c8bd5348721..1a961b50e93 100644
--- a/chromium/cc/input/top_controls_manager.cc
+++ b/chromium/cc/input/top_controls_manager.cc
@@ -12,7 +12,6 @@
#include "cc/input/top_controls_manager_client.h"
#include "cc/output/begin_frame_args.h"
#include "cc/trees/layer_tree_impl.h"
-#include "ui/gfx/frame_time.h"
#include "ui/gfx/geometry/vector2d_f.h"
#include "ui/gfx/transform.h"
@@ -190,7 +189,7 @@ void TopControlsManager::SetupAnimation(AnimationDirection direction) {
}
top_controls_animation_ = KeyframedFloatAnimationCurve::Create();
- base::TimeDelta start_time = gfx::FrameTime::Now() - base::TimeTicks();
+ base::TimeDelta start_time = base::TimeTicks::Now() - base::TimeTicks();
top_controls_animation_->AddKeyframe(
FloatKeyframe::Create(start_time, TopControlsShownRatio(), nullptr));
float max_ending_ratio = (direction == SHOWING_CONTROLS ? 1 : -1);
diff --git a/chromium/cc/input/top_controls_manager_unittest.cc b/chromium/cc/input/top_controls_manager_unittest.cc
index 52e46e674ed..788acbb9ea0 100644
--- a/chromium/cc/input/top_controls_manager_unittest.cc
+++ b/chromium/cc/input/top_controls_manager_unittest.cc
@@ -18,7 +18,6 @@
#include "cc/test/test_task_graph_runner.h"
#include "cc/trees/layer_tree_impl.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/frame_time.h"
#include "ui/gfx/geometry/vector2d_f.h"
namespace cc {
@@ -159,7 +158,7 @@ TEST(TopControlsManagerTest, PartialShownHideAnimation) {
EXPECT_TRUE(manager->animation());
- base::TimeTicks time = gfx::FrameTime::Now();
+ base::TimeTicks time = base::TimeTicks::Now();
float previous;
while (manager->animation()) {
previous = manager->TopControlsShownRatio();
@@ -189,7 +188,7 @@ TEST(TopControlsManagerTest, PartialShownShowAnimation) {
EXPECT_TRUE(manager->animation());
- base::TimeTicks time = gfx::FrameTime::Now();
+ base::TimeTicks time = base::TimeTicks::Now();
float previous;
while (manager->animation()) {
previous = manager->TopControlsShownRatio();
@@ -215,7 +214,7 @@ TEST(TopControlsManagerTest, PartialHiddenWithAmbiguousThresholdShows) {
manager->ScrollEnd();
EXPECT_TRUE(manager->animation());
- base::TimeTicks time = gfx::FrameTime::Now();
+ base::TimeTicks time = base::TimeTicks::Now();
float previous;
while (manager->animation()) {
previous = manager->TopControlsShownRatio();
@@ -241,7 +240,7 @@ TEST(TopControlsManagerTest, PartialHiddenWithAmbiguousThresholdHides) {
manager->ScrollEnd();
EXPECT_TRUE(manager->animation());
- base::TimeTicks time = gfx::FrameTime::Now();
+ base::TimeTicks time = base::TimeTicks::Now();
float previous;
while (manager->animation()) {
previous = manager->TopControlsShownRatio();
@@ -271,7 +270,7 @@ TEST(TopControlsManagerTest, PartialShownWithAmbiguousThresholdHides) {
manager->ScrollEnd();
EXPECT_TRUE(manager->animation());
- base::TimeTicks time = gfx::FrameTime::Now();
+ base::TimeTicks time = base::TimeTicks::Now();
float previous;
while (manager->animation()) {
previous = manager->TopControlsShownRatio();
@@ -301,7 +300,7 @@ TEST(TopControlsManagerTest, PartialShownWithAmbiguousThresholdShows) {
manager->ScrollEnd();
EXPECT_TRUE(manager->animation());
- base::TimeTicks time = gfx::FrameTime::Now();
+ base::TimeTicks time = base::TimeTicks::Now();
float previous;
while (manager->animation()) {
previous = manager->TopControlsShownRatio();
diff --git a/chromium/cc/layers/append_quads_data.h b/chromium/cc/layers/append_quads_data.h
index 50f58775d48..45b0c17b20f 100644
--- a/chromium/cc/layers/append_quads_data.h
+++ b/chromium/cc/layers/append_quads_data.h
@@ -14,7 +14,7 @@ struct AppendQuadsData {
AppendQuadsData()
: num_incomplete_tiles(0),
num_missing_tiles(0),
- visible_content_area(0),
+ visible_layer_area(0),
approximated_visible_content_area(0),
checkerboarded_visible_content_area(0) {}
@@ -23,7 +23,7 @@ struct AppendQuadsData {
// Set by the layer appending quads.
int64 num_missing_tiles;
// Set by the layer appending quads.
- int64 visible_content_area;
+ int64 visible_layer_area;
// Set by the layer appending quads.
int64 approximated_visible_content_area;
// Set by the layer appending quads.
diff --git a/chromium/cc/layers/content_layer.cc b/chromium/cc/layers/content_layer.cc
deleted file mode 100644
index 7efa1c20b00..00000000000
--- a/chromium/cc/layers/content_layer.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/layers/content_layer.h"
-
-#include "base/auto_reset.h"
-#include "base/metrics/histogram.h"
-#include "base/time/time.h"
-#include "cc/layers/content_layer_client.h"
-#include "cc/resources/bitmap_content_layer_updater.h"
-#include "cc/resources/bitmap_skpicture_content_layer_updater.h"
-#include "cc/resources/layer_painter.h"
-#include "cc/trees/layer_tree_host.h"
-#include "third_party/skia/include/core/SkPictureRecorder.h"
-
-namespace cc {
-
-ContentLayerPainter::ContentLayerPainter(ContentLayerClient* client)
- : client_(client) {}
-
-scoped_ptr<ContentLayerPainter> ContentLayerPainter::Create(
- ContentLayerClient* client) {
- return make_scoped_ptr(new ContentLayerPainter(client));
-}
-
-void ContentLayerPainter::Paint(SkCanvas* canvas,
- const gfx::Rect& content_rect) {
- client_->PaintContents(canvas, content_rect,
- ContentLayerClient::PAINTING_BEHAVIOR_NORMAL);
-}
-
-scoped_refptr<ContentLayer> ContentLayer::Create(ContentLayerClient* client) {
- return make_scoped_refptr(new ContentLayer(client));
-}
-
-ContentLayer::ContentLayer(ContentLayerClient* client)
- : TiledLayer(), client_(client) {
-}
-
-ContentLayer::~ContentLayer() {}
-
-void ContentLayer::ClearClient() {
- client_ = nullptr;
- UpdateDrawsContent(HasDrawableContent());
-}
-
-bool ContentLayer::HasDrawableContent() const {
- return client_ && TiledLayer::HasDrawableContent();
-}
-
-void ContentLayer::SetLayerTreeHost(LayerTreeHost* host) {
- TiledLayer::SetLayerTreeHost(host);
-
- if (!updater_.get())
- return;
-}
-
-void ContentLayer::SetTexturePriorities(
- const PriorityCalculator& priority_calc) {
- // Update the tile data before creating all the layer's tiles.
- UpdateTileSizeAndTilingOption();
-
- TiledLayer::SetTexturePriorities(priority_calc);
-}
-
-bool ContentLayer::Update(ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion) {
- {
- base::AutoReset<bool> ignore_set_needs_commit(&ignore_set_needs_commit_,
- true);
-
- CreateUpdaterIfNeeded();
- }
-
- bool updated = TiledLayer::Update(queue, occlusion);
- return updated;
-}
-
-bool ContentLayer::NeedMoreUpdates() {
- return NeedsIdlePaint();
-}
-
-LayerUpdater* ContentLayer::Updater() const {
- return updater_.get();
-}
-
-void ContentLayer::CreateUpdaterIfNeeded() {
- if (updater_.get())
- return;
- scoped_ptr<LayerPainter> painter = ContentLayerPainter::Create(client_);
- if (layer_tree_host()->settings().per_tile_painting_enabled) {
- updater_ = BitmapSkPictureContentLayerUpdater::Create(
- painter.Pass(),
- rendering_stats_instrumentation(),
- id());
- } else {
- updater_ = BitmapContentLayerUpdater::Create(
- painter.Pass(),
- id());
- }
- updater_->SetOpaque(contents_opaque());
- if (client_)
- updater_->SetFillsBoundsCompletely(client_->FillsBoundsCompletely());
- updater_->SetBackgroundColor(background_color());
-
- SetTextureFormat(
- layer_tree_host()->GetRendererCapabilities().best_texture_format);
-}
-
-void ContentLayer::SetContentsOpaque(bool opaque) {
- Layer::SetContentsOpaque(opaque);
- if (updater_.get())
- updater_->SetOpaque(opaque);
-}
-
-skia::RefPtr<SkPicture> ContentLayer::GetPicture() const {
- if (!DrawsContent())
- return skia::RefPtr<SkPicture>();
-
- int width = bounds().width();
- int height = bounds().height();
-
- SkPictureRecorder recorder;
- SkCanvas* canvas = recorder.beginRecording(width, height, nullptr, 0);
- client_->PaintContents(canvas, gfx::Rect(width, height),
- ContentLayerClient::PAINTING_BEHAVIOR_NORMAL);
- skia::RefPtr<SkPicture> picture =
- skia::AdoptRef(recorder.endRecordingAsPicture());
- return picture;
-}
-
-void ContentLayer::OnOutputSurfaceCreated() {
- SetTextureFormat(
- layer_tree_host()->GetRendererCapabilities().best_texture_format);
- TiledLayer::OnOutputSurfaceCreated();
-}
-
-} // namespace cc
diff --git a/chromium/cc/layers/content_layer.h b/chromium/cc/layers/content_layer.h
deleted file mode 100644
index 5d6ac15a801..00000000000
--- a/chromium/cc/layers/content_layer.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_LAYERS_CONTENT_LAYER_H_
-#define CC_LAYERS_CONTENT_LAYER_H_
-
-#include "base/basictypes.h"
-#include "cc/base/cc_export.h"
-#include "cc/layers/tiled_layer.h"
-#include "cc/resources/layer_painter.h"
-
-class SkCanvas;
-
-namespace cc {
-
-class ContentLayerClient;
-class ContentLayerUpdater;
-
-class CC_EXPORT ContentLayerPainter : public LayerPainter {
- public:
- static scoped_ptr<ContentLayerPainter> Create(ContentLayerClient* client);
-
- void Paint(SkCanvas* canvas, const gfx::Rect& content_rect) override;
-
- private:
- explicit ContentLayerPainter(ContentLayerClient* client);
-
- ContentLayerClient* client_;
-
- DISALLOW_COPY_AND_ASSIGN(ContentLayerPainter);
-};
-
-// A layer that renders its contents into an SkCanvas.
-class CC_EXPORT ContentLayer : public TiledLayer {
- public:
- static scoped_refptr<ContentLayer> Create(ContentLayerClient* client);
-
- void ClearClient();
-
- void SetLayerTreeHost(LayerTreeHost* layer_tree_host) override;
- void SetTexturePriorities(const PriorityCalculator& priority_calc) override;
- bool Update(ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion) override;
- bool NeedMoreUpdates() override;
-
- void SetContentsOpaque(bool contents_opaque) override;
-
- skia::RefPtr<SkPicture> GetPicture() const override;
-
- void OnOutputSurfaceCreated() override;
-
- protected:
- explicit ContentLayer(ContentLayerClient* client);
- ~ContentLayer() override;
-
- bool HasDrawableContent() const override;
-
- // TiledLayer implementation.
- LayerUpdater* Updater() const override;
-
- private:
- // TiledLayer implementation.
- void CreateUpdaterIfNeeded() override;
-
- ContentLayerClient* client_;
- scoped_refptr<ContentLayerUpdater> updater_;
-
- DISALLOW_COPY_AND_ASSIGN(ContentLayer);
-};
-
-} // namespace cc
-#endif // CC_LAYERS_CONTENT_LAYER_H_
diff --git a/chromium/cc/layers/content_layer_client.h b/chromium/cc/layers/content_layer_client.h
index 9125b9722b5..3a56263248d 100644
--- a/chromium/cc/layers/content_layer_client.h
+++ b/chromium/cc/layers/content_layer_client.h
@@ -12,7 +12,6 @@ class SkCanvas;
namespace gfx {
class Rect;
-class RectF;
}
namespace cc {
@@ -30,8 +29,7 @@ class CC_EXPORT ContentLayerClient {
const gfx::Rect& clip,
PaintingControlSetting painting_status) = 0;
- virtual void PaintContentsToDisplayList(
- DisplayItemList* display_list,
+ virtual scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
const gfx::Rect& clip,
PaintingControlSetting painting_status) = 0;
diff --git a/chromium/cc/layers/contents_scaling_layer.cc b/chromium/cc/layers/contents_scaling_layer.cc
deleted file mode 100644
index b44830f5fa7..00000000000
--- a/chromium/cc/layers/contents_scaling_layer.cc
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/layers/contents_scaling_layer.h"
-#include "cc/trees/layer_tree_host.h"
-#include "ui/gfx/geometry/size_conversions.h"
-
-namespace cc {
-
-gfx::Size ContentsScalingLayer::ComputeContentBoundsForScale(
- float scale_x,
- float scale_y) const {
- return gfx::ToCeiledSize(gfx::ScaleSize(bounds(), scale_x, scale_y));
-}
-
-ContentsScalingLayer::ContentsScalingLayer()
- : last_update_contents_scale_x_(0.f),
- last_update_contents_scale_y_(0.f) {}
-
-ContentsScalingLayer::~ContentsScalingLayer() {
-}
-
-void ContentsScalingLayer::CalculateContentsScale(
- float ideal_contents_scale,
- float* contents_scale_x,
- float* contents_scale_y,
- gfx::Size* content_bounds) {
- float old_contents_scale_x = *contents_scale_x;
- float old_contents_scale_y = *contents_scale_y;
- gfx::Size old_content_bounds = *content_bounds;
- *contents_scale_x = ideal_contents_scale;
- *contents_scale_y = ideal_contents_scale;
- *content_bounds = ComputeContentBoundsForScale(
- ideal_contents_scale,
- ideal_contents_scale);
-
- if (!layer_tree_host())
- return;
-
- if (old_contents_scale_x != *contents_scale_x ||
- old_contents_scale_y != *contents_scale_y ||
- old_content_bounds != *content_bounds) {
- layer_tree_host()->property_trees()->needs_rebuild = true;
- }
-}
-
-bool ContentsScalingLayer::Update(ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion) {
- bool updated = Layer::Update(queue, occlusion);
-
- if (draw_properties().contents_scale_x == last_update_contents_scale_x_ &&
- draw_properties().contents_scale_y == last_update_contents_scale_y_)
- return updated;
-
- last_update_contents_scale_x_ = draw_properties().contents_scale_x;
- last_update_contents_scale_y_ = draw_properties().contents_scale_y;
- // Invalidate the whole layer if scale changed.
- SetNeedsDisplayRect(gfx::Rect(paint_properties().bounds));
- return updated;
-}
-
-} // namespace cc
diff --git a/chromium/cc/layers/contents_scaling_layer.h b/chromium/cc/layers/contents_scaling_layer.h
deleted file mode 100644
index 15faa005dfc..00000000000
--- a/chromium/cc/layers/contents_scaling_layer.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_LAYERS_CONTENTS_SCALING_LAYER_H_
-#define CC_LAYERS_CONTENTS_SCALING_LAYER_H_
-
-#include "cc/base/cc_export.h"
-#include "cc/layers/layer.h"
-
-namespace cc {
-
-// Base class for layers that need contents scale.
-// The content bounds are determined by bounds and scale of the contents.
-class CC_EXPORT ContentsScalingLayer : public Layer {
- public:
- void CalculateContentsScale(float ideal_contents_scale,
- float* contents_scale_x,
- float* contents_scale_y,
- gfx::Size* content_bounds) override;
-
- bool Update(ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion) override;
-
- protected:
- ContentsScalingLayer();
- ~ContentsScalingLayer() override;
-
- gfx::Size ComputeContentBoundsForScale(float scale_x, float scale_y) const;
-
- private:
- float last_update_contents_scale_x_;
- float last_update_contents_scale_y_;
-
- DISALLOW_COPY_AND_ASSIGN(ContentsScalingLayer);
-};
-
-} // namespace cc
-
-#endif // CC_LAYERS_CONTENTS_SCALING_LAYER_H__
diff --git a/chromium/cc/layers/contents_scaling_layer_unittest.cc b/chromium/cc/layers/contents_scaling_layer_unittest.cc
deleted file mode 100644
index 38385a06ad1..00000000000
--- a/chromium/cc/layers/contents_scaling_layer_unittest.cc
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/layers/contents_scaling_layer.h"
-
-#include <vector>
-
-#include "cc/test/fake_layer_tree_host.h"
-#include "cc/test/geometry_test_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-namespace {
-
-class MockContentsScalingLayer : public ContentsScalingLayer {
- public:
- MockContentsScalingLayer()
- : ContentsScalingLayer() {}
-
- void SetNeedsDisplayRect(const gfx::Rect& dirty_rect) override {
- last_needs_display_rect_ = dirty_rect;
- ContentsScalingLayer::SetNeedsDisplayRect(dirty_rect);
- }
-
- const gfx::Rect& LastNeedsDisplayRect() const {
- return last_needs_display_rect_;
- }
-
- private:
- ~MockContentsScalingLayer() override {}
-
- gfx::Rect last_needs_display_rect_;
-};
-
-static void CalcDrawProps(FakeLayerTreeHost* host, float device_scale_factor) {
- RenderSurfaceLayerList render_surface_layer_list;
- LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
- host->root_layer(), gfx::Size(500, 500), &render_surface_layer_list);
- inputs.device_scale_factor = device_scale_factor;
- LayerTreeHostCommon::CalculateDrawProperties(&inputs);
-}
-
-TEST(ContentsScalingLayerTest, CheckContentsBounds) {
- FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
- scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(&client);
-
- scoped_refptr<MockContentsScalingLayer> test_layer =
- make_scoped_refptr(new MockContentsScalingLayer());
-
- scoped_refptr<Layer> root = Layer::Create();
- root->AddChild(test_layer);
- host->SetRootLayer(root);
-
- test_layer->SetBounds(gfx::Size(320, 240));
-
- CalcDrawProps(host.get(), 1.f);
- EXPECT_FLOAT_EQ(1.f, test_layer->contents_scale_x());
- EXPECT_FLOAT_EQ(1.f, test_layer->contents_scale_y());
- EXPECT_EQ(320, test_layer->content_bounds().width());
- EXPECT_EQ(240, test_layer->content_bounds().height());
-
- CalcDrawProps(host.get(), 2.f);
- EXPECT_EQ(640, test_layer->content_bounds().width());
- EXPECT_EQ(480, test_layer->content_bounds().height());
-
- test_layer->SetBounds(gfx::Size(10, 20));
- CalcDrawProps(host.get(), 2.f);
- EXPECT_EQ(20, test_layer->content_bounds().width());
- EXPECT_EQ(40, test_layer->content_bounds().height());
-
- CalcDrawProps(host.get(), 1.33f);
- EXPECT_EQ(14, test_layer->content_bounds().width());
- EXPECT_EQ(27, test_layer->content_bounds().height());
-}
-
-} // namespace
-} // namespace cc
diff --git a/chromium/cc/layers/delegated_frame_provider_unittest.cc b/chromium/cc/layers/delegated_frame_provider_unittest.cc
index fe8117e797a..3aef0d18c7d 100644
--- a/chromium/cc/layers/delegated_frame_provider_unittest.cc
+++ b/chromium/cc/layers/delegated_frame_provider_unittest.cc
@@ -7,8 +7,10 @@
#include "cc/layers/delegated_renderer_layer.h"
#include "cc/output/delegated_frame_data.h"
#include "cc/quads/texture_draw_quad.h"
+#include "cc/resources/resource_provider.h"
#include "cc/resources/returned_resource.h"
#include "cc/resources/transferable_resource.h"
+#include "cc/trees/layer_tree_settings.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cc {
@@ -35,15 +37,14 @@ class DelegatedFrameProviderTest
}
void AddTransferableResource(DelegatedFrameData* frame,
- ResourceProvider::ResourceId resource_id) {
+ ResourceId resource_id) {
TransferableResource resource;
resource.id = resource_id;
resource.mailbox_holder.texture_target = GL_TEXTURE_2D;
frame->resource_list.push_back(resource);
}
- void AddTextureQuad(DelegatedFrameData* frame,
- ResourceProvider::ResourceId resource_id) {
+ void AddTextureQuad(DelegatedFrameData* frame, ResourceId resource_id) {
SharedQuadState* sqs =
frame->render_pass_list[0]->CreateAndAppendSharedQuadState();
TextureDrawQuad* quad =
@@ -90,6 +91,7 @@ class DelegatedFrameProviderTest
scoped_refptr<DelegatedFrameProvider> frame_provider_;
bool resources_available_;
ReturnedResourceArray resources_;
+ LayerSettings layer_settings_;
};
TEST_F(DelegatedFrameProviderTest, SameResources) {
@@ -153,9 +155,9 @@ TEST_F(DelegatedFrameProviderTest, RefResources) {
SetFrameProvider(frame.Pass());
scoped_refptr<DelegatedRendererLayer> observer1 =
- DelegatedRendererLayer::Create(frame_provider_);
+ DelegatedRendererLayer::Create(layer_settings_, frame_provider_);
scoped_refptr<DelegatedRendererLayer> observer2 =
- DelegatedRendererLayer::Create(frame_provider_);
+ DelegatedRendererLayer::Create(layer_settings_, frame_provider_);
gfx::RectF damage;
@@ -211,9 +213,9 @@ TEST_F(DelegatedFrameProviderTest, RefResourcesInFrameProvider) {
SetFrameProvider(frame.Pass());
scoped_refptr<DelegatedRendererLayer> observer1 =
- DelegatedRendererLayer::Create(frame_provider_);
+ DelegatedRendererLayer::Create(layer_settings_, frame_provider_);
scoped_refptr<DelegatedRendererLayer> observer2 =
- DelegatedRendererLayer::Create(frame_provider_);
+ DelegatedRendererLayer::Create(layer_settings_, frame_provider_);
gfx::RectF damage;
@@ -253,9 +255,9 @@ TEST_F(DelegatedFrameProviderTest, RefResourcesInFrameProviderUntilDestroy) {
SetFrameProvider(frame.Pass());
scoped_refptr<DelegatedRendererLayer> observer1 =
- DelegatedRendererLayer::Create(frame_provider_);
+ DelegatedRendererLayer::Create(layer_settings_, frame_provider_);
scoped_refptr<DelegatedRendererLayer> observer2 =
- DelegatedRendererLayer::Create(frame_provider_);
+ DelegatedRendererLayer::Create(layer_settings_, frame_provider_);
gfx::RectF damage;
@@ -297,9 +299,9 @@ TEST_F(DelegatedFrameProviderTest, Damage) {
SetFrameProvider(frame.Pass());
scoped_refptr<DelegatedRendererLayer> observer1 =
- DelegatedRendererLayer::Create(frame_provider_);
+ DelegatedRendererLayer::Create(layer_settings_, frame_provider_);
scoped_refptr<DelegatedRendererLayer> observer2 =
- DelegatedRendererLayer::Create(frame_provider_);
+ DelegatedRendererLayer::Create(layer_settings_, frame_provider_);
gfx::RectF damage;
diff --git a/chromium/cc/layers/delegated_renderer_layer.cc b/chromium/cc/layers/delegated_renderer_layer.cc
index f95c9bd205b..b48d1eae91e 100644
--- a/chromium/cc/layers/delegated_renderer_layer.cc
+++ b/chromium/cc/layers/delegated_renderer_layer.cc
@@ -12,14 +12,16 @@
namespace cc {
scoped_refptr<DelegatedRendererLayer> DelegatedRendererLayer::Create(
+ const LayerSettings& settings,
const scoped_refptr<DelegatedFrameProvider>& frame_provider) {
return scoped_refptr<DelegatedRendererLayer>(
- new DelegatedRendererLayer(frame_provider));
+ new DelegatedRendererLayer(settings, frame_provider));
}
DelegatedRendererLayer::DelegatedRendererLayer(
+ const LayerSettings& settings,
const scoped_refptr<DelegatedFrameProvider>& frame_provider)
- : Layer(),
+ : Layer(settings),
frame_provider_(frame_provider),
should_collect_new_frame_(true),
frame_data_(nullptr),
@@ -81,9 +83,8 @@ void DelegatedRendererLayer::ProviderHasNewFrame() {
SetNextCommitWaitsForActivation();
}
-bool DelegatedRendererLayer::Update(ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion) {
- bool updated = Layer::Update(queue, occlusion);
+bool DelegatedRendererLayer::Update() {
+ bool updated = Layer::Update();
if (!should_collect_new_frame_)
return updated;
diff --git a/chromium/cc/layers/delegated_renderer_layer.h b/chromium/cc/layers/delegated_renderer_layer.h
index 39d2696c5f1..124b389a0f7 100644
--- a/chromium/cc/layers/delegated_renderer_layer.h
+++ b/chromium/cc/layers/delegated_renderer_layer.h
@@ -19,12 +19,12 @@ namespace cc {
class CC_EXPORT DelegatedRendererLayer : public Layer {
public:
static scoped_refptr<DelegatedRendererLayer> Create(
+ const LayerSettings& settings,
const scoped_refptr<DelegatedFrameProvider>& frame_provider);
scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
void SetLayerTreeHost(LayerTreeHost* host) override;
- bool Update(ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion) override;
+ bool Update() override;
void PushPropertiesTo(LayerImpl* impl) override;
// Called by the DelegatedFrameProvider when a new frame is available to be
@@ -34,6 +34,7 @@ class CC_EXPORT DelegatedRendererLayer : public Layer {
protected:
DelegatedRendererLayer(
+ const LayerSettings& settings,
const scoped_refptr<DelegatedFrameProvider>& frame_provider);
~DelegatedRendererLayer() override;
diff --git a/chromium/cc/layers/delegated_renderer_layer_impl.cc b/chromium/cc/layers/delegated_renderer_layer_impl.cc
index a99cd17b2c7..9235af5a826 100644
--- a/chromium/cc/layers/delegated_renderer_layer_impl.cc
+++ b/chromium/cc/layers/delegated_renderer_layer_impl.cc
@@ -44,24 +44,6 @@ bool DelegatedRendererLayerImpl::HasContributingDelegatedRenderPasses() const {
return render_passes_in_draw_order_.size() > 1;
}
-static ResourceProvider::ResourceId ResourceRemapHelper(
- bool* invalid_frame,
- const ResourceProvider::ResourceIdMap& child_to_parent_map,
- ResourceProvider::ResourceIdSet* resources_in_frame,
- ResourceProvider::ResourceId id) {
- ResourceProvider::ResourceIdMap::const_iterator it =
- child_to_parent_map.find(id);
- if (it == child_to_parent_map.end()) {
- *invalid_frame = true;
- return 0;
- }
-
- DCHECK_EQ(it->first, id);
- ResourceProvider::ResourceId remapped_id = it->second;
- resources_in_frame->insert(id);
- return remapped_id;
-}
-
void DelegatedRendererLayerImpl::PushPropertiesTo(LayerImpl* layer) {
LayerImpl::PushPropertiesTo(layer);
@@ -134,14 +116,22 @@ void DelegatedRendererLayerImpl::SetFrameData(
if (reserve_size)
resources_in_frame.resize(reserve_size);
#endif
- DrawQuad::ResourceIteratorCallback remap_resources_to_parent_callback =
- base::Bind(&ResourceRemapHelper,
- &invalid_frame,
- resource_map,
- &resources_in_frame);
for (const auto& pass : render_pass_list) {
- for (const auto& quad : pass->quad_list)
- quad->IterateResources(remap_resources_to_parent_callback);
+ for (const auto& quad : pass->quad_list) {
+ for (ResourceId& resource_id : quad->resources) {
+ ResourceProvider::ResourceIdMap::const_iterator it =
+ resource_map.find(resource_id);
+ if (it == resource_map.end()) {
+ invalid_frame = true;
+ break;
+ }
+
+ DCHECK_EQ(it->first, resource_id);
+ ResourceId remapped_id = it->second;
+ resources_in_frame.insert(resource_id);
+ resource_id = remapped_id;
+ }
+ }
}
if (invalid_frame) {
@@ -190,7 +180,7 @@ void DelegatedRendererLayerImpl::SetRenderPasses(
RenderPassList::iterator to_take =
render_passes_in_draw_order->begin() + i;
render_passes_index_by_id_.insert(
- std::pair<RenderPassId, int>((*to_take)->id, i));
+ RenderPassToIndexMap::value_type((*to_take)->id, i));
scoped_ptr<RenderPass> taken_render_pass =
render_passes_in_draw_order->take(to_take);
render_passes_in_draw_order_.push_back(taken_render_pass.Pass());
@@ -220,8 +210,13 @@ void DelegatedRendererLayerImpl::ReleaseResources() {
have_render_passes_to_push_ = false;
}
-static inline int IndexToId(int index) { return index + 1; }
-static inline int IdToIndex(int id) { return id - 1; }
+static inline size_t IndexToId(size_t index) {
+ return index + 1;
+}
+static inline size_t IdToIndex(size_t id) {
+ DCHECK_GT(id, 0u);
+ return id - 1;
+}
RenderPassId DelegatedRendererLayerImpl::FirstContributingRenderPassId() const {
return RenderPassId(id(), IndexToId(0));
@@ -235,13 +230,13 @@ RenderPassId DelegatedRendererLayerImpl::NextContributingRenderPassId(
bool DelegatedRendererLayerImpl::ConvertDelegatedRenderPassId(
RenderPassId delegated_render_pass_id,
RenderPassId* output_render_pass_id) const {
- base::hash_map<RenderPassId, int>::const_iterator found =
+ RenderPassToIndexMap::const_iterator found =
render_passes_index_by_id_.find(delegated_render_pass_id);
if (found == render_passes_index_by_id_.end()) {
// Be robust against a RenderPass id that isn't part of the frame.
return false;
}
- unsigned delegated_render_pass_index = found->second;
+ size_t delegated_render_pass_index = found->second;
*output_render_pass_id =
RenderPassId(id(), IndexToId(delegated_render_pass_index));
return true;
@@ -259,7 +254,7 @@ void DelegatedRendererLayerImpl::AppendContributingRenderPasses(
inverse_device_scale_factor_);
for (size_t i = 0; i < render_passes_in_draw_order_.size() - 1; ++i) {
- RenderPassId output_render_pass_id(-1, -1);
+ RenderPassId output_render_pass_id;
bool present =
ConvertDelegatedRenderPassId(render_passes_in_draw_order_[i]->id,
&output_render_pass_id);
@@ -267,7 +262,7 @@ void DelegatedRendererLayerImpl::AppendContributingRenderPasses(
// Don't clash with the RenderPass we generate if we own a RenderSurface.
DCHECK(present) << render_passes_in_draw_order_[i]->id.layer_id << ", "
<< render_passes_in_draw_order_[i]->id.index;
- DCHECK_GT(output_render_pass_id.index, 0);
+ DCHECK_GT(output_render_pass_id.index, 0u);
scoped_ptr<RenderPass> copy_pass =
render_passes_in_draw_order_[i]->Copy(output_render_pass_id);
@@ -318,7 +313,7 @@ void DelegatedRendererLayerImpl::AppendQuads(
// Verify that the RenderPass we are appending to was created by us.
DCHECK(target_render_pass_id.layer_id == id());
- int render_pass_index = IdToIndex(target_render_pass_id.index);
+ size_t render_pass_index = IdToIndex(target_render_pass_id.index);
const RenderPass* delegated_render_pass =
render_passes_in_draw_order_[render_pass_index];
AppendRenderPassQuads(render_pass,
@@ -353,25 +348,19 @@ void DelegatedRendererLayerImpl::AppendRainbowDebugBorder(
const int kStripeWidth = 300;
const int kStripeHeight = 300;
- for (size_t i = 0; ; ++i) {
+ for (int i = 0;; ++i) {
// For horizontal lines.
int x = kStripeWidth * i;
- int width = std::min(kStripeWidth, content_bounds().width() - x - 1);
+ int width = std::min(kStripeWidth, bounds().width() - x - 1);
// For vertical lines.
int y = kStripeHeight * i;
- int height = std::min(kStripeHeight, content_bounds().height() - y - 1);
+ int height = std::min(kStripeHeight, bounds().height() - y - 1);
gfx::Rect top(x, 0, width, border_width);
- gfx::Rect bottom(x,
- content_bounds().height() - border_width,
- width,
- border_width);
+ gfx::Rect bottom(x, bounds().height() - border_width, width, border_width);
gfx::Rect left(0, y, border_width, height);
- gfx::Rect right(content_bounds().width() - border_width,
- y,
- border_width,
- height);
+ gfx::Rect right(bounds().width() - border_width, y, border_width, height);
if (top.IsEmpty() && left.IsEmpty())
break;
@@ -400,7 +389,7 @@ void DelegatedRendererLayerImpl::AppendRainbowDebugBorder(
colors[i % kNumColors],
static_cast<uint8_t>(SkColorGetA(colors[i % kNumColors]) *
kFillOpacity));
- gfx::Rect fill_rect(x, 0, width, content_bounds().height());
+ gfx::Rect fill_rect(x, 0, width, bounds().height());
solid_quad->SetNew(shared_quad_state, fill_rect, fill_rect, fill_color,
force_anti_aliasing_off);
}
@@ -440,13 +429,13 @@ void DelegatedRendererLayerImpl::AppendRenderPassQuads(
output_shared_quad_state->CopyFrom(delegated_shared_quad_state);
if (is_root_delegated_render_pass) {
- output_shared_quad_state->content_to_target_transform.ConcatTransform(
+ output_shared_quad_state->quad_to_target_transform.ConcatTransform(
delegated_frame_to_target_transform);
if (render_target() == this) {
DCHECK(!is_clipped());
DCHECK(render_surface());
- DCHECK_EQ(0, num_unclipped_descendants());
+ DCHECK_EQ(0u, num_unclipped_descendants());
output_shared_quad_state->clip_rect =
MathUtil::MapEnclosingClippedRect(
delegated_frame_to_target_transform,
@@ -468,7 +457,7 @@ void DelegatedRendererLayerImpl::AppendRenderPassQuads(
DCHECK(output_shared_quad_state);
gfx::Transform quad_content_to_delegated_target_space =
- output_shared_quad_state->content_to_target_transform;
+ output_shared_quad_state->quad_to_target_transform;
if (!is_root_delegated_render_pass) {
quad_content_to_delegated_target_space.ConcatTransform(
delegated_render_pass->transform_to_root_target);
@@ -496,7 +485,7 @@ void DelegatedRendererLayerImpl::AppendRenderPassQuads(
} else {
RenderPassId delegated_contributing_render_pass_id =
RenderPassDrawQuad::MaterialCast(delegated_quad)->render_pass_id;
- RenderPassId output_contributing_render_pass_id(-1, -1);
+ RenderPassId output_contributing_render_pass_id;
bool present =
ConvertDelegatedRenderPassId(delegated_contributing_render_pass_id,
diff --git a/chromium/cc/layers/delegated_renderer_layer_impl.h b/chromium/cc/layers/delegated_renderer_layer_impl.h
index 617d76f3b1e..2543894c5d4 100644
--- a/chromium/cc/layers/delegated_renderer_layer_impl.h
+++ b/chromium/cc/layers/delegated_renderer_layer_impl.h
@@ -87,7 +87,9 @@ class CC_EXPORT DelegatedRendererLayerImpl : public LayerImpl {
bool have_render_passes_to_push_;
float inverse_device_scale_factor_;
RenderPassList render_passes_in_draw_order_;
- base::hash_map<RenderPassId, int> render_passes_index_by_id_;
+
+ using RenderPassToIndexMap = base::hash_map<RenderPassId, size_t>;
+ RenderPassToIndexMap render_passes_index_by_id_;
ResourceProvider::ResourceIdSet resources_;
int child_id_;
diff --git a/chromium/cc/layers/delegated_renderer_layer_impl_unittest.cc b/chromium/cc/layers/delegated_renderer_layer_impl_unittest.cc
index cc45c53f19e..a2e8d704725 100644
--- a/chromium/cc/layers/delegated_renderer_layer_impl_unittest.cc
+++ b/chromium/cc/layers/delegated_renderer_layer_impl_unittest.cc
@@ -24,7 +24,6 @@
#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/single_thread_proxy.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/frame_time.h"
#include "ui/gfx/transform.h"
namespace cc {
@@ -73,19 +72,16 @@ class DelegatedRendererLayerImplTestSimple
layer_before->SetPosition(gfx::Point(20, 20));
layer_before->SetBounds(gfx::Size(14, 14));
- layer_before->SetContentBounds(gfx::Size(14, 14));
layer_before->SetDrawsContent(true);
layer_before->SetHasRenderSurface(true);
layer_after->SetPosition(gfx::Point(5, 5));
layer_after->SetBounds(gfx::Size(15, 15));
- layer_after->SetContentBounds(gfx::Size(15, 15));
layer_after->SetDrawsContent(true);
layer_after->SetHasRenderSurface(true);
delegated_renderer_layer->SetPosition(gfx::Point(3, 3));
delegated_renderer_layer->SetBounds(gfx::Size(10, 10));
- delegated_renderer_layer->SetContentBounds(gfx::Size(10, 10));
delegated_renderer_layer->SetDrawsContent(true);
gfx::Transform transform;
transform.Translate(1.0, 1.0);
@@ -149,7 +145,6 @@ TEST_F(DelegatedRendererLayerImplTest,
delegated_renderer_layer->SetPosition(gfx::Point(3, 3));
delegated_renderer_layer->SetBounds(gfx::Size(10, 10));
- delegated_renderer_layer->SetContentBounds(gfx::Size(10, 10));
delegated_renderer_layer->SetDrawsContent(true);
delegated_renderer_layer->SetHasRenderSurface(true);
gfx::Transform transform;
@@ -229,7 +224,6 @@ TEST_F(DelegatedRendererLayerImplTest,
delegated_renderer_layer->SetPosition(gfx::Point(3, 3));
delegated_renderer_layer->SetBounds(gfx::Size(10, 10));
- delegated_renderer_layer->SetContentBounds(gfx::Size(10, 10));
delegated_renderer_layer->SetDrawsContent(true);
delegated_renderer_layer->SetHasRenderSurface(true);
gfx::Transform transform;
@@ -308,16 +302,16 @@ TEST_F(DelegatedRendererLayerImplTestSimple, AddsContributingRenderPasses) {
// The DelegatedRendererLayer should have added its contributing RenderPasses
// to the frame.
EXPECT_EQ(4, frame.render_passes[1]->id.layer_id);
- EXPECT_EQ(1, frame.render_passes[1]->id.index);
+ EXPECT_EQ(1u, frame.render_passes[1]->id.index);
EXPECT_EQ(4, frame.render_passes[2]->id.layer_id);
- EXPECT_EQ(2, frame.render_passes[2]->id.index);
+ EXPECT_EQ(2u, frame.render_passes[2]->id.index);
// And all other RenderPasses should be non-delegated.
EXPECT_NE(4, frame.render_passes[0]->id.layer_id);
- EXPECT_EQ(0, frame.render_passes[0]->id.index);
+ EXPECT_EQ(0u, frame.render_passes[0]->id.index);
EXPECT_NE(4, frame.render_passes[3]->id.layer_id);
- EXPECT_EQ(0, frame.render_passes[3]->id.index);
+ EXPECT_EQ(0u, frame.render_passes[3]->id.index);
EXPECT_NE(4, frame.render_passes[4]->id.layer_id);
- EXPECT_EQ(0, frame.render_passes[4]->id.index);
+ EXPECT_EQ(0u, frame.render_passes[4]->id.index);
// The DelegatedRendererLayer should have added its RenderPasses to the frame
// in order.
@@ -342,9 +336,9 @@ TEST_F(DelegatedRendererLayerImplTestSimple,
// The DelegatedRendererLayer should have added its contributing RenderPasses
// to the frame.
EXPECT_EQ(4, frame.render_passes[1]->id.layer_id);
- EXPECT_EQ(1, frame.render_passes[1]->id.index);
+ EXPECT_EQ(1u, frame.render_passes[1]->id.index);
EXPECT_EQ(4, frame.render_passes[2]->id.layer_id);
- EXPECT_EQ(2, frame.render_passes[2]->id.index);
+ EXPECT_EQ(2u, frame.render_passes[2]->id.index);
// The DelegatedRendererLayer should have added copies of its quads to
// contributing RenderPasses.
@@ -408,21 +402,26 @@ TEST_F(DelegatedRendererLayerImplTestSimple,
gfx::Transform transform;
transform.Translate(4.0, 4.0);
EXPECT_TRANSFORMATION_MATRIX_EQ(
- transform, frame.render_passes[3]->quad_list.front()->quadTransform());
+ transform, frame.render_passes[3]
+ ->quad_list.front()
+ ->shared_quad_state->quad_to_target_transform);
// Quads from non-root RenderPasses should not be shifted though.
ASSERT_EQ(2u, frame.render_passes[2]->quad_list.size());
EXPECT_TRANSFORMATION_MATRIX_EQ(
- gfx::Transform(),
- frame.render_passes[2]->quad_list.front()->quadTransform());
+ gfx::Transform(), frame.render_passes[2]
+ ->quad_list.front()
+ ->shared_quad_state->quad_to_target_transform);
EXPECT_TRANSFORMATION_MATRIX_EQ(
- gfx::Transform(),
- frame.render_passes[2]->quad_list.ElementAt(1)->quadTransform());
+ gfx::Transform(), frame.render_passes[2]
+ ->quad_list.ElementAt(1)
+ ->shared_quad_state->quad_to_target_transform);
ASSERT_EQ(1u, frame.render_passes[1]->quad_list.size());
EXPECT_TRANSFORMATION_MATRIX_EQ(
- gfx::Transform(),
- frame.render_passes[1]->quad_list.front()->quadTransform());
+ gfx::Transform(), frame.render_passes[1]
+ ->quad_list.front()
+ ->shared_quad_state->quad_to_target_transform);
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
@@ -481,20 +480,20 @@ TEST_F(DelegatedRendererLayerImplTestOwnSurface, AddsRenderPasses) {
// The DelegatedRendererLayer should have added its contributing RenderPasses
// to the frame.
EXPECT_EQ(4, frame.render_passes[1]->id.layer_id);
- EXPECT_EQ(1, frame.render_passes[1]->id.index);
+ EXPECT_EQ(1u, frame.render_passes[1]->id.index);
EXPECT_EQ(4, frame.render_passes[2]->id.layer_id);
- EXPECT_EQ(2, frame.render_passes[2]->id.index);
+ EXPECT_EQ(2u, frame.render_passes[2]->id.index);
// The DelegatedRendererLayer should have added a RenderPass for its surface
// to the frame.
EXPECT_EQ(4, frame.render_passes[1]->id.layer_id);
- EXPECT_EQ(0, frame.render_passes[3]->id.index);
+ EXPECT_EQ(0u, frame.render_passes[3]->id.index);
// And all other RenderPasses should be non-delegated.
EXPECT_NE(4, frame.render_passes[0]->id.layer_id);
- EXPECT_EQ(0, frame.render_passes[0]->id.index);
+ EXPECT_EQ(0u, frame.render_passes[0]->id.index);
EXPECT_NE(4, frame.render_passes[4]->id.layer_id);
- EXPECT_EQ(0, frame.render_passes[4]->id.index);
+ EXPECT_EQ(0u, frame.render_passes[4]->id.index);
EXPECT_NE(4, frame.render_passes[5]->id.layer_id);
- EXPECT_EQ(0, frame.render_passes[5]->id.index);
+ EXPECT_EQ(0u, frame.render_passes[5]->id.index);
// The DelegatedRendererLayer should have added its RenderPasses to the frame
// in order.
@@ -520,9 +519,9 @@ TEST_F(DelegatedRendererLayerImplTestOwnSurface,
// The DelegatedRendererLayer should have added its contributing RenderPasses
// to the frame.
EXPECT_EQ(4, frame.render_passes[1]->id.layer_id);
- EXPECT_EQ(1, frame.render_passes[1]->id.index);
+ EXPECT_EQ(1u, frame.render_passes[1]->id.index);
EXPECT_EQ(4, frame.render_passes[2]->id.layer_id);
- EXPECT_EQ(2, frame.render_passes[2]->id.index);
+ EXPECT_EQ(2u, frame.render_passes[2]->id.index);
// The DelegatedRendererLayer should have added copies of its quads to
// contributing RenderPasses.
@@ -583,22 +582,26 @@ TEST_F(DelegatedRendererLayerImplTestOwnSurface,
// Because the DelegatedRendererLayer owns a RenderSurfaceImpl, its root
// RenderPass' quads do not need to be translated at all.
EXPECT_TRANSFORMATION_MATRIX_EQ(
- gfx::Transform(),
- frame.render_passes[3]->quad_list.front()->quadTransform());
+ gfx::Transform(), frame.render_passes[3]
+ ->quad_list.front()
+ ->shared_quad_state->quad_to_target_transform);
// Quads from non-root RenderPasses should not be shifted either.
ASSERT_EQ(2u, frame.render_passes[2]->quad_list.size());
EXPECT_TRANSFORMATION_MATRIX_EQ(
- gfx::Transform(),
- frame.render_passes[2]->quad_list.front()->quadTransform());
+ gfx::Transform(), frame.render_passes[2]
+ ->quad_list.front()
+ ->shared_quad_state->quad_to_target_transform);
EXPECT_TRANSFORMATION_MATRIX_EQ(
- gfx::Transform(),
- frame.render_passes[2]->quad_list.ElementAt(1)->quadTransform());
+ gfx::Transform(), frame.render_passes[2]
+ ->quad_list.ElementAt(1)
+ ->shared_quad_state->quad_to_target_transform);
ASSERT_EQ(1u, frame.render_passes[1]->quad_list.size());
EXPECT_TRANSFORMATION_MATRIX_EQ(
- gfx::Transform(),
- frame.render_passes[1]->quad_list.front()->quadTransform());
+ gfx::Transform(), frame.render_passes[1]
+ ->quad_list.front()
+ ->shared_quad_state->quad_to_target_transform);
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
@@ -625,7 +628,6 @@ class DelegatedRendererLayerImplTestTransform
delegated_renderer_layer->SetPosition(gfx::Point(20, 20));
delegated_renderer_layer->SetBounds(gfx::Size(75, 75));
- delegated_renderer_layer->SetContentBounds(gfx::Size(75, 75));
delegated_renderer_layer->SetDrawsContent(true);
gfx::Transform transform;
transform.Scale(2.0, 2.0);
@@ -634,7 +636,7 @@ class DelegatedRendererLayerImplTestTransform
RenderPassList delegated_render_passes;
- gfx::Size child_pass_content_bounds(7, 7);
+ gfx::Size child_pass_bounds(7, 7);
gfx::Rect child_pass_rect(20, 20, 7, 7);
gfx::Transform child_pass_transform;
child_pass_transform.Scale(0.8f, 0.8f);
@@ -649,14 +651,10 @@ class DelegatedRendererLayerImplTestTransform
gfx::Transform());
SharedQuadState* shared_quad_state =
pass->CreateAndAppendSharedQuadState();
- shared_quad_state->SetAll(child_pass_transform,
- child_pass_content_bounds,
- child_pass_rect,
- child_pass_clip_rect,
- child_pass_clipped,
- 1.f,
- SkXfermode::kSrcOver_Mode,
- 0);
+ shared_quad_state->SetAll(child_pass_transform, child_pass_bounds,
+ child_pass_rect, child_pass_clip_rect,
+ child_pass_clipped, 1.f,
+ SkXfermode::kSrcOver_Mode, 0);
SolidColorDrawQuad* color_quad;
color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
@@ -674,7 +672,7 @@ class DelegatedRendererLayerImplTestTransform
false);
}
- gfx::Size root_pass_content_bounds(100, 100);
+ gfx::Size root_pass_bounds(100, 100);
gfx::Rect root_pass_rect(0, 0, 100, 100);
gfx::Transform root_pass_transform;
root_pass_transform.Scale(1.5, 1.5);
@@ -687,13 +685,9 @@ class DelegatedRendererLayerImplTestTransform
root_pass_rect,
gfx::Transform());
SharedQuadState* shared_quad_state = pass->CreateAndAppendSharedQuadState();
- shared_quad_state->SetAll(root_pass_transform,
- root_pass_content_bounds,
- root_pass_rect,
- root_pass_clip_rect,
- root_pass_clipped,
- 1.f,
- SkXfermode::kSrcOver_Mode,
+ shared_quad_state->SetAll(root_pass_transform, root_pass_bounds,
+ root_pass_rect, root_pass_clip_rect,
+ root_pass_clipped, 1.f, SkXfermode::kSrcOver_Mode,
0);
RenderPassDrawQuad* render_pass_quad =
@@ -756,10 +750,10 @@ class DelegatedRendererLayerImplTestTransform
ASSERT_EQ(num_render_passes, frame.render_passes.size());
// The contributing render pass in the DelegatedRendererLayer.
EXPECT_EQ(2, frame.render_passes[0]->id.layer_id);
- EXPECT_EQ(1, frame.render_passes[0]->id.index);
+ EXPECT_EQ(1u, frame.render_passes[0]->id.index);
// The root render pass.
EXPECT_EQ(1, frame.render_passes.back()->id.layer_id);
- EXPECT_EQ(0, frame.render_passes.back()->id.index);
+ EXPECT_EQ(0u, frame.render_passes.back()->id.index);
const QuadList& contrib_delegated_quad_list =
frame.render_passes[0]->quad_list;
@@ -835,7 +829,7 @@ TEST_F(DelegatedRendererLayerImplTestTransform, QuadsUnclipped_NoSurface) {
expected.Scale(1.5, 1.5);
expected.Translate(7.0, 7.0);
EXPECT_TRANSFORMATION_MATRIX_EQ(
- expected, root_delegated_shared_quad_state->content_to_target_transform);
+ expected, root_delegated_shared_quad_state->quad_to_target_transform);
// The contributing render pass should not be transformed from its input.
EXPECT_EQ(gfx::Rect(21, 21, 3, 3).ToString(),
@@ -845,8 +839,7 @@ TEST_F(DelegatedRendererLayerImplTestTransform, QuadsUnclipped_NoSurface) {
expected.Scale(0.8f, 0.8f);
expected.Translate(9.0, 9.0);
EXPECT_TRANSFORMATION_MATRIX_EQ(
- expected,
- contrib_delegated_shared_quad_state->content_to_target_transform);
+ expected, contrib_delegated_shared_quad_state->quad_to_target_transform);
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
@@ -894,7 +887,7 @@ TEST_F(DelegatedRendererLayerImplTestTransform, QuadsClipped_NoSurface) {
expected.Scale(1.5, 1.5);
expected.Translate(7.0, 7.0);
EXPECT_TRANSFORMATION_MATRIX_EQ(
- expected, root_delegated_shared_quad_state->content_to_target_transform);
+ expected, root_delegated_shared_quad_state->quad_to_target_transform);
// The contributing render pass should not be transformed from its input.
EXPECT_EQ(gfx::Rect(21, 21, 3, 3).ToString(),
@@ -904,8 +897,7 @@ TEST_F(DelegatedRendererLayerImplTestTransform, QuadsClipped_NoSurface) {
expected.Scale(0.8f, 0.8f);
expected.Translate(9.0, 9.0);
EXPECT_TRANSFORMATION_MATRIX_EQ(
- expected,
- contrib_delegated_shared_quad_state->content_to_target_transform);
+ expected, contrib_delegated_shared_quad_state->quad_to_target_transform);
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
@@ -943,7 +935,7 @@ TEST_F(DelegatedRendererLayerImplTestTransform, QuadsUnclipped_Surface) {
expected.Scale(3.0, 3.0);
expected.Translate(7.0, 7.0);
EXPECT_TRANSFORMATION_MATRIX_EQ(
- expected, root_delegated_shared_quad_state->content_to_target_transform);
+ expected, root_delegated_shared_quad_state->quad_to_target_transform);
// The contributing render pass should not be transformed from its input.
EXPECT_EQ(gfx::Rect(21, 21, 3, 3).ToString(),
@@ -953,8 +945,7 @@ TEST_F(DelegatedRendererLayerImplTestTransform, QuadsUnclipped_Surface) {
expected.Scale(0.8f, 0.8f);
expected.Translate(9.0, 9.0);
EXPECT_TRANSFORMATION_MATRIX_EQ(
- expected,
- contrib_delegated_shared_quad_state->content_to_target_transform);
+ expected, contrib_delegated_shared_quad_state->quad_to_target_transform);
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
@@ -991,7 +982,7 @@ TEST_F(DelegatedRendererLayerImplTestTransform, QuadsClipped_Surface) {
expected.Scale(3.0, 3.0);
expected.Translate(7.0, 7.0);
EXPECT_TRANSFORMATION_MATRIX_EQ(
- expected, root_delegated_shared_quad_state->content_to_target_transform);
+ expected, root_delegated_shared_quad_state->quad_to_target_transform);
// The contributing render pass should not be transformed from its input.
EXPECT_EQ(gfx::Rect(21, 21, 3, 3).ToString(),
@@ -1001,8 +992,7 @@ TEST_F(DelegatedRendererLayerImplTestTransform, QuadsClipped_Surface) {
expected.Scale(0.8f, 0.8f);
expected.Translate(9.0, 9.0);
EXPECT_TRANSFORMATION_MATRIX_EQ(
- expected,
- contrib_delegated_shared_quad_state->content_to_target_transform);
+ expected, contrib_delegated_shared_quad_state->quad_to_target_transform);
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
@@ -1041,7 +1031,7 @@ TEST_F(DelegatedRendererLayerImplTestTransform, MismatchedDeviceScaleFactor) {
expected.Scale(1.5, 1.5);
expected.Translate(7.0, 7.0);
EXPECT_TRANSFORMATION_MATRIX_EQ(
- expected, root_delegated_shared_quad_state->content_to_target_transform);
+ expected, root_delegated_shared_quad_state->quad_to_target_transform);
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
@@ -1066,12 +1056,11 @@ class DelegatedRendererLayerImplTestClip
delegated_renderer_layer->SetPosition(gfx::Point(20, 20));
delegated_renderer_layer->SetBounds(gfx::Size(50, 50));
- delegated_renderer_layer->SetContentBounds(gfx::Size(50, 50));
delegated_renderer_layer->SetDrawsContent(true);
RenderPassList delegated_render_passes;
- gfx::Size child_pass_content_bounds(7, 7);
+ gfx::Size child_pass_bounds(7, 7);
gfx::Rect child_pass_rect(20, 20, 7, 7);
gfx::Transform child_pass_transform;
gfx::Rect child_pass_clip_rect(21, 21, 3, 3);
@@ -1084,14 +1073,10 @@ class DelegatedRendererLayerImplTestClip
gfx::Transform());
SharedQuadState* shared_quad_state =
pass->CreateAndAppendSharedQuadState();
- shared_quad_state->SetAll(child_pass_transform,
- child_pass_content_bounds,
- child_pass_rect,
- child_pass_clip_rect,
- child_pass_clipped,
- 1.f,
- SkXfermode::kSrcOver_Mode,
- 0);
+ shared_quad_state->SetAll(child_pass_transform, child_pass_bounds,
+ child_pass_rect, child_pass_clip_rect,
+ child_pass_clipped, 1.f,
+ SkXfermode::kSrcOver_Mode, 0);
SolidColorDrawQuad* color_quad;
color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
@@ -1109,7 +1094,7 @@ class DelegatedRendererLayerImplTestClip
false);
}
- gfx::Size root_pass_content_bounds(50, 50);
+ gfx::Size root_pass_bounds(50, 50);
gfx::Rect root_pass_rect(0, 0, 50, 50);
gfx::Transform root_pass_transform;
gfx::Rect root_pass_clip_rect(5, 5, 40, 40);
@@ -1120,13 +1105,9 @@ class DelegatedRendererLayerImplTestClip
root_pass_rect,
gfx::Transform());
SharedQuadState* shared_quad_state = pass->CreateAndAppendSharedQuadState();
- shared_quad_state->SetAll(root_pass_transform,
- root_pass_content_bounds,
- root_pass_rect,
- root_pass_clip_rect,
- root_pass_clipped,
- 1.f,
- SkXfermode::kSrcOver_Mode,
+ shared_quad_state->SetAll(root_pass_transform, root_pass_bounds,
+ root_pass_rect, root_pass_clip_rect,
+ root_pass_clipped, 1.f, SkXfermode::kSrcOver_Mode,
0);
RenderPassDrawQuad* render_pass_quad =
@@ -1182,7 +1163,6 @@ class DelegatedRendererLayerImplTestClip
clip_layer->SetPosition(clip_rect.origin());
clip_layer->SetBounds(clip_rect.size());
- clip_layer->SetContentBounds(clip_rect.size());
clip_layer->SetMasksToBounds(true);
origin_layer->SetPosition(
@@ -1454,7 +1434,6 @@ TEST_F(DelegatedRendererLayerImplTest, Occlusion) {
FakeDelegatedRendererLayerImpl* delegated_renderer_layer_impl =
impl.AddChildToRoot<FakeDelegatedRendererLayerImpl>();
delegated_renderer_layer_impl->SetBounds(layer_size);
- delegated_renderer_layer_impl->SetContentBounds(layer_size);
delegated_renderer_layer_impl->SetDrawsContent(true);
// Contributing render pass is offset by a transform and holds a quad that
@@ -1513,7 +1492,7 @@ TEST_F(DelegatedRendererLayerImplTest, Occlusion) {
{
SCOPED_TRACE("Full occlusion");
{
- gfx::Rect occluded(delegated_renderer_layer_impl->visible_content_rect());
+ gfx::Rect occluded(delegated_renderer_layer_impl->visible_layer_rect());
SCOPED_TRACE("Root render pass");
impl.AppendQuadsForPassWithOcclusion(delegated_renderer_layer_impl, pass1,
@@ -1523,7 +1502,7 @@ TEST_F(DelegatedRendererLayerImplTest, Occlusion) {
EXPECT_EQ(pass1->quad_list.size(), 0u);
}
{
- gfx::Rect occluded(delegated_renderer_layer_impl->visible_content_rect());
+ gfx::Rect occluded(delegated_renderer_layer_impl->visible_layer_rect());
SCOPED_TRACE("Contributing render pass");
impl.AppendQuadsForPassWithOcclusion(delegated_renderer_layer_impl, pass2,
@@ -1583,6 +1562,9 @@ TEST_F(DelegatedRendererLayerImplTest, Occlusion) {
gfx::Transform layer_transform;
layer_transform.Translate(11.0, 0.0);
delegated_renderer_layer_impl->SetTransform(layer_transform);
+ delegated_renderer_layer_impl->layer_tree_impl()
+ ->property_trees()
+ ->needs_rebuild = true;
occlusion_in_target_of_delegated_quad += gfx::Vector2d(11, 0);
@@ -1619,7 +1601,6 @@ TEST_F(DelegatedRendererLayerImplTest, DeviceScaleFactorOcclusion) {
FakeDelegatedRendererLayerImpl* delegated_renderer_layer_impl =
impl.AddChildToRoot<FakeDelegatedRendererLayerImpl>();
delegated_renderer_layer_impl->SetBounds(layer_size);
- delegated_renderer_layer_impl->SetContentBounds(layer_size);
delegated_renderer_layer_impl->SetDrawsContent(true);
// Contributing render pass is offset by a transform and holds a quad that
@@ -1677,7 +1658,6 @@ TEST_F(DelegatedRendererLayerImplTest, PushPropertiesTo) {
scoped_ptr<FakeDelegatedRendererLayerImpl> delegated_renderer_layer_impl =
FakeDelegatedRendererLayerImpl::Create(host_impl_->active_tree(), 5);
delegated_renderer_layer_impl->SetBounds(layer_size);
- delegated_renderer_layer_impl->SetContentBounds(layer_size);
delegated_renderer_layer_impl->SetDrawsContent(true);
RenderPassList delegated_render_passes;
diff --git a/chromium/cc/layers/delegated_renderer_layer_unittest.cc b/chromium/cc/layers/delegated_renderer_layer_unittest.cc
index f243d73c260..ad4a345fc0f 100644
--- a/chromium/cc/layers/delegated_renderer_layer_unittest.cc
+++ b/chromium/cc/layers/delegated_renderer_layer_unittest.cc
@@ -11,6 +11,7 @@
#include "cc/test/fake_delegated_renderer_layer.h"
#include "cc/test/fake_layer_tree_host.h"
#include "cc/test/fake_proxy.h"
+#include "cc/test/test_task_graph_runner.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cc {
@@ -23,13 +24,15 @@ class DelegatedRendererLayerTest : public testing::Test {
LayerTreeSettings settings;
settings.minimum_occlusion_tracking_size = gfx::Size();
- host_impl_ = FakeLayerTreeHost::Create(&host_client_, settings);
+ host_impl_ =
+ FakeLayerTreeHost::Create(&host_client_, &task_graph_runner_, settings);
host_impl_->SetViewportSize(gfx::Size(10, 10));
}
protected:
FakeProxy proxy_;
FakeLayerTreeHostClient host_client_;
+ TestTaskGraphRunner task_graph_runner_;
TestSharedBitmapManager shared_bitmap_manager_;
scoped_ptr<LayerTreeHost> host_impl_;
};
@@ -44,10 +47,11 @@ class DelegatedRendererLayerTestSimple : public DelegatedRendererLayerTest {
frame_data->render_pass_list.push_back(root_pass.Pass());
resources_ = new DelegatedFrameResourceCollection;
provider_ = new DelegatedFrameProvider(resources_, frame_data.Pass());
- root_layer_ = SolidColorLayer::Create();
- layer_before_ = SolidColorLayer::Create();
+ LayerSettings layer_settings;
+ root_layer_ = SolidColorLayer::Create(layer_settings);
+ layer_before_ = SolidColorLayer::Create(layer_settings);
delegated_renderer_layer_ =
- FakeDelegatedRendererLayer::Create(provider_.get());
+ FakeDelegatedRendererLayer::Create(layer_settings, provider_.get());
}
protected:
diff --git a/chromium/cc/layers/draw_properties.h b/chromium/cc/layers/draw_properties.h
index 3dfb203b33b..5a07af04e32 100644
--- a/chromium/cc/layers/draw_properties.h
+++ b/chromium/cc/layers/draw_properties.h
@@ -27,25 +27,17 @@ struct CC_EXPORT DrawProperties {
can_use_lcd_text(false),
is_clipped(false),
render_target(nullptr),
- contents_scale_x(1.f),
- contents_scale_y(1.f),
num_unclipped_descendants(0),
layer_or_descendant_has_copy_request(false),
layer_or_descendant_has_input_handler(false),
- layer_or_descendant_is_drawn(false),
has_child_with_a_scroll_parent(false),
- sorted_for_recursion(false),
- visited(false),
index_of_first_descendants_addition(0),
num_descendants_added(0),
index_of_first_render_surface_layer_list_addition(0),
num_render_surfaces_added(0),
last_drawn_render_surface_layer_list_id(0),
- ideal_contents_scale(0.f),
maximum_animation_contents_scale(0.f),
- starting_animation_contents_scale(0.f),
- page_scale_factor(0.f),
- device_scale_factor(0.f) {}
+ starting_animation_contents_scale(0.f) {}
// Transforms objects from content space to target surface space, where
// this layer would be drawn.
@@ -86,8 +78,9 @@ struct CC_EXPORT DrawProperties {
// ancestor of this layer.
LayerType* render_target;
- // This rect is in the layer's content space.
- gfx::Rect visible_content_rect;
+ // This rect is a bounding box around what part of the layer is visible, in
+ // the layer's coordinate space.
+ gfx::Rect visible_layer_rect;
// In target surface space, the rect that encloses the clipped, drawable
// content of the layer.
@@ -97,17 +90,9 @@ struct CC_EXPORT DrawProperties {
// value is used to avoid unnecessarily changing GL scissor state.
gfx::Rect clip_rect;
- // The scale used to move between layer space and content space, and bounds
- // of the space. One is always a function of the other, but which one
- // depends on the layer type. For picture layers, this is an ideal scale,
- // and not always the one used.
- float contents_scale_x;
- float contents_scale_y;
- gfx::Size content_bounds;
-
// Number of descendants with a clip parent that is our ancestor. NB - this
// does not include our clip children because they are clipped by us.
- int num_unclipped_descendants;
+ size_t num_unclipped_descendants;
// If true, the layer or some layer in its sub-tree has a CopyOutputRequest
// present on it.
@@ -116,22 +101,12 @@ struct CC_EXPORT DrawProperties {
// If true, the layer or one of its descendants has a wheel or touch handler.
bool layer_or_descendant_has_input_handler;
- // If true, the layer or one of its descendants is drawn
- bool layer_or_descendant_is_drawn;
-
// This is true if the layer has any direct child that has a scroll parent.
// This layer will not be the scroll parent in this case. This information
// lets us avoid work in CalculateDrawPropertiesInternal -- if none of our
// children have scroll parents, we will not need to recur out of order.
bool has_child_with_a_scroll_parent;
- // This is true if the order (wrt to its siblings in the tree) in which the
- // layer will be visited while computing draw properties has been determined.
- bool sorted_for_recursion;
-
- // This is used to sanity-check CDP and ensure that we don't revisit a layer.
- bool visited;
-
// If this layer is visited out of order, its contribution to the descendant
// and render surface layer lists will be put aside in a temporary list.
// These values will allow for an efficient reordering of these additions.
@@ -149,10 +124,6 @@ struct CC_EXPORT DrawProperties {
// of date or 0.
int last_drawn_render_surface_layer_list_id;
- // The scale at which content for the layer should be rastered in order to be
- // perfectly crisp.
- float ideal_contents_scale;
-
// The maximum scale during the layers current animation at which content
// should be rastered at to be crisp.
float maximum_animation_contents_scale;
@@ -160,13 +131,6 @@ struct CC_EXPORT DrawProperties {
// The scale during the layer animation start at which content should be
// rastered at to be crisp.
float starting_animation_contents_scale;
-
- // The page scale factor that is applied to the layer. Since some layers may
- // have page scale applied and others not, this may differ between layers.
- float page_scale_factor;
-
- // The device scale factor that is applied to the layer.
- float device_scale_factor;
};
} // namespace cc
diff --git a/chromium/cc/layers/heads_up_display_layer.cc b/chromium/cc/layers/heads_up_display_layer.cc
index 5dd4bd24d52..388c2ad2473 100644
--- a/chromium/cc/layers/heads_up_display_layer.cc
+++ b/chromium/cc/layers/heads_up_display_layer.cc
@@ -12,11 +12,13 @@
namespace cc {
-scoped_refptr<HeadsUpDisplayLayer> HeadsUpDisplayLayer::Create() {
- return make_scoped_refptr(new HeadsUpDisplayLayer());
+scoped_refptr<HeadsUpDisplayLayer> HeadsUpDisplayLayer::Create(
+ const LayerSettings& settings) {
+ return make_scoped_refptr(new HeadsUpDisplayLayer(settings));
}
-HeadsUpDisplayLayer::HeadsUpDisplayLayer() {
+HeadsUpDisplayLayer::HeadsUpDisplayLayer(const LayerSettings& settings)
+ : Layer(settings) {
SetIsDrawable(true);
UpdateDrawsContent(HasDrawableContent());
}
diff --git a/chromium/cc/layers/heads_up_display_layer.h b/chromium/cc/layers/heads_up_display_layer.h
index ddc34f286d8..0760353ed9f 100644
--- a/chromium/cc/layers/heads_up_display_layer.h
+++ b/chromium/cc/layers/heads_up_display_layer.h
@@ -15,7 +15,8 @@ namespace cc {
class CC_EXPORT HeadsUpDisplayLayer : public Layer {
public:
- static scoped_refptr<HeadsUpDisplayLayer> Create();
+ static scoped_refptr<HeadsUpDisplayLayer> Create(
+ const LayerSettings& settings);
void PrepareForCalculateDrawProperties(
const gfx::Size& device_viewport, float device_scale_factor);
@@ -23,7 +24,7 @@ class CC_EXPORT HeadsUpDisplayLayer : public Layer {
scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
protected:
- HeadsUpDisplayLayer();
+ explicit HeadsUpDisplayLayer(const LayerSettings& settings);
bool HasDrawableContent() const override;
private:
diff --git a/chromium/cc/layers/heads_up_display_layer_impl.cc b/chromium/cc/layers/heads_up_display_layer_impl.cc
index 986c332e406..dffa6d18d65 100644
--- a/chromium/cc/layers/heads_up_display_layer_impl.cc
+++ b/chromium/cc/layers/heads_up_display_layer_impl.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include <vector>
+#include "base/numerics/safe_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"
@@ -129,7 +130,7 @@ bool HeadsUpDisplayLayerImpl::WillDraw(DrawMode draw_mode,
if (draw_mode == DRAW_MODE_RESOURCELESS_SOFTWARE)
return false;
- internal_contents_scale_ = draw_properties().ideal_contents_scale;
+ internal_contents_scale_ = GetIdealContentsScale();
internal_content_bounds_ =
gfx::ToCeiledSize(gfx::ScaleSize(bounds(), internal_contents_scale_));
@@ -225,6 +226,7 @@ void HeadsUpDisplayLayerImpl::ReleaseResources() {
}
gfx::Rect HeadsUpDisplayLayerImpl::GetEnclosingRectInTargetSpace() const {
+ DCHECK_GT(internal_contents_scale_, 0.f);
return GetScaledEnclosingRectInTargetSpace(internal_contents_scale_);
}
@@ -383,7 +385,8 @@ SkRect HeadsUpDisplayLayerImpl::DrawFPSDisplay(
const int kFontHeight = 15;
- const int kGraphWidth = fps_counter->time_stamp_history_size() - 2;
+ const int kGraphWidth =
+ base::saturated_cast<int>(fps_counter->time_stamp_history_size()) - 2;
const int kGraphHeight = 40;
const int kHistogramWidth = 37;
@@ -625,7 +628,8 @@ SkRect HeadsUpDisplayLayerImpl::DrawPaintTimeDisplay(
const int kPadding = 4;
const int kFontHeight = 14;
- const int kGraphWidth = paint_time_counter->HistorySize();
+ const int kGraphWidth =
+ base::saturated_cast<int>(paint_time_counter->HistorySize());
const int kGraphHeight = 40;
SkPaint paint = CreatePaint();
diff --git a/chromium/cc/layers/heads_up_display_layer_impl_unittest.cc b/chromium/cc/layers/heads_up_display_layer_impl_unittest.cc
index ab38fdd087d..ad2215595aa 100644
--- a/chromium/cc/layers/heads_up_display_layer_impl_unittest.cc
+++ b/chromium/cc/layers/heads_up_display_layer_impl_unittest.cc
@@ -8,6 +8,7 @@
#include "cc/test/fake_layer_tree_host_impl.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/test_shared_bitmap_manager.h"
+#include "cc/test/test_task_graph_runner.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cc {
@@ -32,13 +33,14 @@ void CheckDrawLayer(HeadsUpDisplayLayerImpl* layer,
TEST(HeadsUpDisplayLayerImplTest, ResourcelessSoftwareDrawAfterResourceLoss) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
host_impl.CreatePendingTree();
host_impl.InitializeRenderer(FakeOutputSurface::Create3d());
scoped_ptr<HeadsUpDisplayLayerImpl> layer =
HeadsUpDisplayLayerImpl::Create(host_impl.pending_tree(), 1);
layer->SetBounds(gfx::Size(100, 100));
- layer->draw_properties().ideal_contents_scale = 1.f;
// Check regular hardware draw is ok.
CheckDrawLayer(
diff --git a/chromium/cc/layers/heads_up_display_unittest.cc b/chromium/cc/layers/heads_up_display_unittest.cc
index 312e482ff2d..532a169c368 100644
--- a/chromium/cc/layers/heads_up_display_unittest.cc
+++ b/chromium/cc/layers/heads_up_display_unittest.cc
@@ -26,7 +26,7 @@ class DrawsContentLayer : public Layer {
bool DrawsContent() const override { return true; }
private:
- DrawsContentLayer() : Layer() {}
+ DrawsContentLayer() : Layer(LayerSettings()) {}
~DrawsContentLayer() override {}
};
diff --git a/chromium/cc/layers/image_layer.cc b/chromium/cc/layers/image_layer.cc
deleted file mode 100644
index 67e620c6e2e..00000000000
--- a/chromium/cc/layers/image_layer.cc
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/layers/image_layer.h"
-
-#include "base/compiler_specific.h"
-#include "cc/resources/image_layer_updater.h"
-#include "cc/resources/layer_updater.h"
-#include "cc/resources/prioritized_resource.h"
-#include "cc/resources/resource_update_queue.h"
-#include "cc/trees/layer_tree_host.h"
-
-namespace cc {
-
-scoped_refptr<ImageLayer> ImageLayer::Create() {
- return make_scoped_refptr(new ImageLayer());
-}
-
-ImageLayer::ImageLayer() : TiledLayer() {}
-
-ImageLayer::~ImageLayer() {}
-
-void ImageLayer::SetBitmap(const SkBitmap& bitmap) {
- // SetBitmap() currently gets called whenever there is any
- // style change that affects the layer even if that change doesn't
- // affect the actual contents of the image (e.g. a CSS animation).
- // With this check in place we avoid unecessary texture uploads.
- if (bitmap.pixelRef() && bitmap.pixelRef() == bitmap_.pixelRef())
- return;
-
- bitmap_ = bitmap;
- UpdateDrawsContent(HasDrawableContent());
- SetNeedsDisplay();
-}
-
-bool ImageLayer::HasDrawableContent() const {
- return !bitmap_.isNull() && TiledLayer::HasDrawableContent();
-}
-
-void ImageLayer::SetTexturePriorities(const PriorityCalculator& priority_calc) {
- // Update the tile data before creating all the layer's tiles.
- UpdateTileSizeAndTilingOption();
-
- TiledLayer::SetTexturePriorities(priority_calc);
-}
-
-bool ImageLayer::Update(ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion) {
- CreateUpdaterIfNeeded();
- if (!updater_->UsingBitmap(bitmap_)) {
- updater_->SetBitmap(bitmap_);
- UpdateTileSizeAndTilingOption();
- InvalidateContentRect(gfx::Rect(content_bounds()));
- }
- return TiledLayer::Update(queue, occlusion);
-}
-
-void ImageLayer::CreateUpdaterIfNeeded() {
- if (updater_.get())
- return;
-
- updater_ = ImageLayerUpdater::Create();
- SetTextureFormat(
- layer_tree_host()->GetRendererCapabilities().best_texture_format);
-}
-
-LayerUpdater* ImageLayer::Updater() const {
- return updater_.get();
-}
-
-void ImageLayer::CalculateContentsScale(float ideal_contents_scale,
- float* contents_scale_x,
- float* contents_scale_y,
- gfx::Size* content_bounds) {
- *contents_scale_x = ImageContentsScaleX();
- *contents_scale_y = ImageContentsScaleY();
- *content_bounds = gfx::Size(bitmap_.width(), bitmap_.height());
-}
-
-void ImageLayer::OnOutputSurfaceCreated() {
- SetTextureFormat(
- layer_tree_host()->GetRendererCapabilities().best_texture_format);
- TiledLayer::OnOutputSurfaceCreated();
-}
-
-float ImageLayer::ImageContentsScaleX() const {
- if (bounds().IsEmpty() || bitmap_.width() == 0)
- return 1;
- return static_cast<float>(bitmap_.width()) / bounds().width();
-}
-
-float ImageLayer::ImageContentsScaleY() const {
- if (bounds().IsEmpty() || bitmap_.height() == 0)
- return 1;
- return static_cast<float>(bitmap_.height()) / bounds().height();
-}
-
-} // namespace cc
diff --git a/chromium/cc/layers/image_layer.h b/chromium/cc/layers/image_layer.h
deleted file mode 100644
index ed2a2a3bd89..00000000000
--- a/chromium/cc/layers/image_layer.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_LAYERS_IMAGE_LAYER_H_
-#define CC_LAYERS_IMAGE_LAYER_H_
-
-#include "cc/base/cc_export.h"
-#include "cc/layers/content_layer.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-
-namespace cc {
-
-class ImageLayerUpdater;
-
-// A Layer that contains only an Image element.
-class CC_EXPORT ImageLayer : public TiledLayer {
- public:
- static scoped_refptr<ImageLayer> Create();
-
- // Layer implementation.
- void SetTexturePriorities(const PriorityCalculator& priority_calc) override;
- bool Update(ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion) override;
- void CalculateContentsScale(float ideal_contents_scale,
- float* contents_scale_x,
- float* contents_scale_y,
- gfx::Size* content_bounds) override;
- void OnOutputSurfaceCreated() override;
-
- void SetBitmap(const SkBitmap& image);
-
- protected:
- bool HasDrawableContent() const override;
-
- private:
- ImageLayer();
- ~ImageLayer() override;
-
- // TiledLayer Implementation.
- LayerUpdater* Updater() const override;
- void CreateUpdaterIfNeeded() override;
-
- float ImageContentsScaleX() const;
- float ImageContentsScaleY() const;
-
- SkBitmap bitmap_;
-
- scoped_refptr<ImageLayerUpdater> updater_;
-
- DISALLOW_COPY_AND_ASSIGN(ImageLayer);
-};
-
-} // namespace cc
-
-#endif // CC_LAYERS_IMAGE_LAYER_H_
diff --git a/chromium/cc/layers/io_surface_layer.cc b/chromium/cc/layers/io_surface_layer.cc
index 05d5fb90f04..c2e35304b60 100644
--- a/chromium/cc/layers/io_surface_layer.cc
+++ b/chromium/cc/layers/io_surface_layer.cc
@@ -8,11 +8,14 @@
namespace cc {
-scoped_refptr<IOSurfaceLayer> IOSurfaceLayer::Create() {
- return make_scoped_refptr(new IOSurfaceLayer());
+scoped_refptr<IOSurfaceLayer> IOSurfaceLayer::Create(
+ const LayerSettings& settings) {
+ return make_scoped_refptr(new IOSurfaceLayer(settings));
}
-IOSurfaceLayer::IOSurfaceLayer() : Layer(), io_surface_id_(0) {}
+IOSurfaceLayer::IOSurfaceLayer(const LayerSettings& settings)
+ : Layer(settings), io_surface_id_(0) {
+}
IOSurfaceLayer::~IOSurfaceLayer() {}
@@ -41,10 +44,8 @@ void IOSurfaceLayer::PushPropertiesTo(LayerImpl* layer) {
io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_);
}
-bool IOSurfaceLayer::Update(ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion) {
- bool updated = Layer::Update(queue, occlusion);
-
+bool IOSurfaceLayer::Update() {
+ bool updated = Layer::Update();
// This layer doesn't update any resources from the main thread side,
// but repaint rects need to be sent to the layer impl via commit.
return updated || !update_rect_.IsEmpty();
diff --git a/chromium/cc/layers/io_surface_layer.h b/chromium/cc/layers/io_surface_layer.h
index 90bcf3e8323..14eabd98a1e 100644
--- a/chromium/cc/layers/io_surface_layer.h
+++ b/chromium/cc/layers/io_surface_layer.h
@@ -12,18 +12,17 @@ namespace cc {
class CC_EXPORT IOSurfaceLayer : public Layer {
public:
- static scoped_refptr<IOSurfaceLayer> Create();
+ static scoped_refptr<IOSurfaceLayer> Create(const LayerSettings& settings);
void SetIOSurfaceProperties(uint32_t io_surface_id, const gfx::Size& size);
scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
void PushPropertiesTo(LayerImpl* layer) override;
- bool Update(ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion) override;
+ bool Update() override;
protected:
bool HasDrawableContent() const override;
- IOSurfaceLayer();
+ explicit IOSurfaceLayer(const LayerSettings& settings);
private:
~IOSurfaceLayer() override;
diff --git a/chromium/cc/layers/io_surface_layer_impl.cc b/chromium/cc/layers/io_surface_layer_impl.cc
index a7da986859d..234d3f3a767 100644
--- a/chromium/cc/layers/io_surface_layer_impl.cc
+++ b/chromium/cc/layers/io_surface_layer_impl.cc
@@ -66,10 +66,10 @@ void IOSurfaceLayerImpl::AppendQuads(
render_pass->CreateAndAppendSharedQuadState();
PopulateSharedQuadState(shared_quad_state);
- AppendDebugBorderQuad(
- render_pass, content_bounds(), shared_quad_state, append_quads_data);
+ AppendDebugBorderQuad(render_pass, bounds(), shared_quad_state,
+ append_quads_data);
- gfx::Rect quad_rect(content_bounds());
+ gfx::Rect quad_rect(bounds());
gfx::Rect opaque_rect(contents_opaque() ? quad_rect : gfx::Rect());
gfx::Rect visible_quad_rect =
draw_properties().occlusion_in_content_space.GetUnoccludedContentRect(
diff --git a/chromium/cc/layers/io_surface_layer_impl_unittest.cc b/chromium/cc/layers/io_surface_layer_impl_unittest.cc
index 1c9256c2551..75c2cf77f83 100644
--- a/chromium/cc/layers/io_surface_layer_impl_unittest.cc
+++ b/chromium/cc/layers/io_surface_layer_impl_unittest.cc
@@ -19,7 +19,6 @@ TEST(IOSurfaceLayerImplTest, Occlusion) {
IOSurfaceLayerImpl* io_surface_layer_impl =
impl.AddChildToRoot<IOSurfaceLayerImpl>();
io_surface_layer_impl->SetBounds(layer_size);
- io_surface_layer_impl->SetContentBounds(layer_size);
io_surface_layer_impl->SetDrawsContent(true);
io_surface_layer_impl->SetIOSurfaceProperties(1, gfx::Size(1, 1));
@@ -40,7 +39,7 @@ TEST(IOSurfaceLayerImplTest, Occlusion) {
{
SCOPED_TRACE("Full occlusion");
- gfx::Rect occluded(io_surface_layer_impl->visible_content_rect());
+ gfx::Rect occluded(io_surface_layer_impl->visible_layer_rect());
impl.AppendQuadsWithOcclusion(io_surface_layer_impl, occluded);
LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect());
diff --git a/chromium/cc/layers/layer.cc b/chromium/cc/layers/layer.cc
index 9a10f5d55be..b9867d6217c 100644
--- a/chromium/cc/layers/layer.cc
+++ b/chromium/cc/layers/layer.cc
@@ -34,13 +34,13 @@ namespace cc {
base::StaticAtomicSequenceNumber g_next_layer_id;
-scoped_refptr<Layer> Layer::Create() {
- return make_scoped_refptr(new Layer());
+scoped_refptr<Layer> Layer::Create(const LayerSettings& settings) {
+ return make_scoped_refptr(new Layer(settings));
}
-Layer::Layer()
+Layer::Layer(const LayerSettings& settings)
: needs_push_properties_(false),
- num_dependents_need_push_properties_(false),
+ num_dependents_need_push_properties_(0),
stacking_order_changed_(false),
// Layer IDs start from 1.
layer_id_(g_next_layer_id.GetNext() + 1),
@@ -56,6 +56,7 @@ Layer::Layer()
property_tree_sequence_number_(-1),
num_layer_or_descendants_with_copy_request_(0),
num_layer_or_descendants_with_input_handler_(0),
+ num_children_with_scroll_parent_(0),
should_flatten_transform_from_property_tree_(false),
should_scroll_on_main_thread_(false),
have_wheel_event_handlers_(false),
@@ -81,14 +82,18 @@ Layer::Layer()
opacity_(1.f),
blend_mode_(SkXfermode::kSrcOver_Mode),
scroll_parent_(nullptr),
+ layer_or_descendant_is_drawn_tracker_(0),
+ sorted_for_recursion_tracker_(0),
+ visited_tracker_(0),
clip_parent_(nullptr),
replica_layer_(nullptr),
- raster_scale_(0.f),
client_(nullptr),
frame_timing_requests_dirty_(false) {
- layer_animation_controller_ = LayerAnimationController::Create(layer_id_);
- layer_animation_controller_->AddValueObserver(this);
- layer_animation_controller_->set_value_provider(this);
+ if (!settings.use_compositor_animation_timelines) {
+ layer_animation_controller_ = LayerAnimationController::Create(layer_id_);
+ layer_animation_controller_->AddValueObserver(this);
+ layer_animation_controller_->set_value_provider(this);
+ }
}
Layer::~Layer() {
@@ -99,8 +104,10 @@ Layer::~Layer() {
// reference to us.
DCHECK(!layer_tree_host());
- layer_animation_controller_->RemoveValueObserver(this);
- layer_animation_controller_->remove_value_provider(this);
+ if (layer_animation_controller_) {
+ layer_animation_controller_->RemoveValueObserver(this);
+ layer_animation_controller_->remove_value_provider(this);
+ }
RemoveFromScrollTree();
RemoveFromClipTree();
@@ -121,11 +128,14 @@ void Layer::SetLayerTreeHost(LayerTreeHost* host) {
if (layer_tree_host_ == host)
return;
- if (layer_tree_host_)
+ if (layer_tree_host_) {
layer_tree_host_->property_trees()->needs_rebuild = true;
-
- if (host)
+ layer_tree_host_->UnregisterLayer(this);
+ }
+ if (host) {
host->property_trees()->needs_rebuild = true;
+ host->RegisterLayer(this);
+ }
InvalidatePropertyTreesIndices();
@@ -143,15 +153,16 @@ void Layer::SetLayerTreeHost(LayerTreeHost* host) {
if (replica_layer_.get())
replica_layer_->SetLayerTreeHost(host);
- if (host) {
- layer_animation_controller_->SetAnimationRegistrar(
- host->animation_registrar());
+ if (host)
+ RegisterForAnimations(host->animation_registrar());
- if (host->settings().layer_transforms_should_scale_layer_contents)
- reset_raster_scale_to_unknown();
- }
+ bool has_any_animation = false;
+ if (layer_animation_controller_)
+ has_any_animation = layer_animation_controller_->has_any_animation();
+ else if (layer_tree_host_)
+ has_any_animation = layer_tree_host_->HasAnyAnimation(this);
- if (host && layer_animation_controller_->has_any_animation())
+ if (host && has_any_animation)
host->SetNeedsCommit();
}
@@ -234,15 +245,6 @@ bool Layer::IsPropertyChangeAllowed() const {
return !layer_tree_host_->in_paint_layer_contents();
}
-gfx::Rect Layer::LayerRectToContentRect(const gfx::Rect& layer_rect) const {
- gfx::Rect content_rect = gfx::ScaleToEnclosingRect(
- layer_rect, contents_scale_x(), contents_scale_y());
- // Intersect with content rect to avoid the extra pixel because for some
- // values x and y, ceil((x / y) * y) may be x + 1.
- content_rect.Intersect(gfx::Rect(content_bounds()));
- return content_rect;
-}
-
skia::RefPtr<SkPicture> Layer::GetPicture() const {
return skia::RefPtr<SkPicture>();
}
@@ -264,16 +266,6 @@ void Layer::SetParent(Layer* layer) {
return;
layer_tree_host_->property_trees()->needs_rebuild = true;
-
- const LayerTreeSettings& settings = layer_tree_host_->settings();
- if (!settings.layer_transforms_should_scale_layer_contents)
- return;
-
- reset_raster_scale_to_unknown();
- if (mask_layer_.get())
- mask_layer_->reset_raster_scale_to_unknown();
- if (replica_layer_.get() && replica_layer_->mask_layer_.get())
- replica_layer_->mask_layer_->reset_raster_scale_to_unknown();
}
void Layer::AddChild(scoped_refptr<Layer> child) {
@@ -336,12 +328,14 @@ void Layer::ReplaceChild(Layer* reference, scoped_refptr<Layer> new_layer) {
if (reference == new_layer.get())
return;
- int reference_index = IndexOfChild(reference);
- if (reference_index == -1) {
- NOTREACHED();
- return;
- }
-
+ // Find the index of |reference| in |children_|.
+ auto reference_it =
+ std::find_if(children_.begin(), children_.end(),
+ [reference](const scoped_refptr<Layer>& layer) {
+ return layer.get() == reference;
+ });
+ DCHECK(reference_it != children_.end());
+ size_t reference_index = reference_it - children_.begin();
reference->RemoveFromParent();
if (new_layer.get()) {
@@ -350,14 +344,6 @@ void Layer::ReplaceChild(Layer* reference, scoped_refptr<Layer> new_layer) {
}
}
-int Layer::IndexOfChild(const Layer* reference) {
- for (size_t i = 0; i < children_.size(); ++i) {
- if (children_[i].get() == reference)
- return i;
- }
- return -1;
-}
-
void Layer::SetBounds(const gfx::Size& size) {
DCHECK(IsPropertyChangeAllowed());
if (bounds() == size)
@@ -415,7 +401,7 @@ bool Layer::HasAncestor(const Layer* ancestor) const {
void Layer::RequestCopyOfOutput(
scoped_ptr<CopyOutputRequest> request) {
DCHECK(IsPropertyChangeAllowed());
- int size = copy_requests_.size();
+ bool had_no_copy_requests = copy_requests_.empty();
if (void* source = request->source()) {
auto it = std::find_if(
copy_requests_.begin(), copy_requests_.end(),
@@ -426,7 +412,7 @@ void Layer::RequestCopyOfOutput(
if (request->IsEmpty())
return;
copy_requests_.push_back(request.Pass());
- if (size == 0) {
+ if (had_no_copy_requests) {
bool copy_request_added = true;
UpdateNumCopyRequestsForSubtree(copy_request_added);
}
@@ -470,17 +456,6 @@ SkColor Layer::SafeOpaqueBackgroundColor() const {
return color;
}
-void Layer::CalculateContentsScale(float ideal_contents_scale,
- float* contents_scale_x,
- float* contents_scale_y,
- gfx::Size* content_bounds) {
- DCHECK(layer_tree_host_);
-
- *contents_scale_x = 1;
- *contents_scale_y = 1;
- *content_bounds = bounds();
-}
-
void Layer::SetMasksToBounds(bool masks_to_bounds) {
DCHECK(IsPropertyChangeAllowed());
if (masks_to_bounds_ == masks_to_bounds)
@@ -533,7 +508,11 @@ void Layer::SetFilters(const FilterOperations& filters) {
}
bool Layer::FilterIsAnimating() const {
- return layer_animation_controller_->IsAnimatingProperty(Animation::FILTER);
+ DCHECK(layer_tree_host_);
+ return layer_animation_controller_
+ ? layer_animation_controller_->IsAnimatingProperty(
+ Animation::FILTER)
+ : layer_tree_host_->IsAnimatingFilterProperty(this);
}
void Layer::SetBackgroundFilters(const FilterOperations& filters) {
@@ -553,7 +532,24 @@ void Layer::SetOpacity(float opacity) {
}
bool Layer::OpacityIsAnimating() const {
- return layer_animation_controller_->IsAnimatingProperty(Animation::OPACITY);
+ DCHECK(layer_tree_host_);
+ return layer_animation_controller_
+ ? layer_animation_controller_->IsAnimatingProperty(
+ Animation::OPACITY)
+ : layer_tree_host_->IsAnimatingOpacityProperty(this);
+}
+
+bool Layer::HasPotentiallyRunningOpacityAnimation() const {
+ if (layer_animation_controller_) {
+ if (Animation* animation =
+ layer_animation_controller()->GetAnimation(Animation::OPACITY)) {
+ return !animation->is_finished();
+ }
+ return false;
+ } else {
+ DCHECK(layer_tree_host_);
+ return layer_tree_host_->HasPotentiallyRunningOpacityAnimation(this);
+ }
}
bool Layer::OpacityCanAnimateOnImplThread() const {
@@ -737,11 +733,39 @@ void Layer::SetTransformOrigin(const gfx::Point3F& transform_origin) {
}
bool Layer::AnimationsPreserveAxisAlignment() const {
- return layer_animation_controller_->AnimationsPreserveAxisAlignment();
+ DCHECK(layer_tree_host_);
+ return layer_animation_controller_
+ ? layer_animation_controller_->AnimationsPreserveAxisAlignment()
+ : layer_tree_host_->AnimationsPreserveAxisAlignment(this);
}
bool Layer::TransformIsAnimating() const {
- return layer_animation_controller_->IsAnimatingProperty(Animation::TRANSFORM);
+ DCHECK(layer_tree_host_);
+ return layer_animation_controller_
+ ? layer_animation_controller_->IsAnimatingProperty(
+ Animation::TRANSFORM)
+ : layer_tree_host_->IsAnimatingTransformProperty(this);
+}
+
+bool Layer::HasPotentiallyRunningTransformAnimation() const {
+ if (layer_animation_controller_) {
+ if (Animation* animation =
+ layer_animation_controller()->GetAnimation(Animation::TRANSFORM)) {
+ return !animation->is_finished();
+ }
+ return false;
+ } else {
+ DCHECK(layer_tree_host_);
+ return layer_tree_host_->HasPotentiallyRunningTransformAnimation(this);
+ }
+}
+
+bool Layer::ScrollOffsetAnimationWasInterrupted() const {
+ DCHECK(layer_tree_host_);
+ return layer_animation_controller_
+ ? layer_animation_controller_
+ ->scroll_offset_animation_was_interrupted()
+ : layer_tree_host_->ScrollOffsetAnimationWasInterrupted(this);
}
void Layer::SetScrollParent(Layer* parent) {
@@ -764,6 +788,10 @@ void Layer::AddScrollChild(Layer* child) {
if (!scroll_children_)
scroll_children_.reset(new std::set<Layer*>);
scroll_children_->insert(child);
+ if (layer_tree_host_ && !layer_tree_host_->needs_meta_info_recomputation()) {
+ num_children_with_scroll_parent_++;
+ draw_properties().has_child_with_a_scroll_parent = true;
+ }
SetNeedsCommit();
}
@@ -771,6 +799,12 @@ void Layer::RemoveScrollChild(Layer* child) {
scroll_children_->erase(child);
if (scroll_children_->empty())
scroll_children_ = nullptr;
+ if (layer_tree_host_ && !layer_tree_host_->needs_meta_info_recomputation()) {
+ num_children_with_scroll_parent_--;
+ DCHECK_GE(num_children_with_scroll_parent_, 0);
+ draw_properties().has_child_with_a_scroll_parent =
+ (num_children_with_scroll_parent_ != 0);
+ }
SetNeedsCommit();
}
@@ -820,8 +854,7 @@ void Layer::SetScrollOffset(const gfx::ScrollOffset& scroll_offset) {
layer_tree_host_->property_trees()->transform_tree.Node(
transform_tree_index())) {
if (transform_node->owner_id == id()) {
- transform_node->data.scroll_offset =
- gfx::ScrollOffsetToVector2dF(CurrentScrollOffset());
+ transform_node->data.scroll_offset = CurrentScrollOffset();
transform_node->data.needs_local_transform_update = true;
layer_tree_host_->property_trees()->transform_tree.set_needs_update(true);
SetNeedsCommitNoRebuild();
@@ -860,8 +893,7 @@ void Layer::SetScrollOffsetFromImplSide(
layer_tree_host_->property_trees()->transform_tree.Node(
transform_tree_index())) {
if (transform_node->owner_id == id()) {
- transform_node->data.scroll_offset =
- gfx::ScrollOffsetToVector2dF(CurrentScrollOffset());
+ transform_node->data.scroll_offset = CurrentScrollOffset();
transform_node->data.needs_local_transform_update = true;
layer_tree_host_->property_trees()->transform_tree.set_needs_update(true);
needs_rebuild = false;
@@ -1146,25 +1178,19 @@ void Layer::PushPropertiesTo(LayerImpl* layer) {
layer->SetBounds(use_paint_properties ? paint_properties_.bounds
: bounds_);
- // TODO(enne): This is needed because CDP does this. Once main thread CDP
- // goes away, content scale / bounds can be removed.
- if (layer_tree_host()->settings().impl_side_painting) {
- layer->SetContentsScale(1.f, 1.f);
- layer->SetContentBounds(bounds());
- } else {
- layer->SetContentBounds(content_bounds());
- layer->SetContentsScale(contents_scale_x(), contents_scale_y());
- }
-
if (frame_viewer_instrumentation::IsTracingLayerTreeSnapshots())
layer->SetDebugInfo(TakeDebugInfo());
+ layer->SetTransformTreeIndex(transform_tree_index());
+ layer->SetOpacityTreeIndex(opacity_tree_index());
+ layer->SetClipTreeIndex(clip_tree_index());
+ layer->set_offset_to_transform_parent(offset_to_transform_parent_);
layer->SetDoubleSided(double_sided_);
layer->SetDrawCheckerboardForMissingTiles(
draw_checkerboard_for_missing_tiles_);
layer->SetDrawsContent(DrawsContent());
layer->SetHideLayerAndSubtree(hide_layer_and_subtree_);
- layer->SetHasRenderSurface(has_render_surface_ || layer->HasCopyRequest());
+ layer->SetHasRenderSurface(has_render_surface_);
if (!layer->FilterIsAnimatingOnImplOnly() && !FilterIsAnimating())
layer->SetFilters(filters_);
DCHECK(!(FilterIsAnimating() && layer->FilterIsAnimatingOnImplOnly()));
@@ -1195,10 +1221,6 @@ void Layer::PushPropertiesTo(LayerImpl* layer) {
DCHECK(!(TransformIsAnimating() && layer->TransformIsAnimatingOnImplOnly()));
layer->Set3dSortingContextId(sorting_context_id_);
layer->SetNumDescendantsThatDrawContent(num_descendants_that_draw_content_);
- layer->SetTransformTreeIndex(transform_tree_index());
- layer->SetOpacityTreeIndex(opacity_tree_index());
- layer->SetClipTreeIndex(clip_tree_index());
- layer->set_offset_to_transform_parent(offset_to_transform_parent_);
layer->SetScrollClipLayer(scroll_clip_layer_id_);
layer->set_user_scrollable_horizontal(user_scrollable_horizontal_);
@@ -1253,14 +1275,14 @@ void Layer::PushPropertiesTo(LayerImpl* layer) {
// the pending tree will clobber any impl-side scrolling occuring on the
// active tree. To do so, avoid scrolling the pending tree along with it
// instead of trying to undo that scrolling later.
- if (layer_animation_controller_->scroll_offset_animation_was_interrupted())
+ if (ScrollOffsetAnimationWasInterrupted())
layer->PushScrollOffsetFromMainThreadAndClobberActiveValue(scroll_offset_);
else
layer->PushScrollOffsetFromMainThread(scroll_offset_);
layer->SetScrollCompensationAdjustment(ScrollCompensationAdjustment());
// Wrap the copy_requests_ in a PostTask to the main thread.
- int size = copy_requests_.size();
+ bool had_copy_requests = !copy_requests_.empty();
ScopedPtrVector<CopyOutputRequest> main_thread_copy_requests;
for (ScopedPtrVector<CopyOutputRequest>::iterator it = copy_requests_.begin();
it != copy_requests_.end();
@@ -1279,7 +1301,7 @@ void Layer::PushPropertiesTo(LayerImpl* layer) {
}
if (!copy_requests_.empty() && layer_tree_host_)
layer_tree_host_->property_trees()->needs_rebuild = true;
- if (size != 0)
+ if (had_copy_requests)
UpdateNumCopyRequestsForSubtree(false);
copy_requests_.clear();
layer->PassCopyRequests(&main_thread_copy_requests);
@@ -1293,14 +1315,20 @@ void Layer::PushPropertiesTo(LayerImpl* layer) {
layer->SetStackingOrderChanged(stacking_order_changed_);
- layer_animation_controller_->PushAnimationUpdatesTo(
- layer->layer_animation_controller());
+ if (layer->layer_animation_controller() && layer_animation_controller_)
+ layer_animation_controller_->PushAnimationUpdatesTo(
+ layer->layer_animation_controller());
if (frame_timing_requests_dirty_) {
- layer->PassFrameTimingRequests(&frame_timing_requests_);
+ layer->SetFrameTimingRequests(frame_timing_requests_);
frame_timing_requests_dirty_ = false;
}
+ bool is_page_scale_layer = this == layer_tree_host()->page_scale_layer();
+ bool parent_affected =
+ layer->parent() && layer->parent()->IsAffectedByPageScale();
+ layer->SetIsAffectedByPageScale(is_page_scale_layer || parent_affected);
+
// Reset any state that should be cleared for the next update.
stacking_order_changed_ = false;
update_rect_ = gfx::Rect();
@@ -1357,8 +1385,7 @@ void Layer::SavePaintProperties() {
layer_tree_host_->source_frame_number();
}
-bool Layer::Update(ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion) {
+bool Layer::Update() {
DCHECK(layer_tree_host_);
DCHECK_EQ(layer_tree_host_->source_frame_number(),
paint_properties_.source_frame_number) <<
@@ -1423,8 +1450,10 @@ void Layer::OnOpacityAnimated(float opacity) {
if (OpacityNode* node =
layer_tree_host_->property_trees()->opacity_tree.Node(
opacity_tree_index())) {
- if (node->owner_id == id())
- node->data = opacity;
+ if (node->owner_id == id()) {
+ node->data.opacity = opacity;
+ layer_tree_host_->property_trees()->opacity_tree.set_needs_update(true);
+ }
}
}
}
@@ -1465,6 +1494,7 @@ bool Layer::IsActive() const {
}
bool Layer::AddAnimation(scoped_ptr <Animation> animation) {
+ DCHECK(layer_animation_controller_);
if (!layer_animation_controller_->animation_registrar())
return false;
@@ -1481,24 +1511,28 @@ bool Layer::AddAnimation(scoped_ptr <Animation> animation) {
}
void Layer::PauseAnimation(int animation_id, double time_offset) {
+ DCHECK(layer_animation_controller_);
layer_animation_controller_->PauseAnimation(
animation_id, base::TimeDelta::FromSecondsD(time_offset));
SetNeedsCommit();
}
void Layer::RemoveAnimation(int animation_id) {
+ DCHECK(layer_animation_controller_);
layer_animation_controller_->RemoveAnimation(animation_id);
SetNeedsCommit();
}
void Layer::RemoveAnimation(int animation_id,
Animation::TargetProperty property) {
+ DCHECK(layer_animation_controller_);
layer_animation_controller_->RemoveAnimation(animation_id, property);
SetNeedsCommit();
}
void Layer::SetLayerAnimationControllerForTest(
scoped_refptr<LayerAnimationController> controller) {
+ DCHECK(layer_animation_controller_);
layer_animation_controller_->RemoveValueObserver(this);
layer_animation_controller_ = controller;
layer_animation_controller_->AddValueObserver(this);
@@ -1506,25 +1540,29 @@ void Layer::SetLayerAnimationControllerForTest(
}
bool Layer::HasActiveAnimation() const {
- return layer_animation_controller_->HasActiveAnimation();
+ DCHECK(layer_tree_host_);
+ return layer_animation_controller_
+ ? layer_animation_controller_->HasActiveAnimation()
+ : layer_tree_host_->HasActiveAnimation(this);
+}
+
+void Layer::RegisterForAnimations(AnimationRegistrar* registrar) {
+ if (layer_animation_controller_)
+ layer_animation_controller_->SetAnimationRegistrar(registrar);
}
void Layer::AddLayerAnimationEventObserver(
LayerAnimationEventObserver* animation_observer) {
+ DCHECK(layer_animation_controller_);
layer_animation_controller_->AddEventObserver(animation_observer);
}
void Layer::RemoveLayerAnimationEventObserver(
LayerAnimationEventObserver* animation_observer) {
+ DCHECK(layer_animation_controller_);
layer_animation_controller_->RemoveEventObserver(animation_observer);
}
-SimpleEnclosedRegion Layer::VisibleContentOpaqueRegion() const {
- if (contents_opaque())
- return SimpleEnclosedRegion(visible_content_rect());
- return SimpleEnclosedRegion();
-}
-
ScrollbarLayerInterface* Layer::ToScrollbarLayer() {
return nullptr;
}
@@ -1576,6 +1614,9 @@ bool Layer::HasDelegatedContent() const {
void Layer::SetFrameTimingRequests(
const std::vector<FrameTimingRequest>& requests) {
+ // TODO(vmpstr): Early out if there are no changes earlier in the call stack.
+ if (requests == frame_timing_requests_)
+ return;
frame_timing_requests_ = requests;
frame_timing_requests_dirty_ = true;
SetNeedsCommit();
@@ -1589,4 +1630,39 @@ void Layer::DidBeginTracing() {
SetNeedsPushProperties();
}
+void Layer::set_visited(bool visited) {
+ visited_tracker_ =
+ visited ? layer_tree_host()->meta_information_sequence_number() : 0;
+}
+
+bool Layer::visited() {
+ return visited_tracker_ ==
+ layer_tree_host()->meta_information_sequence_number();
+}
+
+void Layer::set_layer_or_descendant_is_drawn(
+ bool layer_or_descendant_is_drawn) {
+ layer_or_descendant_is_drawn_tracker_ =
+ layer_or_descendant_is_drawn
+ ? layer_tree_host()->meta_information_sequence_number()
+ : 0;
+}
+
+bool Layer::layer_or_descendant_is_drawn() {
+ return layer_or_descendant_is_drawn_tracker_ ==
+ layer_tree_host()->meta_information_sequence_number();
+}
+
+void Layer::set_sorted_for_recursion(bool sorted_for_recursion) {
+ sorted_for_recursion_tracker_ =
+ sorted_for_recursion
+ ? layer_tree_host()->meta_information_sequence_number()
+ : 0;
+}
+
+bool Layer::sorted_for_recursion() {
+ return sorted_for_recursion_tracker_ ==
+ layer_tree_host()->meta_information_sequence_number();
+}
+
} // namespace cc
diff --git a/chromium/cc/layers/layer.h b/chromium/cc/layers/layer.h
index 2e4f172292f..3ff2810c9d6 100644
--- a/chromium/cc/layers/layer.h
+++ b/chromium/cc/layers/layer.h
@@ -58,17 +58,16 @@ class CopyOutputRequest;
class LayerAnimationEventObserver;
class LayerClient;
class LayerImpl;
+class LayerSettings;
class LayerTreeHost;
class LayerTreeHostCommon;
class LayerTreeImpl;
-class PriorityCalculator;
+class LayerTreeSettings;
class RenderingStatsInstrumentation;
class ResourceUpdateQueue;
class ScrollbarLayerInterface;
class SimpleEnclosedRegion;
struct AnimationEvent;
-template <typename LayerType>
-class OcclusionTracker;
// Base class for composited layers. Special layer types are derived from
// this class.
@@ -84,7 +83,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
INVALID_ID = -1,
};
- static scoped_refptr<Layer> Create();
+ static scoped_refptr<Layer> Create(const LayerSettings& settings);
int id() const { return layer_id_; }
@@ -136,6 +135,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
void SetOpacity(float opacity);
float opacity() const { return opacity_; }
bool OpacityIsAnimating() const;
+ bool HasPotentiallyRunningOpacityAnimation() const;
virtual bool OpacityCanAnimateOnImplThread() const;
void SetBlendMode(SkXfermode::Mode blend_mode);
@@ -172,6 +172,8 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
void SetPosition(const gfx::PointF& position);
gfx::PointF position() const { return position_; }
+ // A layer that is a container for fixed position layers cannot be both
+ // scrollable and have a non-identity transform.
void SetIsContainerForFixedPositionLayers(bool container);
bool IsContainerForFixedPositionLayers() const;
@@ -187,12 +189,15 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
void SetTransform(const gfx::Transform& transform);
const gfx::Transform& transform() const { return transform_; }
bool TransformIsAnimating() const;
+ bool HasPotentiallyRunningTransformAnimation() const;
bool AnimationsPreserveAxisAlignment() const;
bool transform_is_invertible() const { return transform_is_invertible_; }
void SetTransformOrigin(const gfx::Point3F&);
gfx::Point3F transform_origin() const { return transform_origin_; }
+ bool ScrollOffsetAnimationWasInterrupted() const;
+
void SetScrollParent(Layer* parent);
Layer* scroll_parent() { return scroll_parent_; }
@@ -252,8 +257,8 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
gfx::Rect drawable_content_rect() const {
return draw_properties_.drawable_content_rect;
}
- gfx::Rect visible_content_rect() const {
- return draw_properties_.visible_content_rect;
+ gfx::Rect visible_layer_rect() const {
+ return draw_properties_.visible_layer_rect;
}
Layer* render_target() {
DCHECK(!draw_properties_.render_target ||
@@ -265,7 +270,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
draw_properties_.render_target->render_surface());
return draw_properties_.render_target;
}
- int num_unclipped_descendants() const {
+ size_t num_unclipped_descendants() const {
return draw_properties_.num_unclipped_descendants;
}
@@ -372,9 +377,8 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
// This methods typically need to be overwritten by derived classes.
virtual void SavePaintProperties();
- // Returns true iff any resources were updated that need to be committed.
- virtual bool Update(ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion);
+ // Returns true iff anything was updated that needs to be committed.
+ virtual bool Update();
virtual bool NeedMoreUpdates();
virtual void SetIsMask(bool is_mask) {}
virtual void ReduceMemoryUsage() {}
@@ -393,53 +397,34 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
void ClearRenderSurfaceLayerList();
- // The contents scale converts from logical, non-page-scaled pixels to target
- // pixels. The contents scale is 1 for the root layer as it is already in
- // physical pixels. By default contents scale is forced to be 1 except for
- // subclasses of ContentsScalingLayer.
- float contents_scale_x() const { return draw_properties_.contents_scale_x; }
- float contents_scale_y() const { return draw_properties_.contents_scale_y; }
- gfx::Size content_bounds() const { return draw_properties_.content_bounds; }
-
- virtual void CalculateContentsScale(float ideal_contents_scale,
- float* contents_scale_x,
- float* contents_scale_y,
- gfx::Size* content_bounds);
-
LayerTreeHost* layer_tree_host() { return layer_tree_host_; }
const LayerTreeHost* layer_tree_host() const { return layer_tree_host_; }
- // Set the priority of all desired textures in this layer.
- virtual void SetTexturePriorities(const PriorityCalculator& priority_calc) {}
-
bool AddAnimation(scoped_ptr<Animation> animation);
void PauseAnimation(int animation_id, double time_offset);
void RemoveAnimation(int animation_id);
void RemoveAnimation(int animation_id, Animation::TargetProperty property);
-
- LayerAnimationController* layer_animation_controller() {
+ LayerAnimationController* layer_animation_controller() const {
return layer_animation_controller_.get();
}
void SetLayerAnimationControllerForTest(
scoped_refptr<LayerAnimationController> controller);
void set_layer_animation_delegate(AnimationDelegate* delegate) {
+ DCHECK(layer_animation_controller_);
layer_animation_controller_->set_layer_animation_delegate(delegate);
}
bool HasActiveAnimation() const;
+ void RegisterForAnimations(AnimationRegistrar* registrar);
void AddLayerAnimationEventObserver(
LayerAnimationEventObserver* animation_observer);
void RemoveLayerAnimationEventObserver(
LayerAnimationEventObserver* animation_observer);
- virtual SimpleEnclosedRegion VisibleContentOpaqueRegion() const;
-
virtual ScrollbarLayerInterface* ToScrollbarLayer();
- gfx::Rect LayerRectToContentRect(const gfx::Rect& layer_rect) const;
-
virtual skia::RefPtr<SkPicture> GetPicture() const;
// Constructs a LayerImpl of the correct runtime type for this Layer type.
@@ -454,14 +439,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
return paint_properties_;
}
- // The scale at which contents should be rastered, to match the scale at
- // which they will drawn to the screen. This scale is a component of the
- // contents scale but does not include page/device scale factors.
- // TODO(danakj): This goes away when TiledLayer goes away.
- void set_raster_scale(float scale) { raster_scale_ = scale; }
- float raster_scale() const { return raster_scale_; }
- bool raster_scale_is_unknown() const { return raster_scale_ == 0.f; }
-
void SetNeedsPushProperties();
bool needs_push_properties() const { return needs_push_properties_; }
bool descendant_needs_push_properties() const {
@@ -559,12 +536,28 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
return num_layer_or_descendants_with_input_handler_;
}
+ void set_num_children_with_scroll_parent(
+ int num_children_with_scroll_parent) {
+ num_children_with_scroll_parent_ = num_children_with_scroll_parent;
+ }
+
+ int num_children_with_scroll_parent() {
+ return num_children_with_scroll_parent_;
+ }
+
+ void set_visited(bool visited);
+ bool visited();
+ void set_layer_or_descendant_is_drawn(bool layer_or_descendant_is_drawn);
+ bool layer_or_descendant_is_drawn();
+ void set_sorted_for_recursion(bool sorted_for_recursion);
+ bool sorted_for_recursion();
+
protected:
friend class LayerImpl;
friend class TreeSynchronizer;
~Layer() override;
- Layer();
+ explicit Layer(const LayerSettings& settings);
// These SetNeeds functions are in order of severity of update:
//
@@ -604,8 +597,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
bool IsPropertyChangeAllowed() const;
- void reset_raster_scale_to_unknown() { raster_scale_ = 0.f; }
-
// This flag is set when the layer needs to push properties to the impl
// side.
bool needs_push_properties_;
@@ -649,9 +640,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
// trigger a Commit.
void SetHasRenderSurface(bool has_render_surface);
- // Returns the index of the child or -1 if not found.
- int IndexOfChild(const Layer* reference);
-
// This should only be called from RemoveFromParent().
void RemoveChildOrDependent(Layer* child);
@@ -707,6 +695,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
int property_tree_sequence_number_;
int num_layer_or_descendants_with_copy_request_;
int num_layer_or_descendants_with_input_handler_;
+ int num_children_with_scroll_parent_;
gfx::Vector2dF offset_to_transform_parent_;
bool should_flatten_transform_from_property_tree_ : 1;
bool should_scroll_on_main_thread_ : 1;
@@ -741,6 +730,14 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
Layer* scroll_parent_;
scoped_ptr<std::set<Layer*>> scroll_children_;
+ // The following three variables are tracker variables. They are bools
+ // wrapped inside an integer variable. If true, their value equals the
+ // LayerTreeHost's meta_information_sequence_number. This wrapping of bools
+ // inside ints is done to avoid a layer tree treewalk to reset their values.
+ int layer_or_descendant_is_drawn_tracker_;
+ int sorted_for_recursion_tracker_;
+ int visited_tracker_;
+
Layer* clip_parent_;
scoped_ptr<std::set<Layer*>> clip_children_;
@@ -750,9 +747,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
// Replica layer used for reflections.
scoped_refptr<Layer> replica_layer_;
- // Transient properties.
- float raster_scale_;
-
LayerClient* client_;
ScopedPtrVector<CopyOutputRequest> copy_requests_;
diff --git a/chromium/cc/layers/layer_impl.cc b/chromium/cc/layers/layer_impl.cc
index 8b3467a9128..588c8ac4d90 100644
--- a/chromium/cc/layers/layer_impl.cc
+++ b/chromium/cc/layers/layer_impl.cc
@@ -5,6 +5,7 @@
#include "cc/layers/layer_impl.h"
#include "base/json/json_reader.h"
+#include "base/numerics/safe_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"
@@ -69,6 +70,7 @@ LayerImpl::LayerImpl(LayerTreeImpl* tree_impl,
hide_layer_and_subtree_(false),
transform_is_invertible_(true),
is_container_for_fixed_position_layers_(false),
+ is_affected_by_page_scale_(true),
background_color_(0),
opacity_(1.0),
blend_mode_(SkXfermode::kSrcOver_Mode),
@@ -81,17 +83,23 @@ LayerImpl::LayerImpl(LayerTreeImpl* tree_impl,
num_dependents_need_push_properties_(0),
sorting_context_id_(0),
current_draw_mode_(DRAW_MODE_NONE),
- frame_timing_requests_dirty_(false) {
+ frame_timing_requests_dirty_(false),
+ visited_(false),
+ layer_or_descendant_is_drawn_(false),
+ sorted_for_recursion_(false) {
DCHECK_GT(layer_id_, 0);
DCHECK(layer_tree_impl_);
layer_tree_impl_->RegisterLayer(this);
- AnimationRegistrar* registrar = layer_tree_impl_->GetAnimationRegistrar();
- layer_animation_controller_ =
- registrar->GetAnimationControllerForId(layer_id_);
- layer_animation_controller_->AddValueObserver(this);
- if (IsActive()) {
- layer_animation_controller_->set_value_provider(this);
- layer_animation_controller_->set_layer_animation_delegate(this);
+
+ if (!layer_tree_impl_->settings().use_compositor_animation_timelines) {
+ AnimationRegistrar* registrar = layer_tree_impl_->GetAnimationRegistrar();
+ layer_animation_controller_ =
+ registrar->GetAnimationControllerForId(layer_id_);
+ layer_animation_controller_->AddValueObserver(this);
+ if (IsActive()) {
+ layer_animation_controller_->set_value_provider(this);
+ layer_animation_controller_->set_layer_animation_delegate(this);
+ }
}
SetNeedsPushProperties();
}
@@ -99,9 +107,11 @@ LayerImpl::LayerImpl(LayerTreeImpl* tree_impl,
LayerImpl::~LayerImpl() {
DCHECK_EQ(DRAW_MODE_NONE, current_draw_mode_);
- layer_animation_controller_->RemoveValueObserver(this);
- layer_animation_controller_->remove_value_provider(this);
- layer_animation_controller_->remove_layer_animation_delegate(this);
+ if (layer_animation_controller_) {
+ layer_animation_controller_->RemoveValueObserver(this);
+ layer_animation_controller_->remove_value_provider(this);
+ layer_animation_controller_->remove_layer_animation_delegate(this);
+ }
if (!copy_requests_.empty() && layer_tree_impl_->IsActiveTree())
layer_tree_impl()->RemoveLayerWithCopyOutputRequest(this);
@@ -224,8 +234,19 @@ void LayerImpl::SetOpacityTreeIndex(int index) {
}
void LayerImpl::PassCopyRequests(ScopedPtrVector<CopyOutputRequest>* requests) {
+ // In the case that a layer still has a copy request, this means that there's
+ // a commit to the active tree without a draw. This only happens in some
+ // edge cases during lost context or visibility changes, so don't try to
+ // handle preserving these output requests (and their surface).
+ if (!copy_requests_.empty()) {
+ layer_tree_impl()->RemoveLayerWithCopyOutputRequest(this);
+ // Destroying these will abort them.
+ copy_requests_.clear();
+ }
+
if (requests->empty())
return;
+
DCHECK(render_surface());
bool was_empty = copy_requests_.empty();
copy_requests_.insert_and_take(copy_requests_.end(), requests);
@@ -252,10 +273,9 @@ void LayerImpl::TakeCopyRequestsAndTransformToTarget(
continue;
gfx::Rect request_in_layer_space = request->area();
- gfx::Rect request_in_content_space =
- LayerRectToContentRect(request_in_layer_space);
+ request_in_layer_space.Intersect(gfx::Rect(bounds()));
request->set_area(MathUtil::MapEnclosingClippedRect(
- draw_properties_.target_space_transform, request_in_content_space));
+ draw_properties_.target_space_transform, request_in_layer_space));
}
layer_tree_impl()->RemoveLayerWithCopyOutputRequest(this);
@@ -268,11 +288,10 @@ void LayerImpl::ClearRenderSurfaceLayerList() {
}
void LayerImpl::PopulateSharedQuadState(SharedQuadState* state) const {
- state->SetAll(
- draw_properties_.target_space_transform, draw_properties_.content_bounds,
- draw_properties_.visible_content_rect, draw_properties_.clip_rect,
- draw_properties_.is_clipped, draw_properties_.opacity,
- draw_properties_.blend_mode, sorting_context_id_);
+ state->SetAll(draw_properties_.target_space_transform, bounds(),
+ draw_properties_.visible_layer_rect, draw_properties_.clip_rect,
+ draw_properties_.is_clipped, draw_properties_.opacity,
+ draw_properties_.blend_mode, sorting_context_id_);
}
void LayerImpl::PopulateScaledSharedQuadState(SharedQuadState* state,
@@ -280,16 +299,15 @@ void LayerImpl::PopulateScaledSharedQuadState(SharedQuadState* state,
gfx::Transform scaled_draw_transform =
draw_properties_.target_space_transform;
scaled_draw_transform.Scale(SK_MScalar1 / scale, SK_MScalar1 / scale);
- gfx::Size scaled_content_bounds =
- gfx::ToCeiledSize(gfx::ScaleSize(bounds(), scale));
- gfx::Rect scaled_visible_content_rect =
- gfx::ScaleToEnclosingRect(visible_content_rect(), scale);
- scaled_visible_content_rect.Intersect(gfx::Rect(scaled_content_bounds));
+ gfx::Size scaled_bounds = gfx::ToCeiledSize(gfx::ScaleSize(bounds(), scale));
+ gfx::Rect scaled_visible_layer_rect =
+ gfx::ScaleToEnclosingRect(visible_layer_rect(), scale);
+ scaled_visible_layer_rect.Intersect(gfx::Rect(scaled_bounds));
- state->SetAll(scaled_draw_transform, scaled_content_bounds,
- scaled_visible_content_rect, draw_properties().clip_rect,
- draw_properties().is_clipped, draw_properties().opacity,
- draw_properties().blend_mode, sorting_context_id_);
+ state->SetAll(scaled_draw_transform, scaled_bounds, scaled_visible_layer_rect,
+ draw_properties().clip_rect, draw_properties().is_clipped,
+ draw_properties().opacity, draw_properties().blend_mode,
+ sorting_context_id_);
}
bool LayerImpl::WillDraw(DrawMode draw_mode,
@@ -329,22 +347,18 @@ void LayerImpl::GetDebugBorderProperties(SkColor* color, float* width) const {
void LayerImpl::AppendDebugBorderQuad(
RenderPass* render_pass,
- const gfx::Size& content_bounds,
+ const gfx::Size& bounds,
const SharedQuadState* shared_quad_state,
AppendQuadsData* append_quads_data) const {
SkColor color;
float width;
GetDebugBorderProperties(&color, &width);
- AppendDebugBorderQuad(render_pass,
- content_bounds,
- shared_quad_state,
- append_quads_data,
- color,
- width);
+ AppendDebugBorderQuad(render_pass, bounds, shared_quad_state,
+ append_quads_data, color, width);
}
void LayerImpl::AppendDebugBorderQuad(RenderPass* render_pass,
- const gfx::Size& content_bounds,
+ const gfx::Size& bounds,
const SharedQuadState* shared_quad_state,
AppendQuadsData* append_quads_data,
SkColor color,
@@ -352,7 +366,7 @@ void LayerImpl::AppendDebugBorderQuad(RenderPass* render_pass,
if (!ShowDebugBorders())
return;
- gfx::Rect quad_rect(content_bounds);
+ gfx::Rect quad_rect(bounds);
gfx::Rect visible_quad_rect(quad_rect);
DebugBorderDrawQuad* debug_border_quad =
render_pass->CreateAndAppendDrawQuad<DebugBorderDrawQuad>();
@@ -394,7 +408,7 @@ RenderPassId LayerImpl::NextContributingRenderPassId(RenderPassId id) const {
return RenderPassId(0, 0);
}
-void LayerImpl::GetContentsResourceId(ResourceProvider::ResourceId* resource_id,
+void LayerImpl::GetContentsResourceId(ResourceId* resource_id,
gfx::Size* resource_size) const {
NOTREACHED();
*resource_id = 0;
@@ -402,12 +416,10 @@ void LayerImpl::GetContentsResourceId(ResourceProvider::ResourceId* resource_id,
gfx::Vector2dF LayerImpl::ScrollBy(const gfx::Vector2dF& scroll) {
gfx::ScrollOffset adjusted_scroll(scroll);
- if (layer_tree_impl()->settings().use_pinch_virtual_viewport) {
- if (!user_scrollable_horizontal_)
- adjusted_scroll.set_x(0);
- if (!user_scrollable_vertical_)
- adjusted_scroll.set_y(0);
- }
+ if (!user_scrollable_horizontal_)
+ adjusted_scroll.set_x(0);
+ if (!user_scrollable_vertical_)
+ adjusted_scroll.set_y(0);
DCHECK(scrollable());
gfx::ScrollOffset old_offset = CurrentScrollOffset();
gfx::ScrollOffset new_offset =
@@ -457,14 +469,8 @@ InputHandler::ScrollStatus LayerImpl::TryScroll(
// SCROLL_ON_MAIN_THREAD in this case?
}
- gfx::PointF hit_test_point_in_content_space =
- MathUtil::ProjectPoint(inverse_screen_space_transform,
- screen_space_point,
- &clipped);
- gfx::PointF hit_test_point_in_layer_space =
- gfx::ScalePoint(hit_test_point_in_content_space,
- 1.f / contents_scale_x(),
- 1.f / contents_scale_y());
+ gfx::PointF hit_test_point_in_layer_space = MathUtil::ProjectPoint(
+ inverse_screen_space_transform, screen_space_point, &clipped);
if (!clipped &&
non_fast_scrollable_region().Contains(
gfx::ToRoundedPoint(hit_test_point_in_layer_space))) {
@@ -502,16 +508,6 @@ InputHandler::ScrollStatus LayerImpl::TryScroll(
return InputHandler::SCROLL_STARTED;
}
-gfx::Rect LayerImpl::LayerRectToContentRect(
- const gfx::RectF& layer_rect) const {
- gfx::RectF content_rect =
- gfx::ScaleRect(layer_rect, contents_scale_x(), contents_scale_y());
- // Intersect with content rect to avoid the extra pixel because for some
- // values x and y, ceil((x / y) * y) may be x + 1.
- content_rect.Intersect(gfx::Rect(content_bounds()));
- return gfx::ToEnclosingRect(content_rect);
-}
-
skia::RefPtr<SkPicture> LayerImpl::GetPicture() {
return skia::RefPtr<SkPicture>();
}
@@ -524,14 +520,12 @@ void LayerImpl::PushPropertiesTo(LayerImpl* layer) {
layer->SetTransformOrigin(transform_origin_);
layer->SetBackgroundColor(background_color_);
layer->SetBounds(bounds_);
- layer->SetContentBounds(content_bounds());
- layer->SetContentsScale(contents_scale_x(), contents_scale_y());
layer->SetDoubleSided(double_sided_);
layer->SetDrawCheckerboardForMissingTiles(
draw_checkerboard_for_missing_tiles_);
layer->SetDrawsContent(DrawsContent());
layer->SetHideLayerAndSubtree(hide_layer_and_subtree_);
- layer->SetHasRenderSurface(!!render_surface() || layer->HasCopyRequest());
+ layer->SetHasRenderSurface(!!render_surface());
layer->SetFilters(filters());
layer->SetBackgroundFilters(background_filters());
layer->SetMasksToBounds(masks_to_bounds_);
@@ -626,7 +620,7 @@ void LayerImpl::PushPropertiesTo(LayerImpl* layer) {
layer->SetDebugInfo(debug_info_);
if (frame_timing_requests_dirty_) {
- layer->PassFrameTimingRequests(&frame_timing_requests_);
+ layer->SetFrameTimingRequests(frame_timing_requests_);
frame_timing_requests_dirty_ = false;
}
@@ -646,31 +640,12 @@ gfx::Vector2dF LayerImpl::FixedContainerSizeDelta() const {
// In virtual-viewport mode, we don't need to compensate for pinch zoom or
// scale since the fixed container is the outer viewport, which sits below
// the page scale.
- if (layer_tree_impl()->settings().use_pinch_virtual_viewport)
- return delta_from_scroll;
-
- float scale_delta = layer_tree_impl()->page_scale_delta();
- float scale = layer_tree_impl()->current_page_scale_factor() /
- layer_tree_impl()->page_scale_delta();
-
- delta_from_scroll.Scale(1.f / scale);
-
- // The delta-from-pinch component requires some explanation: A viewport of
- // size (w,h) will appear to be size (w/s,h/s) under scale s in the content
- // space. If s -> s' on the impl thread, where s' = s * ds, then the apparent
- // viewport size change in the content space due to ds is:
- //
- // (w/s',h/s') - (w/s,h/s) = (w,h)(1/s' - 1/s) = (w,h)(1 - ds)/(s ds)
- //
- gfx::Vector2dF delta_from_pinch =
- gfx::Rect(scroll_clip_layer_->bounds()).bottom_right() - gfx::PointF();
- delta_from_pinch.Scale((1.f - scale_delta) / (scale * scale_delta));
-
- return delta_from_scroll + delta_from_pinch;
+ return delta_from_scroll;
}
base::DictionaryValue* LayerImpl::LayerTreeAsJson() const {
base::DictionaryValue* result = new base::DictionaryValue;
+ result->SetInteger("LayerId", id());
result->SetString("LayerType", LayerTypeAsString());
base::ListValue* list = new base::ListValue;
@@ -761,20 +736,12 @@ void LayerImpl::NoteLayerPropertyChangedForDescendants() {
SetNeedsPushProperties();
}
-#if DCHECK_IS_ON()
-// Verify that the resource id is valid.
-static ResourceProvider::ResourceId ValidateResource(
- const ResourceProvider* provider,
- ResourceProvider::ResourceId id) {
- provider->ValidateResource(id);
- return id;
-}
-#endif
-
void LayerImpl::ValidateQuadResourcesInternal(DrawQuad* quad) const {
#if DCHECK_IS_ON()
- quad->IterateResources(
- base::Bind(&ValidateResource, layer_tree_impl_->resource_provider()));
+ const ResourceProvider* resource_provider =
+ layer_tree_impl_->resource_provider();
+ for (ResourceId resource_id : quad->resources)
+ resource_provider->ValidateResource(resource_id);
#endif
}
@@ -806,6 +773,46 @@ void LayerImpl::ResetAllChangeTrackingForSubtree() {
num_dependents_need_push_properties_ = 0;
}
+void LayerImpl::UpdatePropertyTreeTransform() {
+ if (transform_tree_index_ != -1) {
+ TransformTree& transform_tree =
+ layer_tree_impl()->property_trees()->transform_tree;
+ TransformNode* node = transform_tree.Node(transform_tree_index_);
+ if (node->data.local != transform_) {
+ node->data.local = transform_;
+ node->data.needs_local_transform_update = true;
+ transform_tree.set_needs_update(true);
+ // TODO(ajuma): The current criteria for creating clip nodes means that
+ // property trees may need to be rebuilt when the new transform isn't
+ // axis-aligned wrt the old transform (see Layer::SetTransform). Since
+ // rebuilding property trees every frame of a transform animation is
+ // something we should try to avoid, change property tree-building so that
+ // it doesn't depend on axis aliginment.
+ }
+ }
+}
+
+void LayerImpl::UpdatePropertyTreeOpacity() {
+ if (opacity_tree_index_ != -1) {
+ OpacityTree& opacity_tree =
+ layer_tree_impl()->property_trees()->opacity_tree;
+ OpacityNode* node = opacity_tree.Node(opacity_tree_index_);
+ node->data.opacity = opacity_;
+ opacity_tree.set_needs_update(true);
+ }
+}
+
+void LayerImpl::UpdatePropertyTreeForScrollingAndAnimationIfNeeded() {
+ if (scrollable())
+ UpdatePropertyTreeScrollOffset();
+
+ if (OpacityIsAnimating())
+ UpdatePropertyTreeOpacity();
+
+ if (TransformIsAnimating())
+ UpdatePropertyTreeTransform();
+}
+
gfx::ScrollOffset LayerImpl::ScrollOffsetForAnimation() const {
return CurrentScrollOffset();
}
@@ -816,10 +823,12 @@ void LayerImpl::OnFilterAnimated(const FilterOperations& filters) {
void LayerImpl::OnOpacityAnimated(float opacity) {
SetOpacity(opacity);
+ UpdatePropertyTreeOpacity();
}
void LayerImpl::OnTransformAnimated(const gfx::Transform& transform) {
SetTransform(transform);
+ UpdatePropertyTreeTransform();
}
void LayerImpl::OnScrollOffsetAnimated(const gfx::ScrollOffset& scroll_offset) {
@@ -865,16 +874,36 @@ void LayerImpl::SetBounds(const gfx::Size& bounds) {
}
void LayerImpl::SetBoundsDelta(const gfx::Vector2dF& bounds_delta) {
+ DCHECK(IsActive());
if (bounds_delta_ == bounds_delta)
return;
bounds_delta_ = bounds_delta;
+ TransformTree& transform_tree =
+ layer_tree_impl()->property_trees()->transform_tree;
+ if (this == layer_tree_impl()->InnerViewportContainerLayer())
+ transform_tree.SetInnerViewportBoundsDelta(bounds_delta);
+ else if (this == layer_tree_impl()->OuterViewportContainerLayer())
+ transform_tree.SetOuterViewportBoundsDelta(bounds_delta);
+
ScrollbarParametersDidChange(true);
- if (masks_to_bounds())
+
+ if (masks_to_bounds()) {
+ // If layer is clipping, then update the clip node using the new bounds.
+ ClipNode* clip_node =
+ layer_tree_impl()->property_trees()->clip_tree.Node(clip_tree_index());
+ if (clip_node) {
+ DCHECK(id() == clip_node->owner_id);
+ clip_node->data.clip =
+ gfx::RectF(gfx::PointF() + offset_to_transform_parent(), bounds());
+ layer_tree_impl()->property_trees()->clip_tree.set_needs_update(true);
+ }
+
NoteLayerPropertyChangedForSubtree();
- else
+ } else {
NoteLayerPropertyChanged();
+ }
}
void LayerImpl::SetMaskLayer(scoped_ptr<LayerImpl> mask_layer) {
@@ -984,10 +1013,16 @@ void LayerImpl::SetFilters(const FilterOperations& filters) {
}
bool LayerImpl::FilterIsAnimating() const {
- return layer_animation_controller_->IsAnimatingProperty(Animation::FILTER);
+ return layer_animation_controller_
+ ? layer_animation_controller_->IsAnimatingProperty(
+ Animation::FILTER)
+ : layer_tree_impl_->IsAnimatingFilterProperty(this);
}
bool LayerImpl::FilterIsAnimatingOnImplOnly() const {
+ if (!layer_animation_controller_)
+ return layer_tree_impl_->FilterIsAnimatingOnImplOnly(this);
+
Animation* filter_animation =
layer_animation_controller_->GetAnimation(Animation::FILTER);
return filter_animation && filter_animation->is_impl_only();
@@ -1027,10 +1062,28 @@ void LayerImpl::SetOpacity(float opacity) {
}
bool LayerImpl::OpacityIsAnimating() const {
- return layer_animation_controller_->IsAnimatingProperty(Animation::OPACITY);
+ return layer_animation_controller_
+ ? layer_animation_controller_->IsAnimatingProperty(
+ Animation::OPACITY)
+ : layer_tree_impl_->IsAnimatingOpacityProperty(this);
+}
+
+bool LayerImpl::HasPotentiallyRunningOpacityAnimation() const {
+ if (layer_animation_controller_) {
+ if (Animation* animation =
+ layer_animation_controller()->GetAnimation(Animation::OPACITY)) {
+ return !animation->is_finished();
+ }
+ return false;
+ } else {
+ return layer_tree_impl_->HasPotentiallyRunningOpacityAnimation(this);
+ }
}
bool LayerImpl::OpacityIsAnimatingOnImplOnly() const {
+ if (!layer_animation_controller_)
+ return layer_tree_impl_->OpacityIsAnimatingOnImplOnly(this);
+
Animation* opacity_animation =
layer_animation_controller_->GetAnimation(Animation::OPACITY);
return opacity_animation && opacity_animation->is_impl_only();
@@ -1075,9 +1128,9 @@ void LayerImpl::Set3dSortingContextId(int id) {
NoteLayerPropertyChangedForSubtree();
}
-void LayerImpl::PassFrameTimingRequests(
- std::vector<FrameTimingRequest>* requests) {
- frame_timing_requests_.swap(*requests);
+void LayerImpl::SetFrameTimingRequests(
+ const std::vector<FrameTimingRequest>& requests) {
+ frame_timing_requests_ = requests;
frame_timing_requests_dirty_ = true;
SetNeedsPushProperties();
}
@@ -1109,45 +1162,103 @@ void LayerImpl::SetTransformAndInvertibility(const gfx::Transform& transform,
}
bool LayerImpl::TransformIsAnimating() const {
- return layer_animation_controller_->IsAnimatingProperty(Animation::TRANSFORM);
+ return layer_animation_controller_
+ ? layer_animation_controller_->IsAnimatingProperty(
+ Animation::TRANSFORM)
+ : layer_tree_impl_->IsAnimatingTransformProperty(this);
+}
+
+bool LayerImpl::HasPotentiallyRunningTransformAnimation() const {
+ if (layer_animation_controller_) {
+ if (Animation* animation =
+ layer_animation_controller()->GetAnimation(Animation::TRANSFORM)) {
+ return !animation->is_finished();
+ }
+ return false;
+ } else {
+ return layer_tree_impl_->HasPotentiallyRunningTransformAnimation(this);
+ }
}
bool LayerImpl::TransformIsAnimatingOnImplOnly() const {
+ if (!layer_animation_controller_)
+ return layer_tree_impl_->TransformIsAnimatingOnImplOnly(this);
+
Animation* transform_animation =
layer_animation_controller_->GetAnimation(Animation::TRANSFORM);
return transform_animation && transform_animation->is_impl_only();
}
-void LayerImpl::SetUpdateRect(const gfx::Rect& update_rect) {
- update_rect_ = update_rect;
- SetNeedsPushProperties();
+bool LayerImpl::HasOnlyTranslationTransforms() const {
+ if (!layer_animation_controller_)
+ return layer_tree_impl_->HasOnlyTranslationTransforms(this);
+
+ return layer_animation_controller_->HasOnlyTranslationTransforms();
}
-void LayerImpl::AddDamageRect(const gfx::RectF& damage_rect) {
- damage_rect_ = gfx::UnionRects(damage_rect_, damage_rect);
+bool LayerImpl::MaximumTargetScale(float* max_scale) const {
+ if (!layer_animation_controller_)
+ return layer_tree_impl_->MaximumTargetScale(this, max_scale);
+
+ return layer_animation_controller_->MaximumTargetScale(max_scale);
}
-void LayerImpl::SetContentBounds(const gfx::Size& content_bounds) {
- if (this->content_bounds() == content_bounds)
- return;
+bool LayerImpl::AnimationStartScale(float* start_scale) const {
+ if (!layer_animation_controller_)
+ return layer_tree_impl_->AnimationStartScale(this, start_scale);
- draw_properties_.content_bounds = content_bounds;
- NoteLayerPropertyChanged();
+ return layer_animation_controller_->AnimationStartScale(start_scale);
}
-void LayerImpl::SetContentsScale(float contents_scale_x,
- float contents_scale_y) {
- if (this->contents_scale_x() == contents_scale_x &&
- this->contents_scale_y() == contents_scale_y)
- return;
+bool LayerImpl::HasFilterAnimationThatInflatesBounds() const {
+ if (!layer_animation_controller_)
+ return layer_tree_impl_->HasFilterAnimationThatInflatesBounds(this);
- draw_properties_.contents_scale_x = contents_scale_x;
- draw_properties_.contents_scale_y = contents_scale_y;
- NoteLayerPropertyChanged();
+ return layer_animation_controller_->HasFilterAnimationThatInflatesBounds();
+}
+
+bool LayerImpl::HasTransformAnimationThatInflatesBounds() const {
+ if (!layer_animation_controller_)
+ return layer_tree_impl_->HasTransformAnimationThatInflatesBounds(this);
+
+ return layer_animation_controller_->HasTransformAnimationThatInflatesBounds();
}
-bool LayerImpl::IsExternalFlingActive() const {
- return layer_tree_impl_->IsExternalFlingActive();
+bool LayerImpl::HasAnimationThatInflatesBounds() const {
+ if (!layer_animation_controller_)
+ return layer_tree_impl_->HasAnimationThatInflatesBounds(this);
+
+ return layer_animation_controller_->HasAnimationThatInflatesBounds();
+}
+
+bool LayerImpl::FilterAnimationBoundsForBox(const gfx::BoxF& box,
+ gfx::BoxF* bounds) const {
+ if (!layer_animation_controller_)
+ return layer_tree_impl_->FilterAnimationBoundsForBox(this, box, bounds);
+
+ return layer_animation_controller_->FilterAnimationBoundsForBox(box, bounds);
+}
+
+bool LayerImpl::TransformAnimationBoundsForBox(const gfx::BoxF& box,
+ gfx::BoxF* bounds) const {
+ if (!layer_animation_controller_)
+ return layer_tree_impl_->TransformAnimationBoundsForBox(this, box, bounds);
+
+ return layer_animation_controller_->TransformAnimationBoundsForBox(box,
+ bounds);
+}
+
+void LayerImpl::SetUpdateRect(const gfx::Rect& update_rect) {
+ update_rect_ = update_rect;
+ SetNeedsPushProperties();
+}
+
+void LayerImpl::AddDamageRect(const gfx::RectF& damage_rect) {
+ damage_rect_ = gfx::UnionRects(damage_rect_, damage_rect);
+}
+
+bool LayerImpl::IsExternalScrollActive() const {
+ return layer_tree_impl_->IsExternalScrollActive();
}
void LayerImpl::SetCurrentScrollOffset(const gfx::ScrollOffset& scroll_offset) {
@@ -1205,6 +1316,7 @@ gfx::Vector2dF LayerImpl::ScrollDelta() const {
void LayerImpl::SetScrollDelta(const gfx::Vector2dF& delta) {
DCHECK(IsActive());
+ DCHECK(scrollable() || delta.IsZero());
SetCurrentScrollOffset(scroll_offset_->ActiveBase() +
gfx::ScrollOffset(delta));
}
@@ -1231,16 +1343,37 @@ void LayerImpl::PushScrollOffset(const gfx::ScrollOffset* scroll_offset) {
DidUpdateScrollOffset(false);
}
+void LayerImpl::UpdatePropertyTreeScrollOffset() {
+ // TODO(enne): in the future, scrolling should update the scroll tree
+ // directly instead of going through layers.
+ if (transform_tree_index_ != -1) {
+ TransformTree& transform_tree =
+ layer_tree_impl()->property_trees()->transform_tree;
+ TransformNode* node = transform_tree.Node(transform_tree_index_);
+ gfx::ScrollOffset current_offset = scroll_offset_->Current(IsActive());
+ if (node->data.scroll_offset != current_offset) {
+ node->data.scroll_offset = current_offset;
+ node->data.needs_local_transform_update = true;
+ transform_tree.set_needs_update(true);
+ }
+ }
+}
+
void LayerImpl::DidUpdateScrollOffset(bool is_from_root_delegate) {
+ DCHECK(scroll_offset_);
+
if (!is_from_root_delegate)
layer_tree_impl()->DidUpdateScrollOffset(id());
NoteLayerPropertyChangedForSubtree();
ScrollbarParametersDidChange(false);
+
+ UpdatePropertyTreeScrollOffset();
+
// Inform the pending twin that a property changed.
if (layer_tree_impl()->IsActiveTree()) {
LayerImpl* pending_twin = layer_tree_impl()->FindPendingTreeLayerById(id());
if (pending_twin)
- pending_twin->NoteLayerPropertyChangedForSubtree();
+ pending_twin->DidUpdateScrollOffset(is_from_root_delegate);
}
}
@@ -1252,9 +1385,9 @@ void LayerImpl::SetDoubleSided(bool double_sided) {
NoteLayerPropertyChangedForSubtree();
}
-SimpleEnclosedRegion LayerImpl::VisibleContentOpaqueRegion() const {
+SimpleEnclosedRegion LayerImpl::VisibleOpaqueRegion() const {
if (contents_opaque())
- return SimpleEnclosedRegion(visible_content_rect());
+ return SimpleEnclosedRegion(visible_layer_rect());
return SimpleEnclosedRegion();
}
@@ -1362,7 +1495,7 @@ void LayerImpl::SetScrollbarPosition(ScrollbarLayerImplBase* scrollbar_layer,
scrollbar_needs_animation |=
scrollbar_layer->SetVisibleToTotalLengthRatio(visible_ratio);
if (y_offset_did_change && layer_tree_impl()->IsActiveTree() &&
- this == layer_tree_impl()->InnerViewportScrollLayer()) {
+ this == layer_tree_impl()->OuterViewportScrollLayer()) {
TRACE_COUNTER_ID1("cc", "scroll_offset_y", this->id(),
current_offset.y());
}
@@ -1496,7 +1629,8 @@ void LayerImpl::AsValueInto(base::trace_event::TracedValue* state) const {
MathUtil::AddToTracedValue("position", position_, state);
state->SetInteger("draws_content", DrawsContent());
- state->SetInteger("gpu_memory_usage", GPUMemoryUsageInBytes());
+ state->SetInteger("gpu_memory_usage",
+ base::saturated_cast<int>(GPUMemoryUsageInBytes()));
MathUtil::AddToTracedValue(
"scroll_offset", scroll_offset_ ? scroll_offset_->Current(IsActive())
@@ -1507,9 +1641,7 @@ void LayerImpl::AsValueInto(base::trace_event::TracedValue* state) const {
bool clipped;
gfx::QuadF layer_quad = MathUtil::MapQuad(
- screen_space_transform(),
- gfx::QuadF(gfx::Rect(content_bounds())),
- &clipped);
+ screen_space_transform(), gfx::QuadF(gfx::Rect(bounds())), &clipped);
MathUtil::AddToTracedValue("layer_quad", layer_quad, state);
if (!touch_event_handler_region_.IsEmpty()) {
state->BeginArray("touch_event_handler_region");
@@ -1517,14 +1649,14 @@ void LayerImpl::AsValueInto(base::trace_event::TracedValue* state) const {
state->EndArray();
}
if (have_wheel_event_handlers_) {
- gfx::Rect wheel_rect(content_bounds());
+ gfx::Rect wheel_rect(bounds());
Region wheel_region(wheel_rect);
state->BeginArray("wheel_event_handler_region");
wheel_region.AsValueInto(state);
state->EndArray();
}
if (have_scroll_event_handlers_) {
- gfx::Rect scroll_rect(content_bounds());
+ gfx::Rect scroll_rect(bounds());
Region scroll_region(scroll_rect);
state->BeginArray("scroll_event_handler_region");
scroll_region.AsValueInto(state);
@@ -1568,7 +1700,9 @@ void LayerImpl::AsValueInto(base::trace_event::TracedValue* state) const {
state->SetBoolean(
"has_animation_bounds",
- layer_animation_controller()->HasAnimationThatInflatesBounds());
+ layer_animation_controller_
+ ? layer_animation_controller_->HasAnimationThatInflatesBounds()
+ : layer_tree_impl_->HasAnimationThatInflatesBounds(this));
gfx::BoxF box;
if (LayerUtils::GetAnimationBounds(*this, &box))
@@ -1648,18 +1782,36 @@ Region LayerImpl::GetInvalidationRegion() {
gfx::Rect LayerImpl::GetEnclosingRectInTargetSpace() const {
return MathUtil::MapEnclosingClippedRect(
- draw_properties_.target_space_transform,
- gfx::Rect(draw_properties_.content_bounds));
+ draw_properties_.target_space_transform, gfx::Rect(bounds()));
}
gfx::Rect LayerImpl::GetScaledEnclosingRectInTargetSpace(float scale) const {
gfx::Transform scaled_draw_transform =
draw_properties_.target_space_transform;
scaled_draw_transform.Scale(SK_MScalar1 / scale, SK_MScalar1 / scale);
- gfx::Size scaled_content_bounds =
- gfx::ToCeiledSize(gfx::ScaleSize(content_bounds(), scale));
+ gfx::Size scaled_bounds = gfx::ToCeiledSize(gfx::ScaleSize(bounds(), scale));
return MathUtil::MapEnclosingClippedRect(scaled_draw_transform,
- gfx::Rect(scaled_content_bounds));
+ gfx::Rect(scaled_bounds));
+}
+
+float LayerImpl::GetIdealContentsScale() const {
+ float page_scale = IsAffectedByPageScale()
+ ? layer_tree_impl()->current_page_scale_factor()
+ : 1.f;
+ float device_scale = layer_tree_impl()->device_scale_factor();
+
+ float default_scale = page_scale * device_scale;
+ if (!layer_tree_impl()
+ ->settings()
+ .layer_transforms_should_scale_layer_contents) {
+ return default_scale;
+ }
+
+ // TODO(enne): the transform needs to come from property trees instead of
+ // draw properties.
+ gfx::Vector2dF transform_scales = MathUtil::ComputeTransform2dScaleComponents(
+ draw_properties().target_space_transform, default_scale);
+ return std::max(transform_scales.x(), transform_scales.y());
}
} // namespace cc
diff --git a/chromium/cc/layers/layer_impl.h b/chromium/cc/layers/layer_impl.h
index 08db87f1392..57a0be1204a 100644
--- a/chromium/cc/layers/layer_impl.h
+++ b/chromium/cc/layers/layer_impl.h
@@ -57,8 +57,6 @@ class LayerTreeHostImpl;
class LayerTreeImpl;
class MicroBenchmarkImpl;
class Occlusion;
-template <typename LayerType>
-class OcclusionTracker;
class OpacityTree;
class PrioritizedTile;
class RenderPass;
@@ -185,6 +183,10 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver,
return should_flatten_transform_from_property_tree_;
}
+ void UpdatePropertyTreeTransform();
+ void UpdatePropertyTreeOpacity();
+ void UpdatePropertyTreeScrollOffset();
+
// For compatibility with Layer.
bool has_render_surface() const { return !!render_surface(); }
@@ -250,7 +252,7 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver,
#endif
}
- virtual void GetContentsResourceId(ResourceProvider::ResourceId* resource_id,
+ virtual void GetContentsResourceId(ResourceId* resource_id,
gfx::Size* resource_size) const;
virtual bool HasDelegatedContent() const;
@@ -298,6 +300,7 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver,
void SetOpacity(float opacity);
float opacity() const { return opacity_; }
bool OpacityIsAnimating() const;
+ bool HasPotentiallyRunningOpacityAnimation() const;
bool OpacityIsAnimatingOnImplOnly() const;
void SetBlendMode(SkXfermode::Mode);
@@ -322,6 +325,11 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver,
return is_container_for_fixed_position_layers_;
}
+ bool IsAffectedByPageScale() const { return is_affected_by_page_scale_; }
+ void SetIsAffectedByPageScale(bool is_affected) {
+ is_affected_by_page_scale_ = is_affected;
+ }
+
gfx::Vector2dF FixedContainerSizeDelta() const;
void SetPositionConstraint(const LayerPositionConstraint& constraint) {
@@ -390,8 +398,8 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver,
gfx::Rect drawable_content_rect() const {
return draw_properties_.drawable_content_rect;
}
- gfx::Rect visible_content_rect() const {
- return draw_properties_.visible_content_rect;
+ gfx::Rect visible_layer_rect() const {
+ return draw_properties_.visible_layer_rect;
}
LayerImpl* render_target() {
DCHECK(!draw_properties_.render_target ||
@@ -404,7 +412,7 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver,
return draw_properties_.render_target;
}
- int num_unclipped_descendants() const {
+ size_t num_unclipped_descendants() const {
return draw_properties_.num_unclipped_descendants;
}
@@ -420,14 +428,7 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver,
void SetBoundsDelta(const gfx::Vector2dF& bounds_delta);
gfx::Vector2dF bounds_delta() const { return bounds_delta_; }
- void SetContentBounds(const gfx::Size& content_bounds);
- gfx::Size content_bounds() const { return draw_properties_.content_bounds; }
-
- float contents_scale_x() const { return draw_properties_.contents_scale_x; }
- float contents_scale_y() const { return draw_properties_.contents_scale_y; }
- void SetContentsScale(float contents_scale_x, float contents_scale_y);
-
- bool IsExternalFlingActive() const;
+ bool IsExternalScrollActive() const;
void SetCurrentScrollOffset(const gfx::ScrollOffset& scroll_offset);
void SetCurrentScrollOffsetFromDelegate(
@@ -535,11 +536,25 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver,
void SetTransform(const gfx::Transform& transform);
const gfx::Transform& transform() const { return transform_; }
bool TransformIsAnimating() const;
+ bool HasPotentiallyRunningTransformAnimation() const;
bool TransformIsAnimatingOnImplOnly() const;
+ bool HasOnlyTranslationTransforms() const;
void SetTransformAndInvertibility(const gfx::Transform& transform,
bool transform_is_invertible);
bool transform_is_invertible() const { return transform_is_invertible_; }
+ bool MaximumTargetScale(float* max_scale) const;
+ bool AnimationStartScale(float* start_scale) const;
+
+ bool HasFilterAnimationThatInflatesBounds() const;
+ bool HasTransformAnimationThatInflatesBounds() const;
+ bool HasAnimationThatInflatesBounds() const;
+
+ bool FilterAnimationBoundsForBox(const gfx::BoxF& box,
+ gfx::BoxF* bounds) const;
+ bool TransformAnimationBoundsForBox(const gfx::BoxF& box,
+ gfx::BoxF* bounds) const;
+
// Note this rect is in layer space (not content space).
void SetUpdateRect(const gfx::Rect& update_rect);
gfx::Rect update_rect() const { return update_rect_; }
@@ -564,7 +579,7 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver,
return layer_animation_controller_.get();
}
- virtual SimpleEnclosedRegion VisibleContentOpaqueRegion() const;
+ virtual SimpleEnclosedRegion VisibleOpaqueRegion() const;
virtual void DidBecomeActive();
@@ -593,8 +608,6 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver,
return scroll_clip_layer_ ? scroll_clip_layer_->bounds().height() : 0;
}
- gfx::Rect LayerRectToContentRect(const gfx::RectF& layer_rect) const;
-
virtual skia::RefPtr<SkPicture> GetPicture();
virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl);
@@ -628,8 +641,8 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver,
void Set3dSortingContextId(int id);
int sorting_context_id() { return sorting_context_id_; }
- void PassFrameTimingRequests(
- std::vector<FrameTimingRequest>* frame_timing_requests);
+ void SetFrameTimingRequests(
+ const std::vector<FrameTimingRequest>& frame_timing_requests);
const std::vector<FrameTimingRequest>& frame_timing_requests() const {
return frame_timing_requests_;
}
@@ -643,6 +656,26 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver,
virtual gfx::Rect GetEnclosingRectInTargetSpace() const;
+ void set_visited(bool visited) { visited_ = visited; }
+
+ bool visited() { return visited_; }
+
+ void set_layer_or_descendant_is_drawn(bool layer_or_descendant_is_drawn) {
+ layer_or_descendant_is_drawn_ = layer_or_descendant_is_drawn;
+ }
+
+ bool layer_or_descendant_is_drawn() { return layer_or_descendant_is_drawn_; }
+
+ void set_sorted_for_recursion(bool sorted_for_recursion) {
+ sorted_for_recursion_ = sorted_for_recursion;
+ }
+
+ bool sorted_for_recursion() { return sorted_for_recursion_; }
+
+ void UpdatePropertyTreeForScrollingAndAnimationIfNeeded();
+
+ float GetIdealContentsScale() const;
+
protected:
LayerImpl(LayerTreeImpl* layer_impl,
int id,
@@ -653,11 +686,11 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver,
virtual void GetDebugBorderProperties(SkColor* color, float* width) const;
void AppendDebugBorderQuad(RenderPass* render_pass,
- const gfx::Size& content_bounds,
+ const gfx::Size& bounds,
const SharedQuadState* shared_quad_state,
AppendQuadsData* append_quads_data) const;
void AppendDebugBorderQuad(RenderPass* render_pass,
- const gfx::Size& content_bounds,
+ const gfx::Size& bounds,
const SharedQuadState* shared_quad_state,
AppendQuadsData* append_quads_data,
SkColor color,
@@ -751,6 +784,8 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver,
// Set for the layer that other layers are fixed to.
bool is_container_for_fixed_position_layers_ : 1;
+ bool is_affected_by_page_scale_ : 1;
+
Region non_fast_scrollable_region_;
Region touch_event_handler_region_;
SkColor background_color_;
@@ -825,6 +860,9 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver,
std::vector<FrameTimingRequest> frame_timing_requests_;
bool frame_timing_requests_dirty_;
+ bool visited_;
+ bool layer_or_descendant_is_drawn_;
+ bool sorted_for_recursion_;
DISALLOW_COPY_AND_ASSIGN(LayerImpl);
};
diff --git a/chromium/cc/layers/layer_impl_unittest.cc b/chromium/cc/layers/layer_impl_unittest.cc
index d9811bc1553..964b9994085 100644
--- a/chromium/cc/layers/layer_impl_unittest.cc
+++ b/chromium/cc/layers/layer_impl_unittest.cc
@@ -88,7 +88,9 @@ TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) {
// Create a simple LayerImpl tree:
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
EXPECT_TRUE(host_impl.InitializeRenderer(FakeOutputSurface::Create3d()));
scoped_ptr<LayerImpl> root_clip =
LayerImpl::Create(host_impl.active_tree(), 1);
@@ -172,9 +174,6 @@ TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) {
EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetTransform(arbitrary_transform));
// Changing these properties only affects the layer itself.
- EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(root->SetContentBounds(arbitrary_size));
- EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(
- root->SetContentsScale(arbitrary_number, arbitrary_number));
EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(root->SetDrawsContent(true));
EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(
root->SetBackgroundColor(arbitrary_color));
@@ -226,10 +225,6 @@ TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) {
EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
root->PushScrollOffsetFromMainThread(
gfx::ScrollOffset(arbitrary_vector2d)));
- EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
- root->SetContentBounds(arbitrary_size));
- EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
- root->SetContentsScale(arbitrary_number, arbitrary_number));
EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetContentsOpaque(true));
EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetOpacity(arbitrary_number));
EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
@@ -251,7 +246,9 @@ TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) {
TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
EXPECT_TRUE(host_impl.InitializeRenderer(FakeOutputSurface::Create3d()));
host_impl.active_tree()->SetRootLayer(
LayerImpl::Create(host_impl.active_tree(), 1));
@@ -323,9 +320,6 @@ TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) {
VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
layer->SetDoubleSided(false)); // constructor initializes it to "true".
- VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetContentBounds(arbitrary_size));
- VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
- layer->SetContentsScale(arbitrary_number, arbitrary_number));
VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetDrawsContent(true));
VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
layer->SetBackgroundColor(arbitrary_color));
@@ -347,10 +341,6 @@ TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) {
VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->Set3dSortingContextId(1));
VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
layer->SetDoubleSided(false)); // constructor initializes it to "true".
- VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
- layer->SetContentBounds(arbitrary_size));
- VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
- layer->SetContentsScale(arbitrary_number, arbitrary_number));
VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetDrawsContent(true));
VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
layer->SetBackgroundColor(arbitrary_color));
@@ -369,7 +359,9 @@ TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) {
TEST(LayerImplTest, SafeOpaqueBackgroundColor) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
EXPECT_TRUE(host_impl.InitializeRenderer(FakeOutputSurface::Create3d()));
scoped_ptr<LayerImpl> layer = LayerImpl::Create(host_impl.active_tree(), 1);
@@ -400,7 +392,9 @@ TEST(LayerImplTest, SafeOpaqueBackgroundColor) {
TEST(LayerImplTest, TransformInvertibility) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
scoped_ptr<LayerImpl> layer = LayerImpl::Create(host_impl.active_tree(), 1);
EXPECT_TRUE(layer->transform().IsInvertible());
@@ -458,7 +452,6 @@ class LayerImplScrollTest : public testing::Test {
LayerTreeSettings settings() {
LayerTreeSettings settings;
- settings.use_pinch_virtual_viewport = true;
return settings;
}
@@ -682,7 +675,6 @@ class LayerImplScrollbarSyncTest : public testing::Test {
LayerTreeSettings settings() {
LayerTreeSettings settings;
- settings.use_pinch_virtual_viewport = true;
return settings;
}
diff --git a/chromium/cc/layers/layer_iterator.h b/chromium/cc/layers/layer_iterator.h
index ba5c6aa5da5..2c129e48cb3 100644
--- a/chromium/cc/layers/layer_iterator.h
+++ b/chromium/cc/layers/layer_iterator.h
@@ -6,24 +6,24 @@
#define CC_LAYERS_LAYER_ITERATOR_H_
#include "cc/base/cc_export.h"
+#include "cc/layers/layer_impl.h"
#include "cc/trees/layer_tree_host_common.h"
namespace cc {
// These classes provide means to iterate over the
-// RenderSurface-Layer tree.
+// RenderSurfaceImpl-LayerImpl tree.
-// Example code follows, for a tree of Layer/RenderSurface objects.
+// Example code follows, for a tree of LayerImpl/RenderSurfaceImpl objects.
// See below for details.
//
// void DoStuffOnLayers(
-// const RenderSurfaceLayerList& render_surface_layer_list) {
-// typedef LayerIterator<Layer> LayerIteratorType;
+// const LayerImplList& render_surface_layer_list) {
//
-// LayerIteratorType end =
-// LayerIteratorType::End(&render_surface_layer_list);
-// for (LayerIteratorType
-// it = LayerIteratorType::Begin(&render_surface_layer_list);
+// LayerIterator end =
+// LayerIterator::End(&render_surface_layer_list);
+// for (LayerIterator
+// it = LayerIterator::Begin(&render_surface_layer_list);
// it != end;
// ++it) {
// // Only one of these will be true
@@ -79,47 +79,41 @@ namespace cc {
////////////////////////////////////////////////////////////////////////////////
-// Non-templated constants
struct LayerIteratorValue {
static const int kInvalidTargetRenderSurfaceLayerIndex = -1;
- // This must be -1 since the iterator action code assumes that this value can
- // be reached by subtracting one from the position of the first layer in the
- // current target surface's child layer list, which is 0.
- static const int kLayerIndexRepresentingTargetRenderSurface = -1;
+ // This must be (size_t)-1 since the iterator action code assumes that this
+ // value can be reached by subtracting one from the position of the first
+ // layer in the current target surface's child layer list, which is 0.
+ static const size_t kLayerIndexRepresentingTargetRenderSurface =
+ static_cast<size_t>(-1);
};
// The position of a layer iterator that is independent
// of its many template types.
-template <typename LayerType> struct LayerIteratorPosition {
+struct LayerIteratorPosition {
bool represents_target_render_surface;
bool represents_contributing_render_surface;
bool represents_itself;
- LayerType* target_render_surface_layer;
- LayerType* current_layer;
+ LayerImpl* target_render_surface_layer;
+ LayerImpl* current_layer;
};
// An iterator class for walking over layers in the
// RenderSurface-Layer tree.
-template <typename LayerType>
+// TODO(enne): This class probably shouldn't be entirely inline and
+// should get moved to a .cc file where it makes sense.
class LayerIterator {
- typedef LayerIterator<LayerType> LayerIteratorType;
- typedef typename LayerType::LayerListType LayerList;
- typedef typename LayerType::RenderSurfaceListType RenderSurfaceLayerList;
- typedef typename LayerType::RenderSurfaceType RenderSurfaceType;
-
public:
LayerIterator() : render_surface_layer_list_(nullptr) {}
- static LayerIteratorType Begin(
- const RenderSurfaceLayerList* render_surface_layer_list) {
- return LayerIteratorType(render_surface_layer_list, true);
+ static LayerIterator Begin(const LayerImplList* render_surface_layer_list) {
+ return LayerIterator(render_surface_layer_list, true);
}
- static LayerIteratorType End(
- const RenderSurfaceLayerList* render_surface_layer_list) {
- return LayerIteratorType(render_surface_layer_list, false);
+ static LayerIterator End(const LayerImplList* render_surface_layer_list) {
+ return LayerIterator(render_surface_layer_list, false);
}
- LayerIteratorType& operator++() {
+ LayerIterator& operator++() {
MoveToNext();
return *this;
}
@@ -128,12 +122,12 @@ class LayerIterator {
other.target_render_surface_layer_index_ &&
current_layer_index_ == other.current_layer_index_;
}
- bool operator!=(const LayerIteratorType& other) const {
+ bool operator!=(const LayerIterator& other) const {
return !(*this == other);
}
- LayerType* operator->() const { return current_layer(); }
- LayerType* operator*() const { return current_layer(); }
+ LayerImpl* operator->() const { return current_layer(); }
+ LayerImpl* operator*() const { return current_layer(); }
bool represents_target_render_surface() const {
return current_layer_represents_target_render_surface();
@@ -147,12 +141,12 @@ class LayerIterator {
!represents_contributing_render_surface();
}
- LayerType* target_render_surface_layer() const {
+ LayerImpl* target_render_surface_layer() const {
return render_surface_layer_list_->at(target_render_surface_layer_index_);
}
- operator const LayerIteratorPosition<LayerType>() const {
- LayerIteratorPosition<LayerType> position;
+ operator const LayerIteratorPosition() const {
+ LayerIteratorPosition position;
position.represents_target_render_surface =
represents_target_render_surface();
position.represents_contributing_render_surface =
@@ -164,8 +158,7 @@ class LayerIterator {
}
private:
- LayerIterator(const RenderSurfaceLayerList* render_surface_layer_list,
- bool start)
+ LayerIterator(const LayerImplList* render_surface_layer_list, bool start)
: render_surface_layer_list_(render_surface_layer_list),
target_render_surface_layer_index_(0) {
for (size_t i = 0; i < render_surface_layer_list->size(); ++i) {
@@ -237,7 +230,7 @@ class LayerIterator {
int previous_target_render_surface_layer =
target_render_surface_layer_index_;
- for (LayerType* layer = current_layer();
+ for (LayerImpl* layer = current_layer();
target_render_surface_layer() != layer;
++target_render_surface_layer_index_) {
}
@@ -248,7 +241,7 @@ class LayerIterator {
}
}
- inline LayerType* current_layer() const {
+ inline LayerImpl* current_layer() const {
return current_layer_represents_target_render_surface()
? target_render_surface_layer()
: LayerTreeHostCommon::get_layer_as_raw_ptr(
@@ -256,7 +249,7 @@ class LayerIterator {
}
inline bool current_layer_represents_contributing_render_surface() const {
- return LayerTreeHostCommon::RenderSurfaceContributesToTarget<LayerType>(
+ return LayerTreeHostCommon::RenderSurfaceContributesToTarget<LayerImpl>(
current_layer(), target_render_surface_layer()->id());
}
inline bool current_layer_represents_target_render_surface() const {
@@ -264,14 +257,14 @@ class LayerIterator {
LayerIteratorValue::kLayerIndexRepresentingTargetRenderSurface;
}
- inline RenderSurfaceType* target_render_surface() const {
+ inline RenderSurfaceImpl* target_render_surface() const {
return target_render_surface_layer()->render_surface();
}
- inline const LayerList& target_render_surface_children() const {
+ inline const LayerImplList& target_render_surface_children() const {
return target_render_surface()->layer_list();
}
- const RenderSurfaceLayerList* render_surface_layer_list_;
+ const LayerImplList* render_surface_layer_list_;
// The iterator's current position.
@@ -286,9 +279,10 @@ class LayerIterator {
// current target surface. When pointing to one of these layers,
// this is a value from 0 to n-1 (n = number of children).
// Since the iterator must also stop at the layers representing
- // the target surface, this is done by setting the current_layerIndex
- // to a value of LayerIteratorValue::LayerRepresentingTargetRenderSurface.
- int current_layer_index_;
+ // the target surface, this is done by setting the current_layer_index
+ // to a value of
+ // LayerIteratorValue::kLayerIndexRepresentingTargetRenderSurface.
+ size_t current_layer_index_;
};
} // namespace cc
diff --git a/chromium/cc/layers/layer_iterator_unittest.cc b/chromium/cc/layers/layer_iterator_unittest.cc
index cdc14732b8f..01815f9b36c 100644
--- a/chromium/cc/layers/layer_iterator_unittest.cc
+++ b/chromium/cc/layers/layer_iterator_unittest.cc
@@ -8,6 +8,7 @@
#include "cc/layers/layer.h"
#include "cc/test/fake_layer_tree_host.h"
+#include "cc/test/test_task_graph_runner.h"
#include "cc/trees/layer_tree_host_common.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -21,27 +22,27 @@ using ::testing::AnyNumber;
namespace cc {
namespace {
-class TestLayer : public Layer {
+class TestLayerImpl : public LayerImpl {
public:
- static scoped_refptr<TestLayer> Create() {
- return make_scoped_refptr(new TestLayer());
+ static scoped_ptr<TestLayerImpl> Create(LayerTreeImpl* tree, int id) {
+ return make_scoped_ptr(new TestLayerImpl(tree, id));
}
+ ~TestLayerImpl() override {}
int count_representing_target_surface_;
int count_representing_contributing_surface_;
int count_representing_itself_;
- bool DrawsContent() const override { return draws_content_; }
- void set_draws_content(bool draws_content) { draws_content_ = draws_content; }
-
private:
- TestLayer() : Layer(), draws_content_(true) {
+ explicit TestLayerImpl(LayerTreeImpl* tree, int id)
+ : LayerImpl(tree, id, new SyncedScrollOffset),
+ count_representing_target_surface_(-1),
+ count_representing_contributing_surface_(-1),
+ count_representing_itself_(-1) {
SetBounds(gfx::Size(100, 100));
SetPosition(gfx::Point());
+ SetDrawsContent(true);
}
- ~TestLayer() override {}
-
- bool draws_content_;
};
#define EXPECT_COUNT(layer, target, contrib, itself) \
@@ -49,15 +50,13 @@ class TestLayer : public Layer {
EXPECT_EQ(contrib, layer->count_representing_contributing_surface_); \
EXPECT_EQ(itself, layer->count_representing_itself_);
-typedef LayerIterator<Layer> FrontToBack;
-
-void ResetCounts(RenderSurfaceLayerList* render_surface_layer_list) {
+void ResetCounts(LayerImplList* render_surface_layer_list) {
for (unsigned surface_index = 0;
surface_index < render_surface_layer_list->size();
++surface_index) {
- TestLayer* render_surface_layer = static_cast<TestLayer*>(
+ TestLayerImpl* render_surface_layer = static_cast<TestLayerImpl*>(
render_surface_layer_list->at(surface_index));
- RenderSurface* render_surface = render_surface_layer->render_surface();
+ RenderSurfaceImpl* render_surface = render_surface_layer->render_surface();
render_surface_layer->count_representing_target_surface_ = -1;
render_surface_layer->count_representing_contributing_surface_ = -1;
@@ -66,8 +65,8 @@ void ResetCounts(RenderSurfaceLayerList* render_surface_layer_list) {
for (unsigned layer_index = 0;
layer_index < render_surface->layer_list().size();
++layer_index) {
- TestLayer* layer = static_cast<TestLayer*>(
- render_surface->layer_list().at(layer_index).get());
+ TestLayerImpl* layer = static_cast<TestLayerImpl*>(
+ render_surface->layer_list()[layer_index]);
layer->count_representing_target_surface_ = -1;
layer->count_representing_contributing_surface_ = -1;
@@ -76,14 +75,12 @@ void ResetCounts(RenderSurfaceLayerList* render_surface_layer_list) {
}
}
-void IterateFrontToBack(
- RenderSurfaceLayerList* render_surface_layer_list) {
+void IterateFrontToBack(LayerImplList* render_surface_layer_list) {
ResetCounts(render_surface_layer_list);
int count = 0;
- for (FrontToBack it = FrontToBack::Begin(render_surface_layer_list);
- it != FrontToBack::End(render_surface_layer_list);
- ++it, ++count) {
- TestLayer* layer = static_cast<TestLayer*>(*it);
+ for (LayerIterator it = LayerIterator::Begin(render_surface_layer_list);
+ it != LayerIterator::End(render_surface_layer_list); ++it, ++count) {
+ TestLayerImpl* layer = static_cast<TestLayerImpl*>(*it);
if (it.represents_target_render_surface())
layer->count_representing_target_surface_ = count;
if (it.represents_contributing_render_surface())
@@ -93,126 +90,167 @@ void IterateFrontToBack(
}
}
-TEST(LayerIteratorTest, EmptyTree) {
- RenderSurfaceLayerList render_surface_layer_list;
+class LayerIteratorTest : public testing::Test {
+ public:
+ LayerIteratorTest()
+ : host_impl_(&proxy_, &shared_bitmap_manager_, &task_graph_runner_),
+ id_(1) {}
+
+ scoped_ptr<TestLayerImpl> CreateLayer() {
+ return TestLayerImpl::Create(host_impl_.active_tree(), id_++);
+ }
+
+ protected:
+ FakeImplProxy proxy_;
+ TestSharedBitmapManager shared_bitmap_manager_;
+ TestTaskGraphRunner task_graph_runner_;
+ FakeLayerTreeHostImpl host_impl_;
+
+ int id_;
+};
+
+TEST_F(LayerIteratorTest, EmptyTree) {
+ LayerImplList render_surface_layer_list;
IterateFrontToBack(&render_surface_layer_list);
}
-TEST(LayerIteratorTest, SimpleTree) {
- scoped_refptr<TestLayer> root_layer = TestLayer::Create();
- scoped_refptr<TestLayer> first = TestLayer::Create();
- scoped_refptr<TestLayer> second = TestLayer::Create();
- scoped_refptr<TestLayer> third = TestLayer::Create();
- scoped_refptr<TestLayer> fourth = TestLayer::Create();
-
- root_layer->AddChild(first);
- root_layer->AddChild(second);
- root_layer->AddChild(third);
- root_layer->AddChild(fourth);
-
- FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
- scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(&client);
- host->SetRootLayer(root_layer);
-
- RenderSurfaceLayerList render_surface_layer_list;
- LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
- root_layer.get(), root_layer->bounds(), &render_surface_layer_list);
+TEST_F(LayerIteratorTest, SimpleTree) {
+ scoped_ptr<TestLayerImpl> root_layer = CreateLayer();
+ scoped_ptr<TestLayerImpl> first = CreateLayer();
+ scoped_ptr<TestLayerImpl> second = CreateLayer();
+ scoped_ptr<TestLayerImpl> third = CreateLayer();
+ scoped_ptr<TestLayerImpl> fourth = CreateLayer();
+
+ TestLayerImpl* root_ptr = root_layer.get();
+ TestLayerImpl* first_ptr = first.get();
+ TestLayerImpl* second_ptr = second.get();
+ TestLayerImpl* third_ptr = third.get();
+ TestLayerImpl* fourth_ptr = fourth.get();
+
+ root_layer->AddChild(first.Pass());
+ root_layer->AddChild(second.Pass());
+ root_layer->AddChild(third.Pass());
+ root_layer->AddChild(fourth.Pass());
+
+ root_layer->SetHasRenderSurface(true);
+ host_impl_.active_tree()->SetRootLayer(root_layer.Pass());
+
+ LayerImplList render_surface_layer_list;
+ LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
+ root_ptr, root_ptr->bounds(), &render_surface_layer_list);
LayerTreeHostCommon::CalculateDrawProperties(&inputs);
IterateFrontToBack(&render_surface_layer_list);
- EXPECT_COUNT(root_layer, 5, -1, 4);
- EXPECT_COUNT(first, -1, -1, 3);
- EXPECT_COUNT(second, -1, -1, 2);
- EXPECT_COUNT(third, -1, -1, 1);
- EXPECT_COUNT(fourth, -1, -1, 0);
+ EXPECT_COUNT(root_ptr, 5, -1, 4);
+ EXPECT_COUNT(first_ptr, -1, -1, 3);
+ EXPECT_COUNT(second_ptr, -1, -1, 2);
+ EXPECT_COUNT(third_ptr, -1, -1, 1);
+ EXPECT_COUNT(fourth_ptr, -1, -1, 0);
}
-TEST(LayerIteratorTest, ComplexTree) {
- scoped_refptr<TestLayer> root_layer = TestLayer::Create();
- scoped_refptr<TestLayer> root1 = TestLayer::Create();
- scoped_refptr<TestLayer> root2 = TestLayer::Create();
- scoped_refptr<TestLayer> root3 = TestLayer::Create();
- scoped_refptr<TestLayer> root21 = TestLayer::Create();
- scoped_refptr<TestLayer> root22 = TestLayer::Create();
- scoped_refptr<TestLayer> root23 = TestLayer::Create();
- scoped_refptr<TestLayer> root221 = TestLayer::Create();
- scoped_refptr<TestLayer> root231 = TestLayer::Create();
-
- root_layer->AddChild(root1);
- root_layer->AddChild(root2);
- root_layer->AddChild(root3);
- root2->AddChild(root21);
- root2->AddChild(root22);
- root2->AddChild(root23);
- root22->AddChild(root221);
- root23->AddChild(root231);
-
- FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
- scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(&client);
- host->SetRootLayer(root_layer);
-
- RenderSurfaceLayerList render_surface_layer_list;
- LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
- root_layer.get(), root_layer->bounds(), &render_surface_layer_list);
+TEST_F(LayerIteratorTest, ComplexTree) {
+ scoped_ptr<TestLayerImpl> root_layer = CreateLayer();
+ scoped_ptr<TestLayerImpl> root1 = CreateLayer();
+ scoped_ptr<TestLayerImpl> root2 = CreateLayer();
+ scoped_ptr<TestLayerImpl> root3 = CreateLayer();
+ scoped_ptr<TestLayerImpl> root21 = CreateLayer();
+ scoped_ptr<TestLayerImpl> root22 = CreateLayer();
+ scoped_ptr<TestLayerImpl> root23 = CreateLayer();
+ scoped_ptr<TestLayerImpl> root221 = CreateLayer();
+ scoped_ptr<TestLayerImpl> root231 = CreateLayer();
+
+ TestLayerImpl* root_ptr = root_layer.get();
+ TestLayerImpl* root1_ptr = root1.get();
+ TestLayerImpl* root2_ptr = root2.get();
+ TestLayerImpl* root3_ptr = root3.get();
+ TestLayerImpl* root21_ptr = root21.get();
+ TestLayerImpl* root22_ptr = root22.get();
+ TestLayerImpl* root23_ptr = root23.get();
+ TestLayerImpl* root221_ptr = root221.get();
+ TestLayerImpl* root231_ptr = root231.get();
+
+ root22->AddChild(root221.Pass());
+ root23->AddChild(root231.Pass());
+ root2->AddChild(root21.Pass());
+ root2->AddChild(root22.Pass());
+ root2->AddChild(root23.Pass());
+ root_layer->AddChild(root1.Pass());
+ root_layer->AddChild(root2.Pass());
+ root_layer->AddChild(root3.Pass());
+
+ root_layer->SetHasRenderSurface(true);
+ host_impl_.active_tree()->SetRootLayer(root_layer.Pass());
+
+ LayerImplList render_surface_layer_list;
+ LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
+ root_ptr, root_ptr->bounds(), &render_surface_layer_list);
LayerTreeHostCommon::CalculateDrawProperties(&inputs);
IterateFrontToBack(&render_surface_layer_list);
- EXPECT_COUNT(root_layer, 9, -1, 8);
- EXPECT_COUNT(root1, -1, -1, 7);
- EXPECT_COUNT(root2, -1, -1, 6);
- EXPECT_COUNT(root21, -1, -1, 5);
- EXPECT_COUNT(root22, -1, -1, 4);
- EXPECT_COUNT(root221, -1, -1, 3);
- EXPECT_COUNT(root23, -1, -1, 2);
- EXPECT_COUNT(root231, -1, -1, 1);
- EXPECT_COUNT(root3, -1, -1, 0);
+ EXPECT_COUNT(root_ptr, 9, -1, 8);
+ EXPECT_COUNT(root1_ptr, -1, -1, 7);
+ EXPECT_COUNT(root2_ptr, -1, -1, 6);
+ EXPECT_COUNT(root21_ptr, -1, -1, 5);
+ EXPECT_COUNT(root22_ptr, -1, -1, 4);
+ EXPECT_COUNT(root221_ptr, -1, -1, 3);
+ EXPECT_COUNT(root23_ptr, -1, -1, 2);
+ EXPECT_COUNT(root231_ptr, -1, -1, 1);
+ EXPECT_COUNT(root3_ptr, -1, -1, 0);
}
-TEST(LayerIteratorTest, ComplexTreeMultiSurface) {
- scoped_refptr<TestLayer> root_layer = TestLayer::Create();
- scoped_refptr<TestLayer> root1 = TestLayer::Create();
- scoped_refptr<TestLayer> root2 = TestLayer::Create();
- scoped_refptr<TestLayer> root3 = TestLayer::Create();
- scoped_refptr<TestLayer> root21 = TestLayer::Create();
- scoped_refptr<TestLayer> root22 = TestLayer::Create();
- scoped_refptr<TestLayer> root23 = TestLayer::Create();
- scoped_refptr<TestLayer> root221 = TestLayer::Create();
- scoped_refptr<TestLayer> root231 = TestLayer::Create();
-
- root_layer->AddChild(root1);
- root_layer->AddChild(root2);
- root_layer->AddChild(root3);
- root2->set_draws_content(false);
- root2->SetOpacity(0.5f);
- root2->SetForceRenderSurface(true); // Force the layer to own a new surface.
- root2->AddChild(root21);
- root2->AddChild(root22);
- root2->AddChild(root23);
- root22->SetOpacity(0.5f);
- root22->AddChild(root221);
- root23->SetOpacity(0.5f);
- root23->AddChild(root231);
-
- FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
- scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(&client);
- host->SetRootLayer(root_layer);
-
- RenderSurfaceLayerList render_surface_layer_list;
- LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
- root_layer.get(), root_layer->bounds(), &render_surface_layer_list);
+TEST_F(LayerIteratorTest, ComplexTreeMultiSurface) {
+ scoped_ptr<TestLayerImpl> root_layer = CreateLayer();
+ scoped_ptr<TestLayerImpl> root1 = CreateLayer();
+ scoped_ptr<TestLayerImpl> root2 = CreateLayer();
+ scoped_ptr<TestLayerImpl> root3 = CreateLayer();
+ scoped_ptr<TestLayerImpl> root21 = CreateLayer();
+ scoped_ptr<TestLayerImpl> root22 = CreateLayer();
+ scoped_ptr<TestLayerImpl> root23 = CreateLayer();
+ scoped_ptr<TestLayerImpl> root221 = CreateLayer();
+ scoped_ptr<TestLayerImpl> root231 = CreateLayer();
+
+ TestLayerImpl* root_ptr = root_layer.get();
+ TestLayerImpl* root1_ptr = root1.get();
+ TestLayerImpl* root2_ptr = root2.get();
+ TestLayerImpl* root3_ptr = root3.get();
+ TestLayerImpl* root21_ptr = root21.get();
+ TestLayerImpl* root22_ptr = root22.get();
+ TestLayerImpl* root23_ptr = root23.get();
+ TestLayerImpl* root221_ptr = root221.get();
+ TestLayerImpl* root231_ptr = root231.get();
+
+ root22->SetHasRenderSurface(true);
+ root22->AddChild(root221.Pass());
+ root23->SetHasRenderSurface(true);
+ root23->AddChild(root231.Pass());
+ root2->SetDrawsContent(false);
+ root2->SetHasRenderSurface(true);
+ root2->AddChild(root21.Pass());
+ root2->AddChild(root22.Pass());
+ root2->AddChild(root23.Pass());
+ root_layer->AddChild(root1.Pass());
+ root_layer->AddChild(root2.Pass());
+ root_layer->AddChild(root3.Pass());
+
+ root_layer->SetHasRenderSurface(true);
+ host_impl_.active_tree()->SetRootLayer(root_layer.Pass());
+
+ LayerImplList render_surface_layer_list;
+ LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
+ root_ptr, root_ptr->bounds(), &render_surface_layer_list);
LayerTreeHostCommon::CalculateDrawProperties(&inputs);
IterateFrontToBack(&render_surface_layer_list);
- EXPECT_COUNT(root_layer, 14, -1, 13);
- EXPECT_COUNT(root1, -1, -1, 12);
- EXPECT_COUNT(root2, 10, 11, -1);
- EXPECT_COUNT(root21, -1, -1, 9);
- EXPECT_COUNT(root22, 7, 8, 6);
- EXPECT_COUNT(root221, -1, -1, 5);
- EXPECT_COUNT(root23, 3, 4, 2);
- EXPECT_COUNT(root231, -1, -1, 1);
- EXPECT_COUNT(root3, -1, -1, 0);
+ EXPECT_COUNT(root_ptr, 14, -1, 13);
+ EXPECT_COUNT(root1_ptr, -1, -1, 12);
+ EXPECT_COUNT(root2_ptr, 10, 11, -1);
+ EXPECT_COUNT(root21_ptr, -1, -1, 9);
+ EXPECT_COUNT(root22_ptr, 7, 8, 6);
+ EXPECT_COUNT(root221_ptr, -1, -1, 5);
+ EXPECT_COUNT(root23_ptr, 3, 4, 2);
+ EXPECT_COUNT(root231_ptr, -1, -1, 1);
+ EXPECT_COUNT(root3_ptr, -1, -1, 0);
}
} // namespace
diff --git a/chromium/cc/layers/layer_perftest.cc b/chromium/cc/layers/layer_perftest.cc
index c7cac01f5b2..0c0fb4185a4 100644
--- a/chromium/cc/layers/layer_perftest.cc
+++ b/chromium/cc/layers/layer_perftest.cc
@@ -6,7 +6,6 @@
#include "base/thread_task_runner_handle.h"
#include "cc/debug/lap_timer.h"
-#include "cc/resources/layer_painter.h"
#include "cc/test/fake_impl_proxy.h"
#include "cc/test/fake_layer_tree_host.h"
#include "cc/test/fake_layer_tree_host_client.h"
@@ -22,12 +21,6 @@ static const int kTimeLimitMillis = 3000;
static const int kWarmupRuns = 5;
static const int kTimeCheckInterval = 10;
-class MockLayerPainter : public LayerPainter {
- public:
- void Paint(SkCanvas* canvas, const gfx::Rect& content_rect) override {}
-};
-
-
class LayerPerfTest : public testing::Test {
public:
LayerPerfTest()
@@ -39,7 +32,8 @@ class LayerPerfTest : public testing::Test {
protected:
void SetUp() override {
- layer_tree_host_ = FakeLayerTreeHost::Create(&fake_client_);
+ layer_tree_host_ =
+ FakeLayerTreeHost::Create(&fake_client_, &task_graph_runner_);
layer_tree_host_->InitializeSingleThreaded(
&fake_client_, base::ThreadTaskRunnerHandle::Get(), nullptr);
}
@@ -60,7 +54,7 @@ class LayerPerfTest : public testing::Test {
};
TEST_F(LayerPerfTest, PushPropertiesTo) {
- scoped_refptr<Layer> test_layer = Layer::Create();
+ scoped_refptr<Layer> test_layer = Layer::Create(LayerSettings());
scoped_ptr<LayerImpl> impl_layer =
LayerImpl::Create(host_impl_.active_tree(), 1);
diff --git a/chromium/cc/layers/layer_position_constraint_unittest.cc b/chromium/cc/layers/layer_position_constraint_unittest.cc
index 1eea9c98b44..fdb7f5b6ea4 100644
--- a/chromium/cc/layers/layer_position_constraint_unittest.cc
+++ b/chromium/cc/layers/layer_position_constraint_unittest.cc
@@ -6,11 +6,10 @@
#include <vector>
+#include "cc/layers/layer.h"
#include "cc/layers/layer_impl.h"
-#include "cc/test/fake_impl_proxy.h"
-#include "cc/test/fake_layer_tree_host_impl.h"
+#include "cc/test/fake_layer_tree_host.h"
#include "cc/test/geometry_test_utils.h"
-#include "cc/test/test_shared_bitmap_manager.h"
#include "cc/test/test_task_graph_runner.h"
#include "cc/trees/layer_tree_host_common.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -18,7 +17,22 @@
namespace cc {
namespace {
-void SetLayerPropertiesForTesting(LayerImpl* layer,
+class LayerWithForcedDrawsContent : public Layer {
+ public:
+ explicit LayerWithForcedDrawsContent(const LayerSettings& settings)
+ : Layer(settings) {}
+
+ bool DrawsContent() const override;
+
+ private:
+ ~LayerWithForcedDrawsContent() override {}
+};
+
+bool LayerWithForcedDrawsContent::DrawsContent() const {
+ return true;
+}
+
+void SetLayerPropertiesForTesting(Layer* layer,
const gfx::Transform& transform,
const gfx::Point3F& transform_origin,
const gfx::PointF& position,
@@ -29,110 +43,147 @@ void SetLayerPropertiesForTesting(LayerImpl* layer,
layer->SetPosition(position);
layer->SetBounds(bounds);
layer->SetShouldFlattenTransform(flatten_transform);
- layer->SetContentBounds(bounds);
}
-void ExecuteCalculateDrawProperties(LayerImpl* root_layer,
- float device_scale_factor,
- float page_scale_factor,
- LayerImpl* page_scale_application_layer,
- bool can_use_lcd_text) {
- gfx::Transform identity_matrix;
+void ExecuteCalculateDrawProperties(LayerImpl* root_layer) {
std::vector<LayerImpl*> dummy_render_surface_layer_list;
- LayerImpl* scroll_layer = root_layer->children()[0];
- gfx::Size device_viewport_size =
- gfx::Size(root_layer->bounds().width() * device_scale_factor,
- root_layer->bounds().height() * device_scale_factor);
-
- // We are probably not testing what is intended if the scroll_layer bounds are
- // empty.
- DCHECK(!scroll_layer->bounds().IsEmpty());
LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
- root_layer, device_viewport_size, &dummy_render_surface_layer_list);
- inputs.device_scale_factor = device_scale_factor;
- inputs.page_scale_factor = page_scale_factor;
- inputs.page_scale_application_layer = page_scale_application_layer;
- inputs.can_use_lcd_text = can_use_lcd_text;
+ root_layer, root_layer->bounds(), &dummy_render_surface_layer_list);
+ inputs.inner_viewport_scroll_layer =
+ root_layer->layer_tree_impl()->InnerViewportScrollLayer();
+ inputs.outer_viewport_scroll_layer =
+ root_layer->layer_tree_impl()->OuterViewportScrollLayer();
LayerTreeHostCommon::CalculateDrawProperties(&inputs);
}
-void ExecuteCalculateDrawProperties(LayerImpl* root_layer) {
- LayerImpl* page_scale_application_layer = nullptr;
- ExecuteCalculateDrawProperties(
- root_layer, 1.f, 1.f, page_scale_application_layer, false);
-}
-
class LayerPositionConstraintTest : public testing::Test {
public:
LayerPositionConstraintTest()
- : host_impl_(&proxy_, &shared_bitmap_manager_, &task_graph_runner_) {
- root_ = CreateTreeForTest();
- scroll_ = root_->children()[0];
+ : fake_client_(FakeLayerTreeHostClient::DIRECT_3D),
+ layer_tree_host_(
+ FakeLayerTreeHost::Create(&fake_client_, &task_graph_runner_)),
+ root_impl_(nullptr),
+ inner_viewport_container_layer_impl_(nullptr),
+ scroll_layer_impl_(nullptr),
+ outer_viewport_container_layer_impl_(nullptr),
+ child_transform_layer_impl_(nullptr),
+ child_impl_(nullptr),
+ grand_child_impl_(nullptr),
+ great_grand_child_impl_(nullptr) {
+ layer_tree_host_->InitializeForTesting(scoped_ptr<Proxy>(new FakeProxy));
+ CreateTreeForTest();
fixed_to_top_left_.set_is_fixed_position(true);
fixed_to_bottom_right_.set_is_fixed_position(true);
fixed_to_bottom_right_.set_is_fixed_to_right_edge(true);
fixed_to_bottom_right_.set_is_fixed_to_bottom_edge(true);
}
- scoped_ptr<LayerImpl> CreateTreeForTest() {
- scoped_ptr<LayerImpl> root =
- LayerImpl::Create(host_impl_.active_tree(), 42);
- scoped_ptr<LayerImpl> scroll_layer =
- LayerImpl::Create(host_impl_.active_tree(), 1);
- scoped_ptr<LayerImpl> child =
- LayerImpl::Create(host_impl_.active_tree(), 2);
- scoped_ptr<LayerImpl> grand_child =
- LayerImpl::Create(host_impl_.active_tree(), 3);
- scoped_ptr<LayerImpl> great_grand_child =
- LayerImpl::Create(host_impl_.active_tree(), 4);
-
- root->SetHasRenderSurface(true);
+ void CreateTreeForTest() {
+ // scroll_layer_ is the inner viewport scroll layer and child_ is the outer
+ // viewport scroll layer.
+ root_ = Layer::Create(layer_settings_);
+ inner_viewport_container_layer_ = Layer::Create(layer_settings_);
+ scroll_layer_ = Layer::Create(layer_settings_);
+ outer_viewport_container_layer_ = Layer::Create(layer_settings_);
+ child_transform_layer_ = Layer::Create(layer_settings_);
+ child_ = Layer::Create(layer_settings_);
+ grand_child_ =
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings_));
+ great_grand_child_ =
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings_));
+
gfx::Transform IdentityMatrix;
gfx::Point3F transform_origin;
gfx::PointF position;
gfx::Size bounds(200, 200);
gfx::Size clip_bounds(100, 100);
- SetLayerPropertiesForTesting(scroll_layer.get(),
- IdentityMatrix,
- transform_origin,
- position,
- bounds,
- true);
- SetLayerPropertiesForTesting(
- child.get(), IdentityMatrix, transform_origin, position, bounds, true);
- SetLayerPropertiesForTesting(grand_child.get(),
- IdentityMatrix,
- transform_origin,
- position,
- bounds,
- true);
- SetLayerPropertiesForTesting(great_grand_child.get(),
- IdentityMatrix,
- transform_origin,
- position,
- bounds,
- true);
-
- root->SetBounds(clip_bounds);
- scroll_layer->SetScrollClipLayer(root->id());
- child->SetScrollClipLayer(root->id());
- grand_child->SetScrollClipLayer(root->id());
-
- grand_child->AddChild(great_grand_child.Pass());
- child->AddChild(grand_child.Pass());
- scroll_layer->AddChild(child.Pass());
- root->AddChild(scroll_layer.Pass());
-
- return root.Pass();
+ SetLayerPropertiesForTesting(inner_viewport_container_layer_.get(),
+ IdentityMatrix, transform_origin, position,
+ clip_bounds, true);
+ SetLayerPropertiesForTesting(scroll_layer_.get(), IdentityMatrix,
+ transform_origin, position, bounds, true);
+ SetLayerPropertiesForTesting(outer_viewport_container_layer_.get(),
+ IdentityMatrix, transform_origin, position,
+ clip_bounds, true);
+ SetLayerPropertiesForTesting(child_.get(), IdentityMatrix, transform_origin,
+ position, bounds, true);
+ SetLayerPropertiesForTesting(grand_child_.get(), IdentityMatrix,
+ transform_origin, position, bounds, true);
+ SetLayerPropertiesForTesting(great_grand_child_.get(), IdentityMatrix,
+ transform_origin, position, bounds, true);
+
+ root_->SetBounds(clip_bounds);
+
+ inner_viewport_container_layer_->SetMasksToBounds(true);
+ scroll_layer_->SetScrollClipLayerId(inner_viewport_container_layer_->id());
+ scroll_layer_->SetIsContainerForFixedPositionLayers(true);
+
+ outer_viewport_container_layer_->SetMasksToBounds(true);
+ child_->SetScrollClipLayerId(outer_viewport_container_layer_->id());
+ grand_child_->SetScrollClipLayerId(outer_viewport_container_layer_->id());
+
+ grand_child_->AddChild(great_grand_child_);
+ child_->AddChild(grand_child_);
+ child_transform_layer_->AddChild(child_);
+ outer_viewport_container_layer_->AddChild(child_transform_layer_);
+ scroll_layer_->AddChild(outer_viewport_container_layer_);
+ inner_viewport_container_layer_->AddChild(scroll_layer_);
+ root_->AddChild(inner_viewport_container_layer_);
+
+ layer_tree_host_->SetRootLayer(root_);
+ layer_tree_host_->RegisterViewportLayers(nullptr, root_, scroll_layer_,
+ child_);
+ }
+
+ void CommitAndUpdateImplPointers() {
+ RenderSurfaceLayerList render_surface_layer_list;
+ LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
+ root_.get(), root_->bounds(), &render_surface_layer_list);
+ inputs.inner_viewport_scroll_layer =
+ layer_tree_host_->inner_viewport_scroll_layer();
+ inputs.outer_viewport_scroll_layer =
+ layer_tree_host_->outer_viewport_scroll_layer();
+ LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+
+ // Since scroll deltas aren't sent back to the main thread in this test
+ // setup, clear them to maintain consistent state.
+ if (root_impl_) {
+ scroll_layer_impl_->SetScrollDelta(gfx::Vector2dF());
+ child_impl_->SetScrollDelta(gfx::Vector2dF());
+ grand_child_impl_->SetScrollDelta(gfx::Vector2dF());
+ }
+ root_impl_ = layer_tree_host_->CommitAndCreateLayerImplTree();
+ inner_viewport_container_layer_impl_ = root_impl_->children()[0];
+ scroll_layer_impl_ = inner_viewport_container_layer_impl_->children()[0];
+ outer_viewport_container_layer_impl_ = scroll_layer_impl_->children()[0];
+ child_transform_layer_impl_ =
+ outer_viewport_container_layer_impl_->children()[0];
+ child_impl_ = child_transform_layer_impl_->children()[0];
+ grand_child_impl_ = child_impl_->children()[0];
+ great_grand_child_impl_ = grand_child_impl_->children()[0];
}
protected:
- FakeImplProxy proxy_;
- TestSharedBitmapManager shared_bitmap_manager_;
+ FakeLayerTreeHostClient fake_client_;
TestTaskGraphRunner task_graph_runner_;
- FakeLayerTreeHostImpl host_impl_;
- scoped_ptr<LayerImpl> root_;
- LayerImpl* scroll_;
+ scoped_ptr<FakeLayerTreeHost> layer_tree_host_;
+ LayerSettings layer_settings_;
+ scoped_refptr<Layer> root_;
+ scoped_refptr<Layer> inner_viewport_container_layer_;
+ scoped_refptr<Layer> scroll_layer_;
+ scoped_refptr<Layer> outer_viewport_container_layer_;
+ scoped_refptr<Layer> child_transform_layer_;
+ scoped_refptr<Layer> child_;
+ scoped_refptr<Layer> grand_child_;
+ scoped_refptr<Layer> great_grand_child_;
+ LayerImpl* root_impl_;
+ LayerImpl* inner_viewport_container_layer_impl_;
+ LayerImpl* scroll_layer_impl_;
+ LayerImpl* outer_viewport_container_layer_impl_;
+ LayerImpl* child_transform_layer_impl_;
+ LayerImpl* child_impl_;
+ LayerImpl* grand_child_impl_;
+ LayerImpl* great_grand_child_impl_;
LayerPositionConstraint fixed_to_top_left_;
LayerPositionConstraint fixed_to_bottom_right_;
@@ -154,27 +205,26 @@ TEST_F(LayerPositionConstraintTest,
ScrollCompensationForFixedPositionLayerWithDirectContainer) {
// This test checks for correct scroll compensation when the fixed-position
// container is the direct parent of the fixed-position layer.
- LayerImpl* child = scroll_->children()[0];
- LayerImpl* grand_child = child->children()[0];
+ child_->SetIsContainerForFixedPositionLayers(true);
+ grand_child_->SetPositionConstraint(fixed_to_top_left_);
- child->SetIsContainerForFixedPositionLayers(true);
- grand_child->SetPositionConstraint(fixed_to_top_left_);
+ CommitAndUpdateImplPointers();
// Case 1: scroll delta of 0, 0
- child->SetScrollDelta(gfx::Vector2d(0, 0));
- ExecuteCalculateDrawProperties(root_.get());
+ child_impl_->SetScrollDelta(gfx::Vector2d(0, 0));
+ ExecuteCalculateDrawProperties(root_impl_);
gfx::Transform expected_child_transform;
gfx::Transform expected_grand_child_transform = expected_child_transform;
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
// Case 2: scroll delta of 10, 10
- child->SetScrollDelta(gfx::Vector2d(10, 10));
- ExecuteCalculateDrawProperties(root_.get());
+ child_impl_->SetScrollDelta(gfx::Vector2d(10, 10));
+ ExecuteCalculateDrawProperties(root_impl_);
// Here the child is affected by scroll delta, but the fixed position
// grand_child should not be affected.
@@ -182,129 +232,52 @@ TEST_F(LayerPositionConstraintTest,
expected_child_transform.Translate(-10.0, -10.0);
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
// Case 3: fixed-container size delta of 20, 20
- SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
- ExecuteCalculateDrawProperties(root_.get());
+ SetFixedContainerSizeDelta(child_impl_, gfx::Vector2d(20, 20));
+ ExecuteCalculateDrawProperties(root_impl_);
// Top-left fixed-position layer should not be affected by container size.
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
// Case 4: Bottom-right fixed-position layer.
- grand_child->SetPositionConstraint(fixed_to_bottom_right_);
- ExecuteCalculateDrawProperties(root_.get());
+ grand_child_->SetPositionConstraint(fixed_to_bottom_right_);
+ CommitAndUpdateImplPointers();
- // Bottom-right fixed-position layer moves as container resizes.
- expected_grand_child_transform.MakeIdentity();
- // Apply size delta from the child(container) layer.
- expected_grand_child_transform.Translate(20.0, 20.0);
-
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
-}
-
-TEST_F(LayerPositionConstraintTest,
- ScrollCompensationForFixedPositionLayerWithTransformedDirectContainer) {
- // This test checks for correct scroll compensation when the fixed-position
- // container is the direct parent of the fixed-position layer, but that
- // container is transformed. In this case, the fixed position element
- // inherits the container's transform, but the scroll delta that has to be
- // undone should not be affected by that transform.
- //
- // Transforms are in general non-commutative; using something like a
- // non-uniform scale helps to verify that translations and non-uniform scales
- // are applied in the correct order.
- LayerImpl* child = scroll_->children()[0];
- LayerImpl* grand_child = child->children()[0];
-
- // This scale will cause child and grand_child to be effectively 200 x 800
- // with respect to the render target.
- gfx::Transform non_uniform_scale;
- non_uniform_scale.Scale(2.0, 8.0);
- child->SetTransform(non_uniform_scale);
-
- child->SetIsContainerForFixedPositionLayers(true);
- grand_child->SetPositionConstraint(fixed_to_top_left_);
-
- // Case 1: scroll delta of 0, 0
- child->SetScrollDelta(gfx::Vector2d(0, 0));
- ExecuteCalculateDrawProperties(root_.get());
-
- gfx::Transform expected_child_transform;
- expected_child_transform.PreconcatTransform(non_uniform_scale);
-
- gfx::Transform expected_grand_child_transform = expected_child_transform;
-
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
-
- // Case 2: scroll delta of 10, 20
- child->SetScrollDelta(gfx::Vector2d(10, 20));
- ExecuteCalculateDrawProperties(root_.get());
-
- // The child should be affected by scroll delta, but the fixed position
- // grand_child should not be affected.
- expected_child_transform.MakeIdentity();
- expected_child_transform.Translate(-10.0, -20.0); // scroll delta
- expected_child_transform.PreconcatTransform(non_uniform_scale);
-
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
-
- // Case 3: fixed-container size delta of 20, 20
- SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
- ExecuteCalculateDrawProperties(root_.get());
-
- // Top-left fixed-position layer should not be affected by container size.
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
-
- // Case 4: Bottom-right fixed-position layer.
- grand_child->SetPositionConstraint(fixed_to_bottom_right_);
- ExecuteCalculateDrawProperties(root_.get());
+ child_impl_->SetScrollDelta(gfx::Vector2d(10, 10));
+ SetFixedContainerSizeDelta(child_impl_, gfx::Vector2d(20, 20));
+ ExecuteCalculateDrawProperties(root_impl_);
// Bottom-right fixed-position layer moves as container resizes.
expected_grand_child_transform.MakeIdentity();
- // Apply child layer transform.
- expected_grand_child_transform.PreconcatTransform(non_uniform_scale);
// Apply size delta from the child(container) layer.
expected_grand_child_transform.Translate(20.0, 20.0);
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
}
TEST_F(LayerPositionConstraintTest,
ScrollCompensationForFixedPositionLayerWithDistantContainer) {
// This test checks for correct scroll compensation when the fixed-position
// container is NOT the direct parent of the fixed-position layer.
- LayerImpl* child = scroll_->children()[0];
- LayerImpl* grand_child = child->children()[0];
- LayerImpl* great_grand_child = grand_child->children()[0];
+ child_->SetIsContainerForFixedPositionLayers(true);
+ grand_child_->SetPosition(gfx::PointF(8.f, 6.f));
+ great_grand_child_->SetPositionConstraint(fixed_to_top_left_);
- child->SetIsContainerForFixedPositionLayers(true);
- grand_child->SetPosition(gfx::PointF(8.f, 6.f));
- great_grand_child->SetPositionConstraint(fixed_to_top_left_);
+ CommitAndUpdateImplPointers();
// Case 1: scroll delta of 0, 0
- child->SetScrollDelta(gfx::Vector2d(0, 0));
- ExecuteCalculateDrawProperties(root_.get());
+ child_impl_->SetScrollDelta(gfx::Vector2d(0, 0));
+ ExecuteCalculateDrawProperties(root_impl_);
gfx::Transform expected_child_transform;
gfx::Transform expected_grand_child_transform;
@@ -314,15 +287,15 @@ TEST_F(LayerPositionConstraintTest,
expected_grand_child_transform;
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
- great_grand_child->draw_transform());
+ great_grand_child_impl_->draw_transform());
// Case 2: scroll delta of 10, 10
- child->SetScrollDelta(gfx::Vector2d(10, 10));
- ExecuteCalculateDrawProperties(root_.get());
+ child_impl_->SetScrollDelta(gfx::Vector2d(10, 10));
+ ExecuteCalculateDrawProperties(root_impl_);
// Here the child and grand_child are affected by scroll delta, but the fixed
// position great_grand_child should not be affected.
@@ -331,179 +304,64 @@ TEST_F(LayerPositionConstraintTest,
expected_grand_child_transform.MakeIdentity();
expected_grand_child_transform.Translate(-2.0, -4.0);
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
- great_grand_child->draw_transform());
-
- // Case 3: fixed-container size delta of 20, 20
- SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
- ExecuteCalculateDrawProperties(root_.get());
-
- // Top-left fixed-position layer should not be affected by container size.
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
- great_grand_child->draw_transform());
-
- // Case 4: Bottom-right fixed-position layer.
- great_grand_child->SetPositionConstraint(fixed_to_bottom_right_);
- ExecuteCalculateDrawProperties(root_.get());
-
- // Bottom-right fixed-position layer moves as container resizes.
- expected_great_grand_child_transform.MakeIdentity();
- // Apply size delta from the child(container) layer.
- expected_great_grand_child_transform.Translate(20.0, 20.0);
- // Apply layer position from the grand child layer.
- expected_great_grand_child_transform.Translate(8.0, 6.0);
-
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
- great_grand_child->draw_transform());
-}
-
-TEST_F(LayerPositionConstraintTest,
- ScrollCompensationForFixedPositionLayerWithDistantContainerAndTransforms) {
- // This test checks for correct scroll compensation when the fixed-position
- // container is NOT the direct parent of the fixed-position layer, and the
- // hierarchy has various transforms that have to be processed in the correct
- // order.
- LayerImpl* child = scroll_->children()[0];
- LayerImpl* grand_child = child->children()[0];
- LayerImpl* great_grand_child = grand_child->children()[0];
-
- gfx::Transform rotation_about_z;
- rotation_about_z.RotateAboutZAxis(90.0);
-
- child->SetIsContainerForFixedPositionLayers(true);
- child->SetTransform(rotation_about_z);
- grand_child->SetPosition(gfx::PointF(8.f, 6.f));
- grand_child->SetTransform(rotation_about_z);
- // great_grand_child is positioned upside-down with respect to the render
- // target.
- great_grand_child->SetPositionConstraint(fixed_to_top_left_);
-
- // Case 1: scroll delta of 0, 0
- child->SetScrollDelta(gfx::Vector2d(0, 0));
- ExecuteCalculateDrawProperties(root_.get());
-
- gfx::Transform expected_child_transform;
- expected_child_transform.PreconcatTransform(rotation_about_z);
-
- gfx::Transform expected_grand_child_transform;
- expected_grand_child_transform.PreconcatTransform(
- rotation_about_z); // child's local transform is inherited
- // translation because of position occurs before layer's local transform.
- expected_grand_child_transform.Translate(8.0, 6.0);
- expected_grand_child_transform.PreconcatTransform(
- rotation_about_z); // grand_child's local transform
-
- gfx::Transform expected_great_grand_child_transform =
- expected_grand_child_transform;
-
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
- great_grand_child->draw_transform());
-
- // Case 2: scroll delta of 10, 20
- child->SetScrollDelta(gfx::Vector2d(10, 20));
- ExecuteCalculateDrawProperties(root_.get());
-
- // Here the child and grand_child are affected by scroll delta, but the fixed
- // position great_grand_child should not be affected.
- expected_child_transform.MakeIdentity();
- expected_child_transform.Translate(-10.0, -20.0); // scroll delta
- expected_child_transform.PreconcatTransform(rotation_about_z);
-
- expected_grand_child_transform.MakeIdentity();
- expected_grand_child_transform.Translate(
- -10.0, -20.0); // child's scroll delta is inherited
- expected_grand_child_transform.PreconcatTransform(
- rotation_about_z); // child's local transform is inherited
- // translation because of position occurs before layer's local transform.
- expected_grand_child_transform.Translate(8.0, 6.0);
- expected_grand_child_transform.PreconcatTransform(
- rotation_about_z); // grand_child's local transform
-
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
- great_grand_child->draw_transform());
+ great_grand_child_impl_->draw_transform());
// Case 3: fixed-container size delta of 20, 20
- SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
- ExecuteCalculateDrawProperties(root_.get());
+ SetFixedContainerSizeDelta(child_impl_, gfx::Vector2d(20, 20));
+ ExecuteCalculateDrawProperties(root_impl_);
// Top-left fixed-position layer should not be affected by container size.
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
- great_grand_child->draw_transform());
+ great_grand_child_impl_->draw_transform());
// Case 4: Bottom-right fixed-position layer.
- great_grand_child->SetPositionConstraint(fixed_to_bottom_right_);
- ExecuteCalculateDrawProperties(root_.get());
+ great_grand_child_->SetPositionConstraint(fixed_to_bottom_right_);
+ CommitAndUpdateImplPointers();
+ child_impl_->SetScrollDelta(gfx::Vector2d(10, 10));
+ SetFixedContainerSizeDelta(child_impl_, gfx::Vector2d(20, 20));
+ ExecuteCalculateDrawProperties(root_impl_);
// Bottom-right fixed-position layer moves as container resizes.
expected_great_grand_child_transform.MakeIdentity();
- // Apply child layer transform.
- expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
// Apply size delta from the child(container) layer.
expected_great_grand_child_transform.Translate(20.0, 20.0);
// Apply layer position from the grand child layer.
expected_great_grand_child_transform.Translate(8.0, 6.0);
- // Apply grand child layer transform.
- expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
- great_grand_child->draw_transform());
+ great_grand_child_impl_->draw_transform());
}
TEST_F(LayerPositionConstraintTest,
ScrollCompensationForFixedPositionLayerWithMultipleScrollDeltas) {
// This test checks for correct scroll compensation when the fixed-position
// container has multiple ancestors that have nonzero scroll delta before
- // reaching the space where the layer is fixed. In this test, each scroll
- // delta occurs in a different space because of each layer's local transform.
- // This test checks for correct scroll compensation when the fixed-position
- // container is NOT the direct parent of the fixed-position layer, and the
- // hierarchy has various transforms that have to be processed in the correct
- // order.
- LayerImpl* child = scroll_->children()[0];
- LayerImpl* grand_child = child->children()[0];
- LayerImpl* great_grand_child = grand_child->children()[0];
-
+ // reaching the space where the layer is fixed.
gfx::Transform rotation_about_z;
rotation_about_z.RotateAboutZAxis(90.0);
- child->SetIsContainerForFixedPositionLayers(true);
- child->SetTransform(rotation_about_z);
- grand_child->SetPosition(gfx::PointF(8.f, 6.f));
- grand_child->SetTransform(rotation_about_z);
- // great_grand_child is positioned upside-down with respect to the render
- // target.
- great_grand_child->SetPositionConstraint(fixed_to_top_left_);
+ child_transform_layer_->SetIsContainerForFixedPositionLayers(true);
+ child_transform_layer_->SetTransform(rotation_about_z);
+ grand_child_->SetPosition(gfx::PointF(8.f, 6.f));
+ great_grand_child_->SetPositionConstraint(fixed_to_top_left_);
+
+ CommitAndUpdateImplPointers();
// Case 1: scroll delta of 0, 0
- child->SetScrollDelta(gfx::Vector2d(0, 0));
- ExecuteCalculateDrawProperties(root_.get());
+ child_impl_->SetScrollDelta(gfx::Vector2d(0, 0));
+ ExecuteCalculateDrawProperties(root_impl_);
gfx::Transform expected_child_transform;
expected_child_transform.PreconcatTransform(rotation_about_z);
@@ -513,82 +371,44 @@ TEST_F(LayerPositionConstraintTest,
rotation_about_z); // child's local transform is inherited
// translation because of position occurs before layer's local transform.
expected_grand_child_transform.Translate(8.0, 6.0);
- expected_grand_child_transform.PreconcatTransform(
- rotation_about_z); // grand_child's local transform
gfx::Transform expected_great_grand_child_transform =
expected_grand_child_transform;
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
- great_grand_child->draw_transform());
+ great_grand_child_impl_->draw_transform());
// Case 2: scroll delta of 10, 20
- child->SetScrollDelta(gfx::Vector2d(10, 0));
- grand_child->SetScrollDelta(gfx::Vector2d(5, 0));
- ExecuteCalculateDrawProperties(root_.get());
+ child_impl_->SetScrollDelta(gfx::Vector2d(10, 0));
+ grand_child_impl_->SetScrollDelta(gfx::Vector2d(5, 0));
+ ExecuteCalculateDrawProperties(root_impl_);
// Here the child and grand_child are affected by scroll delta, but the fixed
// position great_grand_child should not be affected.
expected_child_transform.MakeIdentity();
- expected_child_transform.Translate(-10.0, 0.0); // scroll delta
expected_child_transform.PreconcatTransform(rotation_about_z);
+ expected_child_transform.Translate(-10.0, 0.0); // scroll delta
expected_grand_child_transform.MakeIdentity();
- expected_grand_child_transform.Translate(
- -10.0, 0.0); // child's scroll delta is inherited
expected_grand_child_transform.PreconcatTransform(
rotation_about_z); // child's local transform is inherited
+ expected_grand_child_transform.Translate(
+ -10.0, 0.0); // child's scroll delta is inherited
expected_grand_child_transform.Translate(-5.0,
0.0); // grand_child's scroll delta
- // translation because of position occurs before layer's local transform.
+ // translation because of position
expected_grand_child_transform.Translate(8.0, 6.0);
- expected_grand_child_transform.PreconcatTransform(
- rotation_about_z); // grand_child's local transform
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
- great_grand_child->draw_transform());
-
- // Case 3: fixed-container size delta of 20, 20
- SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
- ExecuteCalculateDrawProperties(root_.get());
-
- // Top-left fixed-position layer should not be affected by container size.
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
- great_grand_child->draw_transform());
-
- // Case 4: Bottom-right fixed-position layer.
- great_grand_child->SetPositionConstraint(fixed_to_bottom_right_);
- ExecuteCalculateDrawProperties(root_.get());
-
- // Bottom-right fixed-position layer moves as container resizes.
- expected_great_grand_child_transform.MakeIdentity();
- // Apply child layer transform.
- expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
- // Apply size delta from the child(container) layer.
- expected_great_grand_child_transform.Translate(20.0, 20.0);
- // Apply layer position from the grand child layer.
- expected_great_grand_child_transform.Translate(8.0, 6.0);
- // Apply grand child layer transform.
- expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
-
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
- great_grand_child->draw_transform());
+ great_grand_child_impl_->draw_transform());
}
TEST_F(LayerPositionConstraintTest,
@@ -597,44 +417,41 @@ TEST_F(LayerPositionConstraintTest,
// container contributes to a different render surface than the fixed-position
// layer. In this case, the surface draw transforms also have to be accounted
// for when checking the scroll delta.
- LayerImpl* child = scroll_->children()[0];
- LayerImpl* grand_child = child->children()[0];
- LayerImpl* great_grand_child = grand_child->children()[0];
-
- child->SetIsContainerForFixedPositionLayers(true);
- grand_child->SetPosition(gfx::PointF(8.f, 6.f));
- grand_child->SetHasRenderSurface(true);
- great_grand_child->SetPositionConstraint(fixed_to_top_left_);
- great_grand_child->SetDrawsContent(true);
+ child_->SetIsContainerForFixedPositionLayers(true);
+ grand_child_->SetPosition(gfx::PointF(8.f, 6.f));
+ grand_child_->SetForceRenderSurface(true);
+ great_grand_child_->SetPositionConstraint(fixed_to_top_left_);
gfx::Transform rotation_about_z;
rotation_about_z.RotateAboutZAxis(90.0);
- grand_child->SetTransform(rotation_about_z);
+ great_grand_child_->SetTransform(rotation_about_z);
+
+ CommitAndUpdateImplPointers();
// Case 1: scroll delta of 0, 0
- child->SetScrollDelta(gfx::Vector2d(0, 0));
- ExecuteCalculateDrawProperties(root_.get());
+ child_impl_->SetScrollDelta(gfx::Vector2d(0, 0));
+ ExecuteCalculateDrawProperties(root_impl_);
gfx::Transform expected_child_transform;
gfx::Transform expected_surface_draw_transform;
expected_surface_draw_transform.Translate(8.0, 6.0);
- expected_surface_draw_transform.PreconcatTransform(rotation_about_z);
gfx::Transform expected_grand_child_transform;
gfx::Transform expected_great_grand_child_transform;
- ASSERT_TRUE(grand_child->render_surface());
+ expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
+ EXPECT_TRUE(grand_child_impl_->render_surface());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(
expected_surface_draw_transform,
- grand_child->render_surface()->draw_transform());
+ grand_child_impl_->render_surface()->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
- great_grand_child->draw_transform());
+ great_grand_child_impl_->draw_transform());
// Case 2: scroll delta of 10, 30
- child->SetScrollDelta(gfx::Vector2d(10, 30));
- ExecuteCalculateDrawProperties(root_.get());
+ child_impl_->SetScrollDelta(gfx::Vector2d(10, 30));
+ ExecuteCalculateDrawProperties(root_impl_);
// Here the grand_child remains unchanged, because it scrolls along with the
// render surface, and the translation is actually in the render surface. But,
@@ -650,55 +467,47 @@ TEST_F(LayerPositionConstraintTest,
expected_surface_draw_transform.MakeIdentity();
expected_surface_draw_transform.Translate(-10.0, -30.0); // scroll delta
expected_surface_draw_transform.Translate(8.0, 6.0);
- expected_surface_draw_transform.PreconcatTransform(rotation_about_z);
- // The rotation and its inverse are needed to place the scroll delta
- // compensation in the correct space. This test will fail if the
- // rotation/inverse are backwards, too, so it requires perfect order of
- // operations.
expected_great_grand_child_transform.MakeIdentity();
- expected_great_grand_child_transform.PreconcatTransform(
- Inverse(rotation_about_z));
// explicit canceling out the scroll delta that gets embedded in the fixed
// position layer's surface.
expected_great_grand_child_transform.Translate(10.0, 30.0);
expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
- ASSERT_TRUE(grand_child->render_surface());
+ EXPECT_TRUE(grand_child_impl_->render_surface());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(
expected_surface_draw_transform,
- grand_child->render_surface()->draw_transform());
+ grand_child_impl_->render_surface()->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
- great_grand_child->draw_transform());
+ great_grand_child_impl_->draw_transform());
// Case 3: fixed-container size delta of 20, 20
- SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
- ExecuteCalculateDrawProperties(root_.get());
+ SetFixedContainerSizeDelta(child_impl_, gfx::Vector2d(20, 20));
+ ExecuteCalculateDrawProperties(root_impl_);
// Top-left fixed-position layer should not be affected by container size.
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
- great_grand_child->draw_transform());
+ great_grand_child_impl_->draw_transform());
// Case 4: Bottom-right fixed-position layer.
- great_grand_child->SetPositionConstraint(fixed_to_bottom_right_);
- ExecuteCalculateDrawProperties(root_.get());
+ great_grand_child_->SetPositionConstraint(fixed_to_bottom_right_);
+
+ CommitAndUpdateImplPointers();
+ child_impl_->SetScrollDelta(gfx::Vector2d(10, 30));
+ SetFixedContainerSizeDelta(child_impl_, gfx::Vector2d(20, 20));
+
+ ExecuteCalculateDrawProperties(root_impl_);
// Bottom-right fixed-position layer moves as container resizes.
expected_great_grand_child_transform.MakeIdentity();
- // The rotation and its inverse are needed to place the scroll delta
- // compensation in the correct space. This test will fail if the
- // rotation/inverse are backwards, too, so it requires perfect order of
- // operations.
- expected_great_grand_child_transform.PreconcatTransform(
- Inverse(rotation_about_z));
// explicit canceling out the scroll delta that gets embedded in the fixed
// position layer's surface.
expected_great_grand_child_transform.Translate(10.0, 30.0);
@@ -707,11 +516,11 @@ TEST_F(LayerPositionConstraintTest,
expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
- great_grand_child->draw_transform());
+ great_grand_child_impl_->draw_transform());
}
TEST_F(LayerPositionConstraintTest,
@@ -721,35 +530,24 @@ TEST_F(LayerPositionConstraintTest,
// layer, with additional render surfaces in-between. This checks that the
// conversion to ancestor surfaces is accumulated properly in the final matrix
// transform.
- LayerImpl* child = scroll_->children()[0];
- LayerImpl* grand_child = child->children()[0];
- LayerImpl* great_grand_child = grand_child->children()[0];
// Add one more layer to the test tree for this scenario.
- {
- gfx::Transform identity;
- scoped_ptr<LayerImpl> fixed_position_child =
- LayerImpl::Create(host_impl_.active_tree(), 5);
- SetLayerPropertiesForTesting(fixed_position_child.get(),
- identity,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(100, 100),
- true);
- great_grand_child->AddChild(fixed_position_child.Pass());
- }
- LayerImpl* fixed_position_child = great_grand_child->children()[0];
+ scoped_refptr<Layer> fixed_position_child =
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings_));
+ SetLayerPropertiesForTesting(fixed_position_child.get(), gfx::Transform(),
+ gfx::Point3F(), gfx::PointF(),
+ gfx::Size(100, 100), true);
+ great_grand_child_->AddChild(fixed_position_child);
// Actually set up the scenario here.
- child->SetIsContainerForFixedPositionLayers(true);
- grand_child->SetPosition(gfx::PointF(8.f, 6.f));
- grand_child->SetHasRenderSurface(true);
- great_grand_child->SetPosition(gfx::PointF(40.f, 60.f));
- great_grand_child->SetHasRenderSurface(true);
+ child_->SetIsContainerForFixedPositionLayers(true);
+ grand_child_->SetPosition(gfx::PointF(8.f, 6.f));
+ grand_child_->SetForceRenderSurface(true);
+ great_grand_child_->SetPosition(gfx::PointF(40.f, 60.f));
+ great_grand_child_->SetForceRenderSurface(true);
fixed_position_child->SetPositionConstraint(fixed_to_top_left_);
- fixed_position_child->SetDrawsContent(true);
- // The additional rotations, which are non-commutative with translations, help
+ // The additional rotation, which is non-commutative with translations, helps
// to verify that we have correct order-of-operations in the final scroll
// compensation. Note that rotating about the center of the layer ensures we
// do not accidentally clip away layers that we want to test.
@@ -757,51 +555,50 @@ TEST_F(LayerPositionConstraintTest,
rotation_about_z.Translate(50.0, 50.0);
rotation_about_z.RotateAboutZAxis(90.0);
rotation_about_z.Translate(-50.0, -50.0);
- grand_child->SetTransform(rotation_about_z);
- great_grand_child->SetTransform(rotation_about_z);
+ fixed_position_child->SetTransform(rotation_about_z);
+
+ CommitAndUpdateImplPointers();
+ LayerImpl* fixed_position_child_impl = great_grand_child_impl_->children()[0];
// Case 1: scroll delta of 0, 0
- child->SetScrollDelta(gfx::Vector2d(0, 0));
- ExecuteCalculateDrawProperties(root_.get());
+ child_impl_->SetScrollDelta(gfx::Vector2d(0, 0));
+ ExecuteCalculateDrawProperties(root_impl_);
gfx::Transform expected_child_transform;
gfx::Transform expected_grand_child_surface_draw_transform;
expected_grand_child_surface_draw_transform.Translate(8.0, 6.0);
- expected_grand_child_surface_draw_transform.PreconcatTransform(
- rotation_about_z);
gfx::Transform expected_grand_child_transform;
gfx::Transform expected_great_grand_child_surface_draw_transform;
expected_great_grand_child_surface_draw_transform.Translate(40.0, 60.0);
- expected_great_grand_child_surface_draw_transform.PreconcatTransform(
- rotation_about_z);
gfx::Transform expected_great_grand_child_transform;
gfx::Transform expected_fixed_position_child_transform;
+ expected_fixed_position_child_transform.PreconcatTransform(rotation_about_z);
- ASSERT_TRUE(grand_child->render_surface());
- ASSERT_TRUE(great_grand_child->render_surface());
+ EXPECT_TRUE(grand_child_impl_->render_surface());
+ EXPECT_TRUE(great_grand_child_impl_->render_surface());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(
expected_grand_child_surface_draw_transform,
- grand_child->render_surface()->draw_transform());
+ grand_child_impl_->render_surface()->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(
expected_great_grand_child_surface_draw_transform,
- great_grand_child->render_surface()->draw_transform());
+ great_grand_child_impl_->render_surface()->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
- great_grand_child->draw_transform());
+ great_grand_child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
- fixed_position_child->draw_transform());
+ fixed_position_child_impl->draw_transform());
// Case 2: scroll delta of 10, 30
- child->SetScrollDelta(gfx::Vector2d(10, 30));
- ExecuteCalculateDrawProperties(root_.get());
+ child_impl_->SetScrollDelta(gfx::Vector2d(10, 30));
+ ExecuteCalculateDrawProperties(root_impl_);
expected_child_transform.MakeIdentity();
expected_child_transform.Translate(-10.0, -30.0); // scroll delta
@@ -810,8 +607,6 @@ TEST_F(LayerPositionConstraintTest,
expected_grand_child_surface_draw_transform.Translate(-10.0,
-30.0); // scroll delta
expected_grand_child_surface_draw_transform.Translate(8.0, 6.0);
- expected_grand_child_surface_draw_transform.PreconcatTransform(
- rotation_about_z);
// grand_child, great_grand_child, and great_grand_child's surface are not
// expected to change, since they are all not fixed, and they are all drawn
@@ -819,85 +614,191 @@ TEST_F(LayerPositionConstraintTest,
// accounted for.
// But the great-great grandchild, "fixed_position_child", should have a
- // transform that explicitly cancels out the scroll delta. The expected
- // transform is: compound_draw_transform.Inverse() * translate(positive scroll
- // delta) * compound_origin_transform from great_grand_childSurface's origin
- // to the root surface.
- gfx::Transform compound_draw_transform;
- compound_draw_transform.Translate(8.0,
- 6.0); // origin translation of grand_child
- compound_draw_transform.PreconcatTransform(
- rotation_about_z); // rotation of grand_child
- compound_draw_transform.Translate(
- 40.0, 60.0); // origin translation of great_grand_child
- compound_draw_transform.PreconcatTransform(
- rotation_about_z); // rotation of great_grand_child
-
+ // transform that explicitly cancels out the scroll delta.
expected_fixed_position_child_transform.MakeIdentity();
- expected_fixed_position_child_transform.PreconcatTransform(
- Inverse(compound_draw_transform));
- // explicit canceling out the scroll delta that gets embedded in the fixed
- // position layer's surface.
expected_fixed_position_child_transform.Translate(10.0, 30.0);
- expected_fixed_position_child_transform.PreconcatTransform(
- compound_draw_transform);
+ expected_fixed_position_child_transform.PreconcatTransform(rotation_about_z);
- ASSERT_TRUE(grand_child->render_surface());
- ASSERT_TRUE(great_grand_child->render_surface());
+ EXPECT_TRUE(grand_child_impl_->render_surface());
+ EXPECT_TRUE(great_grand_child_impl_->render_surface());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(
expected_grand_child_surface_draw_transform,
- grand_child->render_surface()->draw_transform());
+ grand_child_impl_->render_surface()->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(
expected_great_grand_child_surface_draw_transform,
- great_grand_child->render_surface()->draw_transform());
+ great_grand_child_impl_->render_surface()->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
- great_grand_child->draw_transform());
+ great_grand_child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
- fixed_position_child->draw_transform());
-
+ fixed_position_child_impl->draw_transform());
// Case 3: fixed-container size delta of 20, 20
- SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
- ExecuteCalculateDrawProperties(root_.get());
+ SetFixedContainerSizeDelta(child_impl_, gfx::Vector2d(20, 20));
+ ExecuteCalculateDrawProperties(root_impl_);
// Top-left fixed-position layer should not be affected by container size.
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
- great_grand_child->draw_transform());
+ great_grand_child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
- fixed_position_child->draw_transform());
+ fixed_position_child_impl->draw_transform());
// Case 4: Bottom-right fixed-position layer.
fixed_position_child->SetPositionConstraint(fixed_to_bottom_right_);
- ExecuteCalculateDrawProperties(root_.get());
+ CommitAndUpdateImplPointers();
+ fixed_position_child_impl = great_grand_child_impl_->children()[0];
+ child_impl_->SetScrollDelta(gfx::Vector2d(10, 30));
+ SetFixedContainerSizeDelta(child_impl_, gfx::Vector2d(20, 20));
+ ExecuteCalculateDrawProperties(root_impl_);
// Bottom-right fixed-position layer moves as container resizes.
expected_fixed_position_child_transform.MakeIdentity();
- expected_fixed_position_child_transform.PreconcatTransform(
- Inverse(compound_draw_transform));
// explicit canceling out the scroll delta that gets embedded in the fixed
// position layer's surface.
expected_fixed_position_child_transform.Translate(10.0, 30.0);
// Also apply size delta in the child(container) layer space.
expected_fixed_position_child_transform.Translate(20.0, 20.0);
- expected_fixed_position_child_transform.PreconcatTransform(
- compound_draw_transform);
+ expected_fixed_position_child_transform.PreconcatTransform(rotation_about_z);
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
- great_grand_child->draw_transform());
+ great_grand_child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
- fixed_position_child->draw_transform());
+ fixed_position_child_impl->draw_transform());
+}
+
+TEST_F(
+ LayerPositionConstraintTest,
+ ScrollCompensationForFixedPositionLayerWithMultipleSurfacesAndTransforms) {
+ // This test checks for correct scroll compensation when the fixed-position
+ // container contributes to a different render surface than the fixed-position
+ // layer, with additional render surfaces in-between, and the fixed-position
+ // container is transformed. This checks that the conversion to ancestor
+ // surfaces is accumulated properly in the final matrix transform.
+
+ // Add one more layer to the test tree for this scenario.
+ scoped_refptr<Layer> fixed_position_child =
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings_));
+ SetLayerPropertiesForTesting(fixed_position_child.get(), gfx::Transform(),
+ gfx::Point3F(), gfx::PointF(),
+ gfx::Size(100, 100), true);
+ great_grand_child_->AddChild(fixed_position_child);
+
+ // Actually set up the scenario here.
+ child_transform_layer_->SetIsContainerForFixedPositionLayers(true);
+ grand_child_->SetPosition(gfx::PointF(8.f, 6.f));
+ grand_child_->SetForceRenderSurface(true);
+ great_grand_child_->SetPosition(gfx::PointF(40.f, 60.f));
+ great_grand_child_->SetForceRenderSurface(true);
+ fixed_position_child->SetPositionConstraint(fixed_to_top_left_);
+
+ // The additional rotations, which are non-commutative with translations, help
+ // to verify that we have correct order-of-operations in the final scroll
+ // compensation. Note that rotating about the center of the layer ensures we
+ // do not accidentally clip away layers that we want to test.
+ gfx::Transform rotation_about_z;
+ rotation_about_z.Translate(50.0, 50.0);
+ rotation_about_z.RotateAboutZAxis(90.0);
+ rotation_about_z.Translate(-50.0, -50.0);
+ child_transform_layer_->SetTransform(rotation_about_z);
+ fixed_position_child->SetTransform(rotation_about_z);
+
+ CommitAndUpdateImplPointers();
+ LayerImpl* fixed_position_child_impl = great_grand_child_impl_->children()[0];
+
+ // Case 1: scroll delta of 0, 0
+ child_impl_->SetScrollDelta(gfx::Vector2d(0, 0));
+ ExecuteCalculateDrawProperties(root_impl_);
+
+ gfx::Transform expected_child_transform;
+ expected_child_transform.PreconcatTransform(rotation_about_z);
+
+ gfx::Transform expected_grand_child_surface_draw_transform;
+ expected_grand_child_surface_draw_transform.PreconcatTransform(
+ rotation_about_z);
+ expected_grand_child_surface_draw_transform.Translate(8.0, 6.0);
+
+ gfx::Transform expected_grand_child_transform;
+
+ gfx::Transform expected_great_grand_child_surface_draw_transform;
+ expected_great_grand_child_surface_draw_transform.Translate(40.0, 60.0);
+
+ gfx::Transform expected_great_grand_child_transform;
+
+ gfx::Transform expected_fixed_position_child_transform;
+ expected_fixed_position_child_transform.PreconcatTransform(rotation_about_z);
+
+ EXPECT_TRUE(grand_child_impl_->render_surface());
+ EXPECT_TRUE(great_grand_child_impl_->render_surface());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
+ child_impl_->draw_transform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(
+ expected_grand_child_surface_draw_transform,
+ grand_child_impl_->render_surface()->draw_transform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
+ grand_child_impl_->draw_transform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(
+ expected_great_grand_child_surface_draw_transform,
+ great_grand_child_impl_->render_surface()->draw_transform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
+ great_grand_child_impl_->draw_transform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
+ fixed_position_child_impl->draw_transform());
+
+ // Case 2: scroll delta of 10, 30
+ child_impl_->SetScrollDelta(gfx::Vector2d(10, 30));
+ ExecuteCalculateDrawProperties(root_impl_);
+
+ expected_child_transform.MakeIdentity();
+ expected_child_transform.PreconcatTransform(rotation_about_z);
+ expected_child_transform.Translate(-10.0, -30.0); // scroll delta
+
+ expected_grand_child_surface_draw_transform.MakeIdentity();
+ expected_grand_child_surface_draw_transform.PreconcatTransform(
+ rotation_about_z);
+ expected_grand_child_surface_draw_transform.Translate(-10.0,
+ -30.0); // scroll delta
+ expected_grand_child_surface_draw_transform.Translate(8.0, 6.0);
+
+ // grand_child, great_grand_child, and great_grand_child's surface are not
+ // expected to change, since they are all not fixed, and they are all drawn
+ // with respect to grand_child's surface that already has the scroll delta
+ // accounted for.
+
+ // But the great-great grandchild, "fixed_position_child", should have a
+ // transform that explicitly cancels out the scroll delta.
+ expected_fixed_position_child_transform.MakeIdentity();
+ // explicit canceling out the scroll delta that gets embedded in the fixed
+ // position layer's surface.
+ expected_fixed_position_child_transform.Translate(10.0, 30.0);
+ expected_fixed_position_child_transform.PreconcatTransform(rotation_about_z);
+
+ EXPECT_TRUE(grand_child_impl_->render_surface());
+ EXPECT_TRUE(great_grand_child_impl_->render_surface());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
+ child_impl_->draw_transform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(
+ expected_grand_child_surface_draw_transform,
+ grand_child_impl_->render_surface()->draw_transform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
+ grand_child_impl_->draw_transform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(
+ expected_great_grand_child_surface_draw_transform,
+ great_grand_child_impl_->render_surface()->draw_transform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
+ great_grand_child_impl_->draw_transform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
+ fixed_position_child_impl->draw_transform());
}
TEST_F(LayerPositionConstraintTest,
@@ -907,33 +808,31 @@ TEST_F(LayerPositionConstraintTest,
// should be treated like a layer that contributes to a render target, and
// that render target is completely irrelevant; it should not affect the
// scroll compensation.
- LayerImpl* child = scroll_->children()[0];
- LayerImpl* grand_child = child->children()[0];
+ child_->SetIsContainerForFixedPositionLayers(true);
+ child_->SetForceRenderSurface(true);
+ grand_child_->SetPositionConstraint(fixed_to_top_left_);
- child->SetIsContainerForFixedPositionLayers(true);
- child->SetHasRenderSurface(true);
- grand_child->SetPositionConstraint(fixed_to_top_left_);
- grand_child->SetDrawsContent(true);
+ CommitAndUpdateImplPointers();
// Case 1: scroll delta of 0, 0
- child->SetScrollDelta(gfx::Vector2d(0, 0));
- ExecuteCalculateDrawProperties(root_.get());
+ child_impl_->SetScrollDelta(gfx::Vector2d(0, 0));
+ ExecuteCalculateDrawProperties(root_impl_);
gfx::Transform expected_surface_draw_transform;
- expected_surface_draw_transform.Translate(0.0, 0.0);
gfx::Transform expected_child_transform;
gfx::Transform expected_grand_child_transform;
- ASSERT_TRUE(child->render_surface());
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_surface_draw_transform,
- child->render_surface()->draw_transform());
+ EXPECT_TRUE(child_impl_->render_surface());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(
+ expected_surface_draw_transform,
+ child_impl_->render_surface()->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
// Case 2: scroll delta of 10, 10
- child->SetScrollDelta(gfx::Vector2d(10, 10));
- ExecuteCalculateDrawProperties(root_.get());
+ child_impl_->SetScrollDelta(gfx::Vector2d(10, 10));
+ ExecuteCalculateDrawProperties(root_impl_);
// The surface is translated by scroll delta, the child transform doesn't
// change because it scrolls along with the surface, but the fixed position
@@ -943,27 +842,31 @@ TEST_F(LayerPositionConstraintTest,
expected_grand_child_transform.MakeIdentity();
expected_grand_child_transform.Translate(10.0, 10.0);
- ASSERT_TRUE(child->render_surface());
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_surface_draw_transform,
- child->render_surface()->draw_transform());
+ EXPECT_TRUE(child_impl_->render_surface());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(
+ expected_surface_draw_transform,
+ child_impl_->render_surface()->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
// Case 3: fixed-container size delta of 20, 20
- SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
- ExecuteCalculateDrawProperties(root_.get());
+ SetFixedContainerSizeDelta(child_impl_, gfx::Vector2d(20, 20));
+ ExecuteCalculateDrawProperties(root_impl_);
// Top-left fixed-position layer should not be affected by container size.
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
// Case 4: Bottom-right fixed-position layer.
- grand_child->SetPositionConstraint(fixed_to_bottom_right_);
- ExecuteCalculateDrawProperties(root_.get());
+ grand_child_->SetPositionConstraint(fixed_to_bottom_right_);
+ CommitAndUpdateImplPointers();
+ child_impl_->SetScrollDelta(gfx::Vector2d(10, 10));
+ SetFixedContainerSizeDelta(child_impl_, gfx::Vector2d(20, 20));
+ ExecuteCalculateDrawProperties(root_impl_);
// Bottom-right fixed-position layer moves as container resizes.
expected_grand_child_transform.MakeIdentity();
@@ -975,9 +878,9 @@ TEST_F(LayerPositionConstraintTest,
expected_grand_child_transform.Translate(20.0, 20.0);
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
}
TEST_F(LayerPositionConstraintTest,
@@ -985,53 +888,56 @@ TEST_F(LayerPositionConstraintTest,
// This test checks the scenario where a fixed-position layer also happens to
// be a container itself for a descendant fixed position layer. In particular,
// the layer should not accidentally be fixed to itself.
- LayerImpl* child = scroll_->children()[0];
- LayerImpl* grand_child = child->children()[0];
-
- child->SetIsContainerForFixedPositionLayers(true);
- grand_child->SetPositionConstraint(fixed_to_top_left_);
+ child_->SetIsContainerForFixedPositionLayers(true);
+ grand_child_->SetPositionConstraint(fixed_to_top_left_);
// This should not confuse the grand_child. If correct, the grand_child would
// still be considered fixed to its container (i.e. "child").
- grand_child->SetIsContainerForFixedPositionLayers(true);
+ grand_child_->SetIsContainerForFixedPositionLayers(true);
+
+ CommitAndUpdateImplPointers();
// Case 1: scroll delta of 0, 0
- child->SetScrollDelta(gfx::Vector2d(0, 0));
- ExecuteCalculateDrawProperties(root_.get());
+ child_impl_->SetScrollDelta(gfx::Vector2d(0, 0));
+ ExecuteCalculateDrawProperties(root_impl_);
gfx::Transform expected_child_transform;
gfx::Transform expected_grand_child_transform;
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
// Case 2: scroll delta of 10, 10
- child->SetScrollDelta(gfx::Vector2d(10, 10));
- ExecuteCalculateDrawProperties(root_.get());
+ child_impl_->SetScrollDelta(gfx::Vector2d(10, 10));
+ ExecuteCalculateDrawProperties(root_impl_);
// Here the child is affected by scroll delta, but the fixed position
// grand_child should not be affected.
expected_child_transform.MakeIdentity();
expected_child_transform.Translate(-10.0, -10.0);
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
// Case 3: fixed-container size delta of 20, 20
- SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
- ExecuteCalculateDrawProperties(root_.get());
+ SetFixedContainerSizeDelta(child_impl_, gfx::Vector2d(20, 20));
+ ExecuteCalculateDrawProperties(root_impl_);
// Top-left fixed-position layer should not be affected by container size.
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
// Case 4: Bottom-right fixed-position layer.
- grand_child->SetPositionConstraint(fixed_to_bottom_right_);
- ExecuteCalculateDrawProperties(root_.get());
+ grand_child_->SetPositionConstraint(fixed_to_bottom_right_);
+ CommitAndUpdateImplPointers();
+ child_impl_->SetScrollDelta(gfx::Vector2d(10, 10));
+ SetFixedContainerSizeDelta(child_impl_, gfx::Vector2d(20, 20));
+
+ ExecuteCalculateDrawProperties(root_impl_);
// Bottom-right fixed-position layer moves as container resizes.
expected_grand_child_transform.MakeIdentity();
@@ -1039,9 +945,9 @@ TEST_F(LayerPositionConstraintTest,
expected_grand_child_transform.Translate(20.0, 20.0);
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
}
TEST_F(LayerPositionConstraintTest,
@@ -1051,22 +957,19 @@ TEST_F(LayerPositionConstraintTest,
// In this situation, the parent fixed-position layer will receive
// the scroll compensation, and the child fixed-position layer does not
// need to compensate further.
-
- LayerImpl* child = scroll_->children()[0];
- LayerImpl* grand_child = child->children()[0];
- LayerImpl* great_grand_child = grand_child->children()[0];
-
- child->SetIsContainerForFixedPositionLayers(true);
- grand_child->SetPositionConstraint(fixed_to_top_left_);
+ child_->SetIsContainerForFixedPositionLayers(true);
+ grand_child_->SetPositionConstraint(fixed_to_top_left_);
// Note carefully - great_grand_child is fixed to bottom right, to test
// sizeDelta being applied correctly; the compensation skips the grand_child
// because it is fixed to top left.
- great_grand_child->SetPositionConstraint(fixed_to_bottom_right_);
+ great_grand_child_->SetPositionConstraint(fixed_to_bottom_right_);
+
+ CommitAndUpdateImplPointers();
// Case 1: scrollDelta
- child->SetScrollDelta(gfx::Vector2d(10, 10));
- ExecuteCalculateDrawProperties(root_.get());
+ child_impl_->SetScrollDelta(gfx::Vector2d(10, 10));
+ ExecuteCalculateDrawProperties(root_impl_);
// Here the child is affected by scroll delta, but the fixed position
// grand_child should not be affected.
@@ -1077,16 +980,16 @@ TEST_F(LayerPositionConstraintTest,
gfx::Transform expected_great_grand_child_transform;
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
- great_grand_child->draw_transform());
+ great_grand_child_impl_->draw_transform());
// Case 2: sizeDelta
- child->SetScrollDelta(gfx::Vector2d(0, 0));
- SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
- ExecuteCalculateDrawProperties(root_.get());
+ child_impl_->SetScrollDelta(gfx::Vector2d(0, 0));
+ SetFixedContainerSizeDelta(child_impl_, gfx::Vector2d(20, 20));
+ ExecuteCalculateDrawProperties(root_impl_);
expected_child_transform.MakeIdentity();
@@ -1097,11 +1000,11 @@ TEST_F(LayerPositionConstraintTest,
expected_great_grand_child_transform.Translate(20.0, 20.0);
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
+ child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
- grand_child->draw_transform());
+ grand_child_impl_->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
- great_grand_child->draw_transform());
+ great_grand_child_impl_->draw_transform());
}
TEST_F(LayerPositionConstraintTest,
@@ -1111,27 +1014,27 @@ TEST_F(LayerPositionConstraintTest,
// position containers. In this situation, the child fixed-position element
// would still have to compensate with respect to its container.
- LayerImpl* container1 = scroll_->children()[0];
- LayerImpl* fixed_to_container1 = container1->children()[0];
- LayerImpl* container2 = fixed_to_container1->children()[0];
+ // Add one more layer to the hierarchy for this test.
+ scoped_refptr<Layer> great_great_grand_child =
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings_));
+ great_grand_child_->AddChild(great_great_grand_child);
- {
- // Add one more layer to the hierarchy for this test.
- scoped_ptr<LayerImpl> fixed_to_container2_ptr =
- LayerImpl::Create(host_impl_.active_tree(), 5);
- container2->AddChild(fixed_to_container2_ptr.Pass());
- }
+ child_->SetIsContainerForFixedPositionLayers(true);
+ grand_child_->SetPositionConstraint(fixed_to_top_left_);
+ great_grand_child_->SetIsContainerForFixedPositionLayers(true);
+ great_grand_child_->SetScrollClipLayerId(root_->id());
+ great_great_grand_child->SetPositionConstraint(fixed_to_top_left_);
- LayerImpl* fixed_to_container2 = container2->children()[0];
+ CommitAndUpdateImplPointers();
- container1->SetIsContainerForFixedPositionLayers(true);
- fixed_to_container1->SetPositionConstraint(fixed_to_top_left_);
- container2->SetIsContainerForFixedPositionLayers(true);
- fixed_to_container2->SetPositionConstraint(fixed_to_top_left_);
+ LayerImpl* container1 = child_impl_;
+ LayerImpl* fixed_to_container1 = grand_child_impl_;
+ LayerImpl* container2 = great_grand_child_impl_;
+ LayerImpl* fixed_to_container2 = container2->children()[0];
container1->SetScrollDelta(gfx::Vector2d(0, 15));
container2->SetScrollDelta(gfx::Vector2d(30, 0));
- ExecuteCalculateDrawProperties(root_.get());
+ ExecuteCalculateDrawProperties(root_impl_);
gfx::Transform expected_container1_transform;
expected_container1_transform.Translate(0.0, -15.0);
@@ -1158,5 +1061,57 @@ TEST_F(LayerPositionConstraintTest,
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_to_container2_transform,
fixed_to_container2->draw_transform());
}
+
+TEST_F(LayerPositionConstraintTest,
+ ScrollCompensationForInnerViewportBoundsDelta) {
+ // This test checks for correct scroll compensation when the fixed-position
+ // container is the inner viewport scroll layer and has non-zero bounds delta.
+ scoped_refptr<Layer> fixed_child =
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings_));
+ fixed_child->SetBounds(gfx::Size(300, 300));
+ scroll_layer_->AddChild(fixed_child);
+ fixed_child->SetPositionConstraint(fixed_to_top_left_);
+
+ CommitAndUpdateImplPointers();
+
+ LayerImpl* fixed_child_impl =
+ root_impl_->layer_tree_impl()->FindActiveTreeLayerById(fixed_child->id());
+
+ // Case 1: fixed-container size delta of 20, 20
+ scroll_layer_impl_->SetScrollDelta(gfx::Vector2d(10, 10));
+ SetFixedContainerSizeDelta(scroll_layer_impl_, gfx::Vector2d(20, 20));
+ gfx::Transform expected_scroll_layer_transform;
+ expected_scroll_layer_transform.Translate(-10.0, -10.0);
+ gfx::Transform expected_fixed_child_transform;
+
+ ExecuteCalculateDrawProperties(root_impl_);
+
+ // Top-left fixed-position layer should not be affected by container size.
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expected_scroll_layer_transform,
+ scroll_layer_impl_->draw_transform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_child_transform,
+ fixed_child_impl->draw_transform());
+
+ // Case 2: Bottom-right fixed-position layer.
+ fixed_child->SetPositionConstraint(fixed_to_bottom_right_);
+ CommitAndUpdateImplPointers();
+ fixed_child_impl =
+ root_impl_->layer_tree_impl()->FindActiveTreeLayerById(fixed_child->id());
+
+ scroll_layer_impl_->SetScrollDelta(gfx::Vector2d(10, 10));
+ SetFixedContainerSizeDelta(scroll_layer_impl_, gfx::Vector2d(20, 20));
+ ExecuteCalculateDrawProperties(root_impl_);
+
+ // Bottom-right fixed-position layer moves as container resizes.
+ expected_fixed_child_transform.MakeIdentity();
+ // Apply size delta.
+ expected_fixed_child_transform.Translate(20.0, 20.0);
+
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expected_scroll_layer_transform,
+ scroll_layer_impl_->draw_transform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_child_transform,
+ fixed_child_impl->draw_transform());
+}
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/layers/layer_unittest.cc b/chromium/cc/layers/layer_unittest.cc
index 6b4d36b9412..ba8e92d75b9 100644
--- a/chromium/cc/layers/layer_unittest.cc
+++ b/chromium/cc/layers/layer_unittest.cc
@@ -10,7 +10,6 @@
#include "cc/layers/layer_impl.h"
#include "cc/output/copy_output_request.h"
#include "cc/output/copy_output_result.h"
-#include "cc/resources/layer_painter.h"
#include "cc/test/animation_test_common.h"
#include "cc/test/fake_impl_proxy.h"
#include "cc/test/fake_layer_tree_host_client.h"
@@ -56,11 +55,6 @@ class MockLayerTreeHost : public LayerTreeHost {
MOCK_METHOD0(SetNeedsFullTreeSync, void());
};
-class MockLayerPainter : public LayerPainter {
- public:
- void Paint(SkCanvas* canvas, const gfx::Rect& content_rect) override {}
-};
-
class LayerTest : public testing::Test {
public:
LayerTest()
@@ -73,6 +67,7 @@ class LayerTest : public testing::Test {
LayerTreeSettings settings;
params.client = &fake_client_;
params.settings = &settings;
+ params.task_graph_runner = &task_graph_runner_;
layer_tree_host_.reset(
new StrictMock<MockLayerTreeHost>(&fake_client_, &params));
}
@@ -115,13 +110,13 @@ class LayerTest : public testing::Test {
}
void CreateSimpleTestTree() {
- parent_ = Layer::Create();
- child1_ = Layer::Create();
- child2_ = Layer::Create();
- child3_ = Layer::Create();
- grand_child1_ = Layer::Create();
- grand_child2_ = Layer::Create();
- grand_child3_ = Layer::Create();
+ parent_ = Layer::Create(layer_settings_);
+ child1_ = Layer::Create(layer_settings_);
+ child2_ = Layer::Create(layer_settings_);
+ child3_ = Layer::Create(layer_settings_);
+ grand_child1_ = Layer::Create(layer_settings_);
+ grand_child2_ = Layer::Create(layer_settings_);
+ grand_child3_ = Layer::Create(layer_settings_);
EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(AnyNumber());
layer_tree_host_->SetRootLayer(parent_);
@@ -152,10 +147,12 @@ class LayerTest : public testing::Test {
scoped_refptr<Layer> grand_child1_;
scoped_refptr<Layer> grand_child2_;
scoped_refptr<Layer> grand_child3_;
+
+ LayerSettings layer_settings_;
};
TEST_F(LayerTest, BasicCreateAndDestroy) {
- scoped_refptr<Layer> test_layer = Layer::Create();
+ scoped_refptr<Layer> test_layer = Layer::Create(layer_settings_);
ASSERT_TRUE(test_layer.get());
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
@@ -167,8 +164,8 @@ TEST_F(LayerTest, BasicCreateAndDestroy) {
}
TEST_F(LayerTest, AddAndRemoveChild) {
- scoped_refptr<Layer> parent = Layer::Create();
- scoped_refptr<Layer> child = Layer::Create();
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> child = Layer::Create(layer_settings_);
// Upon creation, layers should not have children or parent.
ASSERT_EQ(0U, parent->children().size());
@@ -188,8 +185,8 @@ TEST_F(LayerTest, AddAndRemoveChild) {
TEST_F(LayerTest, AddSameChildTwice) {
EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(AtLeast(1));
- scoped_refptr<Layer> parent = Layer::Create();
- scoped_refptr<Layer> child = Layer::Create();
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> child = Layer::Create(layer_settings_);
layer_tree_host_->SetRootLayer(parent);
@@ -205,11 +202,11 @@ TEST_F(LayerTest, AddSameChildTwice) {
}
TEST_F(LayerTest, InsertChild) {
- scoped_refptr<Layer> parent = Layer::Create();
- scoped_refptr<Layer> child1 = Layer::Create();
- scoped_refptr<Layer> child2 = Layer::Create();
- scoped_refptr<Layer> child3 = Layer::Create();
- scoped_refptr<Layer> child4 = Layer::Create();
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> child1 = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> child2 = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> child3 = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> child4 = Layer::Create(layer_settings_);
EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(parent));
@@ -250,9 +247,9 @@ TEST_F(LayerTest, InsertChild) {
}
TEST_F(LayerTest, InsertChildPastEndOfList) {
- scoped_refptr<Layer> parent = Layer::Create();
- scoped_refptr<Layer> child1 = Layer::Create();
- scoped_refptr<Layer> child2 = Layer::Create();
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> child1 = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> child2 = Layer::Create(layer_settings_);
ASSERT_EQ(0U, parent->children().size());
@@ -271,9 +268,9 @@ TEST_F(LayerTest, InsertChildPastEndOfList) {
}
TEST_F(LayerTest, InsertSameChildTwice) {
- scoped_refptr<Layer> parent = Layer::Create();
- scoped_refptr<Layer> child1 = Layer::Create();
- scoped_refptr<Layer> child2 = Layer::Create();
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> child1 = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> child2 = Layer::Create(layer_settings_);
EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(parent));
@@ -300,7 +297,7 @@ TEST_F(LayerTest, InsertSameChildTwice) {
TEST_F(LayerTest, ReplaceChildWithNewChild) {
CreateSimpleTestTree();
- scoped_refptr<Layer> child4 = Layer::Create();
+ scoped_refptr<Layer> child4 = Layer::Create(layer_settings_);
EXPECT_FALSE(child4->parent());
@@ -325,8 +322,8 @@ TEST_F(LayerTest, ReplaceChildWithNewChildThatHasOtherParent) {
CreateSimpleTestTree();
// create another simple tree with test_layer and child4.
- scoped_refptr<Layer> test_layer = Layer::Create();
- scoped_refptr<Layer> child4 = Layer::Create();
+ scoped_refptr<Layer> test_layer = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> child4 = Layer::Create(layer_settings_);
test_layer->AddChild(child4);
ASSERT_EQ(1U, test_layer->children().size());
EXPECT_EQ(child4, test_layer->children()[0]);
@@ -348,9 +345,9 @@ TEST_F(LayerTest, ReplaceChildWithNewChildThatHasOtherParent) {
}
TEST_F(LayerTest, DeleteRemovedScrollParent) {
- scoped_refptr<Layer> parent = Layer::Create();
- scoped_refptr<Layer> child1 = Layer::Create();
- scoped_refptr<Layer> child2 = Layer::Create();
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> child1 = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> child2 = Layer::Create(layer_settings_);
EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(parent));
@@ -377,9 +374,9 @@ TEST_F(LayerTest, DeleteRemovedScrollParent) {
}
TEST_F(LayerTest, DeleteRemovedScrollChild) {
- scoped_refptr<Layer> parent = Layer::Create();
- scoped_refptr<Layer> child1 = Layer::Create();
- scoped_refptr<Layer> child2 = Layer::Create();
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> child1 = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> child2 = Layer::Create(layer_settings_);
EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(parent));
@@ -429,11 +426,11 @@ TEST_F(LayerTest, RemoveAllChildren) {
}
TEST_F(LayerTest, SetChildren) {
- scoped_refptr<Layer> old_parent = Layer::Create();
- scoped_refptr<Layer> new_parent = Layer::Create();
+ scoped_refptr<Layer> old_parent = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> new_parent = Layer::Create(layer_settings_);
- scoped_refptr<Layer> child1 = Layer::Create();
- scoped_refptr<Layer> child2 = Layer::Create();
+ scoped_refptr<Layer> child1 = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> child2 = Layer::Create(layer_settings_);
LayerList new_children;
new_children.push_back(child1);
@@ -460,17 +457,17 @@ TEST_F(LayerTest, SetChildren) {
}
TEST_F(LayerTest, HasAncestor) {
- scoped_refptr<Layer> parent = Layer::Create();
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings_);
EXPECT_FALSE(parent->HasAncestor(parent.get()));
- scoped_refptr<Layer> child = Layer::Create();
+ scoped_refptr<Layer> child = Layer::Create(layer_settings_);
parent->AddChild(child);
EXPECT_FALSE(child->HasAncestor(child.get()));
EXPECT_TRUE(child->HasAncestor(parent.get()));
EXPECT_FALSE(parent->HasAncestor(child.get()));
- scoped_refptr<Layer> child_child = Layer::Create();
+ scoped_refptr<Layer> child_child = Layer::Create(layer_settings_);
child->AddChild(child_child);
EXPECT_FALSE(child_child->HasAncestor(child_child.get()));
@@ -486,7 +483,7 @@ TEST_F(LayerTest, GetRootLayerAfterTreeManipulations) {
// For this test we don't care about SetNeedsFullTreeSync calls.
EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(AnyNumber());
- scoped_refptr<Layer> child4 = Layer::Create();
+ scoped_refptr<Layer> child4 = Layer::Create(layer_settings_);
EXPECT_EQ(parent_.get(), parent_->RootLayer());
EXPECT_EQ(parent_.get(), child1_->RootLayer());
@@ -541,7 +538,7 @@ TEST_F(LayerTest, CheckSetNeedsDisplayCausesCorrectBehavior) {
// 2. indirectly calls SetNeedsUpdate, exactly once for each call to
// SetNeedsDisplay.
- scoped_refptr<Layer> test_layer = Layer::Create();
+ scoped_refptr<Layer> test_layer = Layer::Create(layer_settings_);
EXPECT_SET_NEEDS_FULL_TREE_SYNC(
1, layer_tree_host_->SetRootLayer(test_layer));
EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsDrawable(true));
@@ -594,13 +591,13 @@ TEST_F(LayerTest, CheckSetNeedsDisplayCausesCorrectBehavior) {
}
TEST_F(LayerTest, CheckPropertyChangeCausesCorrectBehavior) {
- scoped_refptr<Layer> test_layer = Layer::Create();
+ scoped_refptr<Layer> test_layer = Layer::Create(layer_settings_);
EXPECT_SET_NEEDS_FULL_TREE_SYNC(
1, layer_tree_host_->SetRootLayer(test_layer));
EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsDrawable(true));
- scoped_refptr<Layer> dummy_layer1 = Layer::Create();
- scoped_refptr<Layer> dummy_layer2 = Layer::Create();
+ scoped_refptr<Layer> dummy_layer1 = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> dummy_layer2 = Layer::Create(layer_settings_);
// sanity check of initial test condition
EXPECT_FALSE(test_layer->NeedsDisplayForTesting());
@@ -653,7 +650,7 @@ TEST_F(LayerTest, CheckPropertyChangeCausesCorrectBehavior) {
}
TEST_F(LayerTest, PushPropertiesAccumulatesUpdateRect) {
- scoped_refptr<Layer> test_layer = Layer::Create();
+ scoped_refptr<Layer> test_layer = Layer::Create(layer_settings_);
scoped_ptr<LayerImpl> impl_layer =
LayerImpl::Create(host_impl_.active_tree(), 1);
@@ -682,7 +679,7 @@ TEST_F(LayerTest, PushPropertiesAccumulatesUpdateRect) {
}
TEST_F(LayerTest, PushPropertiesCausesLayerPropertyChangedForTransform) {
- scoped_refptr<Layer> test_layer = Layer::Create();
+ scoped_refptr<Layer> test_layer = Layer::Create(layer_settings_);
scoped_ptr<LayerImpl> impl_layer =
LayerImpl::Create(host_impl_.active_tree(), 1);
@@ -701,7 +698,7 @@ TEST_F(LayerTest, PushPropertiesCausesLayerPropertyChangedForTransform) {
}
TEST_F(LayerTest, PushPropertiesCausesLayerPropertyChangedForOpacity) {
- scoped_refptr<Layer> test_layer = Layer::Create();
+ scoped_refptr<Layer> test_layer = Layer::Create(layer_settings_);
scoped_ptr<LayerImpl> impl_layer =
LayerImpl::Create(host_impl_.active_tree(), 1);
@@ -719,7 +716,7 @@ TEST_F(LayerTest, PushPropertiesCausesLayerPropertyChangedForOpacity) {
TEST_F(LayerTest,
PushPropsDoesntCauseLayerPropertyChangedDuringImplOnlyTransformAnim) {
- scoped_refptr<Layer> test_layer = Layer::Create();
+ scoped_refptr<Layer> test_layer = Layer::Create(layer_settings_);
scoped_ptr<LayerImpl> impl_layer =
LayerImpl::Create(host_impl_.active_tree(), 1);
@@ -761,7 +758,7 @@ TEST_F(LayerTest,
TEST_F(LayerTest,
PushPropsDoesntCauseLayerPropertyChangedDuringImplOnlyOpacityAnim) {
- scoped_refptr<Layer> test_layer = Layer::Create();
+ scoped_refptr<Layer> test_layer = Layer::Create(layer_settings_);
scoped_ptr<LayerImpl> impl_layer =
LayerImpl::Create(host_impl_.active_tree(), 1);
@@ -802,7 +799,7 @@ TEST_F(LayerTest,
TEST_F(LayerTest,
PushPropsDoesntCauseLayerPropertyChangedDuringImplOnlyFilterAnim) {
- scoped_refptr<Layer> test_layer = Layer::Create();
+ scoped_refptr<Layer> test_layer = Layer::Create(layer_settings_);
scoped_ptr<LayerImpl> impl_layer =
LayerImpl::Create(host_impl_.active_tree(), 1);
@@ -839,14 +836,15 @@ TEST_F(LayerTest,
}
TEST_F(LayerTest, MaskAndReplicaHasParent) {
- scoped_refptr<Layer> parent = Layer::Create();
- scoped_refptr<Layer> child = Layer::Create();
- scoped_refptr<Layer> mask = Layer::Create();
- scoped_refptr<Layer> replica = Layer::Create();
- scoped_refptr<Layer> replica_mask = Layer::Create();
- scoped_refptr<Layer> mask_replacement = Layer::Create();
- scoped_refptr<Layer> replica_replacement = Layer::Create();
- scoped_refptr<Layer> replica_mask_replacement = Layer::Create();
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> child = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> mask = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> replica = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> replica_mask = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> mask_replacement = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> replica_replacement = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> replica_mask_replacement =
+ Layer::Create(layer_settings_);
parent->AddChild(child);
child->SetMaskLayer(mask.get());
@@ -874,7 +872,7 @@ TEST_F(LayerTest, MaskAndReplicaHasParent) {
}
TEST_F(LayerTest, CheckTranformIsInvertible) {
- scoped_refptr<Layer> layer = Layer::Create();
+ scoped_refptr<Layer> layer = Layer::Create(layer_settings_);
scoped_ptr<LayerImpl> impl_layer =
LayerImpl::Create(host_impl_.active_tree(), 1);
EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(1);
@@ -905,7 +903,7 @@ TEST_F(LayerTest, CheckTranformIsInvertible) {
}
TEST_F(LayerTest, TranformIsInvertibleAnimation) {
- scoped_refptr<Layer> layer = Layer::Create();
+ scoped_refptr<Layer> layer = Layer::Create(layer_settings_);
scoped_ptr<LayerImpl> impl_layer =
LayerImpl::Create(host_impl_.active_tree(), 1);
EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(1);
@@ -938,18 +936,16 @@ TEST_F(LayerTest, TranformIsInvertibleAnimation) {
class LayerTreeHostFactory {
public:
- LayerTreeHostFactory()
- : client_(FakeLayerTreeHostClient::DIRECT_3D),
- shared_bitmap_manager_(new TestSharedBitmapManager),
- gpu_memory_buffer_manager_(new TestGpuMemoryBufferManager) {}
+ LayerTreeHostFactory() : client_(FakeLayerTreeHostClient::DIRECT_3D) {}
scoped_ptr<LayerTreeHost> Create() { return Create(LayerTreeSettings()); }
scoped_ptr<LayerTreeHost> Create(LayerTreeSettings settings) {
LayerTreeHost::InitParams params;
params.client = &client_;
- params.shared_bitmap_manager = shared_bitmap_manager_.get();
- params.gpu_memory_buffer_manager = gpu_memory_buffer_manager_.get();
+ params.shared_bitmap_manager = &shared_bitmap_manager_;
+ params.task_graph_runner = &task_graph_runner_;
+ params.gpu_memory_buffer_manager = &gpu_memory_buffer_manager_;
params.settings = &settings;
params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
return LayerTreeHost::CreateSingleThreaded(&client_, &params);
@@ -957,8 +953,9 @@ class LayerTreeHostFactory {
private:
FakeLayerTreeHostClient client_;
- scoped_ptr<TestSharedBitmapManager> shared_bitmap_manager_;
- scoped_ptr<TestGpuMemoryBufferManager> gpu_memory_buffer_manager_;
+ TestSharedBitmapManager shared_bitmap_manager_;
+ TestTaskGraphRunner task_graph_runner_;
+ TestGpuMemoryBufferManager gpu_memory_buffer_manager_;
};
void AssertLayerTreeHostMatchesForSubtree(Layer* layer, LayerTreeHost* host) {
@@ -974,12 +971,18 @@ void AssertLayerTreeHostMatchesForSubtree(Layer* layer, LayerTreeHost* host) {
AssertLayerTreeHostMatchesForSubtree(layer->replica_layer(), host);
}
-TEST(LayerLayerTreeHostTest, EnteringTree) {
- scoped_refptr<Layer> parent = Layer::Create();
- scoped_refptr<Layer> child = Layer::Create();
- scoped_refptr<Layer> mask = Layer::Create();
- scoped_refptr<Layer> replica = Layer::Create();
- scoped_refptr<Layer> replica_mask = Layer::Create();
+class LayerLayerTreeHostTest : public testing::Test {
+ public:
+ protected:
+ LayerSettings layer_settings_;
+};
+
+TEST_F(LayerLayerTreeHostTest, EnteringTree) {
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> child = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> mask = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> replica = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> replica_mask = Layer::Create(layer_settings_);
// Set up a detached tree of layers. The host pointer should be nil for these
// layers.
@@ -1005,8 +1008,8 @@ TEST(LayerLayerTreeHostTest, EnteringTree) {
AssertLayerTreeHostMatchesForSubtree(parent.get(), nullptr);
}
-TEST(LayerLayerTreeHostTest, AddingLayerSubtree) {
- scoped_refptr<Layer> parent = Layer::Create();
+TEST_F(LayerLayerTreeHostTest, AddingLayerSubtree) {
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings_);
LayerTreeHostFactory factory;
scoped_ptr<LayerTreeHost> layer_tree_host = factory.Create();
@@ -1016,16 +1019,16 @@ TEST(LayerLayerTreeHostTest, AddingLayerSubtree) {
// Adding a subtree to a layer already associated with a host should set the
// host pointer on all layers in that subtree.
- scoped_refptr<Layer> child = Layer::Create();
- scoped_refptr<Layer> grand_child = Layer::Create();
+ scoped_refptr<Layer> child = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> grand_child = Layer::Create(layer_settings_);
child->AddChild(grand_child);
// Masks, replicas, and replica masks should pick up the new host too.
- scoped_refptr<Layer> child_mask = Layer::Create();
+ scoped_refptr<Layer> child_mask = Layer::Create(layer_settings_);
child->SetMaskLayer(child_mask.get());
- scoped_refptr<Layer> child_replica = Layer::Create();
+ scoped_refptr<Layer> child_replica = Layer::Create(layer_settings_);
child->SetReplicaLayer(child_replica.get());
- scoped_refptr<Layer> child_replica_mask = Layer::Create();
+ scoped_refptr<Layer> child_replica_mask = Layer::Create(layer_settings_);
child_replica->SetMaskLayer(child_replica_mask.get());
parent->AddChild(child);
@@ -1034,12 +1037,12 @@ TEST(LayerLayerTreeHostTest, AddingLayerSubtree) {
layer_tree_host->SetRootLayer(nullptr);
}
-TEST(LayerLayerTreeHostTest, ChangeHost) {
- scoped_refptr<Layer> parent = Layer::Create();
- scoped_refptr<Layer> child = Layer::Create();
- scoped_refptr<Layer> mask = Layer::Create();
- scoped_refptr<Layer> replica = Layer::Create();
- scoped_refptr<Layer> replica_mask = Layer::Create();
+TEST_F(LayerLayerTreeHostTest, ChangeHost) {
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> child = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> mask = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> replica = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> replica_mask = Layer::Create(layer_settings_);
// Same setup as the previous test.
parent->AddChild(child);
@@ -1065,12 +1068,12 @@ TEST(LayerLayerTreeHostTest, ChangeHost) {
second_layer_tree_host->SetRootLayer(nullptr);
}
-TEST(LayerLayerTreeHostTest, ChangeHostInSubtree) {
- scoped_refptr<Layer> first_parent = Layer::Create();
- scoped_refptr<Layer> first_child = Layer::Create();
- scoped_refptr<Layer> second_parent = Layer::Create();
- scoped_refptr<Layer> second_child = Layer::Create();
- scoped_refptr<Layer> second_grand_child = Layer::Create();
+TEST_F(LayerLayerTreeHostTest, ChangeHostInSubtree) {
+ scoped_refptr<Layer> first_parent = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> first_child = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> second_parent = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> second_child = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> second_grand_child = Layer::Create(layer_settings_);
// First put all children under the first parent and set the first host.
first_parent->AddChild(first_child);
@@ -1101,14 +1104,14 @@ TEST(LayerLayerTreeHostTest, ChangeHostInSubtree) {
second_layer_tree_host->SetRootLayer(nullptr);
}
-TEST(LayerLayerTreeHostTest, ReplaceMaskAndReplicaLayer) {
- scoped_refptr<Layer> parent = Layer::Create();
- scoped_refptr<Layer> mask = Layer::Create();
- scoped_refptr<Layer> replica = Layer::Create();
- scoped_refptr<Layer> mask_child = Layer::Create();
- scoped_refptr<Layer> replica_child = Layer::Create();
- scoped_refptr<Layer> mask_replacement = Layer::Create();
- scoped_refptr<Layer> replica_replacement = Layer::Create();
+TEST_F(LayerLayerTreeHostTest, ReplaceMaskAndReplicaLayer) {
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> mask = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> replica = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> mask_child = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> replica_child = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> mask_replacement = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> replica_replacement = Layer::Create(layer_settings_);
parent->SetMaskLayer(mask.get());
parent->SetReplicaLayer(replica.get());
@@ -1135,9 +1138,9 @@ TEST(LayerLayerTreeHostTest, ReplaceMaskAndReplicaLayer) {
layer_tree_host->SetRootLayer(nullptr);
}
-TEST(LayerLayerTreeHostTest, DestroyHostWithNonNullRootLayer) {
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> child = Layer::Create();
+TEST_F(LayerLayerTreeHostTest, DestroyHostWithNonNullRootLayer) {
+ scoped_refptr<Layer> root = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> child = Layer::Create(layer_settings_);
root->AddChild(child);
LayerTreeHostFactory factory;
scoped_ptr<LayerTreeHost> layer_tree_host = factory.Create();
@@ -1156,15 +1159,15 @@ static bool AddTestAnimation(Layer* layer) {
return layer->AddAnimation(animation.Pass());
}
-TEST(LayerLayerTreeHostTest, ShouldNotAddAnimationWithoutAnimationRegistrar) {
- scoped_refptr<Layer> layer = Layer::Create();
+TEST_F(LayerLayerTreeHostTest, ShouldNotAddAnimationWithoutAnimationRegistrar) {
+ scoped_refptr<Layer> layer = Layer::Create(layer_settings_);
// Case 1: without a LayerTreeHost and without an AnimationRegistrar, the
// animation should not be accepted.
EXPECT_FALSE(AddTestAnimation(layer.get()));
scoped_ptr<AnimationRegistrar> registrar = AnimationRegistrar::Create();
- layer->layer_animation_controller()->SetAnimationRegistrar(registrar.get());
+ layer->RegisterForAnimations(registrar.get());
// Case 2: with an AnimationRegistrar, the animation should be accepted.
EXPECT_TRUE(AddTestAnimation(layer.get()));
@@ -1185,7 +1188,7 @@ TEST_F(LayerTest, SafeOpaqueBackgroundColor) {
LayerTreeHostFactory factory;
scoped_ptr<LayerTreeHost> layer_tree_host = factory.Create();
- scoped_refptr<Layer> layer = Layer::Create();
+ scoped_refptr<Layer> layer = Layer::Create(layer_settings_);
layer_tree_host->SetRootLayer(layer);
for (int contents_opaque = 0; contents_opaque < 2; ++contents_opaque) {
@@ -1214,8 +1217,9 @@ TEST_F(LayerTest, SafeOpaqueBackgroundColor) {
class DrawsContentChangeLayer : public Layer {
public:
- static scoped_refptr<DrawsContentChangeLayer> Create() {
- return make_scoped_refptr(new DrawsContentChangeLayer());
+ static scoped_refptr<DrawsContentChangeLayer> Create(
+ const LayerSettings& settings) {
+ return make_scoped_refptr(new DrawsContentChangeLayer(settings));
}
void SetLayerTreeHost(LayerTreeHost* host) override {
@@ -1233,18 +1237,19 @@ class DrawsContentChangeLayer : public Layer {
}
private:
- DrawsContentChangeLayer() : Layer(), fake_draws_content_(false) {}
+ explicit DrawsContentChangeLayer(const LayerSettings& settings)
+ : Layer(settings), fake_draws_content_(false) {}
~DrawsContentChangeLayer() override {}
bool fake_draws_content_;
};
TEST_F(LayerTest, DrawsContentChangedInSetLayerTreeHost) {
- scoped_refptr<Layer> root_layer = Layer::Create();
+ scoped_refptr<Layer> root_layer = Layer::Create(layer_settings_);
scoped_refptr<DrawsContentChangeLayer> becomes_not_draws_content =
- DrawsContentChangeLayer::Create();
+ DrawsContentChangeLayer::Create(layer_settings_);
scoped_refptr<DrawsContentChangeLayer> becomes_draws_content =
- DrawsContentChangeLayer::Create();
+ DrawsContentChangeLayer::Create(layer_settings_);
root_layer->SetIsDrawable(true);
becomes_not_draws_content->SetIsDrawable(true);
becomes_not_draws_content->SetFakeDrawsContent(true);
@@ -1263,7 +1268,7 @@ void ReceiveCopyOutputResult(int* result_count,
}
TEST_F(LayerTest, DedupesCopyOutputRequestsBySource) {
- scoped_refptr<Layer> layer = Layer::Create();
+ scoped_refptr<Layer> layer = Layer::Create(layer_settings_);
int result_count = 0;
// Create identical requests without the source being set, and expect the
@@ -1281,7 +1286,7 @@ TEST_F(LayerTest, DedupesCopyOutputRequestsBySource) {
layer = nullptr;
EXPECT_EQ(2, result_count);
- layer = Layer::Create();
+ layer = Layer::Create(layer_settings_);
result_count = 0;
// Create identical requests, but this time the source is being set. Expect
diff --git a/chromium/cc/layers/layer_utils.cc b/chromium/cc/layers/layer_utils.cc
index 888174a46d3..42d0e1b1d75 100644
--- a/chromium/cc/layers/layer_utils.cc
+++ b/chromium/cc/layers/layer_utils.cc
@@ -13,17 +13,15 @@ namespace cc {
namespace {
bool HasAnimationThatInflatesBounds(const LayerImpl& layer) {
- return layer.layer_animation_controller()->HasAnimationThatInflatesBounds();
+ return layer.HasAnimationThatInflatesBounds();
}
bool HasFilterAnimationThatInflatesBounds(const LayerImpl& layer) {
- return layer.layer_animation_controller()
- ->HasFilterAnimationThatInflatesBounds();
+ return layer.HasFilterAnimationThatInflatesBounds();
}
bool HasTransformAnimationThatInflatesBounds(const LayerImpl& layer) {
- return layer.layer_animation_controller()
- ->HasTransformAnimationThatInflatesBounds();
+ return layer.HasTransformAnimationThatInflatesBounds();
}
inline bool HasAncestorTransformAnimation(const LayerImpl& layer) {
@@ -112,16 +110,14 @@ bool LayerUtils::GetAnimationBounds(const LayerImpl& layer_in, gfx::BoxF* out) {
// Perform the inflation
if (HasFilterAnimationThatInflatesBounds(*layer)) {
gfx::BoxF inflated;
- if (!layer->layer_animation_controller()->FilterAnimationBoundsForBox(
- box, &inflated))
+ if (!layer->FilterAnimationBoundsForBox(box, &inflated))
return false;
box = inflated;
}
if (HasTransformAnimationThatInflatesBounds(*layer)) {
gfx::BoxF inflated;
- if (!layer->layer_animation_controller()->TransformAnimationBoundsForBox(
- box, &inflated))
+ if (!layer->TransformAnimationBoundsForBox(box, &inflated))
return false;
box = inflated;
}
diff --git a/chromium/cc/layers/nine_patch_layer.cc b/chromium/cc/layers/nine_patch_layer.cc
index ad8f04dfeff..575090cad9e 100644
--- a/chromium/cc/layers/nine_patch_layer.cc
+++ b/chromium/cc/layers/nine_patch_layer.cc
@@ -5,20 +5,20 @@
#include "cc/layers/nine_patch_layer.h"
#include "cc/layers/nine_patch_layer_impl.h"
-#include "cc/resources/prioritized_resource.h"
-#include "cc/resources/resource_update.h"
-#include "cc/resources/resource_update_queue.h"
#include "cc/resources/scoped_ui_resource.h"
#include "cc/resources/ui_resource_bitmap.h"
#include "cc/trees/layer_tree_host.h"
namespace cc {
-scoped_refptr<NinePatchLayer> NinePatchLayer::Create() {
- return make_scoped_refptr(new NinePatchLayer());
+scoped_refptr<NinePatchLayer> NinePatchLayer::Create(
+ const LayerSettings& settings) {
+ return make_scoped_refptr(new NinePatchLayer(settings));
}
-NinePatchLayer::NinePatchLayer() : fill_center_(false) {}
+NinePatchLayer::NinePatchLayer(const LayerSettings& settings)
+ : UIResourceLayer(settings), fill_center_(false) {
+}
NinePatchLayer::~NinePatchLayer() {}
diff --git a/chromium/cc/layers/nine_patch_layer.h b/chromium/cc/layers/nine_patch_layer.h
index 9054610b8ee..714a407ddb0 100644
--- a/chromium/cc/layers/nine_patch_layer.h
+++ b/chromium/cc/layers/nine_patch_layer.h
@@ -19,7 +19,7 @@ class ScopedUIResource;
class CC_EXPORT NinePatchLayer : public UIResourceLayer {
public:
- static scoped_refptr<NinePatchLayer> Create();
+ static scoped_refptr<NinePatchLayer> Create(const LayerSettings& settings);
void PushPropertiesTo(LayerImpl* layer) override;
@@ -40,7 +40,7 @@ class CC_EXPORT NinePatchLayer : public UIResourceLayer {
void SetFillCenter(bool fill_center);
private:
- NinePatchLayer();
+ explicit NinePatchLayer(const LayerSettings& settings);
~NinePatchLayer() override;
scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
diff --git a/chromium/cc/layers/nine_patch_layer_impl.cc b/chromium/cc/layers/nine_patch_layer_impl.cc
index fc2f4575262..b31382f6580 100644
--- a/chromium/cc/layers/nine_patch_layer_impl.cc
+++ b/chromium/cc/layers/nine_patch_layer_impl.cc
@@ -88,13 +88,13 @@ void NinePatchLayerImpl::AppendQuads(
render_pass->CreateAndAppendSharedQuadState();
PopulateSharedQuadState(shared_quad_state);
- AppendDebugBorderQuad(
- render_pass, content_bounds(), shared_quad_state, append_quads_data);
+ AppendDebugBorderQuad(render_pass, bounds(), shared_quad_state,
+ append_quads_data);
if (!ui_resource_id_)
return;
- ResourceProvider::ResourceId resource =
+ ResourceId resource =
layer_tree_impl()->ResourceIdForUIResource(ui_resource_id_);
if (!resource)
diff --git a/chromium/cc/layers/nine_patch_layer_impl_unittest.cc b/chromium/cc/layers/nine_patch_layer_impl_unittest.cc
index a71f92ef0dd..3535c985106 100644
--- a/chromium/cc/layers/nine_patch_layer_impl_unittest.cc
+++ b/chromium/cc/layers/nine_patch_layer_impl_unittest.cc
@@ -37,7 +37,7 @@ void NinePatchLayerLayoutTest(const gfx::Size& bitmap_size,
bool fill_center,
size_t expected_quad_size) {
scoped_ptr<RenderPass> render_pass = RenderPass::Create();
- gfx::Rect visible_content_rect(layer_size);
+ gfx::Rect visible_layer_rect(layer_size);
gfx::Rect expected_remaining(border.x(),
border.y(),
layer_size.width() - border.width(),
@@ -45,14 +45,15 @@ void NinePatchLayerLayoutTest(const gfx::Size& bitmap_size,
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeUIResourceLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
+ TestTaskGraphRunner task_graph_runner;
+ FakeUIResourceLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
host_impl.InitializeRenderer(FakeOutputSurface::Create3d());
scoped_ptr<NinePatchLayerImpl> layer =
NinePatchLayerImpl::Create(host_impl.active_tree(), 1);
- layer->draw_properties().visible_content_rect = visible_content_rect;
+ layer->draw_properties().visible_layer_rect = visible_layer_rect;
layer->SetBounds(layer_size);
- layer->SetContentBounds(layer_size);
layer->SetHasRenderSurface(true);
layer->draw_properties().render_target = layer.get();
@@ -71,11 +72,11 @@ void NinePatchLayerLayoutTest(const gfx::Size& bitmap_size,
const QuadList& quads = render_pass->quad_list;
EXPECT_EQ(expected_quad_size, quads.size());
- Region remaining(visible_content_rect);
+ Region remaining(visible_layer_rect);
for (auto iter = quads.cbegin(); iter != quads.cend(); ++iter) {
gfx::Rect quad_rect = iter->rect;
- EXPECT_TRUE(visible_content_rect.Contains(quad_rect)) << iter.index();
+ EXPECT_TRUE(visible_layer_rect.Contains(quad_rect)) << iter.index();
EXPECT_TRUE(remaining.Contains(quad_rect)) << iter.index();
remaining.Subtract(Region(quad_rect));
}
@@ -229,7 +230,6 @@ TEST(NinePatchLayerImplTest, Occlusion) {
NinePatchLayerImpl* nine_patch_layer_impl =
impl.AddChildToRoot<NinePatchLayerImpl>();
nine_patch_layer_impl->SetBounds(layer_size);
- nine_patch_layer_impl->SetContentBounds(layer_size);
nine_patch_layer_impl->SetDrawsContent(true);
nine_patch_layer_impl->SetUIResourceId(uid);
nine_patch_layer_impl->SetImageBounds(gfx::Size(10, 10));
@@ -252,7 +252,7 @@ TEST(NinePatchLayerImplTest, Occlusion) {
{
SCOPED_TRACE("Full occlusion");
- gfx::Rect occluded(nine_patch_layer_impl->visible_content_rect());
+ gfx::Rect occluded(nine_patch_layer_impl->visible_layer_rect());
impl.AppendQuadsWithOcclusion(nine_patch_layer_impl, occluded);
LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect());
@@ -302,7 +302,6 @@ TEST(NinePatchLayerImplTest, OpaqueRect) {
NinePatchLayerImpl *nine_patch_layer_impl =
impl.AddChildToRoot<NinePatchLayerImpl>();
nine_patch_layer_impl->SetBounds(layer_size);
- nine_patch_layer_impl->SetContentBounds(layer_size);
nine_patch_layer_impl->SetDrawsContent(true);
impl.CalcDrawProps(viewport_size);
diff --git a/chromium/cc/layers/nine_patch_layer_unittest.cc b/chromium/cc/layers/nine_patch_layer_unittest.cc
index 1783ba9fa41..75af3be073e 100644
--- a/chromium/cc/layers/nine_patch_layer_unittest.cc
+++ b/chromium/cc/layers/nine_patch_layer_unittest.cc
@@ -4,18 +4,15 @@
#include "cc/layers/nine_patch_layer.h"
-#include "cc/resources/prioritized_resource_manager.h"
#include "cc/resources/resource_provider.h"
-#include "cc/resources/resource_update_queue.h"
#include "cc/resources/scoped_ui_resource.h"
#include "cc/test/fake_layer_tree_host.h"
#include "cc/test/fake_layer_tree_host_client.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_output_surface_client.h"
#include "cc/test/geometry_test_utils.h"
-#include "cc/test/test_shared_bitmap_manager.h"
+#include "cc/test/test_task_graph_runner.h"
#include "cc/trees/layer_tree_host.h"
-#include "cc/trees/occlusion_tracker.h"
#include "cc/trees/single_thread_proxy.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -35,7 +32,8 @@ class NinePatchLayerTest : public testing::Test {
protected:
void SetUp() override {
- layer_tree_host_ = FakeLayerTreeHost::Create(&fake_client_);
+ layer_tree_host_ =
+ FakeLayerTreeHost::Create(&fake_client_, &task_graph_runner_);
}
void TearDown() override {
@@ -43,11 +41,13 @@ class NinePatchLayerTest : public testing::Test {
}
FakeLayerTreeHostClient fake_client_;
+ TestTaskGraphRunner task_graph_runner_;
scoped_ptr<FakeLayerTreeHost> layer_tree_host_;
};
TEST_F(NinePatchLayerTest, SetLayerProperties) {
- scoped_refptr<NinePatchLayer> test_layer = NinePatchLayer::Create();
+ scoped_refptr<NinePatchLayer> test_layer =
+ NinePatchLayer::Create(LayerSettings());
ASSERT_TRUE(test_layer.get());
test_layer->SetIsDrawable(true);
test_layer->SetBounds(gfx::Size(100, 100));
@@ -56,11 +56,9 @@ TEST_F(NinePatchLayerTest, SetLayerProperties) {
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get());
- ResourceUpdateQueue queue;
gfx::Rect screen_space_clip_rect;
- OcclusionTracker<Layer> occlusion_tracker(screen_space_clip_rect);
test_layer->SavePaintProperties();
- test_layer->Update(&queue, &occlusion_tracker);
+ test_layer->Update();
EXPECT_FALSE(test_layer->DrawsContent());
@@ -72,7 +70,7 @@ TEST_F(NinePatchLayerTest, SetLayerProperties) {
test_layer->SetAperture(aperture);
test_layer->SetUIResourceId(resource->id());
test_layer->SetFillCenter(fill_center);
- test_layer->Update(&queue, &occlusion_tracker);
+ test_layer->Update();
EXPECT_TRUE(test_layer->DrawsContent());
}
diff --git a/chromium/cc/layers/painted_scrollbar_layer.cc b/chromium/cc/layers/painted_scrollbar_layer.cc
index d82ef989589..f537ffc7e07 100644
--- a/chromium/cc/layers/painted_scrollbar_layer.cc
+++ b/chromium/cc/layers/painted_scrollbar_layer.cc
@@ -32,18 +32,21 @@ scoped_ptr<LayerImpl> PaintedScrollbarLayer::CreateLayerImpl(
}
scoped_refptr<PaintedScrollbarLayer> PaintedScrollbarLayer::Create(
+ const LayerSettings& settings,
scoped_ptr<Scrollbar> scrollbar,
int scroll_layer_id) {
return make_scoped_refptr(
- new PaintedScrollbarLayer(scrollbar.Pass(), scroll_layer_id));
+ new PaintedScrollbarLayer(settings, scrollbar.Pass(), scroll_layer_id));
}
-PaintedScrollbarLayer::PaintedScrollbarLayer(scoped_ptr<Scrollbar> scrollbar,
+PaintedScrollbarLayer::PaintedScrollbarLayer(const LayerSettings& settings,
+ scoped_ptr<Scrollbar> scrollbar,
int scroll_layer_id)
- : scrollbar_(scrollbar.Pass()),
+ : Layer(settings),
+ scrollbar_(scrollbar.Pass()),
scroll_layer_id_(scroll_layer_id),
clip_layer_id_(Layer::INVALID_ID),
- internal_contents_scale_(0.f),
+ internal_contents_scale_(1.f),
thumb_thickness_(scrollbar_->ThumbThickness()),
thumb_length_(scrollbar_->ThumbLength()),
is_overlay_(scrollbar_->IsOverlay()),
@@ -205,12 +208,8 @@ void PaintedScrollbarLayer::UpdateInternalContentScale() {
->settings()
.layer_transforms_should_scale_layer_contents) {
gfx::Transform transform;
- if (layer_tree_host()->using_only_property_trees()) {
- transform = DrawTransformFromPropertyTrees(
- this, layer_tree_host()->property_trees()->transform_tree);
- } else {
- transform = draw_transform();
- }
+ transform = DrawTransformFromPropertyTrees(
+ this, layer_tree_host()->property_trees()->transform_tree);
gfx::Vector2dF transform_scales =
MathUtil::ComputeTransform2dScaleComponents(transform, scale);
@@ -228,12 +227,11 @@ void PaintedScrollbarLayer::UpdateInternalContentScale() {
}
}
-bool PaintedScrollbarLayer::Update(ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion) {
+bool PaintedScrollbarLayer::Update() {
{
base::AutoReset<bool> ignore_set_needs_commit(&ignore_set_needs_commit_,
true);
- Layer::Update(queue, occlusion);
+ Layer::Update();
UpdateInternalContentScale();
}
diff --git a/chromium/cc/layers/painted_scrollbar_layer.h b/chromium/cc/layers/painted_scrollbar_layer.h
index ae2b125e785..3e376b1959e 100644
--- a/chromium/cc/layers/painted_scrollbar_layer.h
+++ b/chromium/cc/layers/painted_scrollbar_layer.h
@@ -10,7 +10,6 @@
#include "cc/layers/layer.h"
#include "cc/layers/scrollbar_layer_interface.h"
#include "cc/layers/scrollbar_theme_painter.h"
-#include "cc/resources/layer_updater.h"
#include "cc/resources/scoped_ui_resource.h"
namespace cc {
@@ -22,6 +21,7 @@ class CC_EXPORT PaintedScrollbarLayer : public ScrollbarLayerInterface,
scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
static scoped_refptr<PaintedScrollbarLayer> Create(
+ const LayerSettings& settings,
scoped_ptr<Scrollbar> scrollbar,
int scroll_layer_id);
@@ -36,8 +36,7 @@ class CC_EXPORT PaintedScrollbarLayer : public ScrollbarLayerInterface,
ScrollbarOrientation orientation() const override;
// Layer interface
- bool Update(ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion) override;
+ bool Update() override;
void SetLayerTreeHost(LayerTreeHost* host) override;
void PushPropertiesTo(LayerImpl* layer) override;
void PushScrollClipPropertiesTo(LayerImpl* layer) override;
@@ -47,7 +46,9 @@ class CC_EXPORT PaintedScrollbarLayer : public ScrollbarLayerInterface,
}
protected:
- PaintedScrollbarLayer(scoped_ptr<Scrollbar> scrollbar, int scroll_layer_id);
+ PaintedScrollbarLayer(const LayerSettings& settings,
+ scoped_ptr<Scrollbar> scrollbar,
+ int scroll_layer_id);
~PaintedScrollbarLayer() override;
// For unit tests
diff --git a/chromium/cc/layers/painted_scrollbar_layer_impl.cc b/chromium/cc/layers/painted_scrollbar_layer_impl.cc
index 005e0876948..0b5b5801dd6 100644
--- a/chromium/cc/layers/painted_scrollbar_layer_impl.cc
+++ b/chromium/cc/layers/painted_scrollbar_layer_impl.cc
@@ -95,9 +95,9 @@ void PaintedScrollbarLayerImpl::AppendQuads(
gfx::Rect scaled_visible_thumb_quad_rect = gfx::ScaleToEnclosingRect(
visible_thumb_quad_rect, internal_contents_scale_);
- ResourceProvider::ResourceId thumb_resource_id =
+ ResourceId thumb_resource_id =
layer_tree_impl()->ResourceIdForUIResource(thumb_ui_resource_id_);
- ResourceProvider::ResourceId track_resource_id =
+ ResourceId track_resource_id =
layer_tree_impl()->ResourceIdForUIResource(track_ui_resource_id_);
if (thumb_resource_id && !visible_thumb_quad_rect.IsEmpty()) {
@@ -134,6 +134,9 @@ void PaintedScrollbarLayerImpl::AppendQuads(
}
gfx::Rect PaintedScrollbarLayerImpl::GetEnclosingRectInTargetSpace() const {
+ if (internal_content_bounds_.IsEmpty())
+ return gfx::Rect();
+ DCHECK_GT(internal_contents_scale_, 0.f);
return GetScaledEnclosingRectInTargetSpace(internal_contents_scale_);
}
diff --git a/chromium/cc/layers/painted_scrollbar_layer_impl_unittest.cc b/chromium/cc/layers/painted_scrollbar_layer_impl_unittest.cc
index 3fb3fb22bd1..eac32b67efa 100644
--- a/chromium/cc/layers/painted_scrollbar_layer_impl_unittest.cc
+++ b/chromium/cc/layers/painted_scrollbar_layer_impl_unittest.cc
@@ -38,7 +38,6 @@ TEST(PaintedScrollbarLayerImplTest, Occlusion) {
PaintedScrollbarLayerImpl* scrollbar_layer_impl =
impl.AddChildToRoot<PaintedScrollbarLayerImpl>(orientation);
scrollbar_layer_impl->SetBounds(layer_size);
- scrollbar_layer_impl->SetContentBounds(layer_size);
scrollbar_layer_impl->SetContentsOpaque(true);
scrollbar_layer_impl->set_internal_contents_scale_and_bounds(
scale, scaled_layer_size);
@@ -89,7 +88,7 @@ TEST(PaintedScrollbarLayerImplTest, Occlusion) {
{
SCOPED_TRACE("Full occlusion");
- gfx::Rect occluded(scrollbar_layer_impl->visible_content_rect());
+ gfx::Rect occluded(scrollbar_layer_impl->visible_layer_rect());
impl.AppendQuadsWithOcclusion(scrollbar_layer_impl, occluded);
LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect());
diff --git a/chromium/cc/layers/picture_image_layer.cc b/chromium/cc/layers/picture_image_layer.cc
index 345ee2b4e95..6d903bd40bc 100644
--- a/chromium/cc/layers/picture_image_layer.cc
+++ b/chromium/cc/layers/picture_image_layer.cc
@@ -12,11 +12,14 @@
namespace cc {
-scoped_refptr<PictureImageLayer> PictureImageLayer::Create() {
- return make_scoped_refptr(new PictureImageLayer());
+scoped_refptr<PictureImageLayer> PictureImageLayer::Create(
+ const LayerSettings& settings) {
+ return make_scoped_refptr(new PictureImageLayer(settings));
}
-PictureImageLayer::PictureImageLayer() : PictureLayer(this) {}
+PictureImageLayer::PictureImageLayer(const LayerSettings& settings)
+ : PictureLayer(settings, this) {
+}
PictureImageLayer::~PictureImageLayer() {
ClearClient();
@@ -63,10 +66,15 @@ void PictureImageLayer::PaintContents(
canvas->drawBitmap(bitmap_, 0, 0);
}
-void PictureImageLayer::PaintContentsToDisplayList(
- DisplayItemList* display_list,
+scoped_refptr<DisplayItemList> PictureImageLayer::PaintContentsToDisplayList(
const gfx::Rect& clip,
ContentLayerClient::PaintingControlSetting painting_control) {
+ // Picture image layers can be used with GatherPixelRefs, so cached SkPictures
+ // are currently required.
+ const bool use_cached_picture = true;
+ scoped_refptr<DisplayItemList> display_list =
+ DisplayItemList::Create(clip, use_cached_picture);
+
SkPictureRecorder recorder;
SkCanvas* canvas = recorder.beginRecording(gfx::RectToSkRect(clip));
PaintContents(canvas, clip, painting_control);
@@ -75,6 +83,9 @@ void PictureImageLayer::PaintContentsToDisplayList(
skia::AdoptRef(recorder.endRecordingAsPicture());
auto* item = display_list->CreateAndAppendItem<DrawingDisplayItem>();
item->SetNew(picture.Pass());
+
+ display_list->Finalize();
+ return display_list;
}
bool PictureImageLayer::FillsBoundsCompletely() const {
diff --git a/chromium/cc/layers/picture_image_layer.h b/chromium/cc/layers/picture_image_layer.h
index a12a1b9085d..df597f3bf02 100644
--- a/chromium/cc/layers/picture_image_layer.h
+++ b/chromium/cc/layers/picture_image_layer.h
@@ -15,7 +15,7 @@ namespace cc {
class CC_EXPORT PictureImageLayer : public PictureLayer, ContentLayerClient {
public:
- static scoped_refptr<PictureImageLayer> Create();
+ static scoped_refptr<PictureImageLayer> Create(const LayerSettings& settings);
void SetBitmap(const SkBitmap& image);
@@ -27,8 +27,7 @@ class CC_EXPORT PictureImageLayer : public PictureLayer, ContentLayerClient {
SkCanvas* canvas,
const gfx::Rect& clip,
ContentLayerClient::PaintingControlSetting painting_control) override;
- void PaintContentsToDisplayList(
- DisplayItemList* display_list,
+ scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
const gfx::Rect& clip,
ContentLayerClient::PaintingControlSetting painting_control) override;
bool FillsBoundsCompletely() const override;
@@ -37,7 +36,7 @@ class CC_EXPORT PictureImageLayer : public PictureLayer, ContentLayerClient {
bool HasDrawableContent() const override;
private:
- PictureImageLayer();
+ explicit PictureImageLayer(const LayerSettings& settings);
~PictureImageLayer() override;
SkBitmap bitmap_;
diff --git a/chromium/cc/layers/picture_image_layer_impl_unittest.cc b/chromium/cc/layers/picture_image_layer_impl_unittest.cc
index fa4cb6e7e06..2a9dda710db 100644
--- a/chromium/cc/layers/picture_image_layer_impl_unittest.cc
+++ b/chromium/cc/layers/picture_image_layer_impl_unittest.cc
@@ -11,7 +11,6 @@
#include "cc/test/fake_layer_tree_host_impl.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_picture_pile_impl.h"
-#include "cc/test/impl_side_painting_settings.h"
#include "cc/test/test_shared_bitmap_manager.h"
#include "cc/test/test_task_graph_runner.h"
#include "cc/tiles/tile_priority.h"
@@ -33,11 +32,18 @@ class TestablePictureImageLayerImpl : public PictureImageLayerImpl {
friend class PictureImageLayerImplTest;
};
+class PictureLayerImplImageTestSettings : public LayerTreeSettings {
+ public:
+ PictureLayerImplImageTestSettings() {
+ layer_transforms_should_scale_layer_contents = true;
+ }
+};
+
class PictureImageLayerImplTest : public testing::Test {
public:
PictureImageLayerImplTest()
: proxy_(base::ThreadTaskRunnerHandle::Get()),
- host_impl_(ImplSidePaintingSettings(),
+ host_impl_(PictureLayerImplImageTestSettings(),
&proxy_,
&shared_bitmap_manager_,
&task_graph_runner_) {
@@ -60,7 +66,6 @@ class PictureImageLayerImplTest : public testing::Test {
new TestablePictureImageLayerImpl(tree, id);
layer->raster_source_ = FakePicturePileImpl::CreateInfiniteFilledPile();
layer->SetBounds(layer->raster_source_->GetSize());
- layer->SetContentBounds(layer->raster_source_->GetSize());
return make_scoped_ptr(layer);
}
@@ -71,14 +76,15 @@ class PictureImageLayerImplTest : public testing::Test {
float maximum_animation_contents_scale,
bool animating_transform_to_screen,
gfx::Rect viewport_rect) {
- layer->draw_properties().ideal_contents_scale = ideal_contents_scale;
- layer->draw_properties().device_scale_factor = device_scale_factor;
- layer->draw_properties().page_scale_factor = page_scale_factor;
+ gfx::Transform scale_transform;
+ scale_transform.Scale(ideal_contents_scale, ideal_contents_scale);
+ layer->draw_properties().target_space_transform = scale_transform;
+ DCHECK_EQ(layer->GetIdealContentsScale(), ideal_contents_scale);
layer->draw_properties().maximum_animation_contents_scale =
maximum_animation_contents_scale;
layer->draw_properties().screen_space_transform_is_animating =
animating_transform_to_screen;
- layer->draw_properties().visible_content_rect = viewport_rect;
+ layer->draw_properties().visible_layer_rect = viewport_rect;
bool resourceless_software_draw = false;
layer->UpdateTiles(resourceless_software_draw);
}
@@ -97,9 +103,6 @@ TEST_F(PictureImageLayerImplTest, CalculateContentsScale) {
gfx::Rect viewport(100, 200);
SetupDrawPropertiesAndUpdateTiles(
layer.get(), 2.f, 3.f, 4.f, 1.f, false, viewport);
-
- EXPECT_FLOAT_EQ(1.f, layer->contents_scale_x());
- EXPECT_FLOAT_EQ(1.f, layer->contents_scale_y());
EXPECT_FLOAT_EQ(1.f, layer->MaximumTilingContentsScale());
}
diff --git a/chromium/cc/layers/picture_image_layer_unittest.cc b/chromium/cc/layers/picture_image_layer_unittest.cc
index 786e30979a3..fafdbf12541 100644
--- a/chromium/cc/layers/picture_image_layer_unittest.cc
+++ b/chromium/cc/layers/picture_image_layer_unittest.cc
@@ -6,6 +6,7 @@
#include "cc/playback/display_item.h"
#include "cc/test/skia_common.h"
+#include "cc/trees/layer_tree_settings.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h"
@@ -15,7 +16,8 @@ namespace cc {
namespace {
TEST(PictureImageLayerTest, PaintContentsToDisplayList) {
- scoped_refptr<PictureImageLayer> layer = PictureImageLayer::Create();
+ scoped_refptr<PictureImageLayer> layer =
+ PictureImageLayer::Create(LayerSettings());
gfx::Rect layer_rect(200, 200);
SkBitmap image_bitmap;
@@ -33,46 +35,9 @@ TEST(PictureImageLayerTest, PaintContentsToDisplayList) {
layer->SetBitmap(image_bitmap);
layer->SetBounds(gfx::Size(layer_rect.width(), layer_rect.height()));
- bool use_cached_picture = false;
scoped_refptr<DisplayItemList> display_list =
- DisplayItemList::Create(layer_rect, use_cached_picture);
- layer->PaintContentsToDisplayList(
- display_list.get(), layer_rect,
- ContentLayerClient::PAINTING_BEHAVIOR_NORMAL);
- display_list->ProcessAppendedItems();
- unsigned char actual_pixels[4 * 200 * 200] = {0};
- DrawDisplayList(actual_pixels, layer_rect, display_list);
-
- EXPECT_EQ(0, memcmp(actual_pixels, image_pixels, 4 * 200 * 200));
-}
-
-TEST(PictureImageLayerTest, PaintContentsToCachedDisplayList) {
- scoped_refptr<PictureImageLayer> layer = PictureImageLayer::Create();
- gfx::Rect layer_rect(200, 200);
-
- SkBitmap image_bitmap;
- unsigned char image_pixels[4 * 200 * 200] = {0};
- SkImageInfo info =
- SkImageInfo::MakeN32Premul(layer_rect.width(), layer_rect.height());
- image_bitmap.installPixels(info, image_pixels, info.minRowBytes());
- SkCanvas image_canvas(image_bitmap);
- image_canvas.clear(SK_ColorRED);
- SkPaint blue_paint;
- blue_paint.setColor(SK_ColorBLUE);
- image_canvas.drawRectCoords(0.f, 0.f, 100.f, 100.f, blue_paint);
- image_canvas.drawRectCoords(100.f, 100.f, 200.f, 200.f, blue_paint);
-
- layer->SetBitmap(image_bitmap);
- layer->SetBounds(gfx::Size(layer_rect.width(), layer_rect.height()));
-
- bool use_cached_picture = true;
- scoped_refptr<DisplayItemList> display_list =
- DisplayItemList::Create(layer_rect, use_cached_picture);
- layer->PaintContentsToDisplayList(
- display_list.get(), layer_rect,
- ContentLayerClient::PAINTING_BEHAVIOR_NORMAL);
- display_list->ProcessAppendedItems();
- display_list->CreateAndCacheSkPicture();
+ layer->PaintContentsToDisplayList(
+ layer_rect, ContentLayerClient::PAINTING_BEHAVIOR_NORMAL);
unsigned char actual_pixels[4 * 200 * 200] = {0};
DrawDisplayList(actual_pixels, layer_rect, display_list);
diff --git a/chromium/cc/layers/picture_layer.cc b/chromium/cc/layers/picture_layer.cc
index 999363282a0..53d5d97d456 100644
--- a/chromium/cc/layers/picture_layer.cc
+++ b/chromium/cc/layers/picture_layer.cc
@@ -16,21 +16,25 @@
namespace cc {
-scoped_refptr<PictureLayer> PictureLayer::Create(ContentLayerClient* client) {
- return make_scoped_refptr(new PictureLayer(client));
+scoped_refptr<PictureLayer> PictureLayer::Create(const LayerSettings& settings,
+ ContentLayerClient* client) {
+ return make_scoped_refptr(new PictureLayer(settings, client));
}
-PictureLayer::PictureLayer(ContentLayerClient* client)
- : client_(client),
+PictureLayer::PictureLayer(const LayerSettings& settings,
+ ContentLayerClient* client)
+ : Layer(settings),
+ client_(client),
instrumentation_object_tracker_(id()),
update_source_frame_number_(-1),
is_mask_(false),
nearest_neighbor_(false) {
}
-PictureLayer::PictureLayer(ContentLayerClient* client,
+PictureLayer::PictureLayer(const LayerSettings& settings,
+ ContentLayerClient* client,
scoped_ptr<RecordingSource> source)
- : PictureLayer(client) {
+ : PictureLayer(settings, client) {
recording_source_ = source.Pass();
}
@@ -88,9 +92,8 @@ void PictureLayer::SetLayerTreeHost(LayerTreeHost* host) {
const LayerTreeSettings& settings = layer_tree_host()->settings();
if (!recording_source_) {
if (settings.use_display_lists) {
- recording_source_.reset(new DisplayListRecordingSource(
- settings.default_tile_grid_size,
- settings.use_cached_picture_in_display_list));
+ recording_source_.reset(
+ new DisplayListRecordingSource(settings.default_tile_grid_size));
} else {
recording_source_.reset(new PicturePile(settings.minimum_contents_scale,
settings.default_tile_grid_size));
@@ -99,8 +102,6 @@ void PictureLayer::SetLayerTreeHost(LayerTreeHost* host) {
recording_source_->SetSlowdownRasterScaleFactor(
host->debug_state().slow_down_raster_scale_factor);
recording_source_->SetGatherPixelRefs(settings.gather_pixel_refs);
-
- DCHECK(settings.raster_enabled);
}
void PictureLayer::SetNeedsDisplayRect(const gfx::Rect& layer_rect) {
@@ -112,16 +113,14 @@ void PictureLayer::SetNeedsDisplayRect(const gfx::Rect& layer_rect) {
Layer::SetNeedsDisplayRect(layer_rect);
}
-bool PictureLayer::Update(ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion) {
+bool PictureLayer::Update() {
update_source_frame_number_ = layer_tree_host()->source_frame_number();
- bool updated = Layer::Update(queue, occlusion);
+ bool updated = Layer::Update();
- gfx::Rect visible_layer_rect = gfx::ScaleToEnclosingRect(
- visible_content_rect(), 1.f / contents_scale_x());
+ gfx::Rect update_rect = visible_layer_rect();
gfx::Size layer_size = paint_properties().bounds;
- if (last_updated_visible_content_rect_ == visible_content_rect() &&
+ if (last_updated_visible_layer_rect_ == update_rect &&
recording_source_->GetSize() == layer_size &&
pending_invalidation_.IsEmpty()) {
// Only early out if the visible content rect of this layer hasn't changed.
@@ -146,7 +145,7 @@ bool PictureLayer::Update(ResourceUpdateQueue* queue,
if (layer_tree_host()->settings().record_full_layer) {
// Workaround for http://crbug.com/235910 - to retain backwards compat
// the full page content must always be provided in the picture layer.
- visible_layer_rect = gfx::Rect(layer_size);
+ update_rect = gfx::Rect(layer_size);
}
// UpdateAndExpandInvalidation will give us an invalidation that covers
@@ -155,9 +154,9 @@ bool PictureLayer::Update(ResourceUpdateQueue* queue,
// for them.
DCHECK(client_);
updated |= recording_source_->UpdateAndExpandInvalidation(
- client_, &recording_invalidation_, layer_size, visible_layer_rect,
+ client_, &recording_invalidation_, layer_size, update_rect,
update_source_frame_number_, RecordingSource::RECORD_NORMALLY);
- last_updated_visible_content_rect_ = visible_content_rect();
+ last_updated_visible_layer_rect_ = visible_layer_rect();
if (updated) {
SetNeedsPushProperties();
@@ -186,9 +185,8 @@ skia::RefPtr<SkPicture> PictureLayer::GetPicture() const {
if (settings.use_display_lists) {
scoped_ptr<RecordingSource> recording_source;
- recording_source.reset(new DisplayListRecordingSource(
- settings.default_tile_grid_size,
- settings.use_cached_picture_in_display_list));
+ recording_source.reset(
+ new DisplayListRecordingSource(settings.default_tile_grid_size));
Region recording_invalidation;
recording_source->UpdateAndExpandInvalidation(
client_, &recording_invalidation, layer_size, gfx::Rect(layer_size),
diff --git a/chromium/cc/layers/picture_layer.h b/chromium/cc/layers/picture_layer.h
index 767de273302..771484c19cc 100644
--- a/chromium/cc/layers/picture_layer.h
+++ b/chromium/cc/layers/picture_layer.h
@@ -9,7 +9,6 @@
#include "cc/debug/devtools_instrumentation.h"
#include "cc/debug/micro_benchmark_controller.h"
#include "cc/layers/layer.h"
-#include "cc/trees/occlusion_tracker.h"
namespace cc {
@@ -19,7 +18,8 @@ class ResourceUpdateQueue;
class CC_EXPORT PictureLayer : public Layer {
public:
- static scoped_refptr<PictureLayer> Create(ContentLayerClient* client);
+ static scoped_refptr<PictureLayer> Create(const LayerSettings& settings,
+ ContentLayerClient* client);
void ClearClient();
@@ -30,8 +30,7 @@ class CC_EXPORT PictureLayer : public Layer {
void SetLayerTreeHost(LayerTreeHost* host) override;
void PushPropertiesTo(LayerImpl* layer) override;
void SetNeedsDisplayRect(const gfx::Rect& layer_rect) override;
- bool Update(ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion) override;
+ bool Update() override;
void SetIsMask(bool is_mask) override;
skia::RefPtr<SkPicture> GetPicture() const override;
bool IsSuitableForGpuRasterization() const override;
@@ -45,9 +44,11 @@ class CC_EXPORT PictureLayer : public Layer {
}
protected:
- explicit PictureLayer(ContentLayerClient* client);
+ PictureLayer(const LayerSettings& settings, ContentLayerClient* client);
// Allow tests to inject a recording source.
- PictureLayer(ContentLayerClient* client, scoped_ptr<RecordingSource> source);
+ PictureLayer(const LayerSettings& settings,
+ ContentLayerClient* client,
+ scoped_ptr<RecordingSource> source);
~PictureLayer() override;
bool HasDrawableContent() const override;
@@ -63,7 +64,7 @@ class CC_EXPORT PictureLayer : public Layer {
InvalidationRegion pending_invalidation_;
// Invalidation from the last time update was called.
Region recording_invalidation_;
- gfx::Rect last_updated_visible_content_rect_;
+ gfx::Rect last_updated_visible_layer_rect_;
int update_source_frame_number_;
bool is_mask_;
diff --git a/chromium/cc/layers/picture_layer_impl.cc b/chromium/cc/layers/picture_layer_impl.cc
index f9f6d978714..c7076bdc1e1 100644
--- a/chromium/cc/layers/picture_layer_impl.cc
+++ b/chromium/cc/layers/picture_layer_impl.cc
@@ -12,7 +12,6 @@
#include "base/time/time.h"
#include "base/trace_event/trace_event_argument.h"
#include "cc/base/math_util.h"
-#include "cc/base/util.h"
#include "cc/debug/debug_colors.h"
#include "cc/debug/micro_benchmark_impl.h"
#include "cc/debug/traced_value.h"
@@ -162,7 +161,7 @@ void PictureLayerImpl::AppendQuads(RenderPass* render_pass,
SolidColorLayerImpl::AppendSolidQuads(
render_pass, draw_properties().occlusion_in_content_space,
- shared_quad_state, visible_content_rect(),
+ shared_quad_state, visible_layer_rect(),
raster_source_->GetSolidColor(), append_quads_data);
return;
}
@@ -172,22 +171,22 @@ void PictureLayerImpl::AppendQuads(RenderPass* render_pass,
Occlusion scaled_occlusion =
draw_properties()
.occlusion_in_content_space.GetOcclusionWithGivenDrawTransform(
- shared_quad_state->content_to_target_transform);
+ shared_quad_state->quad_to_target_transform);
if (current_draw_mode_ == DRAW_MODE_RESOURCELESS_SOFTWARE) {
AppendDebugBorderQuad(
- render_pass, shared_quad_state->content_bounds, shared_quad_state,
+ render_pass, shared_quad_state->quad_layer_bounds, shared_quad_state,
append_quads_data, DebugColors::DirectPictureBorderColor(),
DebugColors::DirectPictureBorderWidth(layer_tree_impl()));
- gfx::Rect geometry_rect = shared_quad_state->visible_content_rect;
+ gfx::Rect geometry_rect = shared_quad_state->visible_quad_layer_rect;
gfx::Rect opaque_rect = contents_opaque() ? geometry_rect : gfx::Rect();
gfx::Rect visible_geometry_rect =
scaled_occlusion.GetUnoccludedContentRect(geometry_rect);
if (visible_geometry_rect.IsEmpty())
return;
- gfx::Rect quad_content_rect = shared_quad_state->visible_content_rect;
+ gfx::Rect quad_content_rect = shared_quad_state->visible_quad_layer_rect;
gfx::Size texture_size = quad_content_rect.size();
gfx::RectF texture_rect = gfx::RectF(texture_size);
@@ -201,13 +200,13 @@ void PictureLayerImpl::AppendQuads(RenderPass* render_pass,
return;
}
- AppendDebugBorderQuad(render_pass, shared_quad_state->content_bounds,
+ AppendDebugBorderQuad(render_pass, shared_quad_state->quad_layer_bounds,
shared_quad_state, append_quads_data);
if (ShowDebugBorders()) {
for (PictureLayerTilingSet::CoverageIterator iter(
tilings_.get(), max_contents_scale,
- shared_quad_state->visible_content_rect, ideal_contents_scale_);
+ shared_quad_state->visible_quad_layer_rect, ideal_contents_scale_);
iter; ++iter) {
SkColor color;
float width;
@@ -264,7 +263,7 @@ void PictureLayerImpl::AppendQuads(RenderPass* render_pass,
only_used_low_res_last_append_quads_ = true;
for (PictureLayerTilingSet::CoverageIterator iter(
tilings_.get(), max_contents_scale,
- shared_quad_state->visible_content_rect, ideal_contents_scale_);
+ shared_quad_state->visible_quad_layer_rect, ideal_contents_scale_);
iter; ++iter) {
gfx::Rect geometry_rect = iter.geometry_rect();
gfx::Rect opaque_rect = contents_opaque() ? geometry_rect : gfx::Rect();
@@ -273,7 +272,7 @@ void PictureLayerImpl::AppendQuads(RenderPass* render_pass,
if (visible_geometry_rect.IsEmpty())
continue;
- append_quads_data->visible_content_area +=
+ append_quads_data->visible_layer_area +=
visible_geometry_rect.width() * visible_geometry_rect.height();
bool has_draw_quad = false;
@@ -302,6 +301,7 @@ void PictureLayerImpl::AppendQuads(RenderPass* render_pass,
texture_rect, draw_info.resource_size(),
draw_info.contents_swizzled(), nearest_neighbor_);
ValidateQuadResources(quad);
+ iter->draw_info().set_was_ever_used_to_draw();
has_draw_quad = true;
break;
}
@@ -311,6 +311,7 @@ void PictureLayerImpl::AppendQuads(RenderPass* render_pass,
quad->SetNew(shared_quad_state, geometry_rect, visible_geometry_rect,
draw_info.solid_color(), false);
ValidateQuadResources(quad);
+ iter->draw_info().set_was_ever_used_to_draw();
has_draw_quad = true;
break;
}
@@ -320,23 +321,14 @@ void PictureLayerImpl::AppendQuads(RenderPass* render_pass,
}
if (!has_draw_quad) {
- if (draw_checkerboard_for_missing_tiles()) {
- CheckerboardDrawQuad* quad =
- render_pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
- SkColor color = DebugColors::DefaultCheckerboardColor();
- quad->SetNew(shared_quad_state, geometry_rect, visible_geometry_rect,
- color, draw_properties().device_scale_factor);
- } else {
- SkColor color = SafeOpaqueBackgroundColor();
- SolidColorDrawQuad* quad =
- render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
- quad->SetNew(shared_quad_state,
- geometry_rect,
- visible_geometry_rect,
- color,
- false);
- ValidateQuadResources(quad);
- }
+ // Checkerboard.
+ // TODO(danakj): Make this a different color when debugging.
+ SkColor color = SafeOpaqueBackgroundColor();
+ SolidColorDrawQuad* quad =
+ render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
+ quad->SetNew(shared_quad_state, geometry_rect, visible_geometry_rect,
+ color, false);
+ ValidateQuadResources(quad);
if (geometry_rect.Intersects(scaled_viewport_for_tile_priority)) {
append_quads_data->num_missing_tiles++;
@@ -377,17 +369,14 @@ void PictureLayerImpl::AppendQuads(RenderPass* render_pass,
// Aggressively remove any tilings that are not seen to save memory. Note
// that this is at the expense of doing cause more frequent re-painting. A
- // better scheme would be to maintain a tighter visible_content_rect for the
+ // better scheme would be to maintain a tighter visible_layer_rect for the
// finer tilings.
CleanUpTilingsOnActiveLayer(last_append_quads_tilings_);
}
bool PictureLayerImpl::UpdateTiles(bool resourceless_software_draw) {
- DCHECK_EQ(1.f, contents_scale_x());
- DCHECK_EQ(1.f, contents_scale_y());
-
if (!resourceless_software_draw) {
- visible_rect_for_tile_priority_ = visible_content_rect();
+ visible_rect_for_tile_priority_ = visible_layer_rect();
}
if (!CanHaveTilings()) {
@@ -478,6 +467,21 @@ void PictureLayerImpl::UpdateViewportRectForTilePriorityInContentSpace() {
visible_rect_in_content_space =
gfx::ToEnclosingRect(MathUtil::ProjectClippedRect(
view_to_layer, viewport_rect_for_tile_priority));
+
+ // We have to allow for a viewport that is outside of the layer bounds in
+ // order to compute tile priorities correctly for offscreen content that
+ // is going to make it on screen. However, we also have to limit the
+ // viewport since it can be very large due to screen_space_transforms. As
+ // a heuristic, we clip to bounds padded by skewport_extrapolation_limit *
+ // maximum tiling scale, since this should allow sufficient room for
+ // skewport calculations.
+ gfx::Rect padded_bounds(bounds());
+ int padding_amount = layer_tree_impl()
+ ->settings()
+ .skewport_extrapolation_limit_in_content_pixels *
+ MaximumTilingContentsScale();
+ padded_bounds.Inset(-padding_amount, -padding_amount);
+ visible_rect_in_content_space.Intersect(padded_bounds);
}
}
viewport_rect_for_tile_priority_in_content_space_ =
@@ -490,12 +494,6 @@ PictureLayerImpl* PictureLayerImpl::GetPendingOrActiveTwinLayer() const {
return twin_layer_;
}
-PictureLayerImpl* PictureLayerImpl::GetRecycledTwinLayer() const {
- if (!twin_layer_ || twin_layer_->IsOnActiveOrPendingTree())
- return nullptr;
- return twin_layer_;
-}
-
void PictureLayerImpl::UpdateRasterSource(
scoped_refptr<RasterSource> raster_source,
Region* new_invalidation,
@@ -583,6 +581,12 @@ void PictureLayerImpl::NotifyTileStateChanged(const Tile* tile) {
gfx::ScaleRect(tile->content_rect(), 1.f / tile->contents_scale());
AddDamageRect(layer_damage_rect);
}
+ if (tile->draw_info().NeedsRaster()) {
+ PictureLayerTiling* tiling =
+ tilings_->FindTilingWithScale(tile->contents_scale());
+ if (tiling)
+ tiling->set_all_tiles_done(false);
+ }
}
void PictureLayerImpl::DidBeginTracing() {
@@ -651,12 +655,6 @@ const PictureLayerTiling* PictureLayerImpl::GetPendingOrActiveTwinTiling(
return twin_layer->tilings_->FindTilingWithScale(tiling->contents_scale());
}
-TilePriority::PriorityBin PictureLayerImpl::GetMaxTilePriorityBin() const {
- if (!HasValidTilePriorities())
- return TilePriority::EVENTUALLY;
- return TilePriority::NOW;
-}
-
bool PictureLayerImpl::RequiresHighResToDraw() const {
return layer_tree_impl()->RequiresHighResToDraw();
}
@@ -695,7 +693,7 @@ gfx::Size PictureLayerImpl::CalculateTileSize(
divisor = 2;
if (content_bounds.width() <= viewport_width / 4)
divisor = 1;
- default_tile_height = RoundUp(viewport_height, divisor) / divisor;
+ default_tile_height = MathUtil::RoundUp(viewport_height, divisor) / divisor;
// Grow default sizes to account for overlapping border texels.
default_tile_width += 2 * PictureLayerTiling::kBorderTexels;
@@ -731,12 +729,12 @@ gfx::Size PictureLayerImpl::CalculateTileSize(
// Clamp the tile width/height to the content width/height to save space.
if (content_bounds.width() < default_tile_width) {
tile_width = std::min(tile_width, content_bounds.width());
- tile_width = RoundUp(tile_width, kTileRoundUp);
+ tile_width = MathUtil::RoundUp(tile_width, kTileRoundUp);
tile_width = std::min(tile_width, default_tile_width);
}
if (content_bounds.height() < default_tile_height) {
tile_height = std::min(tile_height, content_bounds.height());
- tile_height = RoundUp(tile_height, kTileRoundUp);
+ tile_height = MathUtil::RoundUp(tile_height, kTileRoundUp);
tile_height = std::min(tile_height, default_tile_height);
}
@@ -746,9 +744,8 @@ gfx::Size PictureLayerImpl::CalculateTileSize(
return gfx::Size(tile_width, tile_height);
}
-void PictureLayerImpl::GetContentsResourceId(
- ResourceProvider::ResourceId* resource_id,
- gfx::Size* resource_size) const {
+void PictureLayerImpl::GetContentsResourceId(ResourceId* resource_id,
+ gfx::Size* resource_size) const {
// The bounds and the pile size may differ if the pile wasn't updated (ie.
// PictureLayer::Update didn't happen). In that case the pile will be empty.
DCHECK_IMPLIES(!raster_source_->GetSize().IsEmpty(),
@@ -813,31 +810,29 @@ void PictureLayerImpl::AddTilingsForRasterScale() {
// We always need a high res tiling, so create one if it doesn't exist.
if (!high_res)
high_res = AddTiling(raster_contents_scale_);
-
- // Try and find a low res tiling.
- PictureLayerTiling* low_res = nullptr;
- if (raster_contents_scale_ == low_res_raster_contents_scale_)
- low_res = high_res;
- else
- low_res = tilings_->FindTilingWithScale(low_res_raster_contents_scale_);
-
- // Only create new low res tilings when the transform is static. This
- // prevents wastefully creating a paired low res tiling for every new high res
- // tiling during a pinch or a CSS animation.
- bool can_have_low_res = layer_tree_impl()->create_low_res_tiling();
- bool needs_low_res = !low_res;
- bool is_pinching = layer_tree_impl()->PinchGestureActive();
- bool is_animating = draw_properties().screen_space_transform_is_animating;
- if (can_have_low_res && needs_low_res && !is_pinching && !is_animating)
- low_res = AddTiling(low_res_raster_contents_scale_);
-
- // Set low-res if we have one.
- if (low_res && low_res != high_res)
- low_res->set_resolution(LOW_RESOLUTION);
-
- // Make sure we always have one high-res (even if high == low).
high_res->set_resolution(HIGH_RESOLUTION);
+ // If the low res scale is the same as the high res scale, that tiling
+ // will be treated as high res.
+ if (layer_tree_impl()->create_low_res_tiling() &&
+ raster_contents_scale_ != low_res_raster_contents_scale_) {
+ PictureLayerTiling* low_res =
+ tilings_->FindTilingWithScale(low_res_raster_contents_scale_);
+
+ // Only create new low res tilings when the transform is static. This
+ // prevents wastefully creating a paired low res tiling for every new high
+ // res tiling during a pinch or a CSS animation.
+ bool is_pinching = layer_tree_impl()->PinchGestureActive();
+ bool is_animating = draw_properties().screen_space_transform_is_animating;
+ if (!low_res && !is_pinching && !is_animating)
+ low_res = AddTiling(low_res_raster_contents_scale_);
+
+ if (low_res) {
+ DCHECK_NE(low_res, high_res);
+ low_res->set_resolution(LOW_RESOLUTION);
+ }
+ }
+
if (layer_tree_impl()->IsPendingTree()) {
// On the pending tree, drop any tilings that are non-ideal since we don't
// need them to activate anyway.
@@ -1038,19 +1033,9 @@ void PictureLayerImpl::CleanUpTilingsOnActiveLayer(
}
PictureLayerTilingSet* twin_set = twin ? twin->tilings_.get() : nullptr;
- // TODO(vmpstr): See if this step is required without tile sharing.
- PictureLayerImpl* recycled_twin = GetRecycledTwinLayer();
- PictureLayerTilingSet* recycled_twin_set =
- recycled_twin ? recycled_twin->tilings_.get() : nullptr;
-
- tilings_->CleanUpTilings(min_acceptable_high_res_scale,
- max_acceptable_high_res_scale, used_tilings,
- layer_tree_impl()->create_low_res_tiling(), twin_set,
- recycled_twin_set);
-
- if (recycled_twin_set && recycled_twin_set->num_tilings() == 0)
- recycled_twin->ResetRasterScale();
-
+ tilings_->CleanUpTilings(
+ min_acceptable_high_res_scale, max_acceptable_high_res_scale,
+ used_tilings, layer_tree_impl()->create_low_res_tiling(), twin_set);
DCHECK_GT(tilings_->num_tilings(), 0u);
SanityCheckTilingState();
}
@@ -1118,10 +1103,6 @@ bool PictureLayerImpl::CanHaveTilings() const {
void PictureLayerImpl::SanityCheckTilingState() const {
#if DCHECK_IS_ON()
- // Recycle tree doesn't have any restrictions.
- if (layer_tree_impl()->IsRecycleTree())
- return;
-
if (!CanHaveTilings()) {
DCHECK_EQ(0u, tilings_->num_tilings());
return;
@@ -1159,21 +1140,14 @@ void PictureLayerImpl::UpdateIdealScales() {
float min_contents_scale = MinimumContentsScale();
DCHECK_GT(min_contents_scale, 0.f);
- float min_page_scale = layer_tree_impl()->min_page_scale_factor();
- DCHECK_GT(min_page_scale, 0.f);
- float min_device_scale = 1.f;
- float min_source_scale =
- min_contents_scale / min_page_scale / min_device_scale;
-
- float ideal_page_scale = draw_properties().page_scale_factor;
- float ideal_device_scale = draw_properties().device_scale_factor;
- float ideal_source_scale = draw_properties().ideal_contents_scale /
- ideal_page_scale / ideal_device_scale;
- ideal_contents_scale_ =
- std::max(draw_properties().ideal_contents_scale, min_contents_scale);
- ideal_page_scale_ = draw_properties().page_scale_factor;
- ideal_device_scale_ = draw_properties().device_scale_factor;
- ideal_source_scale_ = std::max(ideal_source_scale, min_source_scale);
+
+ ideal_page_scale_ = IsAffectedByPageScale()
+ ? layer_tree_impl()->current_page_scale_factor()
+ : 1.f;
+ ideal_device_scale_ = layer_tree_impl()->device_scale_factor();
+ ideal_contents_scale_ = std::max(GetIdealContentsScale(), min_contents_scale);
+ ideal_source_scale_ =
+ ideal_contents_scale_ / ideal_page_scale_ / ideal_device_scale_;
}
void PictureLayerImpl::GetDebugBorderProperties(
@@ -1202,7 +1176,7 @@ void PictureLayerImpl::AsValueInto(
MathUtil::AddToTracedValue("tile_priority_rect",
viewport_rect_for_tile_priority_in_content_space_,
state);
- MathUtil::AddToTracedValue("visible_rect", visible_content_rect(), state);
+ MathUtil::AddToTracedValue("visible_rect", visible_layer_rect(), state);
state->BeginArray("pictures");
raster_source_->AsValueInto(state);
diff --git a/chromium/cc/layers/picture_layer_impl.h b/chromium/cc/layers/picture_layer_impl.h
index bca8224974c..a23dbba61d7 100644
--- a/chromium/cc/layers/picture_layer_impl.h
+++ b/chromium/cc/layers/picture_layer_impl.h
@@ -61,7 +61,7 @@ class CC_EXPORT PictureLayerImpl
const Region* GetPendingInvalidation() override;
const PictureLayerTiling* GetPendingOrActiveTwinTiling(
const PictureLayerTiling* tiling) const override;
- TilePriority::PriorityBin GetMaxTilePriorityBin() const override;
+ bool HasValidTilePriorities() const override;
bool RequiresHighResToDraw() const override;
gfx::Rect GetEnclosingRectInTargetSpace() const override;
@@ -77,7 +77,7 @@ class CC_EXPORT PictureLayerImpl
WhichTree GetTree() const;
// Mask-related functions.
- void GetContentsResourceId(ResourceProvider::ResourceId* resource_id,
+ void GetContentsResourceId(ResourceId* resource_id,
gfx::Size* resource_size) const override;
void SetNearestNeighbor(bool nearest_neighbor);
@@ -93,8 +93,6 @@ class CC_EXPORT PictureLayerImpl
// Functions used by tile manager.
PictureLayerImpl* GetPendingOrActiveTwinLayer() const;
bool IsOnActiveOrPendingTree() const;
- // Virtual for testing.
- virtual bool HasValidTilePriorities() const;
// Used for benchmarking
RasterSource* GetRasterSource() const { return raster_source_.get(); }
diff --git a/chromium/cc/layers/picture_layer_impl_perftest.cc b/chromium/cc/layers/picture_layer_impl_perftest.cc
index adb05976f72..dcbf2fba85f 100644
--- a/chromium/cc/layers/picture_layer_impl_perftest.cc
+++ b/chromium/cc/layers/picture_layer_impl_perftest.cc
@@ -11,7 +11,6 @@
#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_picture_layer_impl.h"
#include "cc/test/fake_picture_pile_impl.h"
-#include "cc/test/impl_side_painting_settings.h"
#include "cc/test/test_shared_bitmap_manager.h"
#include "cc/test/test_task_graph_runner.h"
#include "cc/tiles/tiling_set_raster_queue_all.h"
@@ -41,7 +40,7 @@ class PictureLayerImplPerfTest : public testing::Test {
public:
PictureLayerImplPerfTest()
: proxy_(base::ThreadTaskRunnerHandle::Get()),
- host_impl_(ImplSidePaintingSettings(),
+ host_impl_(LayerTreeSettings(),
&proxy_,
&shared_bitmap_manager_,
&task_graph_runner_),
@@ -53,22 +52,21 @@ class PictureLayerImplPerfTest : public testing::Test {
host_impl_.InitializeRenderer(FakeOutputSurface::Create3d());
}
- void SetupPendingTree(const gfx::Size& layer_bounds,
- const gfx::Size& tile_size) {
+ void SetupActiveTree(const gfx::Size& layer_bounds,
+ const gfx::Size& tile_size) {
scoped_refptr<FakePicturePileImpl> pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
- host_impl_.CreatePendingTree();
- LayerTreeImpl* pending_tree = host_impl_.pending_tree();
- pending_tree->DetachLayerTree();
-
- scoped_ptr<FakePictureLayerImpl> pending_layer =
- FakePictureLayerImpl::CreateWithRasterSource(pending_tree, 7, pile);
- pending_layer->SetDrawsContent(true);
- pending_layer->SetHasRenderSurface(true);
- pending_tree->SetRootLayer(pending_layer.Pass());
-
- pending_layer_ = static_cast<FakePictureLayerImpl*>(
- host_impl_.pending_tree()->LayerById(7));
+ LayerTreeImpl* active_tree = host_impl_.active_tree();
+ active_tree->DetachLayerTree();
+
+ scoped_ptr<FakePictureLayerImpl> active_layer =
+ FakePictureLayerImpl::CreateWithRasterSource(active_tree, 7, pile);
+ active_layer->SetDrawsContent(true);
+ active_layer->SetHasRenderSurface(true);
+ active_tree->SetRootLayer(active_layer.Pass());
+
+ active_layer_ = static_cast<FakePictureLayerImpl*>(
+ host_impl_.active_tree()->LayerById(7));
}
void RunRasterQueueConstructAndIterateTest(const std::string& test_name,
@@ -76,13 +74,13 @@ class PictureLayerImplPerfTest : public testing::Test {
const gfx::Size& viewport_size) {
host_impl_.SetViewportSize(viewport_size);
bool update_lcd_text = false;
- host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
+ host_impl_.active_tree()->UpdateDrawProperties(update_lcd_text);
timer_.Reset();
do {
int count = num_tiles;
scoped_ptr<TilingSetRasterQueueAll> queue(new TilingSetRasterQueueAll(
- pending_layer_->picture_layer_tiling_set(), false));
+ active_layer_->picture_layer_tiling_set(), false));
while (count--) {
ASSERT_TRUE(!queue->IsEmpty()) << "count: " << count;
ASSERT_TRUE(queue->Top().tile()) << "count: " << count;
@@ -98,15 +96,15 @@ class PictureLayerImplPerfTest : public testing::Test {
void RunRasterQueueConstructTest(const std::string& test_name,
const gfx::Rect& viewport) {
host_impl_.SetViewportSize(viewport.size());
- pending_layer_->PushScrollOffsetFromMainThread(
+ active_layer_->PushScrollOffsetFromMainThreadAndClobberActiveValue(
gfx::ScrollOffset(viewport.x(), viewport.y()));
bool update_lcd_text = false;
- host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
+ host_impl_.active_tree()->UpdateDrawProperties(update_lcd_text);
timer_.Reset();
do {
scoped_ptr<TilingSetRasterQueueAll> queue(new TilingSetRasterQueueAll(
- pending_layer_->picture_layer_tiling_set(), false));
+ active_layer_->picture_layer_tiling_set(), false));
timer_.NextLap();
} while (!timer_.HasTimeLimitExpired());
@@ -119,14 +117,15 @@ class PictureLayerImplPerfTest : public testing::Test {
int num_tiles,
const gfx::Size& viewport_size) {
host_impl_.SetViewportSize(viewport_size);
+ active_layer_->MarkAllTilingsUsed();
bool update_lcd_text = false;
- host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
+ host_impl_.active_tree()->UpdateDrawProperties(update_lcd_text);
timer_.Reset();
do {
int count = num_tiles;
scoped_ptr<TilingSetEvictionQueue> queue(new TilingSetEvictionQueue(
- pending_layer_->picture_layer_tiling_set()));
+ active_layer_->picture_layer_tiling_set()));
while (count--) {
ASSERT_TRUE(!queue->IsEmpty()) << "count: " << count;
ASSERT_TRUE(queue->Top().tile()) << "count: " << count;
@@ -143,15 +142,16 @@ class PictureLayerImplPerfTest : public testing::Test {
void RunEvictionQueueConstructTest(const std::string& test_name,
const gfx::Rect& viewport) {
host_impl_.SetViewportSize(viewport.size());
- pending_layer_->PushScrollOffsetFromMainThread(
+ active_layer_->PushScrollOffsetFromMainThreadAndClobberActiveValue(
gfx::ScrollOffset(viewport.x(), viewport.y()));
+ active_layer_->MarkAllTilingsUsed();
bool update_lcd_text = false;
- host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
+ host_impl_.active_tree()->UpdateDrawProperties(update_lcd_text);
timer_.Reset();
do {
scoped_ptr<TilingSetEvictionQueue> queue(new TilingSetEvictionQueue(
- pending_layer_->picture_layer_tiling_set()));
+ active_layer_->picture_layer_tiling_set()));
timer_.NextLap();
} while (!timer_.HasTimeLimitExpired());
@@ -164,7 +164,7 @@ class PictureLayerImplPerfTest : public testing::Test {
TestTaskGraphRunner task_graph_runner_;
FakeImplProxy proxy_;
FakeLayerTreeHostImpl host_impl_;
- FakePictureLayerImpl* pending_layer_;
+ FakePictureLayerImpl* active_layer_;
LapTimer timer_;
private:
@@ -172,15 +172,15 @@ class PictureLayerImplPerfTest : public testing::Test {
};
TEST_F(PictureLayerImplPerfTest, TilingSetRasterQueueConstructAndIterate) {
- SetupPendingTree(gfx::Size(10000, 10000), gfx::Size(256, 256));
+ SetupActiveTree(gfx::Size(10000, 10000), gfx::Size(256, 256));
float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
- pending_layer_->AddTiling(low_res_factor);
- pending_layer_->AddTiling(0.3f);
- pending_layer_->AddTiling(0.7f);
- pending_layer_->AddTiling(1.0f);
- pending_layer_->AddTiling(2.0f);
+ active_layer_->AddTiling(low_res_factor);
+ active_layer_->AddTiling(0.3f);
+ active_layer_->AddTiling(0.7f);
+ active_layer_->AddTiling(1.0f);
+ active_layer_->AddTiling(2.0f);
RunRasterQueueConstructAndIterateTest("32_100x100", 32, gfx::Size(100, 100));
RunRasterQueueConstructAndIterateTest("32_500x500", 32, gfx::Size(500, 500));
@@ -189,15 +189,15 @@ TEST_F(PictureLayerImplPerfTest, TilingSetRasterQueueConstructAndIterate) {
}
TEST_F(PictureLayerImplPerfTest, TilingSetRasterQueueConstruct) {
- SetupPendingTree(gfx::Size(10000, 10000), gfx::Size(256, 256));
+ SetupActiveTree(gfx::Size(10000, 10000), gfx::Size(256, 256));
float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
- pending_layer_->AddTiling(low_res_factor);
- pending_layer_->AddTiling(0.3f);
- pending_layer_->AddTiling(0.7f);
- pending_layer_->AddTiling(1.0f);
- pending_layer_->AddTiling(2.0f);
+ active_layer_->AddTiling(low_res_factor);
+ active_layer_->AddTiling(0.3f);
+ active_layer_->AddTiling(0.7f);
+ active_layer_->AddTiling(1.0f);
+ active_layer_->AddTiling(2.0f);
RunRasterQueueConstructTest("0_0_100x100", gfx::Rect(0, 0, 100, 100));
RunRasterQueueConstructTest("5000_0_100x100", gfx::Rect(5000, 0, 100, 100));
@@ -205,16 +205,16 @@ TEST_F(PictureLayerImplPerfTest, TilingSetRasterQueueConstruct) {
}
TEST_F(PictureLayerImplPerfTest, TilingSetEvictionQueueConstructAndIterate) {
- SetupPendingTree(gfx::Size(10000, 10000), gfx::Size(256, 256));
+ SetupActiveTree(gfx::Size(10000, 10000), gfx::Size(256, 256));
float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
std::vector<Tile*> all_tiles;
- AddTiling(low_res_factor, pending_layer_, &all_tiles);
- AddTiling(0.3f, pending_layer_, &all_tiles);
- AddTiling(0.7f, pending_layer_, &all_tiles);
- AddTiling(1.0f, pending_layer_, &all_tiles);
- AddTiling(2.0f, pending_layer_, &all_tiles);
+ AddTiling(low_res_factor, active_layer_, &all_tiles);
+ AddTiling(0.3f, active_layer_, &all_tiles);
+ AddTiling(0.7f, active_layer_, &all_tiles);
+ AddTiling(1.0f, active_layer_, &all_tiles);
+ AddTiling(2.0f, active_layer_, &all_tiles);
ASSERT_TRUE(host_impl_.tile_manager() != nullptr);
host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(all_tiles);
@@ -230,16 +230,16 @@ TEST_F(PictureLayerImplPerfTest, TilingSetEvictionQueueConstructAndIterate) {
}
TEST_F(PictureLayerImplPerfTest, TilingSetEvictionQueueConstruct) {
- SetupPendingTree(gfx::Size(10000, 10000), gfx::Size(256, 256));
+ SetupActiveTree(gfx::Size(10000, 10000), gfx::Size(256, 256));
float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
std::vector<Tile*> all_tiles;
- AddTiling(low_res_factor, pending_layer_, &all_tiles);
- AddTiling(0.3f, pending_layer_, &all_tiles);
- AddTiling(0.7f, pending_layer_, &all_tiles);
- AddTiling(1.0f, pending_layer_, &all_tiles);
- AddTiling(2.0f, pending_layer_, &all_tiles);
+ AddTiling(low_res_factor, active_layer_, &all_tiles);
+ AddTiling(0.3f, active_layer_, &all_tiles);
+ AddTiling(0.7f, active_layer_, &all_tiles);
+ AddTiling(1.0f, active_layer_, &all_tiles);
+ AddTiling(2.0f, active_layer_, &all_tiles);
ASSERT_TRUE(host_impl_.tile_manager() != nullptr);
host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(all_tiles);
diff --git a/chromium/cc/layers/picture_layer_impl_unittest.cc b/chromium/cc/layers/picture_layer_impl_unittest.cc
index cc89133b781..6e89caa802a 100644
--- a/chromium/cc/layers/picture_layer_impl_unittest.cc
+++ b/chromium/cc/layers/picture_layer_impl_unittest.cc
@@ -63,9 +63,16 @@ class MockCanvas : public SkCanvas {
std::vector<SkRect> rects_;
};
-class NoLowResTilingsSettings : public GpuRasterizationEnabledSettings {};
+class PictureLayerImplTestSettings : public GpuRasterizationEnabledSettings {
+ public:
+ PictureLayerImplTestSettings() {
+ layer_transforms_should_scale_layer_contents = true;
+ }
+};
-class LowResTilingsSettings : public GpuRasterizationEnabledSettings {
+class NoLowResTilingsSettings : public PictureLayerImplTestSettings {};
+
+class LowResTilingsSettings : public PictureLayerImplTestSettings {
public:
LowResTilingsSettings() { create_low_res_tiling = true; }
};
@@ -201,7 +208,8 @@ class PictureLayerImplTest : public testing::Test {
const gfx::Size& tile_size,
const Region& invalidation) {
host_impl_.CreatePendingTree();
- host_impl_.pending_tree()->PushPageScaleFromMainThread(1.f, 0.25f, 100.f);
+ host_impl_.pending_tree()->PushPageScaleFromMainThread(1.f, 0.00001f,
+ 100000.f);
LayerTreeImpl* pending_tree = host_impl_.pending_tree();
// Steal from the recycled tree if possible.
@@ -223,7 +231,6 @@ class PictureLayerImplTest : public testing::Test {
pending_root->SetHasRenderSurface(true);
// The bounds() just mirror the pile size.
pending_layer->SetBounds(raster_source->GetSize());
- pending_layer->SetContentBounds(raster_source->GetSize());
pending_layer->SetRasterSourceOnPending(raster_source, invalidation);
pending_root->AddChild(pending_layer.Pass());
@@ -245,9 +252,13 @@ class PictureLayerImplTest : public testing::Test {
float maximum_animation_contents_scale,
float starting_animation_contents_scale,
bool animating_transform_to_screen) {
- layer->draw_properties().ideal_contents_scale = ideal_contents_scale;
- layer->draw_properties().device_scale_factor = device_scale_factor;
- layer->draw_properties().page_scale_factor = page_scale_factor;
+ host_impl_.SetDeviceScaleFactor(device_scale_factor);
+ host_impl_.SetPageScaleOnActiveTree(page_scale_factor);
+
+ gfx::Transform scale_transform;
+ scale_transform.Scale(ideal_contents_scale, ideal_contents_scale);
+ layer->draw_properties().target_space_transform = scale_transform;
+ DCHECK_EQ(layer->GetIdealContentsScale(), ideal_contents_scale);
layer->draw_properties().maximum_animation_contents_scale =
maximum_animation_contents_scale;
layer->draw_properties().starting_animation_contents_scale =
@@ -342,6 +353,7 @@ class PictureLayerImplTest : public testing::Test {
FakePictureLayerImpl* pending_layer_;
FakePictureLayerImpl* old_pending_layer_;
FakePictureLayerImpl* active_layer_;
+ LayerSettings layer_settings_;
private:
DISALLOW_COPY_AND_ASSIGN(PictureLayerImplTest);
@@ -355,7 +367,7 @@ class NoLowResPictureLayerImplTest : public PictureLayerImplTest {
TEST_F(PictureLayerImplTest, TileGridAlignment) {
// Layer to span 4 raster tiles in x and in y
- ImplSidePaintingSettings settings;
+ LayerTreeSettings settings;
gfx::Size layer_size(settings.default_tile_size.width() * 7 / 2,
settings.default_tile_size.height() * 7 / 2);
@@ -427,10 +439,7 @@ TEST_F(PictureLayerImplTest, CloneNoInvalidation) {
}
TEST_F(PictureLayerImplTest, ExternalViewportRectForPrioritizingTiles) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(400, 400);
@@ -444,9 +453,7 @@ TEST_F(PictureLayerImplTest, ExternalViewportRectForPrioritizingTiles) {
SetupDrawPropertiesAndUpdateTiles(active_layer_, 1.f, 1.f, 1.f, 1.f, 0.f,
false);
- time_ticks += base::TimeDelta::FromMilliseconds(200);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));
// Update tiles with viewport for tile priority as (0, 0, 100, 100) and the
// identify transform for tile priority.
@@ -483,9 +490,7 @@ TEST_F(PictureLayerImplTest, ExternalViewportRectForPrioritizingTiles) {
// screen space and the transform for tile priority is translated and
// rotated. The actual viewport for tile priority used by PictureLayerImpl
// should be (200, 200, 100, 100) applied with the said transform.
- time_ticks += base::TimeDelta::FromMilliseconds(200);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));
viewport_rect_for_tile_priority = gfx::Rect(200, 200, 100, 100);
transform_for_tile_priority.Translate(100, 100);
@@ -523,10 +528,7 @@ TEST_F(PictureLayerImplTest, ExternalViewportRectForPrioritizingTiles) {
}
TEST_F(PictureLayerImplTest, InvalidViewportForPrioritizingTiles) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(400, 400);
@@ -553,7 +555,7 @@ TEST_F(PictureLayerImplTest, InvalidViewportForPrioritizingTiles) {
viewport,
transform,
resourceless_software_draw);
- active_layer_->draw_properties().visible_content_rect = viewport;
+ active_layer_->draw_properties().visible_layer_rect = viewport;
active_layer_->draw_properties().screen_space_transform = transform;
active_layer_->UpdateTiles(resourceless_software_draw);
@@ -565,13 +567,11 @@ TEST_F(PictureLayerImplTest, InvalidViewportForPrioritizingTiles) {
// Expand viewport and set it as invalid for prioritizing tiles.
// Should update viewport and transform, but not update visible rect.
- time_ticks += base::TimeDelta::FromMilliseconds(200);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));
resourceless_software_draw = true;
viewport = gfx::ScaleToEnclosingRect(viewport, 2);
transform.Translate(1.f, 1.f);
- active_layer_->draw_properties().visible_content_rect = viewport;
+ active_layer_->draw_properties().visible_layer_rect = viewport;
active_layer_->draw_properties().screen_space_transform = transform;
host_impl_.SetExternalDrawConstraints(transform,
viewport,
@@ -589,9 +589,7 @@ TEST_F(PictureLayerImplTest, InvalidViewportForPrioritizingTiles) {
active_layer_->visible_rect_for_tile_priority());
// Keep expanded viewport but mark it valid. Should update tile viewport.
- time_ticks += base::TimeDelta::FromMilliseconds(200);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));
resourceless_software_draw = false;
host_impl_.SetExternalDrawConstraints(transform,
viewport,
@@ -607,10 +605,7 @@ TEST_F(PictureLayerImplTest, InvalidViewportForPrioritizingTiles) {
}
TEST_F(PictureLayerImplTest, ViewportRectForTilePriorityIsCached) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(400, 400);
@@ -624,9 +619,7 @@ TEST_F(PictureLayerImplTest, ViewportRectForTilePriorityIsCached) {
SetupDrawPropertiesAndUpdateTiles(active_layer_, 1.f, 1.f, 1.f, 1.f, 0.f,
false);
- time_ticks += base::TimeDelta::FromMilliseconds(200);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));
bool resourceless_software_draw = false;
gfx::Rect viewport = gfx::Rect(layer_bounds);
@@ -642,9 +635,7 @@ TEST_F(PictureLayerImplTest, ViewportRectForTilePriorityIsCached) {
EXPECT_EQ(viewport_rect_for_tile_priority,
active_layer_->viewport_rect_for_tile_priority_in_content_space());
- time_ticks += base::TimeDelta::FromMilliseconds(200);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));
gfx::Rect another_viewport_rect_for_tile_priority(11, 11, 50, 50);
host_impl_.SetExternalDrawConstraints(
@@ -1315,7 +1306,6 @@ TEST_F(PictureLayerImplTest, DontAddLowResForSmallLayers) {
FakePictureLayerImpl::CreateMaskWithRasterSource(
host_impl_.pending_tree(), 3, pending_pile);
mask->SetBounds(layer_bounds);
- mask->SetContentBounds(layer_bounds);
mask->SetDrawsContent(true);
SetupDrawPropertiesAndUpdateTiles(
@@ -1326,10 +1316,7 @@ TEST_F(PictureLayerImplTest, DontAddLowResForSmallLayers) {
}
TEST_F(PictureLayerImplTest, HugeMasksGetScaledDown) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(1000, 1000);
@@ -1342,14 +1329,11 @@ TEST_F(PictureLayerImplTest, HugeMasksGetScaledDown) {
FakePictureLayerImpl::CreateMaskWithRasterSource(
host_impl_.pending_tree(), 3, valid_pile);
mask_ptr->SetBounds(layer_bounds);
- mask_ptr->SetContentBounds(layer_bounds);
mask_ptr->SetDrawsContent(true);
pending_layer_->SetMaskLayer(mask_ptr.Pass());
pending_layer_->SetHasRenderSurface(true);
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
bool update_lcd_text = false;
host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
@@ -1370,7 +1354,7 @@ TEST_F(PictureLayerImplTest, HugeMasksGetScaledDown) {
// Mask layers have a tiling with a single tile in it.
EXPECT_EQ(1u, active_mask->HighResTiling()->AllTilesForTesting().size());
// The mask resource exists.
- ResourceProvider::ResourceId mask_resource_id;
+ ResourceId mask_resource_id;
gfx::Size mask_texture_size;
active_mask->GetContentsResourceId(&mask_resource_id, &mask_texture_size);
EXPECT_NE(0u, mask_resource_id);
@@ -1396,12 +1380,9 @@ TEST_F(PictureLayerImplTest, HugeMasksGetScaledDown) {
SetupPendingTree(huge_pile);
pending_mask->SetBounds(huge_bounds);
- pending_mask->SetContentBounds(huge_bounds);
pending_mask->SetRasterSourceOnPending(huge_pile, Region());
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
// The mask tiling gets scaled down.
@@ -1451,24 +1432,18 @@ TEST_F(PictureLayerImplTest, HugeMasksGetScaledDown) {
SetupPendingTree(extra_huge_pile);
pending_mask->SetBounds(extra_huge_bounds);
- pending_mask->SetContentBounds(extra_huge_bounds);
pending_mask->SetRasterSourceOnPending(extra_huge_pile, Region());
EXPECT_FALSE(pending_mask->CanHaveTilings());
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
EXPECT_EQ(0u, pending_mask->num_tilings());
}
TEST_F(PictureLayerImplTest, ScaledMaskLayer) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(1000, 1000);
@@ -1483,14 +1458,11 @@ TEST_F(PictureLayerImplTest, ScaledMaskLayer) {
FakePictureLayerImpl::CreateMaskWithRasterSource(
host_impl_.pending_tree(), 3, valid_pile);
mask_ptr->SetBounds(layer_bounds);
- mask_ptr->SetContentBounds(layer_bounds);
mask_ptr->SetDrawsContent(true);
pending_layer_->SetMaskLayer(mask_ptr.Pass());
pending_layer_->SetHasRenderSurface(true);
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
bool update_lcd_text = false;
host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
@@ -1512,7 +1484,7 @@ TEST_F(PictureLayerImplTest, ScaledMaskLayer) {
// Mask layers have a tiling with a single tile in it.
EXPECT_EQ(1u, active_mask->HighResTiling()->AllTilesForTesting().size());
// The mask resource exists.
- ResourceProvider::ResourceId mask_resource_id;
+ ResourceId mask_resource_id;
gfx::Size mask_texture_size;
active_mask->GetContentsResourceId(&mask_resource_id, &mask_texture_size);
EXPECT_NE(0u, mask_resource_id);
@@ -1661,8 +1633,7 @@ TEST_F(PictureLayerImplTest, DisallowTileDrawQuads) {
gfx::Rect layer_invalidation(150, 200, 30, 180);
SetupTreesWithInvalidation(pending_pile, active_pile, layer_invalidation);
- active_layer_->draw_properties().visible_content_rect =
- gfx::Rect(layer_bounds);
+ active_layer_->draw_properties().visible_layer_rect = gfx::Rect(layer_bounds);
AppendQuadsData data;
active_layer_->WillDraw(DRAW_MODE_RESOURCELESS_SOFTWARE, nullptr);
@@ -1692,7 +1663,7 @@ TEST_F(PictureLayerImplTest, SolidColorLayerHasVisibleFullCoverage) {
SetupTrees(pending_pile, active_pile);
- active_layer_->draw_properties().visible_content_rect = visible_rect;
+ active_layer_->draw_properties().visible_layer_rect = visible_rect;
AppendQuadsData data;
active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
@@ -1753,9 +1724,7 @@ TEST_F(NoLowResPictureLayerImplTest, MarkRequiredOffscreenTiles) {
EXPECT_EQ(viewport, pending_layer_->visible_rect_for_tile_priority());
base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
pending_layer_->UpdateTiles(resourceless_software_draw);
int num_visible = 0;
@@ -1781,15 +1750,12 @@ TEST_F(NoLowResPictureLayerImplTest, MarkRequiredOffscreenTiles) {
TEST_F(NoLowResPictureLayerImplTest,
TileOutsideOfViewportForTilePriorityNotRequired) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(400, 400);
gfx::Rect external_viewport_for_tile_priority(400, 200);
- gfx::Rect visible_content_rect(200, 400);
+ gfx::Rect visible_layer_rect(200, 400);
scoped_refptr<FakePicturePileImpl> active_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
@@ -1811,25 +1777,21 @@ TEST_F(NoLowResPictureLayerImplTest,
external_viewport_for_tile_priority,
transform_for_tile_priority,
resourceless_software_draw);
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
bool update_lcd_text = false;
host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
// Set visible content rect that is different from
// external_viewport_for_tile_priority.
- pending_layer_->draw_properties().visible_content_rect = visible_content_rect;
- time_ticks += base::TimeDelta::FromMilliseconds(200);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ pending_layer_->draw_properties().visible_layer_rect = visible_layer_rect;
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));
pending_layer_->UpdateTiles(resourceless_software_draw);
// Intersect the two rects. Any tile outside should not be required for
// activation.
gfx::Rect viewport_for_tile_priority =
pending_layer_->viewport_rect_for_tile_priority_in_content_space();
- viewport_for_tile_priority.Intersect(pending_layer_->visible_content_rect());
+ viewport_for_tile_priority.Intersect(pending_layer_->visible_layer_rect());
EXPECT_TRUE(pending_layer_->HighResTiling()->AllTilesForTesting().empty());
@@ -1858,7 +1820,7 @@ TEST_F(NoLowResPictureLayerImplTest,
// Activate and draw active layer.
host_impl_.ActivateSyncTree();
host_impl_.active_tree()->UpdateDrawProperties(update_lcd_text);
- active_layer_->draw_properties().visible_content_rect = visible_content_rect;
+ active_layer_->draw_properties().visible_layer_rect = visible_layer_rect;
scoped_ptr<RenderPass> render_pass = RenderPass::Create();
AppendQuadsData data;
@@ -1873,10 +1835,7 @@ TEST_F(NoLowResPictureLayerImplTest,
}
TEST_F(PictureLayerImplTest, HighResTileIsComplete) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(200, 200);
@@ -1906,10 +1865,7 @@ TEST_F(PictureLayerImplTest, HighResTileIsComplete) {
}
TEST_F(PictureLayerImplTest, HighResTileIsIncomplete) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(200, 200);
@@ -1932,10 +1888,7 @@ TEST_F(PictureLayerImplTest, HighResTileIsIncomplete) {
}
TEST_F(PictureLayerImplTest, HighResTileIsIncompleteLowResComplete) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(200, 200);
@@ -1962,10 +1915,7 @@ TEST_F(PictureLayerImplTest, HighResTileIsIncompleteLowResComplete) {
}
TEST_F(PictureLayerImplTest, LowResTileIsIncomplete) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(200, 200);
@@ -2001,10 +1951,7 @@ TEST_F(PictureLayerImplTest, LowResTileIsIncomplete) {
TEST_F(PictureLayerImplTest,
HighResAndIdealResTileIsCompleteWhenRasterScaleIsNotIdeal) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(200, 200);
@@ -2422,10 +2369,7 @@ TEST_F(PictureLayerImplTest, RecreateInvalidPendingTreeTiles) {
}
TEST_F(PictureLayerImplTest, SyncTilingAfterGpuRasterizationToggles) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(10, 10);
@@ -2451,9 +2395,7 @@ TEST_F(PictureLayerImplTest, SyncTilingAfterGpuRasterizationToggles) {
// Make sure that we can still add tiling to the pending layer,
// that gets synced to the active layer.
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
bool update_lcd_text = false;
host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
EXPECT_TRUE(pending_layer_->tilings()->FindTilingWithScale(1.f));
@@ -2503,11 +2445,8 @@ TEST_F(PictureLayerImplTest, HighResCreatedWhenBoundsShrink) {
// Another sanity check.
EXPECT_EQ(1.f, pending_layer_->MinimumContentsScale());
- // Since the MinContentsScale is 1, the 0.5 tiling should be replaced by a 1.0
- // tiling.
- SetupDrawPropertiesAndUpdateTiles(pending_layer_, 0.5f, 1.f, 1.f, 1.f, 0.f,
- false);
-
+ // Since the MinContentsScale is 1, the 0.5 tiling should have been replaced
+ // by a 1.0 tiling during the UDP in SetupPendingTree.
EXPECT_EQ(1u, pending_layer_->tilings()->num_tilings());
PictureLayerTiling* tiling =
pending_layer_->tilings()->FindTilingWithScale(1.0f);
@@ -2592,11 +2531,12 @@ TEST_F(PictureLayerImplTest, FirstTilingDuringPinch) {
// We start with a tiling at scale 1.
EXPECT_EQ(1.f, pending_layer_->HighResTiling()->contents_scale());
- // When we scale up by 2.3, we get a new tiling that is a power of 2, in this
- // case 4.
+ // When we page scale up by 2.3, we get a new tiling that is a power of 2, in
+ // this case 4.
host_impl_.PinchGestureBegin();
float high_res_scale = 2.3f;
- SetContentsScaleOnBothLayers(high_res_scale, 1.f, 1.f, 1.f, 0.f, false);
+ SetContentsScaleOnBothLayers(high_res_scale, 1.f, high_res_scale, 1.f, 0.f,
+ false);
EXPECT_EQ(4.f, pending_layer_->HighResTiling()->contents_scale());
}
@@ -2900,10 +2840,7 @@ TEST_F(PictureLayerImplTest, HighResTilingDuringAnimationForGpuRasterization) {
}
TEST_F(PictureLayerImplTest, TilingSetRasterQueue) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
host_impl_.SetViewportSize(gfx::Size(500, 500));
@@ -2985,11 +2922,9 @@ TEST_F(PictureLayerImplTest, TilingSetRasterQueue) {
EXPECT_EQ(high_res_now_tiles, required_for_activation_count);
// No NOW tiles.
- time_ticks += base::TimeDelta::FromMilliseconds(200);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));
- pending_layer_->draw_properties().visible_content_rect =
+ pending_layer_->draw_properties().visible_layer_rect =
gfx::Rect(1100, 1100, 500, 500);
bool resourceless_software_draw = false;
pending_layer_->UpdateTiles(resourceless_software_draw);
@@ -3017,11 +2952,9 @@ TEST_F(PictureLayerImplTest, TilingSetRasterQueue) {
EXPECT_EQ(16, high_res_tile_count);
EXPECT_EQ(high_res_tile_count, static_cast<int>(unique_tiles.size()));
- time_ticks += base::TimeDelta::FromMilliseconds(200);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));
- pending_layer_->draw_properties().visible_content_rect =
+ pending_layer_->draw_properties().visible_layer_rect =
gfx::Rect(0, 0, 500, 500);
pending_layer_->UpdateTiles(resourceless_software_draw);
@@ -3058,10 +2991,7 @@ TEST_F(PictureLayerImplTest, TilingSetRasterQueue) {
}
TEST_F(PictureLayerImplTest, TilingSetRasterQueueActiveTree) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
host_impl_.SetViewportSize(gfx::Size(500, 500));
@@ -3144,11 +3074,8 @@ TEST_F(PictureLayerImplTest, TilingSetEvictionQueue) {
for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) {
PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i);
for (PictureLayerTiling::CoverageIterator iter(
- tiling,
- pending_layer_->contents_scale_x(),
- pending_layer_->visible_content_rect());
- iter;
- ++iter) {
+ tiling, 1.f, pending_layer_->visible_layer_rect());
+ iter; ++iter) {
if (mark_required) {
number_of_marked_tiles++;
iter->set_required_for_activation(true);
@@ -3290,7 +3217,7 @@ TEST_F(PictureLayerImplTest, Occlusion) {
{
SCOPED_TRACE("Full occlusion");
- gfx::Rect occluded(active_layer_->visible_content_rect());
+ gfx::Rect occluded(active_layer_->visible_layer_rect());
impl.AppendQuadsWithOcclusion(active_layer_, occluded);
LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect());
@@ -3622,10 +3549,7 @@ TEST_F(NoLowResPictureLayerImplTest, NothingRequiredIfActiveMissingTiles) {
}
TEST_F(NoLowResPictureLayerImplTest, InvalidViewportForPrioritizingTiles) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(400, 400);
@@ -3652,7 +3576,7 @@ TEST_F(NoLowResPictureLayerImplTest, InvalidViewportForPrioritizingTiles) {
viewport,
transform,
resourceless_software_draw);
- active_layer_->draw_properties().visible_content_rect = viewport;
+ active_layer_->draw_properties().visible_layer_rect = viewport;
active_layer_->draw_properties().screen_space_transform = transform;
active_layer_->UpdateTiles(resourceless_software_draw);
@@ -3664,13 +3588,11 @@ TEST_F(NoLowResPictureLayerImplTest, InvalidViewportForPrioritizingTiles) {
// Expand viewport and set it as invalid for prioritizing tiles.
// Should update viewport and transform, but not update visible rect.
- time_ticks += base::TimeDelta::FromMilliseconds(200);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));
resourceless_software_draw = true;
viewport = gfx::ScaleToEnclosingRect(viewport, 2);
transform.Translate(1.f, 1.f);
- active_layer_->draw_properties().visible_content_rect = viewport;
+ active_layer_->draw_properties().visible_layer_rect = viewport;
active_layer_->draw_properties().screen_space_transform = transform;
host_impl_.SetExternalDrawConstraints(transform,
viewport,
@@ -3688,9 +3610,7 @@ TEST_F(NoLowResPictureLayerImplTest, InvalidViewportForPrioritizingTiles) {
active_layer_->visible_rect_for_tile_priority());
// Keep expanded viewport but mark it valid. Should update tile viewport.
- time_ticks += base::TimeDelta::FromMilliseconds(200);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));
resourceless_software_draw = false;
host_impl_.SetExternalDrawConstraints(transform,
viewport,
@@ -3887,21 +3807,21 @@ TEST_F(PictureLayerImplTest, SharedQuadStateContainsMaxTilingScale) {
// SharedQuadState should have be of size 1, as we are doing AppenQuad once.
EXPECT_EQ(1u, render_pass->shared_quad_state_list.size());
- // The content_to_target_transform should be scaled by the
+ // The quad_to_target_transform should be scaled by the
// MaximumTilingContentsScale on the layer.
EXPECT_EQ(scaled_draw_transform.ToString(),
render_pass->shared_quad_state_list.front()
- ->content_to_target_transform.ToString());
+ ->quad_to_target_transform.ToString());
// The content_bounds should be scaled by the
// MaximumTilingContentsScale on the layer.
- EXPECT_EQ(
- gfx::Size(2500u, 5000u).ToString(),
- render_pass->shared_quad_state_list.front()->content_bounds.ToString());
- // The visible_content_rect should be scaled by the
+ EXPECT_EQ(gfx::Size(2500u, 5000u).ToString(),
+ render_pass->shared_quad_state_list.front()
+ ->quad_layer_bounds.ToString());
+ // The visible_layer_rect should be scaled by the
// MaximumTilingContentsScale on the layer.
EXPECT_EQ(gfx::Rect(0u, 0u, 2500u, 5000u).ToString(),
render_pass->shared_quad_state_list.front()
- ->visible_content_rect.ToString());
+ ->visible_quad_layer_rect.ToString());
}
class PictureLayerImplTestWithDelegatingRenderer : public PictureLayerImplTest {
@@ -4018,10 +3938,7 @@ class OcclusionTrackingPictureLayerImplTest : public PictureLayerImplTest {
TEST_F(OcclusionTrackingPictureLayerImplTest,
OccludedTilesSkippedDuringRasterization) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
gfx::Size tile_size(102, 102);
gfx::Size layer_bounds(1000, 1000);
@@ -4048,7 +3965,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
// Some tiles may not be visible (i.e. outside the viewport). The rest are
// visible and at least partially unoccluded, verified by the above expect.
bool tile_is_visible =
- tile->content_rect().Intersects(pending_layer_->visible_content_rect());
+ tile->content_rect().Intersects(pending_layer_->visible_layer_rect());
if (tile_is_visible)
unoccluded_tile_count++;
queue->Pop();
@@ -4059,14 +3976,11 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
pending_layer_->AddChild(LayerImpl::Create(host_impl_.pending_tree(), 1));
LayerImpl* layer1 = pending_layer_->children()[0];
layer1->SetBounds(layer_bounds);
- layer1->SetContentBounds(layer_bounds);
layer1->SetDrawsContent(true);
layer1->SetContentsOpaque(true);
layer1->SetPosition(occluding_layer_position);
- time_ticks += base::TimeDelta::FromMilliseconds(200);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));
bool update_lcd_text = false;
host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
@@ -4080,7 +3994,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
EXPECT_FALSE(prioritized_tile.is_occluded());
bool tile_is_visible =
- tile->content_rect().Intersects(pending_layer_->visible_content_rect());
+ tile->content_rect().Intersects(pending_layer_->visible_layer_rect());
if (tile_is_visible)
unoccluded_tile_count++;
queue->Pop();
@@ -4090,9 +4004,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
// Full occlusion.
layer1->SetPosition(gfx::Point(0, 0));
- time_ticks += base::TimeDelta::FromMilliseconds(200);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));
host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
unoccluded_tile_count = 0;
@@ -4105,7 +4017,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
EXPECT_FALSE(prioritized_tile.is_occluded());
bool tile_is_visible =
- tile->content_rect().Intersects(pending_layer_->visible_content_rect());
+ tile->content_rect().Intersects(pending_layer_->visible_layer_rect());
if (tile_is_visible)
unoccluded_tile_count++;
queue->Pop();
@@ -4115,10 +4027,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
TEST_F(OcclusionTrackingPictureLayerImplTest,
OccludedTilesNotMarkedAsRequired) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
gfx::Size tile_size(102, 102);
gfx::Size layer_bounds(1000, 1000);
@@ -4139,12 +4048,9 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
tiling->UpdateAndGetAllPrioritizedTilesForTesting();
occluded_tile_count = 0;
- for (PictureLayerTiling::CoverageIterator iter(
- tiling,
- pending_layer_->contents_scale_x(),
- gfx::Rect(layer_bounds));
- iter;
- ++iter) {
+ for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f,
+ gfx::Rect(layer_bounds));
+ iter; ++iter) {
if (!*iter)
continue;
const Tile* tile = *iter;
@@ -4162,14 +4068,11 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
pending_layer_->AddChild(LayerImpl::Create(host_impl_.pending_tree(), 1));
LayerImpl* layer1 = pending_layer_->children()[0];
layer1->SetBounds(layer_bounds);
- layer1->SetContentBounds(layer_bounds);
layer1->SetDrawsContent(true);
layer1->SetContentsOpaque(true);
layer1->SetPosition(occluding_layer_position);
- time_ticks += base::TimeDelta::FromMilliseconds(200);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));
bool update_lcd_text = false;
host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
@@ -4179,12 +4082,9 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
tiling->UpdateAndGetAllPrioritizedTilesForTesting();
occluded_tile_count = 0;
- for (PictureLayerTiling::CoverageIterator iter(
- tiling,
- pending_layer_->contents_scale_x(),
- gfx::Rect(layer_bounds));
- iter;
- ++iter) {
+ for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f,
+ gfx::Rect(layer_bounds));
+ iter; ++iter) {
if (!*iter)
continue;
const Tile* tile = *iter;
@@ -4209,9 +4109,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
// Full occlusion.
layer1->SetPosition(gfx::PointF(0, 0));
- time_ticks += base::TimeDelta::FromMilliseconds(200);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));
host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) {
@@ -4220,12 +4118,9 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
tiling->UpdateAndGetAllPrioritizedTilesForTesting();
occluded_tile_count = 0;
- for (PictureLayerTiling::CoverageIterator iter(
- tiling,
- pending_layer_->contents_scale_x(),
- gfx::Rect(layer_bounds));
- iter;
- ++iter) {
+ for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f,
+ gfx::Rect(layer_bounds));
+ iter; ++iter) {
if (!*iter)
continue;
const Tile* tile = *iter;
@@ -4249,10 +4144,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
}
TEST_F(OcclusionTrackingPictureLayerImplTest, OcclusionForDifferentScales) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
gfx::Size tile_size(102, 102);
gfx::Size layer_bounds(1000, 1000);
@@ -4270,7 +4162,6 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, OcclusionForDifferentScales) {
pending_layer_->AddChild(LayerImpl::Create(host_impl_.pending_tree(), 1));
LayerImpl* layer1 = pending_layer_->children()[0];
layer1->SetBounds(layer_bounds);
- layer1->SetContentBounds(layer_bounds);
layer1->SetDrawsContent(true);
layer1->SetContentsOpaque(true);
layer1->SetPosition(occluding_layer_position);
@@ -4283,9 +4174,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, OcclusionForDifferentScales) {
pending_layer_->AddTiling(1.0f);
pending_layer_->AddTiling(2.0f);
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
// UpdateDrawProperties with the occluding layer.
bool update_lcd_text = false;
host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
@@ -4348,7 +4237,6 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, DifferentOcclusionOnTrees) {
pending_layer_->AddChild(LayerImpl::Create(host_impl_.pending_tree(), 2));
LayerImpl* layer1 = pending_layer_->children()[0];
layer1->SetBounds(layer_bounds);
- layer1->SetContentBounds(layer_bounds);
layer1->SetDrawsContent(true);
layer1->SetContentsOpaque(true);
layer1->SetPosition(occluding_layer_position);
@@ -4360,10 +4248,9 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, DifferentOcclusionOnTrees) {
auto prioritized_tiles =
tiling->UpdateAndGetAllPrioritizedTilesForTesting();
- for (
- PictureLayerTiling::CoverageIterator iter(
- tiling, active_layer_->contents_scale_x(), gfx::Rect(layer_bounds));
- iter; ++iter) {
+ for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f,
+ gfx::Rect(layer_bounds));
+ iter; ++iter) {
if (!*iter)
continue;
const Tile* tile = *iter;
@@ -4385,12 +4272,9 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, DifferentOcclusionOnTrees) {
auto prioritized_tiles =
tiling->UpdateAndGetAllPrioritizedTilesForTesting();
- for (PictureLayerTiling::CoverageIterator iter(
- tiling,
- active_layer_->contents_scale_x(),
- gfx::Rect(layer_bounds));
- iter;
- ++iter) {
+ for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f,
+ gfx::Rect(layer_bounds));
+ iter; ++iter) {
if (!*iter)
continue;
const Tile* tile = *iter;
@@ -4419,10 +4303,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, DifferentOcclusionOnTrees) {
TEST_F(OcclusionTrackingPictureLayerImplTest,
OccludedTilesConsideredDuringEviction) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
gfx::Size tile_size(102, 102);
gfx::Size layer_bounds(1000, 1000);
@@ -4445,7 +4326,6 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
pending_layer_->AddChild(LayerImpl::Create(host_impl_.pending_tree(), 2));
LayerImpl* active_occluding_layer = pending_layer_->children()[0];
active_occluding_layer->SetBounds(layer_bounds);
- active_occluding_layer->SetContentBounds(layer_bounds);
active_occluding_layer->SetDrawsContent(true);
active_occluding_layer->SetContentsOpaque(true);
active_occluding_layer->SetPosition(active_occluding_layer_position);
@@ -4460,7 +4340,6 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
pending_layer_->AddChild(LayerImpl::Create(host_impl_.pending_tree(), 3));
LayerImpl* pending_occluding_layer = pending_layer_->children()[0];
pending_occluding_layer->SetBounds(layer_bounds);
- pending_occluding_layer->SetContentBounds(layer_bounds);
pending_occluding_layer->SetDrawsContent(true);
pending_occluding_layer->SetContentsOpaque(true);
pending_occluding_layer->SetPosition(pending_occluding_layer_position);
@@ -4468,9 +4347,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
EXPECT_EQ(2u, pending_layer_->num_tilings());
EXPECT_EQ(2u, active_layer_->num_tilings());
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
// UpdateDrawProperties with the occluding layer.
bool update_lcd_text = false;
host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
@@ -4515,12 +4392,9 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
tiling->UpdateAndGetAllPrioritizedTilesForTesting();
size_t occluded_tile_count_on_active = 0u;
- for (PictureLayerTiling::CoverageIterator iter(
- tiling,
- pending_layer_->contents_scale_x(),
- gfx::Rect(layer_bounds));
- iter;
- ++iter) {
+ for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f,
+ gfx::Rect(layer_bounds));
+ iter; ++iter) {
Tile* tile = *iter;
if (!tile)
@@ -4602,47 +4476,20 @@ TEST_F(PictureLayerImplTest, PendingOrActiveTwinLayer) {
EXPECT_FALSE(active_layer_->GetPendingOrActiveTwinLayer());
}
-TEST_F(PictureLayerImplTest, RecycledTwinLayer) {
- gfx::Size tile_size(102, 102);
- gfx::Size layer_bounds(1000, 1000);
-
- scoped_refptr<FakePicturePileImpl> pile =
- FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
- SetupPendingTree(pile);
- EXPECT_FALSE(pending_layer_->GetRecycledTwinLayer());
-
- ActivateTree();
- EXPECT_TRUE(active_layer_->GetRecycledTwinLayer());
- EXPECT_EQ(old_pending_layer_, active_layer_->GetRecycledTwinLayer());
-
- SetupPendingTree(pile);
- EXPECT_FALSE(pending_layer_->GetRecycledTwinLayer());
- EXPECT_FALSE(active_layer_->GetRecycledTwinLayer());
-
- ActivateTree();
- EXPECT_TRUE(active_layer_->GetRecycledTwinLayer());
- EXPECT_EQ(old_pending_layer_, active_layer_->GetRecycledTwinLayer());
-
- // Make an empty pending tree.
- host_impl_.CreatePendingTree();
- host_impl_.pending_tree()->DetachLayerTree();
- EXPECT_FALSE(active_layer_->GetRecycledTwinLayer());
-}
-
void PictureLayerImplTest::TestQuadsForSolidColor(bool test_for_solid) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(200, 200);
gfx::Rect layer_rect(layer_bounds);
FakeContentLayerClient client;
- scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client);
+ scoped_refptr<PictureLayer> layer =
+ PictureLayer::Create(layer_settings_, &client);
FakeLayerTreeHostClient host_client(FakeLayerTreeHostClient::DIRECT_3D);
- scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(&host_client);
+ TestTaskGraphRunner task_graph_runner;
+ scoped_ptr<FakeLayerTreeHost> host =
+ FakeLayerTreeHost::Create(&host_client, &task_graph_runner);
host->SetRootLayer(layer);
RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
@@ -4693,19 +4540,19 @@ TEST_F(PictureLayerImplTest, DrawNonSolidQuads) {
}
TEST_F(PictureLayerImplTest, NonSolidToSolidNoTilings) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(200, 200);
gfx::Rect layer_rect(layer_bounds);
FakeContentLayerClient client;
- scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client);
+ scoped_refptr<PictureLayer> layer =
+ PictureLayer::Create(layer_settings_, &client);
FakeLayerTreeHostClient host_client(FakeLayerTreeHostClient::DIRECT_3D);
- scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(&host_client);
+ TestTaskGraphRunner task_graph_runner;
+ scoped_ptr<FakeLayerTreeHost> host =
+ FakeLayerTreeHost::Create(&host_client, &task_graph_runner);
host->SetRootLayer(layer);
RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
@@ -4749,10 +4596,7 @@ TEST_F(PictureLayerImplTest, NonSolidToSolidNoTilings) {
}
TEST_F(PictureLayerImplTest, ChangeInViewportAllowsTilingUpdates) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(400, 4000);
@@ -4771,7 +4615,7 @@ TEST_F(PictureLayerImplTest, ChangeInViewportAllowsTilingUpdates) {
host_impl_.SetRequiresHighResToDraw();
// Update tiles.
- pending_layer_->draw_properties().visible_content_rect = viewport;
+ pending_layer_->draw_properties().visible_layer_rect = viewport;
pending_layer_->draw_properties().screen_space_transform = transform;
SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, 0.f,
false);
@@ -4785,7 +4629,7 @@ TEST_F(PictureLayerImplTest, ChangeInViewportAllowsTilingUpdates) {
viewport = gfx::Rect(0, 2000, 100, 100);
// Update tiles.
- pending_layer_->draw_properties().visible_content_rect = viewport;
+ pending_layer_->draw_properties().visible_layer_rect = viewport;
pending_layer_->draw_properties().screen_space_transform = transform;
SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, 0.f,
false);
@@ -4883,10 +4727,7 @@ TEST_F(PictureLayerImplTest, CloneMissingRecordings) {
}
TEST_F(PictureLayerImplTest, ScrollPastLiveTilesRectAndBack) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
gfx::Size tile_size(102, 102);
gfx::Size layer_bounds(100, 100);
@@ -4939,10 +4780,7 @@ TEST_F(PictureLayerImplTest, ScrollPastLiveTilesRectAndBack) {
}
TEST_F(PictureLayerImplTest, ScrollPropagatesToPending) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
gfx::Size tile_size(102, 102);
gfx::Size layer_bounds(1000, 1000);
@@ -4974,10 +4812,7 @@ TEST_F(PictureLayerImplTest, ScrollPropagatesToPending) {
}
TEST_F(PictureLayerImplTest, UpdateLCDInvalidatesPendingTree) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
gfx::Size tile_size(102, 102);
gfx::Size layer_bounds(100, 100);
@@ -5015,7 +4850,51 @@ TEST_F(PictureLayerImplTest, UpdateLCDInvalidatesPendingTree) {
prioritized_tiles[tile].raster_source());
}
-class TileSizeSettings : public GpuRasterizationEnabledSettings {
+TEST_F(PictureLayerImplTest, TilingAllTilesDone) {
+ gfx::Size tile_size = host_impl_.settings().default_tile_size;
+ size_t tile_mem = 4 * tile_size.width() * tile_size.height();
+ gfx::Size layer_bounds(1000, 1000);
+
+ // Create tiles.
+ scoped_refptr<FakePicturePileImpl> pending_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+ SetupPendingTree(pending_pile);
+ pending_layer_->SetBounds(layer_bounds);
+ ActivateTree();
+ host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(
+ active_layer_->HighResTiling()->AllTilesForTesting());
+ host_impl_.SetTreePriority(SAME_PRIORITY_FOR_BOTH_TREES);
+
+ EXPECT_FALSE(active_layer_->HighResTiling()->all_tiles_done());
+
+ {
+ // Set a memory policy that will fit all tiles.
+ size_t max_tiles = 16;
+ size_t memory_limit = max_tiles * tile_mem;
+ ManagedMemoryPolicy policy(memory_limit,
+ gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
+ max_tiles);
+ host_impl_.SetMemoryPolicy(policy);
+ host_impl_.PrepareTiles();
+
+ EXPECT_TRUE(active_layer_->HighResTiling()->all_tiles_done());
+ }
+
+ {
+ // Set a memory policy that will cause tile eviction.
+ size_t max_tiles = 1;
+ size_t memory_limit = max_tiles * tile_mem;
+ ManagedMemoryPolicy policy(memory_limit,
+ gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
+ max_tiles);
+ host_impl_.SetMemoryPolicy(policy);
+ host_impl_.PrepareTiles();
+
+ EXPECT_FALSE(active_layer_->HighResTiling()->all_tiles_done());
+ }
+}
+
+class TileSizeSettings : public PictureLayerImplTestSettings {
public:
TileSizeSettings() {
default_tile_size = gfx::Size(100, 100);
@@ -5087,5 +4966,35 @@ TEST_F(TileSizeTest, TileSizes) {
EXPECT_EQ(result.height(), 500 + 2);
}
+TEST_F(NoLowResPictureLayerImplTest, HighResLowResCollision) {
+ gfx::Size tile_size(400, 400);
+ gfx::Size layer_bounds(1300, 1900);
+
+ float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
+
+ scoped_refptr<FakePicturePileImpl> pending_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+ scoped_refptr<FakePicturePileImpl> active_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+
+ // Set up the high and low res tilings before pinch zoom.
+ SetupTrees(pending_pile, active_pile);
+ ResetTilingsAndRasterScales();
+
+ float page_scale = 2.f;
+ SetContentsScaleOnBothLayers(page_scale, 1.0f, page_scale, 1.0f, 0.f, false);
+ EXPECT_BOTH_EQ(num_tilings(), 1u);
+ EXPECT_BOTH_EQ(tilings()->tiling_at(0)->contents_scale(), page_scale);
+
+ host_impl_.PinchGestureBegin();
+
+ // Zoom out to exactly the low res factor so that the previous high res
+ // would be equal to the current low res (if it were possible to have one).
+ float zoomed = page_scale / low_res_factor;
+ SetContentsScaleOnBothLayers(zoomed, 1.0f, zoomed, 1.0f, 0.f, false);
+ EXPECT_EQ(1u, pending_layer_->num_tilings());
+ EXPECT_EQ(zoomed, pending_layer_->tilings()->tiling_at(0)->contents_scale());
+}
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/layers/picture_layer_unittest.cc b/chromium/cc/layers/picture_layer_unittest.cc
index 37070127a77..b607f2eff99 100644
--- a/chromium/cc/layers/picture_layer_unittest.cc
+++ b/chromium/cc/layers/picture_layer_unittest.cc
@@ -7,13 +7,12 @@
#include "base/thread_task_runner_handle.h"
#include "cc/layers/content_layer_client.h"
#include "cc/layers/picture_layer_impl.h"
-#include "cc/resources/resource_update_queue.h"
#include "cc/test/fake_layer_tree_host.h"
#include "cc/test/fake_picture_layer.h"
#include "cc/test/fake_picture_layer_impl.h"
#include "cc/test/fake_proxy.h"
-#include "cc/test/impl_side_painting_settings.h"
-#include "cc/trees/occlusion_tracker.h"
+#include "cc/test/test_shared_bitmap_manager.h"
+#include "cc/test/test_task_graph_runner.h"
#include "cc/trees/single_thread_proxy.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -25,29 +24,29 @@ class MockContentLayerClient : public ContentLayerClient {
void PaintContents(SkCanvas* canvas,
const gfx::Rect& clip,
PaintingControlSetting picture_control) override {}
- void PaintContentsToDisplayList(
- DisplayItemList* display_list,
+ scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
const gfx::Rect& clip,
PaintingControlSetting picture_control) override {
NOTIMPLEMENTED();
+ return nullptr;
}
bool FillsBoundsCompletely() const override { return false; };
};
TEST(PictureLayerTest, NoTilesIfEmptyBounds) {
MockContentLayerClient client;
- scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client);
+ scoped_refptr<PictureLayer> layer =
+ PictureLayer::Create(LayerSettings(), &client);
layer->SetBounds(gfx::Size(10, 10));
FakeLayerTreeHostClient host_client(FakeLayerTreeHostClient::DIRECT_3D);
- scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(&host_client);
+ TestTaskGraphRunner task_graph_runner;
+ scoped_ptr<FakeLayerTreeHost> host =
+ FakeLayerTreeHost::Create(&host_client, &task_graph_runner);
host->SetRootLayer(layer);
layer->SetIsDrawable(true);
layer->SavePaintProperties();
-
- OcclusionTracker<Layer> occlusion(gfx::Rect(0, 0, 1000, 1000));
- scoped_ptr<ResourceUpdateQueue> queue(new ResourceUpdateQueue);
- layer->Update(queue.get(), &occlusion);
+ layer->Update();
EXPECT_EQ(0, host->source_frame_number());
host->CommitComplete();
@@ -63,8 +62,8 @@ TEST(PictureLayerTest, NoTilesIfEmptyBounds) {
DebugScopedSetImplThread impl_thread(&proxy);
TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(ImplSidePaintingSettings(), &proxy,
- &shared_bitmap_manager, nullptr);
+ FakeLayerTreeHostImpl host_impl(LayerTreeSettings(), &proxy,
+ &shared_bitmap_manager, &task_graph_runner);
host_impl.CreatePendingTree();
scoped_ptr<FakePictureLayerImpl> layer_impl =
FakePictureLayerImpl::Create(host_impl.pending_tree(), 1);
@@ -79,9 +78,12 @@ TEST(PictureLayerTest, NoTilesIfEmptyBounds) {
TEST(PictureLayerTest, SuitableForGpuRasterization) {
MockContentLayerClient client;
- scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client);
+ scoped_refptr<PictureLayer> layer =
+ PictureLayer::Create(LayerSettings(), &client);
FakeLayerTreeHostClient host_client(FakeLayerTreeHostClient::DIRECT_3D);
- scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(&host_client);
+ TestTaskGraphRunner task_graph_runner;
+ scoped_ptr<FakeLayerTreeHost> host =
+ FakeLayerTreeHost::Create(&host_client, &task_graph_runner);
host->SetRootLayer(layer);
RecordingSource* recording_source = layer->GetRecordingSourceForTesting();
@@ -100,10 +102,12 @@ TEST(PictureLayerTest, UseTileGridSize) {
settings.default_tile_grid_size = gfx::Size(123, 123);
MockContentLayerClient client;
- scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client);
+ scoped_refptr<PictureLayer> layer =
+ PictureLayer::Create(LayerSettings(), &client);
FakeLayerTreeHostClient host_client(FakeLayerTreeHostClient::DIRECT_3D);
+ TestTaskGraphRunner task_graph_runner;
scoped_ptr<FakeLayerTreeHost> host =
- FakeLayerTreeHost::Create(&host_client, settings);
+ FakeLayerTreeHost::Create(&host_client, &task_graph_runner, settings);
host->SetRootLayer(layer);
// Tile-grid is set according to its setting.
@@ -120,19 +124,23 @@ TEST(PictureLayerTest, UseTileGridSize) {
TEST(PictureLayerTest, NonMonotonicSourceFrameNumber) {
LayerTreeSettings settings;
settings.single_thread_proxy_scheduler = false;
+ settings.use_zero_copy = true;
+ settings.use_one_copy = false;
FakeLayerTreeHostClient host_client1(FakeLayerTreeHostClient::DIRECT_3D);
FakeLayerTreeHostClient host_client2(FakeLayerTreeHostClient::DIRECT_3D);
- scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
- new TestSharedBitmapManager());
+ TestSharedBitmapManager shared_bitmap_manager;
+ TestTaskGraphRunner task_graph_runner;
MockContentLayerClient client;
- scoped_refptr<FakePictureLayer> layer = FakePictureLayer::Create(&client);
+ scoped_refptr<FakePictureLayer> layer =
+ FakePictureLayer::Create(LayerSettings(), &client);
LayerTreeHost::InitParams params;
params.client = &host_client1;
- params.shared_bitmap_manager = shared_bitmap_manager.get();
+ params.shared_bitmap_manager = &shared_bitmap_manager;
params.settings = &settings;
+ params.task_graph_runner = &task_graph_runner;
params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
scoped_ptr<LayerTreeHost> host1 =
LayerTreeHost::CreateSingleThreaded(&host_client1, &params);
@@ -146,16 +154,16 @@ TEST(PictureLayerTest, NonMonotonicSourceFrameNumber) {
// The PictureLayer is put in one LayerTreeHost.
host1->SetRootLayer(layer);
// Do a main frame, record the picture layers.
- EXPECT_EQ(0u, layer->update_count());
+ EXPECT_EQ(0, layer->update_count());
layer->SetNeedsDisplay();
host1->Composite(base::TimeTicks::Now());
- EXPECT_EQ(1u, layer->update_count());
+ EXPECT_EQ(1, layer->update_count());
EXPECT_EQ(1, host1->source_frame_number());
// The source frame number in |host1| is now higher than host2.
layer->SetNeedsDisplay();
host1->Composite(base::TimeTicks::Now());
- EXPECT_EQ(2u, layer->update_count());
+ EXPECT_EQ(2, layer->update_count());
EXPECT_EQ(2, host1->source_frame_number());
// Then moved to another LayerTreeHost.
@@ -166,7 +174,7 @@ TEST(PictureLayerTest, NonMonotonicSourceFrameNumber) {
// non-monotonically.
layer->SetNeedsDisplay();
host2->Composite(base::TimeTicks::Now());
- EXPECT_EQ(3u, layer->update_count());
+ EXPECT_EQ(3, layer->update_count());
EXPECT_EQ(1, host2->source_frame_number());
}
diff --git a/chromium/cc/layers/render_surface.h b/chromium/cc/layers/render_surface.h
index 1e3719d023b..29401e29951 100644
--- a/chromium/cc/layers/render_surface.h
+++ b/chromium/cc/layers/render_surface.h
@@ -19,8 +19,6 @@
namespace cc {
class Layer;
-template <typename LayerType>
-class LayerIterator;
class CC_EXPORT RenderSurface {
public:
@@ -116,8 +114,6 @@ class CC_EXPORT RenderSurface {
void ClearLayerLists();
private:
- friend class LayerIterator<Layer>;
-
Layer* owning_layer_;
// Uses this surface's space.
@@ -144,10 +140,6 @@ class CC_EXPORT RenderSurface {
// surface, and that ignores outside occlusion. This can point to itself.
RenderSurface* nearest_occlusion_immune_ancestor_;
- // For LayerIteratorActions
- int target_render_surface_layer_index_history_;
- int current_layer_index_history_;
-
DISALLOW_COPY_AND_ASSIGN(RenderSurface);
};
diff --git a/chromium/cc/layers/render_surface_impl.cc b/chromium/cc/layers/render_surface_impl.cc
index 2ca1241f719..ebb3016c64d 100644
--- a/chromium/cc/layers/render_surface_impl.cc
+++ b/chromium/cc/layers/render_surface_impl.cc
@@ -157,9 +157,9 @@ void RenderSurfaceImpl::AppendQuads(RenderPass* render_pass,
LayerImpl* mask_layer,
AppendQuadsData* append_quads_data,
RenderPassId render_pass_id) {
- gfx::Rect visible_content_rect =
+ gfx::Rect visible_layer_rect =
occlusion_in_content_space.GetUnoccludedContentRect(content_rect_);
- if (visible_content_rect.IsEmpty())
+ if (visible_layer_rect.IsEmpty())
return;
SharedQuadState* shared_quad_state =
@@ -173,11 +173,11 @@ void RenderSurfaceImpl::AppendQuads(RenderPass* render_pass,
DebugBorderDrawQuad* debug_border_quad =
render_pass->CreateAndAppendDrawQuad<DebugBorderDrawQuad>();
debug_border_quad->SetNew(shared_quad_state, content_rect_,
- visible_content_rect, debug_border_color,
+ visible_layer_rect, debug_border_color,
debug_border_width);
}
- ResourceProvider::ResourceId mask_resource_id = 0;
+ ResourceId mask_resource_id = 0;
gfx::Size mask_texture_size;
gfx::Vector2dF mask_uv_scale;
if (mask_layer && mask_layer->DrawsContent() &&
@@ -186,10 +186,9 @@ void RenderSurfaceImpl::AppendQuads(RenderPass* render_pass,
gfx::Vector2dF owning_layer_draw_scale =
MathUtil::ComputeTransform2dScaleComponents(
owning_layer_->draw_transform(), 1.f);
- gfx::SizeF unclipped_mask_target_size = gfx::ScaleSize(
- owning_layer_->content_bounds(),
- owning_layer_draw_scale.x(),
- owning_layer_draw_scale.y());
+ gfx::SizeF unclipped_mask_target_size =
+ gfx::ScaleSize(owning_layer_->bounds(), owning_layer_draw_scale.x(),
+ owning_layer_draw_scale.y());
mask_uv_scale = gfx::Vector2dF(
content_rect_.width() / unclipped_mask_target_size.width(),
content_rect_.height() / unclipped_mask_target_size.height());
@@ -198,19 +197,12 @@ void RenderSurfaceImpl::AppendQuads(RenderPass* render_pass,
DCHECK(owning_layer_->draw_properties().target_space_transform.IsScale2d());
gfx::Vector2dF owning_layer_to_target_scale =
owning_layer_->draw_properties().target_space_transform.Scale2d();
- owning_layer_to_target_scale.Scale(owning_layer_->contents_scale_x(),
- owning_layer_->contents_scale_y());
RenderPassDrawQuad* quad =
render_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
- quad->SetNew(shared_quad_state,
- content_rect_,
- visible_content_rect,
- render_pass_id,
- mask_resource_id,
- mask_uv_scale,
- mask_texture_size,
- owning_layer_->filters(),
+ quad->SetNew(shared_quad_state, content_rect_, visible_layer_rect,
+ render_pass_id, mask_resource_id, mask_uv_scale,
+ mask_texture_size, owning_layer_->filters(),
owning_layer_to_target_scale,
owning_layer_->background_filters());
}
diff --git a/chromium/cc/layers/render_surface_impl.h b/chromium/cc/layers/render_surface_impl.h
index 2035e28b127..80a4f720b7b 100644
--- a/chromium/cc/layers/render_surface_impl.h
+++ b/chromium/cc/layers/render_surface_impl.h
@@ -27,7 +27,6 @@ class Occlusion;
class RenderPassId;
class RenderPassSink;
class LayerImpl;
-template <typename LayerType>
class LayerIterator;
struct AppendQuadsData;
@@ -192,9 +191,9 @@ class CC_EXPORT RenderSurfaceImpl {
// For LayerIteratorActions
int target_render_surface_layer_index_history_;
- int current_layer_index_history_;
+ size_t current_layer_index_history_;
- friend class LayerIterator<LayerImpl>;
+ friend class LayerIterator;
DISALLOW_COPY_AND_ASSIGN(RenderSurfaceImpl);
};
diff --git a/chromium/cc/layers/render_surface_impl_unittest.cc b/chromium/cc/layers/render_surface_impl_unittest.cc
index 9934cd652ba..ac406758501 100644
--- a/chromium/cc/layers/render_surface_impl_unittest.cc
+++ b/chromium/cc/layers/render_surface_impl_unittest.cc
@@ -18,7 +18,6 @@ TEST(RenderSurfaceLayerImplTest, Occlusion) {
LayerImpl* owning_layer_impl = impl.AddChildToRoot<LayerImpl>();
owning_layer_impl->SetBounds(layer_size);
- owning_layer_impl->SetContentBounds(layer_size);
owning_layer_impl->SetDrawsContent(true);
owning_layer_impl->SetHasRenderSurface(true);
@@ -39,7 +38,7 @@ TEST(RenderSurfaceLayerImplTest, Occlusion) {
{
SCOPED_TRACE("Full occlusion");
- gfx::Rect occluded(owning_layer_impl->visible_content_rect());
+ gfx::Rect occluded(owning_layer_impl->visible_layer_rect());
impl.AppendSurfaceQuadsWithOcclusion(render_surface_impl, occluded);
LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect());
diff --git a/chromium/cc/layers/render_surface_unittest.cc b/chromium/cc/layers/render_surface_unittest.cc
index 929407c4fe5..5ecf2f7bac8 100644
--- a/chromium/cc/layers/render_surface_unittest.cc
+++ b/chromium/cc/layers/render_surface_unittest.cc
@@ -13,6 +13,7 @@
#include "cc/test/geometry_test_utils.h"
#include "cc/test/mock_occlusion_tracker.h"
#include "cc/test/test_shared_bitmap_manager.h"
+#include "cc/test/test_task_graph_runner.h"
#include "cc/trees/single_thread_proxy.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -38,7 +39,9 @@ TEST(RenderSurfaceTest, VerifySurfaceChangesAreTrackedProperly) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
scoped_ptr<LayerImpl> owning_layer =
LayerImpl::Create(host_impl.active_tree(), 1);
owning_layer->SetHasRenderSurface(true);
@@ -83,7 +86,9 @@ TEST(RenderSurfaceTest, VerifySurfaceChangesAreTrackedProperly) {
TEST(RenderSurfaceTest, SanityCheckSurfaceCreatesCorrectSharedQuadState) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
scoped_ptr<LayerImpl> root_layer =
LayerImpl::Create(host_impl.active_tree(), 1);
@@ -121,11 +126,12 @@ TEST(RenderSurfaceTest, SanityCheckSurfaceCreatesCorrectSharedQuadState) {
EXPECT_EQ(
30.0,
- shared_quad_state->content_to_target_transform.matrix().getDouble(0, 3));
+ shared_quad_state->quad_to_target_transform.matrix().getDouble(0, 3));
EXPECT_EQ(
40.0,
- shared_quad_state->content_to_target_transform.matrix().getDouble(1, 3));
- EXPECT_EQ(content_rect, gfx::Rect(shared_quad_state->visible_content_rect));
+ shared_quad_state->quad_to_target_transform.matrix().getDouble(1, 3));
+ EXPECT_EQ(content_rect,
+ gfx::Rect(shared_quad_state->visible_quad_layer_rect));
EXPECT_EQ(1.f, shared_quad_state->opacity);
EXPECT_EQ(blend_mode, shared_quad_state->blend_mode);
}
@@ -147,7 +153,9 @@ class TestRenderPassSink : public RenderPassSink {
TEST(RenderSurfaceTest, SanityCheckSurfaceCreatesCorrectRenderPass) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
scoped_ptr<LayerImpl> root_layer =
LayerImpl::Create(host_impl.active_tree(), 1);
diff --git a/chromium/cc/layers/scrollbar_layer_impl_base.cc b/chromium/cc/layers/scrollbar_layer_impl_base.cc
index 35e716bdbd8..1d07a8349e4 100644
--- a/chromium/cc/layers/scrollbar_layer_impl_base.cc
+++ b/chromium/cc/layers/scrollbar_layer_impl_base.cc
@@ -94,16 +94,6 @@ void ScrollbarLayerImplBase::SetScrollLayerAndClipLayerByIds(
ScrollbarParametersDidChange(false);
}
-gfx::Rect ScrollbarLayerImplBase::ScrollbarLayerRectToContentRect(
- const gfx::RectF& layer_rect) const {
- // Don't intersect with the bounds as in LayerRectToContentRect() because
- // layer_rect here might be in coordinates of the containing layer.
- gfx::RectF content_rect = gfx::ScaleRect(layer_rect,
- contents_scale_x(),
- contents_scale_y());
- return gfx::ToEnclosingRect(content_rect);
-}
-
bool ScrollbarLayerImplBase::SetCurrentPos(float current_pos) {
if (current_pos_ == current_pos)
return false;
@@ -249,7 +239,7 @@ gfx::Rect ScrollbarLayerImplBase::ComputeThumbQuadRect() const {
thumb_length);
}
- return ScrollbarLayerRectToContentRect(thumb_rect);
+ return gfx::ToEnclosingRect(thumb_rect);
}
void ScrollbarLayerImplBase::ScrollbarParametersDidChange(bool on_resize) {
diff --git a/chromium/cc/layers/scrollbar_layer_impl_base.h b/chromium/cc/layers/scrollbar_layer_impl_base.h
index d905c88f8c7..da7fa52d1f1 100644
--- a/chromium/cc/layers/scrollbar_layer_impl_base.h
+++ b/chromium/cc/layers/scrollbar_layer_impl_base.h
@@ -69,8 +69,6 @@ class CC_EXPORT ScrollbarLayerImplBase : public LayerImpl {
bool is_overlay);
~ScrollbarLayerImplBase() override;
- gfx::Rect ScrollbarLayerRectToContentRect(const gfx::RectF& layer_rect) const;
-
float visible_to_total_length_ratio() const {
return visible_to_total_length_ratio_;
}
diff --git a/chromium/cc/layers/scrollbar_layer_unittest.cc b/chromium/cc/layers/scrollbar_layer_unittest.cc
index 97d1c80a992..0042204505e 100644
--- a/chromium/cc/layers/scrollbar_layer_unittest.cc
+++ b/chromium/cc/layers/scrollbar_layer_unittest.cc
@@ -12,7 +12,6 @@
#include "cc/layers/solid_color_scrollbar_layer.h"
#include "cc/layers/solid_color_scrollbar_layer_impl.h"
#include "cc/quads/solid_color_draw_quad.h"
-#include "cc/resources/resource_update_queue.h"
#include "cc/test/fake_impl_proxy.h"
#include "cc/test/fake_layer_tree_host.h"
#include "cc/test/fake_layer_tree_host_client.h"
@@ -35,24 +34,24 @@
namespace cc {
namespace {
-LayerImpl* LayerImplForScrollAreaAndScrollbar(FakeLayerTreeHost* host,
+LayerImpl* LayerImplForScrollAreaAndScrollbar(const LayerSettings& settings,
+ FakeLayerTreeHost* host,
scoped_ptr<Scrollbar> scrollbar,
bool reverse_order,
bool use_solid_color_scrollbar,
int thumb_thickness,
int track_start) {
- scoped_refptr<Layer> layer_tree_root = Layer::Create();
- scoped_refptr<Layer> child1 = Layer::Create();
+ scoped_refptr<Layer> layer_tree_root = Layer::Create(settings);
+ scoped_refptr<Layer> child1 = Layer::Create(settings);
scoped_refptr<Layer> child2;
if (use_solid_color_scrollbar) {
const bool kIsLeftSideVerticalScrollbar = false;
- child2 = SolidColorScrollbarLayer::Create(scrollbar->Orientation(),
- thumb_thickness,
- track_start,
- kIsLeftSideVerticalScrollbar,
- child1->id());
+ child2 = SolidColorScrollbarLayer::Create(
+ settings, scrollbar->Orientation(), thumb_thickness, track_start,
+ kIsLeftSideVerticalScrollbar, child1->id());
} else {
- child2 = PaintedScrollbarLayer::Create(scrollbar.Pass(), child1->id());
+ child2 =
+ PaintedScrollbarLayer::Create(settings, scrollbar.Pass(), child1->id());
}
child2->ToScrollbarLayer()->SetClipLayer(layer_tree_root->id());
layer_tree_root->AddChild(child1);
@@ -121,10 +120,13 @@ class ScrollbarLayerTest : public testing::Test {
public:
ScrollbarLayerTest() : fake_client_(FakeLayerTreeHostClient::DIRECT_3D) {
layer_tree_settings_.single_thread_proxy_scheduler = false;
+ layer_tree_settings_.use_zero_copy = true;
+ layer_tree_settings_.use_one_copy = false;
LayerTreeHost::InitParams params;
params.client = &fake_client_;
params.settings = &layer_tree_settings_;
+ params.task_graph_runner = &task_graph_runner_;
layer_tree_host_.reset(
new FakeResourceTrackingLayerTreeHost(&fake_client_, &params));
@@ -134,16 +136,21 @@ class ScrollbarLayerTest : public testing::Test {
EXPECT_FALSE(layer_tree_host_->output_surface_lost());
}
+ const LayerSettings& layer_settings() { return layer_settings_; }
+
protected:
FakeLayerTreeHostClient fake_client_;
+ TestTaskGraphRunner task_graph_runner_;
LayerTreeSettings layer_tree_settings_;
+ LayerSettings layer_settings_;
scoped_ptr<FakeResourceTrackingLayerTreeHost> layer_tree_host_;
};
TEST_F(ScrollbarLayerTest, ResolveScrollLayerPointer) {
scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar);
LayerImpl* layer_impl_tree_root = LayerImplForScrollAreaAndScrollbar(
- layer_tree_host_.get(), scrollbar.Pass(), false, false, 0, 0);
+ layer_settings(), layer_tree_host_.get(), scrollbar.Pass(), false, false,
+ 0, 0);
LayerImpl* cc_child1 = layer_impl_tree_root->children()[0];
PaintedScrollbarLayerImpl* cc_child2 =
@@ -157,7 +164,8 @@ TEST_F(ScrollbarLayerTest, ResolveScrollLayerPointer) {
TEST_F(ScrollbarLayerTest, ResolveScrollLayerPointer_ReverseOrder) {
scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar);
LayerImpl* layer_impl_tree_root = LayerImplForScrollAreaAndScrollbar(
- layer_tree_host_.get(), scrollbar.Pass(), true, false, 0, 0);
+ layer_settings(), layer_tree_host_.get(), scrollbar.Pass(), true, false,
+ 0, 0);
PaintedScrollbarLayerImpl* cc_child1 =
static_cast<PaintedScrollbarLayerImpl*>(
@@ -172,7 +180,8 @@ TEST_F(ScrollbarLayerTest, ShouldScrollNonOverlayOnMainThread) {
// Create and attach a non-overlay scrollbar.
scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar);
LayerImpl* layer_impl_tree_root = LayerImplForScrollAreaAndScrollbar(
- layer_tree_host_.get(), scrollbar.Pass(), false, false, 0, 0);
+ layer_settings(), layer_tree_host_.get(), scrollbar.Pass(), false, false,
+ 0, 0);
PaintedScrollbarLayerImpl* scrollbar_layer_impl =
static_cast<PaintedScrollbarLayerImpl*>(
layer_impl_tree_root->children()[1]);
@@ -189,7 +198,8 @@ TEST_F(ScrollbarLayerTest, ShouldScrollNonOverlayOnMainThread) {
scrollbar.reset(new FakeScrollbar(false, false, true));
layer_impl_tree_root = LayerImplForScrollAreaAndScrollbar(
- layer_tree_host_.get(), scrollbar.Pass(), false, false, 0, 0);
+ layer_settings(), layer_tree_host_.get(), scrollbar.Pass(), false, false,
+ 0, 0);
scrollbar_layer_impl = static_cast<PaintedScrollbarLayerImpl*>(
layer_impl_tree_root->children()[1]);
@@ -203,11 +213,11 @@ TEST_F(ScrollbarLayerTest, ShouldScrollNonOverlayOnMainThread) {
TEST_F(ScrollbarLayerTest, ScrollOffsetSynchronization) {
scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar);
- scoped_refptr<Layer> layer_tree_root = Layer::Create();
- scoped_refptr<Layer> scroll_layer = Layer::Create();
- scoped_refptr<Layer> content_layer = Layer::Create();
- scoped_refptr<Layer> scrollbar_layer =
- PaintedScrollbarLayer::Create(scrollbar.Pass(), layer_tree_root->id());
+ scoped_refptr<Layer> layer_tree_root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> scroll_layer = Layer::Create(layer_settings());
+ scoped_refptr<Layer> content_layer = Layer::Create(layer_settings());
+ scoped_refptr<Layer> scrollbar_layer = PaintedScrollbarLayer::Create(
+ layer_settings(), scrollbar.Pass(), layer_tree_root->id());
// Choose bounds to give max_scroll_offset = (30, 50).
layer_tree_root->SetBounds(gfx::Size(70, 150));
@@ -272,11 +282,12 @@ TEST_F(ScrollbarLayerTest, ScrollOffsetSynchronization) {
} while (false)
TEST_F(ScrollbarLayerTest, UpdatePropertiesOfScrollBarWhenThumbRemoved) {
- scoped_refptr<Layer> root_clip_layer = Layer::Create();
- scoped_refptr<Layer> root_layer = Layer::Create();
- scoped_refptr<Layer> content_layer = Layer::Create();
+ scoped_refptr<Layer> root_clip_layer = Layer::Create(layer_settings());
+ scoped_refptr<Layer> root_layer = Layer::Create(layer_settings());
+ scoped_refptr<Layer> content_layer = Layer::Create(layer_settings());
scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer =
- FakePaintedScrollbarLayer::Create(false, true, root_layer->id());
+ FakePaintedScrollbarLayer::Create(layer_settings(), false, true,
+ root_layer->id());
root_layer->SetScrollClipLayerId(root_clip_layer->id());
// Give the root-clip a size that will result in MaxScrollOffset = (80, 0).
@@ -313,11 +324,12 @@ TEST_F(ScrollbarLayerTest, UpdatePropertiesOfScrollBarWhenThumbRemoved) {
}
TEST_F(ScrollbarLayerTest, ThumbRect) {
- scoped_refptr<Layer> root_clip_layer = Layer::Create();
- scoped_refptr<Layer> root_layer = Layer::Create();
- scoped_refptr<Layer> content_layer = Layer::Create();
+ scoped_refptr<Layer> root_clip_layer = Layer::Create(layer_settings());
+ scoped_refptr<Layer> root_layer = Layer::Create(layer_settings());
+ scoped_refptr<Layer> content_layer = Layer::Create(layer_settings());
scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer =
- FakePaintedScrollbarLayer::Create(false, true, root_layer->id());
+ FakePaintedScrollbarLayer::Create(layer_settings(), false, true,
+ root_layer->id());
root_layer->SetScrollClipLayerId(root_clip_layer->id());
// Give the root-clip a size that will result in MaxScrollOffset = (80, 0).
@@ -397,8 +409,8 @@ TEST_F(ScrollbarLayerTest, SolidColorDrawQuads) {
scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar(false, true, true));
LayerImpl* layer_impl_tree_root = LayerImplForScrollAreaAndScrollbar(
- layer_tree_host_.get(), scrollbar.Pass(), false, true, kThumbThickness,
- kTrackStart);
+ layer_settings(), layer_tree_host_.get(), scrollbar.Pass(), false, true,
+ kThumbThickness, kTrackStart);
ScrollbarLayerImplBase* scrollbar_layer_impl =
static_cast<SolidColorScrollbarLayerImpl*>(
layer_impl_tree_root->children()[1]);
@@ -419,22 +431,6 @@ TEST_F(ScrollbarLayerTest, SolidColorDrawQuads) {
EXPECT_EQ(gfx::Rect(6, 0, 39, 3), quads.front()->rect);
}
- // Contents scale should scale the draw quad.
- scrollbar_layer_impl->draw_properties().contents_scale_x = 2.f;
- scrollbar_layer_impl->draw_properties().contents_scale_y = 2.f;
- {
- scoped_ptr<RenderPass> render_pass = RenderPass::Create();
- AppendQuadsData data;
- scrollbar_layer_impl->AppendQuads(render_pass.get(), &data);
-
- const QuadList& quads = render_pass->quad_list;
- ASSERT_EQ(1u, quads.size());
- EXPECT_EQ(DrawQuad::SOLID_COLOR, quads.front()->material);
- EXPECT_EQ(gfx::Rect(12, 0, 78, 6), quads.front()->rect);
- }
- scrollbar_layer_impl->draw_properties().contents_scale_x = 1.f;
- scrollbar_layer_impl->draw_properties().contents_scale_y = 1.f;
-
// For solid color scrollbars, position and size should reflect the
// current viewport state.
scrollbar_layer_impl->SetVisibleToTotalLengthRatio(0.2f);
@@ -472,17 +468,15 @@ TEST_F(ScrollbarLayerTest, LayerDrivenSolidColorDrawQuads) {
scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar(false, true, true));
{
- scoped_refptr<Layer> layer_tree_root = Layer::Create();
- scoped_refptr<Layer> scroll_layer = Layer::Create();
+ scoped_refptr<Layer> layer_tree_root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> scroll_layer = Layer::Create(layer_settings());
scroll_layer->SetScrollClipLayerId(layer_tree_root->id());
- scoped_refptr<Layer> child1 = Layer::Create();
+ scoped_refptr<Layer> child1 = Layer::Create(layer_settings());
scoped_refptr<Layer> child2;
const bool kIsLeftSideVerticalScrollbar = false;
- child2 = SolidColorScrollbarLayer::Create(scrollbar->Orientation(),
- kThumbThickness,
- kTrackStart,
- kIsLeftSideVerticalScrollbar,
- child1->id());
+ child2 = SolidColorScrollbarLayer::Create(
+ layer_settings(), scrollbar->Orientation(), kThumbThickness,
+ kTrackStart, kIsLeftSideVerticalScrollbar, child1->id());
child2->ToScrollbarLayer()->SetScrollLayer(scroll_layer->id());
child2->ToScrollbarLayer()->SetClipLayer(layer_tree_root->id());
scroll_layer->AddChild(child1);
@@ -631,12 +625,12 @@ class ScrollbarLayerTestMaxTextureSize : public LayerTreeTest {
void SetScrollbarBounds(const gfx::Size& bounds) { bounds_ = bounds; }
void BeginTest() override {
- scroll_layer_ = Layer::Create();
+ scroll_layer_ = Layer::Create(layer_settings());
layer_tree_host()->root_layer()->AddChild(scroll_layer_);
scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar);
- scrollbar_layer_ =
- PaintedScrollbarLayer::Create(scrollbar.Pass(), scroll_layer_->id());
+ scrollbar_layer_ = PaintedScrollbarLayer::Create(
+ layer_settings(), scrollbar.Pass(), scroll_layer_->id());
scrollbar_layer_->SetScrollLayer(scroll_layer_->id());
scrollbar_layer_->SetLayerTreeHost(layer_tree_host());
scrollbar_layer_->SetBounds(bounds_);
@@ -675,7 +669,7 @@ TEST_F(ScrollbarLayerTestMaxTextureSize, DirectRenderer) {
int max_size = 0;
context->getIntegerv(GL_MAX_TEXTURE_SIZE, &max_size);
SetScrollbarBounds(gfx::Size(max_size + 100, max_size + 100));
- RunTest(true, false, true);
+ RunTest(true, false);
}
TEST_F(ScrollbarLayerTestMaxTextureSize, DelegatingRenderer) {
@@ -684,7 +678,7 @@ TEST_F(ScrollbarLayerTestMaxTextureSize, DelegatingRenderer) {
int max_size = 0;
context->getIntegerv(GL_MAX_TEXTURE_SIZE, &max_size);
SetScrollbarBounds(gfx::Size(max_size + 100, max_size + 100));
- RunTest(true, true, true);
+ RunTest(true, true);
}
class ScrollbarLayerTestResourceCreationAndRelease : public ScrollbarLayerTest {
@@ -695,22 +689,19 @@ class ScrollbarLayerTestResourceCreationAndRelease : public ScrollbarLayerTest {
int expected_deleted,
bool use_solid_color_scrollbar) {
scoped_ptr<Scrollbar> scrollbar(new FakeScrollbar(false, true, false));
- scoped_refptr<Layer> layer_tree_root = Layer::Create();
- scoped_refptr<Layer> content_layer = Layer::Create();
+ scoped_refptr<Layer> layer_tree_root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> content_layer = Layer::Create(layer_settings());
scoped_refptr<Layer> scrollbar_layer;
if (use_solid_color_scrollbar) {
const int kThumbThickness = 3;
const int kTrackStart = 0;
const bool kIsLeftSideVerticalScrollbar = false;
- scrollbar_layer =
- SolidColorScrollbarLayer::Create(scrollbar->Orientation(),
- kThumbThickness,
- kTrackStart,
- kIsLeftSideVerticalScrollbar,
- layer_tree_root->id());
+ scrollbar_layer = SolidColorScrollbarLayer::Create(
+ layer_settings(), scrollbar->Orientation(), kThumbThickness,
+ kTrackStart, kIsLeftSideVerticalScrollbar, layer_tree_root->id());
} else {
- scrollbar_layer = PaintedScrollbarLayer::Create(scrollbar.Pass(),
- layer_tree_root->id());
+ scrollbar_layer = PaintedScrollbarLayer::Create(
+ layer_settings(), scrollbar.Pass(), layer_tree_root->id());
}
layer_tree_root->AddChild(content_layer);
layer_tree_root->AddChild(scrollbar_layer);
@@ -722,8 +713,7 @@ class ScrollbarLayerTestResourceCreationAndRelease : public ScrollbarLayerTest {
layer_tree_root->SetScrollOffset(gfx::ScrollOffset(10, 20));
layer_tree_root->SetBounds(gfx::Size(100, 200));
content_layer->SetBounds(gfx::Size(100, 200));
- scrollbar_layer->draw_properties().content_bounds = gfx::Size(100, 200);
- scrollbar_layer->draw_properties().visible_content_rect =
+ scrollbar_layer->draw_properties().visible_layer_rect =
gfx::Rect(0, 0, 100, 200);
scrollbar_layer->CreateRenderSurface();
scrollbar_layer->draw_properties().render_target = scrollbar_layer.get();
@@ -731,13 +721,9 @@ class ScrollbarLayerTestResourceCreationAndRelease : public ScrollbarLayerTest {
testing::Mock::VerifyAndClearExpectations(layer_tree_host_.get());
EXPECT_EQ(scrollbar_layer->layer_tree_host(), layer_tree_host_.get());
- ResourceUpdateQueue queue;
- gfx::Rect screen_space_clip_rect;
- OcclusionTracker<Layer> occlusion_tracker(screen_space_clip_rect);
-
scrollbar_layer->SavePaintProperties();
for (int update_counter = 0; update_counter < num_updates; update_counter++)
- scrollbar_layer->Update(&queue, &occlusion_tracker);
+ scrollbar_layer->Update();
// A non-solid-color scrollbar should have requested two textures.
EXPECT_EQ(expected_resources, layer_tree_host_->UIResourceCount());
@@ -773,10 +759,11 @@ TEST_F(ScrollbarLayerTestResourceCreationAndRelease,
TEST_F(ScrollbarLayerTestResourceCreationAndRelease, TestResourceUpdate) {
gfx::Point scrollbar_location(0, 185);
- scoped_refptr<Layer> layer_tree_root = Layer::Create();
- scoped_refptr<Layer> content_layer = Layer::Create();
+ scoped_refptr<Layer> layer_tree_root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> content_layer = Layer::Create(layer_settings());
scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer =
- FakePaintedScrollbarLayer::Create(false, true, layer_tree_root->id());
+ FakePaintedScrollbarLayer::Create(layer_settings(), false, true,
+ layer_tree_root->id());
layer_tree_root->AddChild(content_layer);
layer_tree_root->AddChild(scrollbar_layer);
@@ -789,8 +776,7 @@ TEST_F(ScrollbarLayerTestResourceCreationAndRelease, TestResourceUpdate) {
layer_tree_root->SetBounds(gfx::Size(100, 200));
content_layer->SetBounds(gfx::Size(100, 200));
- scrollbar_layer->draw_properties().content_bounds = gfx::Size(100, 200);
- scrollbar_layer->draw_properties().visible_content_rect =
+ scrollbar_layer->draw_properties().visible_layer_rect =
gfx::Rect(0, 0, 100, 200);
scrollbar_layer->CreateRenderSurface();
@@ -799,17 +785,14 @@ TEST_F(ScrollbarLayerTestResourceCreationAndRelease, TestResourceUpdate) {
testing::Mock::VerifyAndClearExpectations(layer_tree_host_.get());
EXPECT_EQ(scrollbar_layer->layer_tree_host(), layer_tree_host_.get());
- ResourceUpdateQueue queue;
- gfx::Rect screen_space_clip_rect;
size_t resource_count;
int expected_created, expected_deleted;
- OcclusionTracker<Layer> occlusion_tracker(screen_space_clip_rect);
scrollbar_layer->SavePaintProperties();
resource_count = 2;
expected_created = 2;
expected_deleted = 0;
- EXPECT_TRUE(scrollbar_layer->Update(&queue, &occlusion_tracker));
+ EXPECT_TRUE(scrollbar_layer->Update());
EXPECT_NE(0, scrollbar_layer->track_resource_id());
EXPECT_NE(0, scrollbar_layer->thumb_resource_id());
EXPECT_EQ(resource_count, layer_tree_host_->UIResourceCount());
@@ -820,7 +803,7 @@ TEST_F(ScrollbarLayerTestResourceCreationAndRelease, TestResourceUpdate) {
expected_created = 2;
expected_deleted = 2;
scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(0, 0, 0, 0));
- EXPECT_TRUE(scrollbar_layer->Update(&queue, &occlusion_tracker));
+ EXPECT_TRUE(scrollbar_layer->Update());
EXPECT_EQ(0, scrollbar_layer->track_resource_id());
EXPECT_EQ(0, scrollbar_layer->thumb_resource_id());
EXPECT_EQ(resource_count, layer_tree_host_->UIResourceCount());
@@ -831,7 +814,7 @@ TEST_F(ScrollbarLayerTestResourceCreationAndRelease, TestResourceUpdate) {
expected_created = 2;
expected_deleted = 2;
scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(0, 0, 0, 0));
- EXPECT_FALSE(scrollbar_layer->Update(&queue, &occlusion_tracker));
+ EXPECT_FALSE(scrollbar_layer->Update());
EXPECT_EQ(0, scrollbar_layer->track_resource_id());
EXPECT_EQ(0, scrollbar_layer->thumb_resource_id());
EXPECT_EQ(resource_count, layer_tree_host_->UIResourceCount());
@@ -842,7 +825,7 @@ TEST_F(ScrollbarLayerTestResourceCreationAndRelease, TestResourceUpdate) {
expected_created = 4;
expected_deleted = 2;
scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(30, 10, 50, 10));
- EXPECT_TRUE(scrollbar_layer->Update(&queue, &occlusion_tracker));
+ EXPECT_TRUE(scrollbar_layer->Update());
EXPECT_NE(0, scrollbar_layer->track_resource_id());
EXPECT_NE(0, scrollbar_layer->thumb_resource_id());
EXPECT_EQ(resource_count, layer_tree_host_->UIResourceCount());
@@ -853,7 +836,7 @@ TEST_F(ScrollbarLayerTestResourceCreationAndRelease, TestResourceUpdate) {
expected_created = 5;
expected_deleted = 4;
scrollbar_layer->fake_scrollbar()->set_has_thumb(false);
- EXPECT_TRUE(scrollbar_layer->Update(&queue, &occlusion_tracker));
+ EXPECT_TRUE(scrollbar_layer->Update());
EXPECT_NE(0, scrollbar_layer->track_resource_id());
EXPECT_EQ(0, scrollbar_layer->thumb_resource_id());
EXPECT_EQ(resource_count, layer_tree_host_->UIResourceCount());
@@ -864,7 +847,7 @@ TEST_F(ScrollbarLayerTestResourceCreationAndRelease, TestResourceUpdate) {
expected_created = 5;
expected_deleted = 5;
scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(0, 0, 0, 0));
- EXPECT_TRUE(scrollbar_layer->Update(&queue, &occlusion_tracker));
+ EXPECT_TRUE(scrollbar_layer->Update());
EXPECT_EQ(0, scrollbar_layer->track_resource_id());
EXPECT_EQ(0, scrollbar_layer->thumb_resource_id());
EXPECT_EQ(resource_count, layer_tree_host_->UIResourceCount());
@@ -876,7 +859,7 @@ TEST_F(ScrollbarLayerTestResourceCreationAndRelease, TestResourceUpdate) {
expected_deleted = 5;
scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(30, 10, 50, 10));
scrollbar_layer->fake_scrollbar()->set_has_thumb(true);
- EXPECT_TRUE(scrollbar_layer->Update(&queue, &occlusion_tracker));
+ EXPECT_TRUE(scrollbar_layer->Update());
EXPECT_NE(0, scrollbar_layer->track_resource_id());
EXPECT_NE(0, scrollbar_layer->thumb_resource_id());
@@ -886,7 +869,7 @@ TEST_F(ScrollbarLayerTestResourceCreationAndRelease, TestResourceUpdate) {
scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(30, 10, 50, 10));
scrollbar_layer->fake_scrollbar()->set_has_thumb(false);
scrollbar_layer->SetBounds(gfx::Size(90, 15));
- EXPECT_TRUE(scrollbar_layer->Update(&queue, &occlusion_tracker));
+ EXPECT_TRUE(scrollbar_layer->Update());
EXPECT_EQ(resource_count, layer_tree_host_->UIResourceCount());
EXPECT_EQ(expected_created, layer_tree_host_->TotalUIResourceCreated());
EXPECT_EQ(expected_deleted, layer_tree_host_->TotalUIResourceDeleted());
@@ -895,7 +878,7 @@ TEST_F(ScrollbarLayerTestResourceCreationAndRelease, TestResourceUpdate) {
layer_tree_host_->ui_resource_size(scrollbar_layer->track_resource_id()));
scrollbar_layer->ResetNeedsDisplayForTesting();
- EXPECT_FALSE(scrollbar_layer->Update(&queue, &occlusion_tracker));
+ EXPECT_FALSE(scrollbar_layer->Update());
EXPECT_NE(0, scrollbar_layer->track_resource_id());
EXPECT_EQ(0, scrollbar_layer->thumb_resource_id());
EXPECT_EQ(resource_count, layer_tree_host_->UIResourceCount());
@@ -910,10 +893,11 @@ class ScaledScrollbarLayerTestResourceCreation : public ScrollbarLayerTest {
public:
void TestResourceUpload(const float test_scale) {
gfx::Point scrollbar_location(0, 185);
- scoped_refptr<Layer> layer_tree_root = Layer::Create();
- scoped_refptr<Layer> content_layer = Layer::Create();
+ scoped_refptr<Layer> layer_tree_root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> content_layer = Layer::Create(layer_settings());
scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer =
- FakePaintedScrollbarLayer::Create(false, true, layer_tree_root->id());
+ FakePaintedScrollbarLayer::Create(layer_settings(), false, true,
+ layer_tree_root->id());
layer_tree_root->AddChild(content_layer);
layer_tree_root->AddChild(scrollbar_layer);
@@ -925,30 +909,18 @@ class ScaledScrollbarLayerTestResourceCreation : public ScrollbarLayerTest {
scrollbar_layer->SetPosition(scrollbar_location);
layer_tree_root->SetBounds(gfx::Size(100, 200));
content_layer->SetBounds(gfx::Size(100, 200));
- gfx::SizeF scaled_size =
- gfx::ScaleSize(scrollbar_layer->bounds(), test_scale, test_scale);
- gfx::PointF scaled_location =
- gfx::ScalePoint(scrollbar_layer->position(), test_scale, test_scale);
- scrollbar_layer->draw_properties().content_bounds =
- gfx::Size(scaled_size.width(), scaled_size.height());
- scrollbar_layer->draw_properties().contents_scale_x = test_scale;
- scrollbar_layer->draw_properties().contents_scale_y = test_scale;
- scrollbar_layer->draw_properties().visible_content_rect =
- gfx::Rect(scaled_location.x(),
- scaled_location.y(),
- scaled_size.width(),
- scaled_size.height());
+ scrollbar_layer->draw_properties().visible_layer_rect =
+ gfx::Rect(scrollbar_location, scrollbar_layer->bounds());
scrollbar_layer->CreateRenderSurface();
scrollbar_layer->draw_properties().render_target = scrollbar_layer.get();
testing::Mock::VerifyAndClearExpectations(layer_tree_host_.get());
EXPECT_EQ(scrollbar_layer->layer_tree_host(), layer_tree_host_.get());
- ResourceUpdateQueue queue;
- gfx::Rect screen_space_clip_rect;
- OcclusionTracker<Layer> occlusion_tracker(screen_space_clip_rect);
+ layer_tree_host_->SetDeviceScaleFactor(test_scale);
+
scrollbar_layer->SavePaintProperties();
- scrollbar_layer->Update(&queue, &occlusion_tracker);
+ scrollbar_layer->Update();
// Verify that we have not generated any content uploads that are larger
// than their destination textures.
@@ -986,11 +958,10 @@ class ScaledScrollbarLayerTestScaledRasterization : public ScrollbarLayerTest {
void TestScale(const gfx::Rect scrollbar_rect, const float test_scale) {
bool paint_during_update = true;
bool has_thumb = false;
- scoped_refptr<Layer> layer_tree_root = Layer::Create();
+ scoped_refptr<Layer> layer_tree_root = Layer::Create(layer_settings());
scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer =
- FakePaintedScrollbarLayer::Create(paint_during_update,
- has_thumb,
- layer_tree_root->id());
+ FakePaintedScrollbarLayer::Create(layer_settings(), paint_during_update,
+ has_thumb, layer_tree_root->id());
layer_tree_root->AddChild(scrollbar_layer);
@@ -1000,26 +971,14 @@ class ScaledScrollbarLayerTestScaledRasterization : public ScrollbarLayerTest {
scrollbar_layer->SetPosition(scrollbar_rect.origin());
scrollbar_layer->fake_scrollbar()->set_location(scrollbar_rect.origin());
scrollbar_layer->fake_scrollbar()->set_track_rect(scrollbar_rect);
- gfx::SizeF scaled_size =
- gfx::ScaleSize(scrollbar_layer->bounds(), test_scale, test_scale);
- gfx::PointF scaled_location =
- gfx::ScalePoint(scrollbar_layer->position(), test_scale, test_scale);
- scrollbar_layer->draw_properties().content_bounds =
- gfx::Size(scaled_size.width(), scaled_size.height());
- scrollbar_layer->draw_properties().contents_scale_x = test_scale;
- scrollbar_layer->draw_properties().contents_scale_y = test_scale;
- scrollbar_layer->draw_properties().visible_content_rect =
- gfx::Rect(scaled_location.x(),
- scaled_location.y(),
- scaled_size.width(),
- scaled_size.height());
-
- ResourceUpdateQueue queue;
+ scrollbar_layer->draw_properties().visible_layer_rect = scrollbar_rect;
+
+ layer_tree_host_->SetDeviceScaleFactor(test_scale);
+
gfx::Rect screen_space_clip_rect;
- OcclusionTracker<Layer> occlusion_tracker(screen_space_clip_rect);
scrollbar_layer->SavePaintProperties();
- scrollbar_layer->Update(&queue, &occlusion_tracker);
+ scrollbar_layer->Update();
UIResourceBitmap* bitmap = layer_tree_host_->ui_resource_bitmap(
scrollbar_layer->track_resource_id());
diff --git a/chromium/cc/layers/solid_color_layer.cc b/chromium/cc/layers/solid_color_layer.cc
index 25e0ab85fbd..2fbaca167ff 100644
--- a/chromium/cc/layers/solid_color_layer.cc
+++ b/chromium/cc/layers/solid_color_layer.cc
@@ -13,12 +13,14 @@ scoped_ptr<LayerImpl> SolidColorLayer::CreateLayerImpl(
return SolidColorLayerImpl::Create(tree_impl, id());
}
-scoped_refptr<SolidColorLayer> SolidColorLayer::Create() {
- return make_scoped_refptr(new SolidColorLayer());
+scoped_refptr<SolidColorLayer> SolidColorLayer::Create(
+ const LayerSettings& settings) {
+ return make_scoped_refptr(new SolidColorLayer(settings));
}
-SolidColorLayer::SolidColorLayer()
- : Layer() {}
+SolidColorLayer::SolidColorLayer(const LayerSettings& settings)
+ : Layer(settings) {
+}
SolidColorLayer::~SolidColorLayer() {}
diff --git a/chromium/cc/layers/solid_color_layer.h b/chromium/cc/layers/solid_color_layer.h
index 8dc986075a5..b544f66311a 100644
--- a/chromium/cc/layers/solid_color_layer.h
+++ b/chromium/cc/layers/solid_color_layer.h
@@ -15,14 +15,14 @@ namespace cc {
// SetBackgroundColor() on the base class.
class CC_EXPORT SolidColorLayer : public Layer {
public:
- static scoped_refptr<SolidColorLayer> Create();
+ static scoped_refptr<SolidColorLayer> Create(const LayerSettings& settings);
scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
void SetBackgroundColor(SkColor color) override;
protected:
- SolidColorLayer();
+ explicit SolidColorLayer(const LayerSettings& settings);
private:
~SolidColorLayer() override;
diff --git a/chromium/cc/layers/solid_color_layer_impl.cc b/chromium/cc/layers/solid_color_layer_impl.cc
index 276249744e8..76cd3fc4229 100644
--- a/chromium/cc/layers/solid_color_layer_impl.cc
+++ b/chromium/cc/layers/solid_color_layer_impl.cc
@@ -29,29 +29,29 @@ scoped_ptr<LayerImpl> SolidColorLayerImpl::CreateLayerImpl(
void SolidColorLayerImpl::AppendSolidQuads(
RenderPass* render_pass,
- const Occlusion& occlusion_in_content_space,
+ const Occlusion& occlusion_in_layer_space,
SharedQuadState* shared_quad_state,
- const gfx::Rect& visible_content_rect,
+ const gfx::Rect& visible_layer_rect,
SkColor color,
AppendQuadsData* append_quads_data) {
// We create a series of smaller quads instead of just one large one so that
// the culler can reduce the total pixels drawn.
- int right = visible_content_rect.right();
- int bottom = visible_content_rect.bottom();
- for (int x = visible_content_rect.x(); x < visible_content_rect.right();
+ int right = visible_layer_rect.right();
+ int bottom = visible_layer_rect.bottom();
+ for (int x = visible_layer_rect.x(); x < visible_layer_rect.right();
x += kSolidQuadTileSize) {
- for (int y = visible_content_rect.y(); y < visible_content_rect.bottom();
+ for (int y = visible_layer_rect.y(); y < visible_layer_rect.bottom();
y += kSolidQuadTileSize) {
gfx::Rect quad_rect(x,
y,
std::min(right - x, kSolidQuadTileSize),
std::min(bottom - y, kSolidQuadTileSize));
gfx::Rect visible_quad_rect =
- occlusion_in_content_space.GetUnoccludedContentRect(quad_rect);
+ occlusion_in_layer_space.GetUnoccludedContentRect(quad_rect);
if (visible_quad_rect.IsEmpty())
continue;
- append_quads_data->visible_content_area +=
+ append_quads_data->visible_layer_area +=
visible_quad_rect.width() * visible_quad_rect.height();
SolidColorDrawQuad* quad =
@@ -69,14 +69,14 @@ void SolidColorLayerImpl::AppendQuads(
render_pass->CreateAndAppendSharedQuadState();
PopulateSharedQuadState(shared_quad_state);
- AppendDebugBorderQuad(
- render_pass, content_bounds(), shared_quad_state, append_quads_data);
+ AppendDebugBorderQuad(render_pass, bounds(), shared_quad_state,
+ append_quads_data);
// TODO(hendrikw): We need to pass the visible content rect rather than
- // |content_bounds()| here.
+ // |bounds()| here.
AppendSolidQuads(render_pass, draw_properties().occlusion_in_content_space,
- shared_quad_state, gfx::Rect(content_bounds()),
- background_color(), append_quads_data);
+ shared_quad_state, gfx::Rect(bounds()), background_color(),
+ append_quads_data);
}
const char* SolidColorLayerImpl::LayerTypeAsString() const {
diff --git a/chromium/cc/layers/solid_color_layer_impl.h b/chromium/cc/layers/solid_color_layer_impl.h
index 213e3f13a72..2068ac5db3f 100644
--- a/chromium/cc/layers/solid_color_layer_impl.h
+++ b/chromium/cc/layers/solid_color_layer_impl.h
@@ -19,9 +19,9 @@ class CC_EXPORT SolidColorLayerImpl : public LayerImpl {
}
static void AppendSolidQuads(RenderPass* render_pass,
- const Occlusion& occlusion_in_content_space,
+ const Occlusion& occlusion_in_layer_space,
SharedQuadState* shared_quad_state,
- const gfx::Rect& visible_content_rect,
+ const gfx::Rect& visible_layer_rect,
SkColor color,
AppendQuadsData* append_quads_data);
diff --git a/chromium/cc/layers/solid_color_layer_impl_unittest.cc b/chromium/cc/layers/solid_color_layer_impl_unittest.cc
index f35b82a848d..59ef6ba70fa 100644
--- a/chromium/cc/layers/solid_color_layer_impl_unittest.cc
+++ b/chromium/cc/layers/solid_color_layer_impl_unittest.cc
@@ -12,7 +12,7 @@
#include "cc/test/fake_impl_proxy.h"
#include "cc/test/fake_layer_tree_host.h"
#include "cc/test/layer_test_common.h"
-#include "cc/test/test_shared_bitmap_manager.h"
+#include "cc/test/test_task_graph_runner.h"
#include "cc/trees/single_thread_proxy.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -24,16 +24,15 @@ TEST(SolidColorLayerImplTest, VerifyTilingCompleteAndNoOverlap) {
scoped_ptr<RenderPass> render_pass = RenderPass::Create();
gfx::Size layer_size = gfx::Size(800, 600);
- gfx::Rect visible_content_rect = gfx::Rect(layer_size);
+ gfx::Rect visible_layer_rect = gfx::Rect(layer_size);
FakeImplProxy proxy;
- TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, nullptr, &task_graph_runner);
scoped_ptr<SolidColorLayerImpl> layer =
SolidColorLayerImpl::Create(host_impl.active_tree(), 1);
- layer->draw_properties().visible_content_rect = visible_content_rect;
+ layer->draw_properties().visible_layer_rect = visible_layer_rect;
layer->SetBounds(layer_size);
- layer->SetContentBounds(layer_size);
layer->SetHasRenderSurface(true);
layer->draw_properties().render_target = layer.get();
@@ -41,7 +40,7 @@ TEST(SolidColorLayerImplTest, VerifyTilingCompleteAndNoOverlap) {
layer->AppendQuads(render_pass.get(), &data);
LayerTestCommon::VerifyQuadsExactlyCoverRect(render_pass->quad_list,
- visible_content_rect);
+ visible_layer_rect);
}
TEST(SolidColorLayerImplTest, VerifyCorrectBackgroundColorInQuad) {
@@ -50,16 +49,15 @@ TEST(SolidColorLayerImplTest, VerifyCorrectBackgroundColorInQuad) {
scoped_ptr<RenderPass> render_pass = RenderPass::Create();
gfx::Size layer_size = gfx::Size(100, 100);
- gfx::Rect visible_content_rect = gfx::Rect(layer_size);
+ gfx::Rect visible_layer_rect = gfx::Rect(layer_size);
FakeImplProxy proxy;
- TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, nullptr, &task_graph_runner);
scoped_ptr<SolidColorLayerImpl> layer =
SolidColorLayerImpl::Create(host_impl.active_tree(), 1);
- layer->draw_properties().visible_content_rect = visible_content_rect;
+ layer->draw_properties().visible_layer_rect = visible_layer_rect;
layer->SetBounds(layer_size);
- layer->SetContentBounds(layer_size);
layer->SetBackgroundColor(test_color);
layer->SetHasRenderSurface(true);
layer->draw_properties().render_target = layer.get();
@@ -79,16 +77,15 @@ TEST(SolidColorLayerImplTest, VerifyCorrectOpacityInQuad) {
scoped_ptr<RenderPass> render_pass = RenderPass::Create();
gfx::Size layer_size = gfx::Size(100, 100);
- gfx::Rect visible_content_rect = gfx::Rect(layer_size);
+ gfx::Rect visible_layer_rect = gfx::Rect(layer_size);
FakeImplProxy proxy;
- TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, nullptr, &task_graph_runner);
scoped_ptr<SolidColorLayerImpl> layer =
SolidColorLayerImpl::Create(host_impl.active_tree(), 1);
- layer->draw_properties().visible_content_rect = visible_content_rect;
+ layer->draw_properties().visible_layer_rect = visible_layer_rect;
layer->SetBounds(layer_size);
- layer->SetContentBounds(layer_size);
layer->draw_properties().opacity = opacity;
layer->SetHasRenderSurface(true);
layer->draw_properties().render_target = layer.get();
@@ -99,7 +96,7 @@ TEST(SolidColorLayerImplTest, VerifyCorrectOpacityInQuad) {
ASSERT_EQ(render_pass->quad_list.size(), 1U);
EXPECT_EQ(opacity,
SolidColorDrawQuad::MaterialCast(render_pass->quad_list.front())
- ->opacity());
+ ->shared_quad_state->opacity);
}
TEST(SolidColorLayerImplTest, VerifyCorrectBlendModeInQuad) {
@@ -108,15 +105,14 @@ TEST(SolidColorLayerImplTest, VerifyCorrectBlendModeInQuad) {
scoped_ptr<RenderPass> render_pass = RenderPass::Create();
gfx::Size layer_size = gfx::Size(100, 100);
- gfx::Rect visible_content_rect = gfx::Rect(layer_size);
+ gfx::Rect visible_layer_rect = gfx::Rect(layer_size);
FakeImplProxy proxy;
- TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, nullptr, &task_graph_runner);
scoped_ptr<SolidColorLayerImpl> layer =
SolidColorLayerImpl::Create(host_impl.active_tree(), 1);
layer->SetBounds(layer_size);
- layer->SetContentBounds(layer_size);
layer->draw_properties().blend_mode = blend_mode;
AppendQuadsData data;
@@ -129,17 +125,22 @@ TEST(SolidColorLayerImplTest, VerifyCorrectBlendModeInQuad) {
TEST(SolidColorLayerImplTest, VerifyOpaqueRect) {
gfx::Size layer_size = gfx::Size(100, 100);
- gfx::Rect visible_content_rect = gfx::Rect(layer_size);
+ gfx::Rect visible_layer_rect = gfx::Rect(layer_size);
- scoped_refptr<SolidColorLayer> layer = SolidColorLayer::Create();
+ LayerSettings layer_settings;
+
+ scoped_refptr<SolidColorLayer> layer =
+ SolidColorLayer::Create(layer_settings);
layer->SetBounds(layer_size);
layer->SetForceRenderSurface(true);
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings);
root->AddChild(layer);
FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
- scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(&client);
+ TestTaskGraphRunner task_graph_runner;
+ scoped_ptr<FakeLayerTreeHost> host =
+ FakeLayerTreeHost::Create(&client, &task_graph_runner);
host->SetRootLayer(root);
RenderSurfaceLayerList render_surface_layer_list;
@@ -169,7 +170,7 @@ TEST(SolidColorLayerImplTest, VerifyOpaqueRect) {
layer_impl->AppendQuads(render_pass.get(), &data);
ASSERT_EQ(render_pass->quad_list.size(), 1U);
- EXPECT_EQ(visible_content_rect.ToString(),
+ EXPECT_EQ(visible_layer_rect.ToString(),
render_pass->quad_list.front()->opaque_rect.ToString());
}
@@ -210,7 +211,6 @@ TEST(SolidColorLayerImplTest, Occlusion) {
impl.AddChildToRoot<SolidColorLayerImpl>();
solid_color_layer_impl->SetBackgroundColor(SkColorSetARGB(255, 10, 20, 30));
solid_color_layer_impl->SetBounds(layer_size);
- solid_color_layer_impl->SetContentBounds(layer_size);
solid_color_layer_impl->SetDrawsContent(true);
impl.CalcDrawProps(viewport_size);
@@ -227,7 +227,7 @@ TEST(SolidColorLayerImplTest, Occlusion) {
{
SCOPED_TRACE("Full occlusion");
- gfx::Rect occluded(solid_color_layer_impl->visible_content_rect());
+ gfx::Rect occluded(solid_color_layer_impl->visible_layer_rect());
impl.AppendQuadsWithOcclusion(solid_color_layer_impl, occluded);
LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect());
diff --git a/chromium/cc/layers/solid_color_scrollbar_layer.cc b/chromium/cc/layers/solid_color_scrollbar_layer.cc
index b2c1ed495f0..4ed55cacd3a 100644
--- a/chromium/cc/layers/solid_color_scrollbar_layer.cc
+++ b/chromium/cc/layers/solid_color_scrollbar_layer.cc
@@ -23,31 +23,32 @@ scoped_ptr<LayerImpl> SolidColorScrollbarLayer::CreateLayerImpl(
}
scoped_refptr<SolidColorScrollbarLayer> SolidColorScrollbarLayer::Create(
+ const LayerSettings& settings,
ScrollbarOrientation orientation,
int thumb_thickness,
int track_start,
bool is_left_side_vertical_scrollbar,
int scroll_layer_id) {
- return make_scoped_refptr(
- new SolidColorScrollbarLayer(orientation,
- thumb_thickness,
- track_start,
- is_left_side_vertical_scrollbar,
- scroll_layer_id));
+ return make_scoped_refptr(new SolidColorScrollbarLayer(
+ settings, orientation, thumb_thickness, track_start,
+ is_left_side_vertical_scrollbar, scroll_layer_id));
}
SolidColorScrollbarLayer::SolidColorScrollbarLayer(
+ const LayerSettings& settings,
ScrollbarOrientation orientation,
int thumb_thickness,
int track_start,
bool is_left_side_vertical_scrollbar,
int scroll_layer_id)
- : scroll_layer_id_(Layer::INVALID_ID),
+ : Layer(settings),
+ scroll_layer_id_(Layer::INVALID_ID),
clip_layer_id_(scroll_layer_id),
orientation_(orientation),
thumb_thickness_(thumb_thickness),
track_start_(track_start),
- is_left_side_vertical_scrollbar_(is_left_side_vertical_scrollbar) {}
+ is_left_side_vertical_scrollbar_(is_left_side_vertical_scrollbar) {
+}
SolidColorScrollbarLayer::~SolidColorScrollbarLayer() {}
diff --git a/chromium/cc/layers/solid_color_scrollbar_layer.h b/chromium/cc/layers/solid_color_scrollbar_layer.h
index fc6306e47b3..6097014ca22 100644
--- a/chromium/cc/layers/solid_color_scrollbar_layer.h
+++ b/chromium/cc/layers/solid_color_scrollbar_layer.h
@@ -17,6 +17,7 @@ class CC_EXPORT SolidColorScrollbarLayer : public ScrollbarLayerInterface,
scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
static scoped_refptr<SolidColorScrollbarLayer> Create(
+ const LayerSettings& settings,
ScrollbarOrientation orientation,
int thumb_thickness,
int track_start,
@@ -40,7 +41,8 @@ class CC_EXPORT SolidColorScrollbarLayer : public ScrollbarLayerInterface,
ScrollbarOrientation orientation() const override;
protected:
- SolidColorScrollbarLayer(ScrollbarOrientation orientation,
+ SolidColorScrollbarLayer(const LayerSettings& settings,
+ ScrollbarOrientation orientation,
int thumb_thickness,
int track_start,
bool is_left_side_vertical_scrollbar,
diff --git a/chromium/cc/layers/solid_color_scrollbar_layer_impl.cc b/chromium/cc/layers/solid_color_scrollbar_layer_impl.cc
index fa1849e86e8..0b78de7f8c7 100644
--- a/chromium/cc/layers/solid_color_scrollbar_layer_impl.cc
+++ b/chromium/cc/layers/solid_color_scrollbar_layer_impl.cc
@@ -100,8 +100,8 @@ void SolidColorScrollbarLayerImpl::AppendQuads(
render_pass->CreateAndAppendSharedQuadState();
PopulateSharedQuadState(shared_quad_state);
- AppendDebugBorderQuad(
- render_pass, content_bounds(), shared_quad_state, append_quads_data);
+ AppendDebugBorderQuad(render_pass, bounds(), shared_quad_state,
+ append_quads_data);
gfx::Rect thumb_quad_rect(ComputeThumbQuadRect());
gfx::Rect visible_quad_rect =
diff --git a/chromium/cc/layers/solid_color_scrollbar_layer_impl_unittest.cc b/chromium/cc/layers/solid_color_scrollbar_layer_impl_unittest.cc
index b27c84bfae7..c758497c9ce 100644
--- a/chromium/cc/layers/solid_color_scrollbar_layer_impl_unittest.cc
+++ b/chromium/cc/layers/solid_color_scrollbar_layer_impl_unittest.cc
@@ -30,7 +30,6 @@ TEST(SolidColorScrollbarLayerImplTest, Occlusion) {
is_left_side_vertical_scrollbar,
is_overlay);
scrollbar_layer_impl->SetBounds(layer_size);
- scrollbar_layer_impl->SetContentBounds(layer_size);
scrollbar_layer_impl->SetDrawsContent(true);
scrollbar_layer_impl->SetCurrentPos(100.f / 4);
scrollbar_layer_impl->SetMaximum(100);
@@ -55,7 +54,7 @@ TEST(SolidColorScrollbarLayerImplTest, Occlusion) {
{
SCOPED_TRACE("Full occlusion");
- gfx::Rect occluded(scrollbar_layer_impl->visible_content_rect());
+ gfx::Rect occluded(scrollbar_layer_impl->visible_layer_rect());
impl.AppendQuadsWithOcclusion(scrollbar_layer_impl, occluded);
LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect());
diff --git a/chromium/cc/layers/surface_layer.cc b/chromium/cc/layers/surface_layer.cc
index 67a263229de..e1862303caa 100644
--- a/chromium/cc/layers/surface_layer.cc
+++ b/chromium/cc/layers/surface_layer.cc
@@ -36,15 +36,17 @@ class SatisfySwapPromise : public SwapPromise {
};
scoped_refptr<SurfaceLayer> SurfaceLayer::Create(
+ const LayerSettings& settings,
const SatisfyCallback& satisfy_callback,
const RequireCallback& require_callback) {
return make_scoped_refptr(
- new SurfaceLayer(satisfy_callback, require_callback));
+ new SurfaceLayer(settings, satisfy_callback, require_callback));
}
-SurfaceLayer::SurfaceLayer(const SatisfyCallback& satisfy_callback,
+SurfaceLayer::SurfaceLayer(const LayerSettings& settings,
+ const SatisfyCallback& satisfy_callback,
const RequireCallback& require_callback)
- : Layer(),
+ : Layer(settings),
surface_scale_(1.f),
satisfy_callback_(satisfy_callback),
require_callback_(require_callback) {
@@ -92,15 +94,8 @@ void SurfaceLayer::PushPropertiesTo(LayerImpl* layer) {
SurfaceLayerImpl* layer_impl = static_cast<SurfaceLayerImpl*>(layer);
layer_impl->SetSurfaceId(surface_id_);
-}
-
-void SurfaceLayer::CalculateContentsScale(float ideal_contents_scale,
- float* contents_scale_x,
- float* contents_scale_y,
- gfx::Size* content_bounds) {
- *content_bounds = surface_size_;
- *contents_scale_x = surface_scale_;
- *contents_scale_y = surface_scale_;
+ layer_impl->SetSurfaceSize(surface_size_);
+ layer_impl->SetSurfaceScale(surface_scale_);
}
void SurfaceLayer::CreateNewDestroySequence() {
diff --git a/chromium/cc/layers/surface_layer.h b/chromium/cc/layers/surface_layer.h
index 381369f5c61..e62d6a2c9dc 100644
--- a/chromium/cc/layers/surface_layer.h
+++ b/chromium/cc/layers/surface_layer.h
@@ -27,6 +27,7 @@ class CC_EXPORT SurfaceLayer : public Layer {
using RequireCallback = base::Callback<void(SurfaceId, SurfaceSequence)>;
static scoped_refptr<SurfaceLayer> Create(
+ const LayerSettings& settings,
const SatisfyCallback& satisfy_callback,
const RequireCallback& require_callback);
@@ -36,13 +37,10 @@ class CC_EXPORT SurfaceLayer : public Layer {
scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
void SetLayerTreeHost(LayerTreeHost* host) override;
void PushPropertiesTo(LayerImpl* layer) override;
- void CalculateContentsScale(float ideal_contents_scale,
- float* contents_scale_x,
- float* contents_scale_y,
- gfx::Size* content_bounds) override;
protected:
- SurfaceLayer(const SatisfyCallback& satisfy_callback,
+ SurfaceLayer(const LayerSettings& settings,
+ const SatisfyCallback& satisfy_callback,
const RequireCallback& require_callback);
bool HasDrawableContent() const override;
diff --git a/chromium/cc/layers/surface_layer_impl.cc b/chromium/cc/layers/surface_layer_impl.cc
index 966112d7f54..0cd4f248645 100644
--- a/chromium/cc/layers/surface_layer_impl.cc
+++ b/chromium/cc/layers/surface_layer_impl.cc
@@ -12,7 +12,7 @@
namespace cc {
SurfaceLayerImpl::SurfaceLayerImpl(LayerTreeImpl* tree_impl, int id)
- : LayerImpl(tree_impl, id) {
+ : LayerImpl(tree_impl, id), surface_scale_(0.f) {
}
SurfaceLayerImpl::~SurfaceLayerImpl() {}
@@ -30,26 +30,44 @@ void SurfaceLayerImpl::SetSurfaceId(SurfaceId surface_id) {
NoteLayerPropertyChanged();
}
+void SurfaceLayerImpl::SetSurfaceScale(float scale) {
+ if (surface_scale_ == scale)
+ return;
+
+ surface_scale_ = scale;
+ NoteLayerPropertyChanged();
+}
+
+void SurfaceLayerImpl::SetSurfaceSize(const gfx::Size& size) {
+ if (surface_size_ == size)
+ return;
+
+ surface_size_ = size;
+ NoteLayerPropertyChanged();
+}
+
void SurfaceLayerImpl::PushPropertiesTo(LayerImpl* layer) {
LayerImpl::PushPropertiesTo(layer);
SurfaceLayerImpl* layer_impl = static_cast<SurfaceLayerImpl*>(layer);
layer_impl->SetSurfaceId(surface_id_);
+ layer_impl->SetSurfaceSize(surface_size_);
+ layer_impl->SetSurfaceScale(surface_scale_);
}
void SurfaceLayerImpl::AppendQuads(RenderPass* render_pass,
AppendQuadsData* append_quads_data) {
SharedQuadState* shared_quad_state =
render_pass->CreateAndAppendSharedQuadState();
- PopulateSharedQuadState(shared_quad_state);
+ PopulateScaledSharedQuadState(shared_quad_state, surface_scale_);
- AppendDebugBorderQuad(
- render_pass, content_bounds(), shared_quad_state, append_quads_data);
+ AppendDebugBorderQuad(render_pass, surface_size_, shared_quad_state,
+ append_quads_data);
if (surface_id_.is_null())
return;
- gfx::Rect quad_rect(content_bounds());
+ gfx::Rect quad_rect(surface_size_);
gfx::Rect visible_quad_rect =
draw_properties().occlusion_in_content_space.GetUnoccludedContentRect(
quad_rect);
@@ -58,6 +76,7 @@ void SurfaceLayerImpl::AppendQuads(RenderPass* render_pass,
SurfaceDrawQuad* quad =
render_pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect, surface_id_);
+ render_pass->referenced_surfaces.push_back(surface_id_);
}
void SurfaceLayerImpl::GetDebugBorderProperties(SkColor* color,
diff --git a/chromium/cc/layers/surface_layer_impl.h b/chromium/cc/layers/surface_layer_impl.h
index 90c0f4565c6..b190b3af940 100644
--- a/chromium/cc/layers/surface_layer_impl.h
+++ b/chromium/cc/layers/surface_layer_impl.h
@@ -20,6 +20,8 @@ class CC_EXPORT SurfaceLayerImpl : public LayerImpl {
~SurfaceLayerImpl() override;
void SetSurfaceId(SurfaceId surface_id);
+ void SetSurfaceScale(float scale);
+ void SetSurfaceSize(const gfx::Size& size);
// LayerImpl overrides.
scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
@@ -36,6 +38,8 @@ class CC_EXPORT SurfaceLayerImpl : public LayerImpl {
const char* LayerTypeAsString() const override;
SurfaceId surface_id_;
+ gfx::Size surface_size_;
+ float surface_scale_;
DISALLOW_COPY_AND_ASSIGN(SurfaceLayerImpl);
};
diff --git a/chromium/cc/layers/surface_layer_impl_unittest.cc b/chromium/cc/layers/surface_layer_impl_unittest.cc
index 74543a84428..3ff8255f151 100644
--- a/chromium/cc/layers/surface_layer_impl_unittest.cc
+++ b/chromium/cc/layers/surface_layer_impl_unittest.cc
@@ -19,10 +19,11 @@ TEST(SurfaceLayerImplTest, Occlusion) {
SurfaceLayerImpl* surface_layer_impl =
impl.AddChildToRoot<SurfaceLayerImpl>();
surface_layer_impl->SetBounds(layer_size);
- surface_layer_impl->SetContentBounds(layer_size);
surface_layer_impl->SetDrawsContent(true);
SurfaceId surface_id(9);
surface_layer_impl->SetSurfaceId(surface_id);
+ surface_layer_impl->SetSurfaceScale(1.f);
+ surface_layer_impl->SetSurfaceSize(layer_size);
impl.CalcDrawProps(viewport_size);
@@ -38,7 +39,7 @@ TEST(SurfaceLayerImplTest, Occlusion) {
{
SCOPED_TRACE("Full occlusion");
- gfx::Rect occluded(surface_layer_impl->visible_content_rect());
+ gfx::Rect occluded(surface_layer_impl->visible_layer_rect());
impl.AppendQuadsWithOcclusion(surface_layer_impl, occluded);
LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect());
diff --git a/chromium/cc/layers/surface_layer_unittest.cc b/chromium/cc/layers/surface_layer_unittest.cc
index 6661a1a243a..eac14a0c245 100644
--- a/chromium/cc/layers/surface_layer_unittest.cc
+++ b/chromium/cc/layers/surface_layer_unittest.cc
@@ -16,7 +16,7 @@
#include "cc/test/fake_layer_tree_host_impl.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/layer_tree_test.h"
-#include "cc/test/test_shared_bitmap_manager.h"
+#include "cc/test/test_task_graph_runner.h"
#include "cc/trees/layer_tree_host.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -32,7 +32,8 @@ class SurfaceLayerTest : public testing::Test {
protected:
void SetUp() override {
- layer_tree_host_ = FakeLayerTreeHost::Create(&fake_client_);
+ layer_tree_host_ =
+ FakeLayerTreeHost::Create(&fake_client_, &task_graph_runner_);
layer_tree_host_->SetViewportSize(gfx::Size(10, 10));
}
@@ -43,9 +44,10 @@ class SurfaceLayerTest : public testing::Test {
}
}
- scoped_ptr<FakeLayerTreeHost> layer_tree_host_;
FakeLayerTreeHostClient fake_client_;
- TestSharedBitmapManager shared_bitmap_manager_;
+ TestTaskGraphRunner task_graph_runner_;
+ scoped_ptr<FakeLayerTreeHost> layer_tree_host_;
+ LayerSettings layer_settings_;
};
void SatisfyCallback(SurfaceSequence* out, SurfaceSequence in) {
@@ -68,16 +70,16 @@ TEST_F(SurfaceLayerTest, MultipleFramesOneSurface) {
SurfaceId required_id;
std::set<SurfaceSequence> required_seq;
scoped_refptr<SurfaceLayer> layer(SurfaceLayer::Create(
- base::Bind(&SatisfyCallback, &blank_change),
+ layer_settings_, base::Bind(&SatisfyCallback, &blank_change),
base::Bind(&RequireCallback, &required_id, &required_seq)));
layer->SetSurfaceId(SurfaceId(1), 1.f, gfx::Size(1, 1));
layer_tree_host_->set_surface_id_namespace(1);
layer_tree_host_->SetRootLayer(layer);
scoped_ptr<FakeLayerTreeHost> layer_tree_host2 =
- FakeLayerTreeHost::Create(&fake_client_);
+ FakeLayerTreeHost::Create(&fake_client_, &task_graph_runner_);
scoped_refptr<SurfaceLayer> layer2(SurfaceLayer::Create(
- base::Bind(&SatisfyCallback, &blank_change),
+ layer_settings_, base::Bind(&SatisfyCallback, &blank_change),
base::Bind(&RequireCallback, &required_id, &required_seq)));
layer2->SetSurfaceId(SurfaceId(1), 1.f, gfx::Size(1, 1));
layer_tree_host2->set_surface_id_namespace(2);
@@ -115,36 +117,6 @@ TEST_F(SurfaceLayerTest, MultipleFramesOneSurface) {
EXPECT_EQ(2u, required_seq.size());
}
-static void CalcDrawProps(FakeLayerTreeHost* host, float device_scale_factor) {
- RenderSurfaceLayerList render_surface_layer_list;
- LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
- host->root_layer(), gfx::Size(500, 500), &render_surface_layer_list);
- inputs.device_scale_factor = device_scale_factor;
- LayerTreeHostCommon::CalculateDrawProperties(&inputs);
-}
-
-// Check that setting content scale on the surface works.
-TEST_F(SurfaceLayerTest, ScaleSurface) {
- SurfaceSequence blank_change;
- SurfaceId required_id;
- std::set<SurfaceSequence> required_seq;
- scoped_refptr<SurfaceLayer> layer(SurfaceLayer::Create(
- base::Bind(&SatisfyCallback, &blank_change),
- base::Bind(&RequireCallback, &required_id, &required_seq)));
- gfx::Size surface_size(10, 15);
- layer->SetSurfaceId(SurfaceId(1), 2.f, surface_size);
- layer->SetBounds(gfx::Size(25, 45));
- layer_tree_host_->SetRootLayer(layer);
-
- CalcDrawProps(layer_tree_host_.get(), 5.f);
- EXPECT_EQ(2.f, layer->contents_scale_x());
- EXPECT_EQ(2.f, layer->contents_scale_y());
- EXPECT_EQ(surface_size.ToString(), layer->content_bounds().ToString());
-
- layer_tree_host_->SetRootLayer(nullptr);
- layer_tree_host_.reset();
-}
-
// Check that SurfaceSequence is sent through swap promise.
class SurfaceLayerSwapPromise : public LayerTreeTest {
public:
@@ -154,7 +126,7 @@ class SurfaceLayerSwapPromise : public LayerTreeTest {
void BeginTest() override {
layer_tree_host()->set_surface_id_namespace(1);
layer_ = SurfaceLayer::Create(
- base::Bind(&SatisfyCallback, &satisfied_sequence_),
+ layer_settings(), base::Bind(&SatisfyCallback, &satisfied_sequence_),
base::Bind(&RequireCallback, &required_id_, &required_set_));
layer_->SetSurfaceId(SurfaceId(1), 1.f, gfx::Size(1, 1));
@@ -185,7 +157,7 @@ class SurfaceLayerSwapPromise : public LayerTreeTest {
switch (commit_count_) {
case 1:
// Remove SurfaceLayer from tree to cause SwapPromise to be created.
- blank_layer_ = SolidColorLayer::Create();
+ blank_layer_ = SolidColorLayer::Create(layer_settings());
blank_layer_->SetIsDrawable(true);
blank_layer_->SetBounds(gfx::Size(10, 10));
layer_tree_host()->SetRootLayer(blank_layer_);
diff --git a/chromium/cc/layers/texture_layer.cc b/chromium/cc/layers/texture_layer.cc
index cf1149b5161..20741fddad8 100644
--- a/chromium/cc/layers/texture_layer.cc
+++ b/chromium/cc/layers/texture_layer.cc
@@ -19,12 +19,14 @@
namespace cc {
scoped_refptr<TextureLayer> TextureLayer::CreateForMailbox(
+ const LayerSettings& settings,
TextureLayerClient* client) {
- return scoped_refptr<TextureLayer>(new TextureLayer(client));
+ return scoped_refptr<TextureLayer>(new TextureLayer(settings, client));
}
-TextureLayer::TextureLayer(TextureLayerClient* client)
- : Layer(),
+TextureLayer::TextureLayer(const LayerSettings& settings,
+ TextureLayerClient* client)
+ : Layer(settings),
client_(client),
flipped_(true),
nearest_neighbor_(false),
@@ -214,9 +216,8 @@ bool TextureLayer::HasDrawableContent() const {
return (client_ || holder_ref_) && Layer::HasDrawableContent();
}
-bool TextureLayer::Update(ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion) {
- bool updated = Layer::Update(queue, occlusion);
+bool TextureLayer::Update() {
+ bool updated = Layer::Update();
if (client_) {
TextureMailbox mailbox;
scoped_ptr<SingleReleaseCallback> release_callback;
@@ -266,16 +267,6 @@ void TextureLayer::PushPropertiesTo(LayerImpl* layer) {
}
}
-SimpleEnclosedRegion TextureLayer::VisibleContentOpaqueRegion() const {
- if (contents_opaque())
- return SimpleEnclosedRegion(visible_content_rect());
-
- if (blend_background_color_ && (SkColorGetA(background_color()) == 0xFF))
- return SimpleEnclosedRegion(visible_content_rect());
-
- return SimpleEnclosedRegion();
-}
-
TextureLayer::TextureMailboxHolder::MainThreadReference::MainThreadReference(
TextureMailboxHolder* holder)
: holder_(holder) {
diff --git a/chromium/cc/layers/texture_layer.h b/chromium/cc/layers/texture_layer.h
index 00c9e7452ad..53f2d8d4065 100644
--- a/chromium/cc/layers/texture_layer.h
+++ b/chromium/cc/layers/texture_layer.h
@@ -86,6 +86,7 @@ class CC_EXPORT TextureLayer : public Layer {
// Used when mailbox names are specified instead of texture IDs.
static scoped_refptr<TextureLayer> CreateForMailbox(
+ const LayerSettings& settings,
TextureLayerClient* client);
// Resets the client, which also resets the texture.
@@ -141,13 +142,11 @@ class CC_EXPORT TextureLayer : public Layer {
void SetNeedsDisplayRect(const gfx::Rect& dirty_rect) override;
void SetLayerTreeHost(LayerTreeHost* layer_tree_host) override;
- bool Update(ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion) override;
+ bool Update() override;
void PushPropertiesTo(LayerImpl* layer) override;
- SimpleEnclosedRegion VisibleContentOpaqueRegion() const override;
protected:
- explicit TextureLayer(TextureLayerClient* client);
+ TextureLayer(const LayerSettings& settings, TextureLayerClient* client);
~TextureLayer() override;
bool HasDrawableContent() const override;
diff --git a/chromium/cc/layers/texture_layer_impl.cc b/chromium/cc/layers/texture_layer_impl.cc
index 8728b89db9c..404d479721a 100644
--- a/chromium/cc/layers/texture_layer_impl.cc
+++ b/chromium/cc/layers/texture_layer_impl.cc
@@ -99,12 +99,12 @@ bool TextureLayerImpl::WillDraw(DrawMode draw_mode,
// hardware draw.
if (!texture_copy_)
texture_copy_ = ScopedResource::Create(resource_provider);
- if (texture_copy_->size() != texture_mailbox_.shared_memory_size() ||
+ if (texture_copy_->size() != texture_mailbox_.size_in_pixels() ||
resource_provider->InUseByConsumer(texture_copy_->id()))
texture_copy_->Free();
if (!texture_copy_->id()) {
- texture_copy_->Allocate(texture_mailbox_.shared_memory_size(),
+ texture_copy_->Allocate(texture_mailbox_.size_in_pixels(),
ResourceProvider::TEXTURE_HINT_IMMUTABLE,
resource_provider->best_texture_format());
}
@@ -126,12 +126,8 @@ bool TextureLayerImpl::WillDraw(DrawMode draw_mode,
pixels = &swizzled[0];
}
- resource_provider->SetPixels(
- texture_copy_->id(),
- pixels,
- gfx::Rect(texture_mailbox_.shared_memory_size()),
- gfx::Rect(texture_mailbox_.shared_memory_size()),
- gfx::Vector2d());
+ resource_provider->CopyToResource(texture_copy_->id(), pixels,
+ texture_mailbox_.size_in_pixels());
valid_texture_copy_ = true;
}
@@ -148,14 +144,14 @@ void TextureLayerImpl::AppendQuads(RenderPass* render_pass,
render_pass->CreateAndAppendSharedQuadState();
PopulateSharedQuadState(shared_quad_state);
- AppendDebugBorderQuad(
- render_pass, content_bounds(), shared_quad_state, append_quads_data);
+ AppendDebugBorderQuad(render_pass, bounds(), shared_quad_state,
+ append_quads_data);
SkColor bg_color = blend_background_color_ ?
background_color() : SK_ColorTRANSPARENT;
bool opaque = contents_opaque() || (SkColorGetA(bg_color) == 0xFF);
- gfx::Rect quad_rect(content_bounds());
+ gfx::Rect quad_rect(bounds());
gfx::Rect opaque_rect = opaque ? quad_rect : gfx::Rect();
gfx::Rect visible_quad_rect =
draw_properties().occlusion_in_content_space.GetUnoccludedContentRect(
@@ -165,7 +161,7 @@ void TextureLayerImpl::AppendQuads(RenderPass* render_pass,
TextureDrawQuad* quad =
render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
- ResourceProvider::ResourceId id =
+ ResourceId id =
valid_texture_copy_ ? texture_copy_->id() : external_texture_resource_;
quad->SetNew(shared_quad_state,
quad_rect,
@@ -179,15 +175,19 @@ void TextureLayerImpl::AppendQuads(RenderPass* render_pass,
vertex_opacity_,
flipped_,
nearest_neighbor_);
+ if (!valid_texture_copy_) {
+ quad->set_resource_size_in_pixels(texture_mailbox_.size_in_pixels());
+ quad->set_allow_overlay(texture_mailbox_.allow_overlay());
+ }
ValidateQuadResources(quad);
}
-SimpleEnclosedRegion TextureLayerImpl::VisibleContentOpaqueRegion() const {
+SimpleEnclosedRegion TextureLayerImpl::VisibleOpaqueRegion() const {
if (contents_opaque())
- return SimpleEnclosedRegion(visible_content_rect());
+ return SimpleEnclosedRegion(visible_layer_rect());
if (blend_background_color_ && (SkColorGetA(background_color()) == 0xFF))
- return SimpleEnclosedRegion(visible_content_rect());
+ return SimpleEnclosedRegion(visible_layer_rect());
return SimpleEnclosedRegion();
}
diff --git a/chromium/cc/layers/texture_layer_impl.h b/chromium/cc/layers/texture_layer_impl.h
index 56def7a0541..680aaf0aec0 100644
--- a/chromium/cc/layers/texture_layer_impl.h
+++ b/chromium/cc/layers/texture_layer_impl.h
@@ -30,7 +30,7 @@ class CC_EXPORT TextureLayerImpl : public LayerImpl {
ResourceProvider* resource_provider) override;
void AppendQuads(RenderPass* render_pass,
AppendQuadsData* append_quads_data) override;
- SimpleEnclosedRegion VisibleContentOpaqueRegion() const override;
+ SimpleEnclosedRegion VisibleOpaqueRegion() const override;
void ReleaseResources() override;
// These setter methods don't cause any implicit damage, so the texture client
@@ -59,7 +59,7 @@ class CC_EXPORT TextureLayerImpl : public LayerImpl {
const char* LayerTypeAsString() const override;
void FreeTextureMailbox();
- ResourceProvider::ResourceId external_texture_resource_;
+ ResourceId external_texture_resource_;
bool premultiplied_alpha_;
bool blend_background_color_;
bool flipped_;
diff --git a/chromium/cc/layers/texture_layer_impl_unittest.cc b/chromium/cc/layers/texture_layer_impl_unittest.cc
index cbe80e161d9..27efd971502 100644
--- a/chromium/cc/layers/texture_layer_impl_unittest.cc
+++ b/chromium/cc/layers/texture_layer_impl_unittest.cc
@@ -17,6 +17,32 @@ void IgnoreCallback(uint32 sync_point,
BlockingTaskRunner* main_thread_task_runner) {
}
+TEST(TextureLayerImplTest, VisibleOpaqueRegion) {
+ const gfx::Size layer_bounds(100, 100);
+ const gfx::Rect layer_rect(layer_bounds);
+ const Region layer_region(layer_rect);
+
+ LayerTestCommon::LayerImplTest impl;
+
+ TextureLayerImpl* layer = impl.AddChildToRoot<TextureLayerImpl>();
+ layer->SetBounds(layer_bounds);
+ layer->draw_properties().visible_layer_rect = layer_rect;
+ layer->SetBlendBackgroundColor(true);
+
+ // Verify initial conditions.
+ EXPECT_FALSE(layer->contents_opaque());
+ EXPECT_EQ(0u, layer->background_color());
+ EXPECT_EQ(Region().ToString(), layer->VisibleOpaqueRegion().ToString());
+
+ // Opaque background.
+ layer->SetBackgroundColor(SK_ColorWHITE);
+ EXPECT_EQ(layer_region.ToString(), layer->VisibleOpaqueRegion().ToString());
+
+ // Transparent background.
+ layer->SetBackgroundColor(SkColorSetARGB(100, 255, 255, 255));
+ EXPECT_EQ(Region().ToString(), layer->VisibleOpaqueRegion().ToString());
+}
+
TEST(TextureLayerImplTest, Occlusion) {
gfx::Size layer_size(1000, 1000);
gfx::Size viewport_size(1000, 1000);
@@ -31,7 +57,6 @@ TEST(TextureLayerImplTest, Occlusion) {
TextureLayerImpl* texture_layer_impl =
impl.AddChildToRoot<TextureLayerImpl>();
texture_layer_impl->SetBounds(layer_size);
- texture_layer_impl->SetContentBounds(layer_size);
texture_layer_impl->SetDrawsContent(true);
texture_layer_impl->SetTextureMailbox(
texture_mailbox,
@@ -51,7 +76,7 @@ TEST(TextureLayerImplTest, Occlusion) {
{
SCOPED_TRACE("Full occlusion");
- gfx::Rect occluded(texture_layer_impl->visible_content_rect());
+ gfx::Rect occluded(texture_layer_impl->visible_layer_rect());
impl.AppendQuadsWithOcclusion(texture_layer_impl, occluded);
LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect());
diff --git a/chromium/cc/layers/texture_layer_unittest.cc b/chromium/cc/layers/texture_layer_unittest.cc
index c33db7c3b1c..97bb7a15b20 100644
--- a/chromium/cc/layers/texture_layer_unittest.cc
+++ b/chromium/cc/layers/texture_layer_unittest.cc
@@ -54,9 +54,12 @@ gpu::Mailbox MailboxFromChar(char value) {
class MockLayerTreeHost : public LayerTreeHost {
public:
- static scoped_ptr<MockLayerTreeHost> Create(FakeLayerTreeHostClient* client) {
+ static scoped_ptr<MockLayerTreeHost> Create(
+ FakeLayerTreeHostClient* client,
+ TaskGraphRunner* task_graph_runner) {
LayerTreeHost::InitParams params;
params.client = client;
+ params.task_graph_runner = task_graph_runner;
LayerTreeSettings settings;
params.settings = &settings;
return make_scoped_ptr(new MockLayerTreeHost(client, &params));
@@ -190,7 +193,8 @@ class TextureLayerTest : public testing::Test {
protected:
void SetUp() override {
- layer_tree_host_ = MockLayerTreeHost::Create(&fake_client_);
+ layer_tree_host_ =
+ MockLayerTreeHost::Create(&fake_client_, &task_graph_runner_);
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
layer_tree_host_->SetViewportSize(gfx::Size(10, 10));
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
@@ -211,11 +215,12 @@ class TextureLayerTest : public testing::Test {
TestTaskGraphRunner task_graph_runner_;
FakeLayerTreeHostImpl host_impl_;
CommonMailboxObjects test_data_;
+ LayerSettings layer_settings_;
};
TEST_F(TextureLayerTest, CheckPropertyChangeCausesCorrectBehavior) {
scoped_refptr<TextureLayer> test_layer =
- TextureLayer::CreateForMailbox(nullptr);
+ TextureLayer::CreateForMailbox(layer_settings_, nullptr);
EXPECT_SET_NEEDS_COMMIT(1, layer_tree_host_->SetRootLayer(test_layer));
// Test properties that should call SetNeedsCommit. All properties need to
@@ -230,37 +235,10 @@ TEST_F(TextureLayerTest, CheckPropertyChangeCausesCorrectBehavior) {
EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBlendBackgroundColor(true));
}
-TEST_F(TextureLayerTest, VisibleContentOpaqueRegion) {
- const gfx::Size layer_bounds(100, 100);
- const gfx::Rect layer_rect(layer_bounds);
- const Region layer_region(layer_rect);
-
- scoped_refptr<TextureLayer> layer = TextureLayer::CreateForMailbox(nullptr);
- layer->SetBounds(layer_bounds);
- layer->draw_properties().visible_content_rect = layer_rect;
- layer->SetBlendBackgroundColor(true);
-
- // Verify initial conditions.
- EXPECT_FALSE(layer->contents_opaque());
- EXPECT_EQ(0u, layer->background_color());
- EXPECT_EQ(Region().ToString(),
- layer->VisibleContentOpaqueRegion().ToString());
-
- // Opaque background.
- layer->SetBackgroundColor(SK_ColorWHITE);
- EXPECT_EQ(layer_region.ToString(),
- layer->VisibleContentOpaqueRegion().ToString());
-
- // Transparent background.
- layer->SetBackgroundColor(SkColorSetARGB(100, 255, 255, 255));
- EXPECT_EQ(Region().ToString(),
- layer->VisibleContentOpaqueRegion().ToString());
-}
-
TEST_F(TextureLayerTest, RateLimiter) {
FakeTextureLayerClient client;
- scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(
- &client);
+ scoped_refptr<TextureLayer> test_layer =
+ TextureLayer::CreateForMailbox(layer_settings_, &client);
test_layer->SetIsDrawable(true);
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
layer_tree_host_->SetRootLayer(test_layer);
@@ -288,8 +266,7 @@ TEST_F(TextureLayerTest, RateLimiter) {
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
// Reset to a layer with a client, that started the rate limiter.
- test_layer = TextureLayer::CreateForMailbox(
- &client);
+ test_layer = TextureLayer::CreateForMailbox(layer_settings_, &client);
test_layer->SetIsDrawable(true);
test_layer->SetRateLimitContext(true);
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
@@ -329,7 +306,7 @@ class TextureLayerWithMailboxTest : public TextureLayerTest {
TEST_F(TextureLayerWithMailboxTest, ReplaceMailboxOnMainThreadBeforeCommit) {
scoped_refptr<TextureLayer> test_layer =
- TextureLayer::CreateForMailbox(nullptr);
+ TextureLayer::CreateForMailbox(layer_settings_, nullptr);
ASSERT_TRUE(test_layer.get());
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
@@ -387,7 +364,7 @@ TEST_F(TextureLayerWithMailboxTest, ReplaceMailboxOnMainThreadBeforeCommit) {
TEST_F(TextureLayerTest, SetTextureMailboxWithoutReleaseCallback) {
scoped_refptr<TextureLayer> test_layer =
- TextureLayer::CreateForMailbox(nullptr);
+ TextureLayer::CreateForMailbox(layer_settings_, nullptr);
ASSERT_TRUE(test_layer.get());
// These use the same gpu::Mailbox, but different sync points.
@@ -467,7 +444,7 @@ class TextureLayerMailboxHolderTest : public TextureLayerTest {
TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) {
scoped_refptr<TextureLayer> test_layer =
- TextureLayer::CreateForMailbox(nullptr);
+ TextureLayer::CreateForMailbox(layer_settings_, nullptr);
ASSERT_TRUE(test_layer.get());
main_thread_.message_loop()->task_runner()->PostTask(
@@ -517,7 +494,7 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) {
TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) {
scoped_refptr<TextureLayer> test_layer =
- TextureLayer::CreateForMailbox(nullptr);
+ TextureLayer::CreateForMailbox(layer_settings_, nullptr);
ASSERT_TRUE(test_layer.get());
main_thread_.message_loop()->task_runner()->PostTask(
@@ -568,7 +545,7 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) {
TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) {
scoped_refptr<TextureLayer> test_layer =
- TextureLayer::CreateForMailbox(nullptr);
+ TextureLayer::CreateForMailbox(layer_settings_, nullptr);
ASSERT_TRUE(test_layer.get());
main_thread_.message_loop()->task_runner()->PostTask(
@@ -619,7 +596,7 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) {
TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_SecondImplRefShortcut) {
scoped_refptr<TextureLayer> test_layer =
- TextureLayer::CreateForMailbox(nullptr);
+ TextureLayer::CreateForMailbox(layer_settings_, nullptr);
ASSERT_TRUE(test_layer.get());
main_thread_.message_loop()->task_runner()->PostTask(
@@ -717,10 +694,10 @@ class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
EXPECT_EQ(true, main_thread_.CalledOnValidThread());
gfx::Size bounds(100, 100);
- root_ = Layer::Create();
+ root_ = Layer::Create(layer_settings());
root_->SetBounds(bounds);
- layer_ = TextureLayer::CreateForMailbox(nullptr);
+ layer_ = TextureLayer::CreateForMailbox(layer_settings(), nullptr);
layer_->SetIsDrawable(true);
layer_->SetBounds(bounds);
@@ -761,17 +738,13 @@ class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
layer_->SetTextureMailbox(TextureMailbox(), nullptr);
break;
case 4:
- if (layer_tree_host()->settings().impl_side_painting) {
- // With impl painting, the texture mailbox will still be on the impl
- // thread when the commit finishes, because the layer is not drawble
- // when it has no texture mailbox, and thus does not block the commit
- // on activation. So, we wait for activation.
- // TODO(danakj): fix this. crbug.com/277953
- layer_tree_host()->SetNeedsCommit();
- break;
- } else {
- ++commit_count_;
- }
+ // With impl painting, the texture mailbox will still be on the impl
+ // thread when the commit finishes, because the layer is not drawble
+ // when it has no texture mailbox, and thus does not block the commit
+ // on activation. So, we wait for activation.
+ // TODO(danakj): fix this. crbug.com/277953
+ layer_tree_host()->SetNeedsCommit();
+ break;
case 5:
EXPECT_EQ(4, callback_count_);
// Restore a mailbox for the next step.
@@ -784,16 +757,12 @@ class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
layer_->RemoveFromParent();
break;
case 7:
- if (layer_tree_host()->settings().impl_side_painting) {
- // With impl painting, the texture mailbox will still be on the impl
- // thread when the commit finishes, because the layer is not around to
- // block the commit on activation anymore. So, we wait for activation.
- // TODO(danakj): fix this. crbug.com/277953
- layer_tree_host()->SetNeedsCommit();
- break;
- } else {
- ++commit_count_;
- }
+ // With impl painting, the texture mailbox will still be on the impl
+ // thread when the commit finishes, because the layer is not around to
+ // block the commit on activation anymore. So, we wait for activation.
+ // TODO(danakj): fix this. crbug.com/277953
+ layer_tree_host()->SetNeedsCommit();
+ break;
case 8:
EXPECT_EQ(4, callback_count_);
// Resetting the mailbox will call the callback now.
@@ -838,10 +807,10 @@ class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest {
void BeginTest() override {
gfx::Size bounds(100, 100);
- root_ = Layer::Create();
+ root_ = Layer::Create(layer_settings());
root_->SetBounds(bounds);
- layer_ = TextureLayer::CreateForMailbox(nullptr);
+ layer_ = TextureLayer::CreateForMailbox(layer_settings(), nullptr);
layer_->SetIsDrawable(true);
layer_->SetBounds(bounds);
@@ -918,7 +887,8 @@ class TextureLayerImplWithMailboxTest : public TextureLayerTest {
void SetUp() override {
TextureLayerTest::SetUp();
- layer_tree_host_ = MockLayerTreeHost::Create(&fake_client_);
+ layer_tree_host_ =
+ MockLayerTreeHost::Create(&fake_client_, &task_graph_runner_);
EXPECT_TRUE(host_impl_.InitializeRenderer(FakeOutputSurface::Create3d()));
}
@@ -1086,7 +1056,7 @@ TEST_F(TextureLayerImplWithMailboxTest,
TEST_F(TextureLayerImplWithMailboxTest, TestCallbackOnInUseResource) {
ResourceProvider* provider = host_impl_.active_tree()->resource_provider();
- ResourceProvider::ResourceId id = provider->CreateResourceFromTextureMailbox(
+ ResourceId id = provider->CreateResourceFromTextureMailbox(
test_data_.mailbox1_,
SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
provider->AllocateForTesting(id);
@@ -1139,11 +1109,11 @@ class TextureLayerNoExtraCommitForMailboxTest
}
void SetupTree() override {
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
root->SetBounds(gfx::Size(10, 10));
root->SetIsDrawable(true);
- texture_layer_ = TextureLayer::CreateForMailbox(this);
+ texture_layer_ = TextureLayer::CreateForMailbox(layer_settings(), this);
texture_layer_->SetBounds(gfx::Size(10, 10));
texture_layer_->SetIsDrawable(true);
root->AddChild(texture_layer_);
@@ -1234,22 +1204,22 @@ class TextureLayerChangeInvisibleMailboxTest
}
void SetupTree() override {
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
root->SetBounds(gfx::Size(10, 10));
root->SetIsDrawable(true);
- solid_layer_ = SolidColorLayer::Create();
+ solid_layer_ = SolidColorLayer::Create(layer_settings());
solid_layer_->SetBounds(gfx::Size(10, 10));
solid_layer_->SetIsDrawable(true);
solid_layer_->SetBackgroundColor(SK_ColorWHITE);
root->AddChild(solid_layer_);
- parent_layer_ = Layer::Create();
+ parent_layer_ = Layer::Create(layer_settings());
parent_layer_->SetBounds(gfx::Size(10, 10));
parent_layer_->SetIsDrawable(true);
root->AddChild(parent_layer_);
- texture_layer_ = TextureLayer::CreateForMailbox(this);
+ texture_layer_ = TextureLayer::CreateForMailbox(layer_settings(), this);
texture_layer_->SetBounds(gfx::Size(10, 10));
texture_layer_->SetIsDrawable(true);
parent_layer_->AddChild(texture_layer_);
@@ -1364,7 +1334,7 @@ class TextureLayerReleaseResourcesBase
LayerTreeTest::SetupTree();
scoped_refptr<TextureLayer> texture_layer =
- TextureLayer::CreateForMailbox(this);
+ TextureLayer::CreateForMailbox(layer_settings(), this);
texture_layer->SetBounds(gfx::Size(10, 10));
texture_layer->SetIsDrawable(true);
@@ -1428,10 +1398,10 @@ class TextureLayerWithMailboxMainThreadDeleted : public LayerTreeTest {
void SetupTree() override {
gfx::Size bounds(100, 100);
- root_ = Layer::Create();
+ root_ = Layer::Create(layer_settings());
root_->SetBounds(bounds);
- layer_ = TextureLayer::CreateForMailbox(nullptr);
+ layer_ = TextureLayer::CreateForMailbox(layer_settings(), nullptr);
layer_->SetIsDrawable(true);
layer_->SetBounds(bounds);
@@ -1497,10 +1467,10 @@ class TextureLayerWithMailboxImplThreadDeleted : public LayerTreeTest {
void SetupTree() override {
gfx::Size bounds(100, 100);
- root_ = Layer::Create();
+ root_ = Layer::Create(layer_settings());
root_->SetBounds(bounds);
- layer_ = TextureLayer::CreateForMailbox(nullptr);
+ layer_ = TextureLayer::CreateForMailbox(layer_settings(), nullptr);
layer_->SetIsDrawable(true);
layer_->SetBounds(bounds);
diff --git a/chromium/cc/layers/tiled_layer.cc b/chromium/cc/layers/tiled_layer.cc
deleted file mode 100644
index 55143befe93..00000000000
--- a/chromium/cc/layers/tiled_layer.cc
+++ /dev/null
@@ -1,869 +0,0 @@
-// Copyright 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/layers/tiled_layer.h"
-
-#include <algorithm>
-#include <vector>
-
-#include "base/auto_reset.h"
-#include "base/basictypes.h"
-#include "build/build_config.h"
-#include "cc/base/simple_enclosed_region.h"
-#include "cc/layers/layer_impl.h"
-#include "cc/layers/tiled_layer_impl.h"
-#include "cc/resources/layer_updater.h"
-#include "cc/resources/prioritized_resource.h"
-#include "cc/resources/priority_calculator.h"
-#include "cc/trees/layer_tree_host.h"
-#include "cc/trees/occlusion_tracker.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-
-namespace cc {
-
-// Maximum predictive expansion of the visible area.
-static const int kMaxPredictiveTilesCount = 2;
-
-// Number of rows/columns of tiles to pre-paint.
-// We should increase these further as all textures are
-// prioritized and we insure performance doesn't suffer.
-static const int kPrepaintRows = 4;
-static const int kPrepaintColumns = 2;
-
-class UpdatableTile : public LayerTilingData::Tile {
- public:
- static scoped_ptr<UpdatableTile> Create(
- scoped_ptr<LayerUpdater::Resource> updater_resource) {
- return make_scoped_ptr(new UpdatableTile(updater_resource.Pass()));
- }
-
- LayerUpdater::Resource* updater_resource() { return updater_resource_.get(); }
- PrioritizedResource* managed_resource() {
- return updater_resource_->texture();
- }
-
- bool is_dirty() const { return !dirty_rect.IsEmpty(); }
-
- // Reset update state for the current frame. This should occur before painting
- // for all layers. Since painting one layer can invalidate another layer after
- // it has already painted, mark all non-dirty tiles as valid before painting
- // such that invalidations during painting won't prevent them from being
- // pushed.
- void ResetUpdateState() {
- update_rect = gfx::Rect();
- occluded = false;
- partial_update = false;
- valid_for_frame = !is_dirty();
- }
-
- // This promises to update the tile and therefore also guarantees the tile
- // will be valid for this frame. dirty_rect is copied into update_rect so we
- // can continue to track re-entrant invalidations that occur during painting.
- void MarkForUpdate() {
- valid_for_frame = true;
- update_rect = dirty_rect;
- dirty_rect = gfx::Rect();
- }
-
- gfx::Rect dirty_rect;
- gfx::Rect update_rect;
- bool partial_update;
- bool valid_for_frame;
- bool occluded;
-
- private:
- explicit UpdatableTile(scoped_ptr<LayerUpdater::Resource> updater_resource)
- : partial_update(false),
- valid_for_frame(false),
- occluded(false),
- updater_resource_(updater_resource.Pass()) {}
-
- scoped_ptr<LayerUpdater::Resource> updater_resource_;
-
- DISALLOW_COPY_AND_ASSIGN(UpdatableTile);
-};
-
-TiledLayer::TiledLayer()
- : ContentsScalingLayer(),
- texture_format_(RGBA_8888),
- skips_draw_(false),
- failed_update_(false),
- tiling_option_(AUTO_TILE) {
- tiler_ =
- LayerTilingData::Create(gfx::Size(), LayerTilingData::HAS_BORDER_TEXELS);
-}
-
-TiledLayer::~TiledLayer() {}
-
-scoped_ptr<LayerImpl> TiledLayer::CreateLayerImpl(LayerTreeImpl* tree_impl) {
- return TiledLayerImpl::Create(tree_impl, id());
-}
-
-void TiledLayer::UpdateTileSizeAndTilingOption() {
- DCHECK(layer_tree_host());
-
- gfx::Size default_tile_size = layer_tree_host()->settings().default_tile_size;
- gfx::Size max_untiled_layer_size =
- layer_tree_host()->settings().max_untiled_layer_size;
- int layer_width = content_bounds().width();
- int layer_height = content_bounds().height();
-
- gfx::Size tile_size(std::min(default_tile_size.width(), layer_width),
- std::min(default_tile_size.height(), layer_height));
-
- // Tile if both dimensions large, or any one dimension large and the other
- // extends into a second tile but the total layer area isn't larger than that
- // of the largest possible untiled layer. This heuristic allows for long
- // skinny layers (e.g. scrollbars) that are Nx1 tiles to minimize wasted
- // texture space but still avoids creating very large tiles.
- bool any_dimension_large = layer_width > max_untiled_layer_size.width() ||
- layer_height > max_untiled_layer_size.height();
- bool any_dimension_one_tile =
- (layer_width <= default_tile_size.width() ||
- layer_height <= default_tile_size.height()) &&
- (layer_width * layer_height) <= (max_untiled_layer_size.width() *
- max_untiled_layer_size.height());
- bool auto_tiled = any_dimension_large && !any_dimension_one_tile;
-
- bool is_tiled;
- if (tiling_option_ == ALWAYS_TILE)
- is_tiled = true;
- else if (tiling_option_ == NEVER_TILE)
- is_tiled = false;
- else
- is_tiled = auto_tiled;
-
- gfx::Size requested_size = is_tiled ? tile_size : content_bounds();
- const int max_size =
- layer_tree_host()->GetRendererCapabilities().max_texture_size;
- requested_size.SetToMin(gfx::Size(max_size, max_size));
- SetTileSize(requested_size);
-}
-
-void TiledLayer::UpdateBounds() {
- gfx::Size old_tiling_size = tiler_->tiling_size();
- gfx::Size new_tiling_size = content_bounds();
- if (old_tiling_size == new_tiling_size)
- return;
- tiler_->SetTilingSize(new_tiling_size);
-
- // Invalidate any areas that the new bounds exposes.
- Region new_region =
- SubtractRegions(gfx::Rect(new_tiling_size), gfx::Rect(old_tiling_size));
- for (Region::Iterator new_rects(new_region); new_rects.has_rect();
- new_rects.next())
- InvalidateContentRect(new_rects.rect());
- UpdateDrawsContent(HasDrawableContent());
-}
-
-void TiledLayer::SetTileSize(const gfx::Size& size) {
- tiler_->SetTileSize(size);
- UpdateDrawsContent(HasDrawableContent());
-}
-
-void TiledLayer::SetBorderTexelOption(
- LayerTilingData::BorderTexelOption border_texel_option) {
- tiler_->SetBorderTexelOption(border_texel_option);
- UpdateDrawsContent(HasDrawableContent());
-}
-
-bool TiledLayer::HasDrawableContent() const {
- bool has_more_than_one_tile =
- (tiler_->num_tiles_x() > 1) || (tiler_->num_tiles_y() > 1);
-
- return !(tiling_option_ == NEVER_TILE && has_more_than_one_tile) &&
- ContentsScalingLayer::HasDrawableContent();
-}
-
-void TiledLayer::ReduceMemoryUsage() {
- if (Updater())
- Updater()->ReduceMemoryUsage();
-}
-
-void TiledLayer::SetIsMask(bool is_mask) {
- set_tiling_option(is_mask ? NEVER_TILE : AUTO_TILE);
-}
-
-void TiledLayer::PushPropertiesTo(LayerImpl* layer) {
- ContentsScalingLayer::PushPropertiesTo(layer);
-
- TiledLayerImpl* tiled_layer = static_cast<TiledLayerImpl*>(layer);
-
- tiled_layer->set_skips_draw(skips_draw_);
- tiled_layer->SetTilingData(*tiler_);
- std::vector<UpdatableTile*> invalid_tiles;
-
- for (LayerTilingData::TileMap::const_iterator iter = tiler_->tiles().begin();
- iter != tiler_->tiles().end();
- ++iter) {
- int i = iter->first.first;
- int j = iter->first.second;
- UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second);
- // TODO(enne): This should not ever be null.
- if (!tile)
- continue;
-
- if (!tile->managed_resource()->have_backing_texture()) {
- // Evicted tiles get deleted from both layers
- invalid_tiles.push_back(tile);
- continue;
- }
-
- if (!tile->valid_for_frame) {
- // Invalidated tiles are set so they can get different debug colors.
- tiled_layer->PushInvalidTile(i, j);
- continue;
- }
-
- tiled_layer->PushTileProperties(
- i,
- j,
- tile->managed_resource()->resource_id(),
- tile->managed_resource()->contents_swizzled());
- }
- for (std::vector<UpdatableTile*>::const_iterator iter = invalid_tiles.begin();
- iter != invalid_tiles.end();
- ++iter)
- tiler_->TakeTile((*iter)->i(), (*iter)->j());
-
- // TiledLayer must push properties every frame, since viewport state and
- // occlusion from anywhere in the tree can change what the layer decides to
- // push to the impl tree.
- needs_push_properties_ = true;
-}
-
-PrioritizedResourceManager* TiledLayer::ResourceManager() {
- if (!layer_tree_host())
- return nullptr;
- return layer_tree_host()->contents_texture_manager();
-}
-
-const PrioritizedResource* TiledLayer::ResourceAtForTesting(int i,
- int j) const {
- UpdatableTile* tile = TileAt(i, j);
- if (!tile)
- return nullptr;
- return tile->managed_resource();
-}
-
-void TiledLayer::SetLayerTreeHost(LayerTreeHost* host) {
- if (host && host != layer_tree_host()) {
- for (LayerTilingData::TileMap::const_iterator
- iter = tiler_->tiles().begin();
- iter != tiler_->tiles().end();
- ++iter) {
- UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second);
- // TODO(enne): This should not ever be null.
- if (!tile)
- continue;
- tile->managed_resource()->SetTextureManager(
- host->contents_texture_manager());
- }
- }
- ContentsScalingLayer::SetLayerTreeHost(host);
-}
-
-UpdatableTile* TiledLayer::TileAt(int i, int j) const {
- return static_cast<UpdatableTile*>(tiler_->TileAt(i, j));
-}
-
-UpdatableTile* TiledLayer::CreateTile(int i, int j) {
- CreateUpdaterIfNeeded();
-
- scoped_ptr<UpdatableTile> tile(
- UpdatableTile::Create(Updater()->CreateResource(ResourceManager())));
- tile->managed_resource()->SetDimensions(tiler_->tile_size(), texture_format_);
-
- UpdatableTile* added_tile = tile.get();
- tiler_->AddTile(tile.Pass(), i, j);
-
- added_tile->dirty_rect = tiler_->TileRect(added_tile);
-
- // Temporary diagnostic crash.
- CHECK(added_tile);
- CHECK(TileAt(i, j));
-
- return added_tile;
-}
-
-void TiledLayer::SetNeedsDisplayRect(const gfx::Rect& dirty_rect) {
- InvalidateContentRect(LayerRectToContentRect(dirty_rect));
- ContentsScalingLayer::SetNeedsDisplayRect(dirty_rect);
-}
-
-void TiledLayer::InvalidateContentRect(const gfx::Rect& content_rect) {
- UpdateBounds();
- if (tiler_->is_empty() || content_rect.IsEmpty() || skips_draw_)
- return;
-
- for (LayerTilingData::TileMap::const_iterator iter = tiler_->tiles().begin();
- iter != tiler_->tiles().end();
- ++iter) {
- UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second);
- DCHECK(tile);
- // TODO(enne): This should not ever be null.
- if (!tile)
- continue;
- gfx::Rect bound = tiler_->TileRect(tile);
- bound.Intersect(content_rect);
- tile->dirty_rect.Union(bound);
- }
-}
-
-// Returns true if tile is dirty and only part of it needs to be updated.
-bool TiledLayer::TileOnlyNeedsPartialUpdate(UpdatableTile* tile) {
- return !tile->dirty_rect.Contains(tiler_->TileRect(tile)) &&
- tile->managed_resource()->have_backing_texture();
-}
-
-bool TiledLayer::UpdateTiles(int left,
- int top,
- int right,
- int bottom,
- ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion,
- bool* updated) {
- CreateUpdaterIfNeeded();
-
- bool ignore_occlusions = !occlusion;
- if (!HaveTexturesForTiles(left, top, right, bottom, ignore_occlusions)) {
- failed_update_ = true;
- return false;
- }
-
- gfx::Rect update_rect;
- gfx::Rect paint_rect;
- MarkTilesForUpdate(
- &update_rect, &paint_rect, left, top, right, bottom, ignore_occlusions);
-
- if (paint_rect.IsEmpty())
- return true;
-
- *updated = true;
- UpdateTileTextures(
- update_rect, paint_rect, left, top, right, bottom, queue, occlusion);
- return true;
-}
-
-void TiledLayer::MarkOcclusionsAndRequestTextures(
- int left,
- int top,
- int right,
- int bottom,
- const OcclusionTracker<Layer>* occlusion) {
- int occluded_tile_count = 0;
- bool succeeded = true;
- for (int j = top; j <= bottom; ++j) {
- for (int i = left; i <= right; ++i) {
- UpdatableTile* tile = TileAt(i, j);
- DCHECK(tile); // Did SetTexturePriorities get skipped?
- // TODO(enne): This should not ever be null.
- if (!tile)
- continue;
- // Did ResetUpdateState get skipped? Are we doing more than one occlusion
- // pass?
- DCHECK(!tile->occluded);
- gfx::Rect visible_tile_rect = gfx::IntersectRects(
- tiler_->tile_bounds(i, j), visible_content_rect());
- if (!draw_transform_is_animating() && occlusion &&
- occlusion->GetCurrentOcclusionForLayer(draw_transform())
- .IsOccluded(visible_tile_rect)) {
- tile->occluded = true;
- occluded_tile_count++;
- } else {
- succeeded &= tile->managed_resource()->RequestLate();
- }
- }
- }
-}
-
-bool TiledLayer::HaveTexturesForTiles(int left,
- int top,
- int right,
- int bottom,
- bool ignore_occlusions) {
- for (int j = top; j <= bottom; ++j) {
- for (int i = left; i <= right; ++i) {
- UpdatableTile* tile = TileAt(i, j);
- DCHECK(tile); // Did SetTexturePriorites get skipped?
- // TODO(enne): This should not ever be null.
- if (!tile)
- continue;
-
- // Ensure the entire tile is dirty if we don't have the texture.
- if (!tile->managed_resource()->have_backing_texture())
- tile->dirty_rect = tiler_->TileRect(tile);
-
- // If using occlusion and the visible region of the tile is occluded,
- // don't reserve a texture or update the tile.
- if (tile->occluded && !ignore_occlusions)
- continue;
-
- if (!tile->managed_resource()->can_acquire_backing_texture())
- return false;
- }
- }
- return true;
-}
-
-void TiledLayer::MarkTilesForUpdate(gfx::Rect* update_rect,
- gfx::Rect* paint_rect,
- int left,
- int top,
- int right,
- int bottom,
- bool ignore_occlusions) {
- for (int j = top; j <= bottom; ++j) {
- for (int i = left; i <= right; ++i) {
- UpdatableTile* tile = TileAt(i, j);
- DCHECK(tile); // Did SetTexturePriorites get skipped?
- // TODO(enne): This should not ever be null.
- if (!tile)
- continue;
- if (tile->occluded && !ignore_occlusions)
- continue;
-
- // Prepare update rect from original dirty rects.
- update_rect->Union(tile->dirty_rect);
-
- // TODO(reveman): Decide if partial update should be allowed based on cost
- // of update. https://bugs.webkit.org/show_bug.cgi?id=77376
- if (tile->is_dirty() &&
- !layer_tree_host()->AlwaysUsePartialTextureUpdates()) {
- // If we get a partial update, we use the same texture, otherwise return
- // the current texture backing, so we don't update visible textures
- // non-atomically. If the current backing is in-use, it won't be
- // deleted until after the commit as the texture manager will not allow
- // deletion or recycling of in-use textures.
- if (TileOnlyNeedsPartialUpdate(tile) &&
- layer_tree_host()->RequestPartialTextureUpdate()) {
- tile->partial_update = true;
- } else {
- tile->dirty_rect = tiler_->TileRect(tile);
- tile->managed_resource()->ReturnBackingTexture();
- }
- }
-
- paint_rect->Union(tile->dirty_rect);
- tile->MarkForUpdate();
- }
- }
-}
-
-void TiledLayer::UpdateTileTextures(const gfx::Rect& update_rect,
- const gfx::Rect& paint_rect,
- int left,
- int top,
- int right,
- int bottom,
- ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion) {
- // The update_rect should be in layer space. So we have to convert the
- // paint_rect from content space to layer space.
- float width_scale = 1 / draw_properties().contents_scale_x;
- float height_scale = 1 / draw_properties().contents_scale_y;
- update_rect_ =
- gfx::ScaleToEnclosingRect(update_rect, width_scale, height_scale);
-
- // Calling PrepareToUpdate() calls into WebKit to paint, which may have the
- // side effect of disabling compositing, which causes our reference to the
- // texture updater to be deleted. However, we can't free the memory backing
- // the SkCanvas until the paint finishes, so we grab a local reference here to
- // hold the updater alive until the paint completes.
- scoped_refptr<LayerUpdater> protector(Updater());
- Updater()->PrepareToUpdate(content_bounds(),
- paint_rect,
- tiler_->tile_size(),
- 1.f / width_scale,
- 1.f / height_scale);
-
- for (int j = top; j <= bottom; ++j) {
- for (int i = left; i <= right; ++i) {
- UpdatableTile* tile = TileAt(i, j);
- DCHECK(tile); // Did SetTexturePriorites get skipped?
- // TODO(enne): This should not ever be null.
- if (!tile)
- continue;
-
- gfx::Rect tile_rect = tiler_->tile_bounds(i, j);
-
- // Use update_rect as the above loop copied the dirty rect for this frame
- // to update_rect.
- gfx::Rect dirty_rect = tile->update_rect;
- if (dirty_rect.IsEmpty())
- continue;
-
- // source_rect starts as a full-sized tile with border texels included.
- gfx::Rect source_rect = tiler_->TileRect(tile);
- source_rect.Intersect(dirty_rect);
- // Paint rect not guaranteed to line up on tile boundaries, so
- // make sure that source_rect doesn't extend outside of it.
- source_rect.Intersect(paint_rect);
-
- tile->update_rect = source_rect;
-
- if (source_rect.IsEmpty())
- continue;
-
- const gfx::Point anchor = tiler_->TileRect(tile).origin();
-
- // Calculate tile-space rectangle to upload into.
- gfx::Vector2d dest_offset = source_rect.origin() - anchor;
- CHECK_GE(dest_offset.x(), 0);
- CHECK_GE(dest_offset.y(), 0);
-
- // Offset from paint rectangle to this tile's dirty rectangle.
- gfx::Vector2d paint_offset = source_rect.origin() - paint_rect.origin();
- CHECK_GE(paint_offset.x(), 0);
- CHECK_GE(paint_offset.y(), 0);
- CHECK_LE(paint_offset.x() + source_rect.width(), paint_rect.width());
- CHECK_LE(paint_offset.y() + source_rect.height(), paint_rect.height());
-
- tile->updater_resource()->Update(
- queue, source_rect, dest_offset, tile->partial_update);
- }
- }
-}
-
-// This picks a small animated layer to be anything less than one viewport. This
-// is specifically for page transitions which are viewport-sized layers. The
-// extra tile of padding is due to these layers being slightly larger than the
-// viewport in some cases.
-bool TiledLayer::IsSmallAnimatedLayer() const {
- if (!draw_transform_is_animating() && !screen_space_transform_is_animating())
- return false;
- gfx::Size viewport_size =
- layer_tree_host() ? layer_tree_host()->device_viewport_size()
- : gfx::Size();
- gfx::Rect content_rect(content_bounds());
- return content_rect.width() <=
- viewport_size.width() + tiler_->tile_size().width() &&
- content_rect.height() <=
- viewport_size.height() + tiler_->tile_size().height();
-}
-
-namespace {
-// TODO(epenner): Remove this and make this based on distance once distance can
-// be calculated for offscreen layers. For now, prioritize all small animated
-// layers after 512 pixels of pre-painting.
-void SetPriorityForTexture(const gfx::Rect& visible_rect,
- const gfx::Rect& tile_rect,
- bool draws_to_root,
- bool is_small_animated_layer,
- PrioritizedResource* texture) {
- int priority = PriorityCalculator::LowestPriority();
- if (!visible_rect.IsEmpty()) {
- priority = PriorityCalculator::PriorityFromDistance(
- visible_rect, tile_rect, draws_to_root);
- }
-
- if (is_small_animated_layer) {
- priority = PriorityCalculator::max_priority(
- priority, PriorityCalculator::SmallAnimatedLayerMinPriority());
- }
-
- if (priority != PriorityCalculator::LowestPriority())
- texture->set_request_priority(priority);
-}
-} // namespace
-
-void TiledLayer::SetTexturePriorities(const PriorityCalculator& priority_calc) {
- UpdateBounds();
- ResetUpdateState();
- UpdateScrollPrediction();
-
- if (tiler_->has_empty_bounds())
- return;
-
- bool draws_to_root = !render_target()->parent();
- bool small_animated_layer = IsSmallAnimatedLayer();
-
- // Minimally create the tiles in the desired pre-paint rect.
- gfx::Rect create_tiles_rect = IdlePaintRect();
- if (small_animated_layer)
- create_tiles_rect = gfx::Rect(content_bounds());
- if (!create_tiles_rect.IsEmpty()) {
- int left, top, right, bottom;
- tiler_->ContentRectToTileIndices(
- create_tiles_rect, &left, &top, &right, &bottom);
- for (int j = top; j <= bottom; ++j) {
- for (int i = left; i <= right; ++i) {
- if (!TileAt(i, j))
- CreateTile(i, j);
- }
- }
- }
-
- // Now update priorities on all tiles we have in the layer, no matter where
- // they are.
- for (LayerTilingData::TileMap::const_iterator iter = tiler_->tiles().begin();
- iter != tiler_->tiles().end();
- ++iter) {
- UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second);
- // TODO(enne): This should not ever be null.
- if (!tile)
- continue;
- gfx::Rect tile_rect = tiler_->TileRect(tile);
- SetPriorityForTexture(predicted_visible_rect_,
- tile_rect,
- draws_to_root,
- small_animated_layer,
- tile->managed_resource());
- }
-}
-
-SimpleEnclosedRegion TiledLayer::VisibleContentOpaqueRegion() const {
- if (skips_draw_)
- return SimpleEnclosedRegion();
- return Layer::VisibleContentOpaqueRegion();
-}
-
-void TiledLayer::ResetUpdateState() {
- skips_draw_ = false;
- failed_update_ = false;
-
- LayerTilingData::TileMap::const_iterator end = tiler_->tiles().end();
- for (LayerTilingData::TileMap::const_iterator iter = tiler_->tiles().begin();
- iter != end;
- ++iter) {
- UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second);
- // TODO(enne): This should not ever be null.
- if (!tile)
- continue;
- tile->ResetUpdateState();
- }
-}
-
-namespace {
-gfx::Rect ExpandRectByDelta(const gfx::Rect& rect, const gfx::Vector2d& delta) {
- int width = rect.width() + std::abs(delta.x());
- int height = rect.height() + std::abs(delta.y());
- int x = rect.x() + ((delta.x() < 0) ? delta.x() : 0);
- int y = rect.y() + ((delta.y() < 0) ? delta.y() : 0);
- return gfx::Rect(x, y, width, height);
-}
-}
-
-void TiledLayer::UpdateScrollPrediction() {
- // This scroll prediction is very primitive and should be replaced by a
- // a recursive calculation on all layers which uses actual scroll/animation
- // velocities. To insure this doesn't miss-predict, we only use it to predict
- // the visible_rect if:
- // - content_bounds() hasn't changed.
- // - visible_rect.size() hasn't changed.
- // These two conditions prevent rotations, scales, pinch-zooms etc. where
- // the prediction would be incorrect.
- gfx::Vector2d delta = visible_content_rect().CenterPoint() -
- previous_visible_rect_.CenterPoint();
- predicted_scroll_ = -delta;
- predicted_visible_rect_ = visible_content_rect();
- if (previous_content_bounds_ == content_bounds() &&
- previous_visible_rect_.size() == visible_content_rect().size()) {
- // Only expand the visible rect in the major scroll direction, to prevent
- // massive paints due to diagonal scrolls.
- gfx::Vector2d major_scroll_delta =
- (std::abs(delta.x()) > std::abs(delta.y())) ?
- gfx::Vector2d(delta.x(), 0) :
- gfx::Vector2d(0, delta.y());
- predicted_visible_rect_ =
- ExpandRectByDelta(visible_content_rect(), major_scroll_delta);
-
- // Bound the prediction to prevent unbounded paints, and clamp to content
- // bounds.
- gfx::Rect bound = visible_content_rect();
- bound.Inset(-tiler_->tile_size().width() * kMaxPredictiveTilesCount,
- -tiler_->tile_size().height() * kMaxPredictiveTilesCount);
- bound.Intersect(gfx::Rect(content_bounds()));
- predicted_visible_rect_.Intersect(bound);
- }
- previous_content_bounds_ = content_bounds();
- previous_visible_rect_ = visible_content_rect();
-}
-
-bool TiledLayer::Update(ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion) {
- DCHECK(!skips_draw_ && !failed_update_); // Did ResetUpdateState get skipped?
-
- // Tiled layer always causes commits to wait for activation, as it does
- // not support pending trees.
- SetNextCommitWaitsForActivation();
-
- bool updated = false;
-
- {
- base::AutoReset<bool> ignore_set_needs_commit(&ignore_set_needs_commit_,
- true);
-
- updated |= ContentsScalingLayer::Update(queue, occlusion);
- UpdateBounds();
- }
-
- if (tiler_->has_empty_bounds() || !DrawsContent())
- return false;
-
- // Animation pre-paint. If the layer is small, try to paint it all
- // immediately whether or not it is occluded, to avoid paint/upload
- // hiccups while it is animating.
- if (IsSmallAnimatedLayer()) {
- int left, top, right, bottom;
- tiler_->ContentRectToTileIndices(gfx::Rect(content_bounds()),
- &left,
- &top,
- &right,
- &bottom);
- UpdateTiles(left, top, right, bottom, queue, nullptr, &updated);
- if (updated)
- return updated;
- // This was an attempt to paint the entire layer so if we fail it's okay,
- // just fallback on painting visible etc. below.
- failed_update_ = false;
- }
-
- if (predicted_visible_rect_.IsEmpty())
- return updated;
-
- // Visible painting. First occlude visible tiles and paint the non-occluded
- // tiles.
- int left, top, right, bottom;
- tiler_->ContentRectToTileIndices(
- predicted_visible_rect_, &left, &top, &right, &bottom);
- MarkOcclusionsAndRequestTextures(left, top, right, bottom, occlusion);
- skips_draw_ = !UpdateTiles(
- left, top, right, bottom, queue, occlusion, &updated);
- if (skips_draw_)
- tiler_->reset();
- if (skips_draw_ || updated)
- return true;
-
- // If we have already painting everything visible. Do some pre-painting while
- // idle.
- gfx::Rect idle_paint_content_rect = IdlePaintRect();
- if (idle_paint_content_rect.IsEmpty())
- return updated;
-
- // Prepaint anything that was occluded but inside the layer's visible region.
- if (!UpdateTiles(left, top, right, bottom, queue, nullptr, &updated) ||
- updated)
- return updated;
-
- int prepaint_left, prepaint_top, prepaint_right, prepaint_bottom;
- tiler_->ContentRectToTileIndices(idle_paint_content_rect,
- &prepaint_left,
- &prepaint_top,
- &prepaint_right,
- &prepaint_bottom);
-
- // Then expand outwards one row/column at a time until we find a dirty
- // row/column to update. Increment along the major and minor scroll directions
- // first.
- gfx::Vector2d delta = -predicted_scroll_;
- delta = gfx::Vector2d(delta.x() == 0 ? 1 : delta.x(),
- delta.y() == 0 ? 1 : delta.y());
- gfx::Vector2d major_delta =
- (std::abs(delta.x()) > std::abs(delta.y())) ? gfx::Vector2d(delta.x(), 0)
- : gfx::Vector2d(0, delta.y());
- gfx::Vector2d minor_delta =
- (std::abs(delta.x()) <= std::abs(delta.y())) ? gfx::Vector2d(delta.x(), 0)
- : gfx::Vector2d(0, delta.y());
- gfx::Vector2d deltas[4] = { major_delta, minor_delta, -major_delta,
- -minor_delta };
- for (int i = 0; i < 4; i++) {
- if (deltas[i].y() > 0) {
- while (bottom < prepaint_bottom) {
- ++bottom;
- if (!UpdateTiles(
- left, bottom, right, bottom, queue, nullptr, &updated) ||
- updated)
- return updated;
- }
- }
- if (deltas[i].y() < 0) {
- while (top > prepaint_top) {
- --top;
- if (!UpdateTiles(left, top, right, top, queue, nullptr, &updated) ||
- updated)
- return updated;
- }
- }
- if (deltas[i].x() < 0) {
- while (left > prepaint_left) {
- --left;
- if (!UpdateTiles(left, top, left, bottom, queue, nullptr, &updated) ||
- updated)
- return updated;
- }
- }
- if (deltas[i].x() > 0) {
- while (right < prepaint_right) {
- ++right;
- if (!UpdateTiles(right, top, right, bottom, queue, nullptr, &updated) ||
- updated)
- return updated;
- }
- }
- }
- return updated;
-}
-
-void TiledLayer::OnOutputSurfaceCreated() {
- // Ensure that all textures are of the right format.
- for (LayerTilingData::TileMap::const_iterator iter = tiler_->tiles().begin();
- iter != tiler_->tiles().end();
- ++iter) {
- UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second);
- if (!tile)
- continue;
- PrioritizedResource* resource = tile->managed_resource();
- resource->SetDimensions(resource->size(), texture_format_);
- }
-}
-
-bool TiledLayer::NeedsIdlePaint() {
- // Don't trigger more paints if we failed (as we'll just fail again).
- if (failed_update_ || visible_content_rect().IsEmpty() ||
- tiler_->has_empty_bounds() || !DrawsContent())
- return false;
-
- gfx::Rect idle_paint_content_rect = IdlePaintRect();
- if (idle_paint_content_rect.IsEmpty())
- return false;
-
- int left, top, right, bottom;
- tiler_->ContentRectToTileIndices(
- idle_paint_content_rect, &left, &top, &right, &bottom);
-
- for (int j = top; j <= bottom; ++j) {
- for (int i = left; i <= right; ++i) {
- UpdatableTile* tile = TileAt(i, j);
- DCHECK(tile); // Did SetTexturePriorities get skipped?
- if (!tile)
- continue;
-
- bool updated = !tile->update_rect.IsEmpty();
- bool can_acquire =
- tile->managed_resource()->can_acquire_backing_texture();
- bool dirty =
- tile->is_dirty() || !tile->managed_resource()->have_backing_texture();
- if (!updated && can_acquire && dirty)
- return true;
- }
- }
- return false;
-}
-
-gfx::Rect TiledLayer::IdlePaintRect() {
- // Don't inflate an empty rect.
- if (visible_content_rect().IsEmpty())
- return gfx::Rect();
-
- gfx::Rect prepaint_rect = visible_content_rect();
- prepaint_rect.Inset(-tiler_->tile_size().width() * kPrepaintColumns,
- -tiler_->tile_size().height() * kPrepaintRows);
- gfx::Rect content_rect(content_bounds());
- prepaint_rect.Intersect(content_rect);
-
- return prepaint_rect;
-}
-
-} // namespace cc
diff --git a/chromium/cc/layers/tiled_layer.h b/chromium/cc/layers/tiled_layer.h
deleted file mode 100644
index 80697607ee6..00000000000
--- a/chromium/cc/layers/tiled_layer.h
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_LAYERS_TILED_LAYER_H_
-#define CC_LAYERS_TILED_LAYER_H_
-
-#include "cc/base/cc_export.h"
-#include "cc/layers/contents_scaling_layer.h"
-#include "cc/resources/resource_format.h"
-#include "cc/tiles/layer_tiling_data.h"
-
-namespace cc {
-class LayerUpdater;
-class PrioritizedResourceManager;
-class PrioritizedResource;
-class UpdatableTile;
-
-class CC_EXPORT TiledLayer : public ContentsScalingLayer {
- public:
- enum TilingOption {
- ALWAYS_TILE,
- NEVER_TILE,
- AUTO_TILE,
- };
-
- // Layer implementation.
- void SetIsMask(bool is_mask) override;
- void PushPropertiesTo(LayerImpl* layer) override;
- void ReduceMemoryUsage() override;
- void SetNeedsDisplayRect(const gfx::Rect& dirty_rect) override;
- void SetLayerTreeHost(LayerTreeHost* layer_tree_host) override;
- void SetTexturePriorities(const PriorityCalculator& priority_calc) override;
- SimpleEnclosedRegion VisibleContentOpaqueRegion() const override;
- bool Update(ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion) override;
- void OnOutputSurfaceCreated() override;
-
- protected:
- TiledLayer();
- ~TiledLayer() override;
-
- void UpdateTileSizeAndTilingOption();
- void UpdateBounds();
-
- // Exposed to subclasses for testing.
- void SetTileSize(const gfx::Size& size);
- void SetTextureFormat(ResourceFormat texture_format) {
- texture_format_ = texture_format;
- }
- void SetBorderTexelOption(LayerTilingData::BorderTexelOption option);
- size_t NumPaintedTiles() { return tiler_->tiles().size(); }
-
- virtual LayerUpdater* Updater() const = 0;
- virtual void CreateUpdaterIfNeeded() = 0;
-
- // Set invalidations to be potentially repainted during Update().
- void InvalidateContentRect(const gfx::Rect& content_rect);
-
- // Reset state on tiles that will be used for updating the layer.
- void ResetUpdateState();
-
- // After preparing an update, returns true if more painting is needed.
- bool NeedsIdlePaint();
- gfx::Rect IdlePaintRect();
-
- bool SkipsDraw() const { return skips_draw_; }
-
- bool HasDrawableContent() const override;
-
- // Virtual for testing
- virtual PrioritizedResourceManager* ResourceManager();
- const LayerTilingData* TilerForTesting() const { return tiler_.get(); }
- const PrioritizedResource* ResourceAtForTesting(int i, int j) const;
-
- private:
- scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
-
- void CreateTilerIfNeeded();
- void set_tiling_option(TilingOption tiling_option) {
- tiling_option_ = tiling_option;
- }
-
- bool TileOnlyNeedsPartialUpdate(UpdatableTile* tile);
- bool TileNeedsBufferedUpdate(UpdatableTile* tile);
-
- void MarkOcclusionsAndRequestTextures(
- int left,
- int top,
- int right,
- int bottom,
- const OcclusionTracker<Layer>* occlusion);
-
- bool UpdateTiles(int left,
- int top,
- int right,
- int bottom,
- ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion,
- bool* did_paint);
- bool HaveTexturesForTiles(int left,
- int top,
- int right,
- int bottom,
- bool ignore_occlusions);
- void MarkTilesForUpdate(gfx::Rect* update_rect,
- gfx::Rect* paint_rect,
- int left,
- int top,
- int right,
- int bottom,
- bool ignore_occlusions);
- void UpdateTileTextures(const gfx::Rect& update_rect,
- const gfx::Rect& paint_rect,
- int left,
- int top,
- int right,
- int bottom,
- ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion);
- void UpdateScrollPrediction();
-
- UpdatableTile* TileAt(int i, int j) const;
- UpdatableTile* CreateTile(int i, int j);
-
- bool IsSmallAnimatedLayer() const;
-
- ResourceFormat texture_format_;
- bool skips_draw_;
- bool failed_update_;
-
- // Used for predictive painting.
- gfx::Vector2d predicted_scroll_;
- gfx::Rect predicted_visible_rect_;
- gfx::Rect previous_visible_rect_;
- gfx::Size previous_content_bounds_;
-
- TilingOption tiling_option_;
- scoped_ptr<LayerTilingData> tiler_;
-
- DISALLOW_COPY_AND_ASSIGN(TiledLayer);
-};
-
-} // namespace cc
-
-#endif // CC_LAYERS_TILED_LAYER_H_
diff --git a/chromium/cc/layers/tiled_layer_impl.cc b/chromium/cc/layers/tiled_layer_impl.cc
deleted file mode 100644
index 66aee5282c6..00000000000
--- a/chromium/cc/layers/tiled_layer_impl.cc
+++ /dev/null
@@ -1,324 +0,0 @@
-// Copyright 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/layers/tiled_layer_impl.h"
-
-#include "base/basictypes.h"
-#include "base/strings/stringprintf.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "cc/base/math_util.h"
-#include "cc/base/simple_enclosed_region.h"
-#include "cc/debug/debug_colors.h"
-#include "cc/layers/append_quads_data.h"
-#include "cc/quads/checkerboard_draw_quad.h"
-#include "cc/quads/debug_border_draw_quad.h"
-#include "cc/quads/solid_color_draw_quad.h"
-#include "cc/quads/tile_draw_quad.h"
-#include "cc/tiles/layer_tiling_data.h"
-#include "cc/trees/layer_tree_impl.h"
-#include "cc/trees/occlusion.h"
-#include "third_party/skia/include/core/SkColor.h"
-#include "ui/gfx/geometry/quad_f.h"
-
-namespace cc {
-
-class DrawableTile : public LayerTilingData::Tile {
- public:
- static scoped_ptr<DrawableTile> Create() {
- return make_scoped_ptr(new DrawableTile());
- }
-
- ResourceProvider::ResourceId resource_id() const { return resource_id_; }
- void set_resource_id(ResourceProvider::ResourceId resource_id) {
- resource_id_ = resource_id;
- }
- bool contents_swizzled() { return contents_swizzled_; }
- void set_contents_swizzled(bool contents_swizzled) {
- contents_swizzled_ = contents_swizzled;
- }
-
- private:
- DrawableTile() : resource_id_(0), contents_swizzled_(false) {}
-
- ResourceProvider::ResourceId resource_id_;
- bool contents_swizzled_;
-
- DISALLOW_COPY_AND_ASSIGN(DrawableTile);
-};
-
-TiledLayerImpl::TiledLayerImpl(LayerTreeImpl* tree_impl, int id)
- : TiledLayerImpl(tree_impl, id, new LayerImpl::SyncedScrollOffset) {
-}
-
-TiledLayerImpl::TiledLayerImpl(
- LayerTreeImpl* tree_impl,
- int id,
- scoped_refptr<LayerImpl::SyncedScrollOffset> synced_scroll_offset)
- : LayerImpl(tree_impl, id, synced_scroll_offset), skips_draw_(true) {
-}
-
-TiledLayerImpl::~TiledLayerImpl() {
-}
-
-void TiledLayerImpl::GetContentsResourceId(
- ResourceProvider::ResourceId* resource_id,
- gfx::Size* resource_size) const {
- // This function is only valid for single texture layers, e.g. masks.
- DCHECK(tiler_);
- // It's possible the mask layer is created but has no size or otherwise
- // can't draw.
- if (tiler_->num_tiles_x() == 0 || tiler_->num_tiles_y() == 0) {
- *resource_id = 0;
- return;
- }
-
- // Any other number of tiles other than 0 or 1 is incorrect for masks.
- DCHECK_EQ(tiler_->num_tiles_x(), 1);
- DCHECK_EQ(tiler_->num_tiles_y(), 1);
-
- DrawableTile* tile = TileAt(0, 0);
- *resource_id = tile ? tile->resource_id() : 0;
- *resource_size = tiler_->tile_size();
-}
-
-bool TiledLayerImpl::HasTileAt(int i, int j) const {
- return !!tiler_->TileAt(i, j);
-}
-
-bool TiledLayerImpl::HasResourceIdForTileAt(int i, int j) const {
- return HasTileAt(i, j) && TileAt(i, j)->resource_id();
-}
-
-DrawableTile* TiledLayerImpl::TileAt(int i, int j) const {
- return static_cast<DrawableTile*>(tiler_->TileAt(i, j));
-}
-
-DrawableTile* TiledLayerImpl::CreateTile(int i, int j) {
- scoped_ptr<DrawableTile> tile(DrawableTile::Create());
- DrawableTile* added_tile = tile.get();
- tiler_->AddTile(tile.Pass(), i, j);
-
- return added_tile;
-}
-
-void TiledLayerImpl::GetDebugBorderProperties(SkColor* color,
- float* width) const {
- *color = DebugColors::TiledContentLayerBorderColor();
- *width = DebugColors::TiledContentLayerBorderWidth(layer_tree_impl());
-}
-
-scoped_ptr<LayerImpl> TiledLayerImpl::CreateLayerImpl(
- LayerTreeImpl* tree_impl) {
- return TiledLayerImpl::Create(tree_impl, id(), synced_scroll_offset());
-}
-
-void TiledLayerImpl::AsValueInto(base::trace_event::TracedValue* state) const {
- LayerImpl::AsValueInto(state);
- MathUtil::AddToTracedValue("invalidation", update_rect(), state);
-}
-
-size_t TiledLayerImpl::GPUMemoryUsageInBytes() const {
- size_t amount = 0;
- const size_t kMemoryUsagePerTileInBytes =
- 4 * tiler_->tile_size().width() * tiler_->tile_size().height();
- for (LayerTilingData::TileMap::const_iterator iter = tiler_->tiles().begin();
- iter != tiler_->tiles().end();
- ++iter) {
- const DrawableTile* tile = static_cast<DrawableTile*>(iter->second);
- DCHECK(tile);
- if (!tile->resource_id())
- continue;
- amount += kMemoryUsagePerTileInBytes;
- }
- return amount;
-}
-
-void TiledLayerImpl::PushPropertiesTo(LayerImpl* layer) {
- LayerImpl::PushPropertiesTo(layer);
-
- TiledLayerImpl* tiled_layer = static_cast<TiledLayerImpl*>(layer);
-
- tiled_layer->set_skips_draw(skips_draw_);
- tiled_layer->SetTilingData(*tiler_);
-
- for (LayerTilingData::TileMap::const_iterator iter = tiler_->tiles().begin();
- iter != tiler_->tiles().end();
- ++iter) {
- int i = iter->first.first;
- int j = iter->first.second;
- DrawableTile* tile = static_cast<DrawableTile*>(iter->second);
- DCHECK(tile);
- tiled_layer->PushTileProperties(i,
- j,
- tile->resource_id(),
- tile->contents_swizzled());
- }
-}
-
-bool TiledLayerImpl::WillDraw(DrawMode draw_mode,
- ResourceProvider* resource_provider) {
- if (!tiler_ || tiler_->has_empty_bounds() ||
- visible_content_rect().IsEmpty() ||
- draw_mode == DRAW_MODE_RESOURCELESS_SOFTWARE)
- return false;
- return LayerImpl::WillDraw(draw_mode, resource_provider);
-}
-
-void TiledLayerImpl::AppendQuads(RenderPass* render_pass,
- AppendQuadsData* append_quads_data) {
- DCHECK(tiler_);
- DCHECK(!tiler_->has_empty_bounds());
- DCHECK(!visible_content_rect().IsEmpty());
-
- gfx::Rect content_rect = visible_content_rect();
- SharedQuadState* shared_quad_state =
- render_pass->CreateAndAppendSharedQuadState();
- PopulateSharedQuadState(shared_quad_state);
-
- AppendDebugBorderQuad(
- render_pass, content_bounds(), shared_quad_state, append_quads_data);
-
- int left, top, right, bottom;
- tiler_->ContentRectToTileIndices(content_rect, &left, &top, &right, &bottom);
-
- if (ShowDebugBorders()) {
- for (int j = top; j <= bottom; ++j) {
- for (int i = left; i <= right; ++i) {
- DrawableTile* tile = TileAt(i, j);
- gfx::Rect tile_rect = tiler_->tile_bounds(i, j);
- gfx::Rect visible_tile_rect = tile_rect;
- SkColor border_color;
- float border_width;
-
- if (skips_draw_ || !tile || !tile->resource_id()) {
- border_color = DebugColors::MissingTileBorderColor();
- border_width = DebugColors::MissingTileBorderWidth(layer_tree_impl());
- } else {
- border_color = DebugColors::HighResTileBorderColor();
- border_width = DebugColors::HighResTileBorderWidth(layer_tree_impl());
- }
- DebugBorderDrawQuad* debug_border_quad =
- render_pass->CreateAndAppendDrawQuad<DebugBorderDrawQuad>();
- debug_border_quad->SetNew(shared_quad_state,
- tile_rect,
- visible_tile_rect,
- border_color,
- border_width);
- }
- }
- }
-
- if (skips_draw_)
- return;
-
- for (int j = top; j <= bottom; ++j) {
- for (int i = left; i <= right; ++i) {
- DrawableTile* tile = TileAt(i, j);
- gfx::Rect tile_rect = tiler_->tile_bounds(i, j);
- gfx::Rect display_rect = tile_rect;
- tile_rect.Intersect(content_rect);
-
- // Skip empty tiles.
- if (tile_rect.IsEmpty())
- continue;
-
- gfx::Rect visible_tile_rect =
- draw_properties().occlusion_in_content_space.GetUnoccludedContentRect(
- tile_rect);
- if (visible_tile_rect.IsEmpty())
- continue;
-
- if (!tile || !tile->resource_id()) {
- SkColor checker_color;
- if (ShowDebugBorders()) {
- checker_color =
- tile ? DebugColors::InvalidatedTileCheckerboardColor()
- : DebugColors::EvictedTileCheckerboardColor();
- } else {
- checker_color = DebugColors::DefaultCheckerboardColor();
- }
-
- CheckerboardDrawQuad* checkerboard_quad =
- render_pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
- checkerboard_quad->SetNew(shared_quad_state, tile_rect,
- visible_tile_rect, checker_color, 1.f);
- append_quads_data->num_missing_tiles++;
- continue;
- }
-
- gfx::Rect tile_opaque_rect = contents_opaque() ? tile_rect : gfx::Rect();
-
- // Keep track of how the top left has moved, so the texture can be
- // offset the same amount.
- gfx::Vector2d display_offset = tile_rect.origin() - display_rect.origin();
- gfx::Vector2d texture_offset =
- tiler_->texture_offset(i, j) + display_offset;
- gfx::RectF tex_coord_rect = gfx::RectF(tile_rect.size()) + texture_offset;
-
- float tile_width = static_cast<float>(tiler_->tile_size().width());
- float tile_height = static_cast<float>(tiler_->tile_size().height());
- gfx::Size texture_size(tile_width, tile_height);
-
- TileDrawQuad* quad = render_pass->CreateAndAppendDrawQuad<TileDrawQuad>();
- quad->SetNew(shared_quad_state,
- tile_rect,
- tile_opaque_rect,
- visible_tile_rect,
- tile->resource_id(),
- tex_coord_rect,
- texture_size,
- tile->contents_swizzled(),
- false);
- ValidateQuadResources(quad);
- }
- }
-}
-
-void TiledLayerImpl::SetTilingData(const LayerTilingData& tiler) {
- if (tiler_) {
- tiler_->reset();
- } else {
- tiler_ = LayerTilingData::Create(tiler.tile_size(),
- tiler.has_border_texels()
- ? LayerTilingData::HAS_BORDER_TEXELS
- : LayerTilingData::NO_BORDER_TEXELS);
- }
- *tiler_ = tiler;
-}
-
-void TiledLayerImpl::PushTileProperties(
- int i,
- int j,
- ResourceProvider::ResourceId resource_id,
- bool contents_swizzled) {
- DrawableTile* tile = TileAt(i, j);
- if (!tile)
- tile = CreateTile(i, j);
- tile->set_resource_id(resource_id);
- tile->set_contents_swizzled(contents_swizzled);
-}
-
-void TiledLayerImpl::PushInvalidTile(int i, int j) {
- DrawableTile* tile = TileAt(i, j);
- if (!tile)
- tile = CreateTile(i, j);
- tile->set_resource_id(0);
- tile->set_contents_swizzled(false);
-}
-
-SimpleEnclosedRegion TiledLayerImpl::VisibleContentOpaqueRegion() const {
- if (skips_draw_)
- return SimpleEnclosedRegion();
- return LayerImpl::VisibleContentOpaqueRegion();
-}
-
-void TiledLayerImpl::ReleaseResources() {
- tiler_->reset();
-}
-
-const char* TiledLayerImpl::LayerTypeAsString() const {
- return "cc::TiledLayerImpl";
-}
-
-} // namespace cc
diff --git a/chromium/cc/layers/tiled_layer_impl.h b/chromium/cc/layers/tiled_layer_impl.h
deleted file mode 100644
index c292790d0a5..00000000000
--- a/chromium/cc/layers/tiled_layer_impl.h
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_LAYERS_TILED_LAYER_IMPL_H_
-#define CC_LAYERS_TILED_LAYER_IMPL_H_
-
-#include <string>
-
-#include "cc/base/cc_export.h"
-#include "cc/layers/layer_impl.h"
-
-namespace cc {
-
-class LayerTilingData;
-class DrawableTile;
-
-class CC_EXPORT TiledLayerImpl : public LayerImpl {
- public:
- static scoped_ptr<TiledLayerImpl> Create(LayerTreeImpl* tree_impl, int id) {
- return make_scoped_ptr(
- new TiledLayerImpl(tree_impl, id, new LayerImpl::SyncedScrollOffset));
- }
- static scoped_ptr<TiledLayerImpl> Create(
- LayerTreeImpl* tree_impl,
- int id,
- scoped_refptr<LayerImpl::SyncedScrollOffset> synced_scroll_offset) {
- return make_scoped_ptr(
- new TiledLayerImpl(tree_impl, id, synced_scroll_offset));
- }
- ~TiledLayerImpl() override;
-
- scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
- void PushPropertiesTo(LayerImpl* layer) override;
-
- bool WillDraw(DrawMode draw_mode,
- ResourceProvider* resource_provider) override;
- void AppendQuads(RenderPass* render_pass,
- AppendQuadsData* append_quads_data) override;
-
- void GetContentsResourceId(ResourceProvider::ResourceId* resource_id,
- gfx::Size* resource_size) const override;
-
- void set_skips_draw(bool skips_draw) { skips_draw_ = skips_draw; }
- void SetTilingData(const LayerTilingData& tiler);
- void PushTileProperties(int i,
- int j,
- ResourceProvider::ResourceId resource,
- bool contents_swizzled);
- void PushInvalidTile(int i, int j);
-
- SimpleEnclosedRegion VisibleContentOpaqueRegion() const override;
- void ReleaseResources() override;
-
- const LayerTilingData* TilingForTesting() const { return tiler_.get(); }
-
- size_t GPUMemoryUsageInBytes() const override;
-
- protected:
- TiledLayerImpl(LayerTreeImpl* tree_impl, int id);
- TiledLayerImpl(
- LayerTreeImpl* tree_impl,
- int id,
- scoped_refptr<LayerImpl::SyncedScrollOffset> synced_scroll_offset);
- // Exposed for testing.
- bool HasTileAt(int i, int j) const;
- bool HasResourceIdForTileAt(int i, int j) const;
-
- void GetDebugBorderProperties(SkColor* color, float* width) const override;
- void AsValueInto(base::trace_event::TracedValue* dict) const override;
-
- private:
- const char* LayerTypeAsString() const override;
-
- DrawableTile* TileAt(int i, int j) const;
- DrawableTile* CreateTile(int i, int j);
-
- bool skips_draw_;
-
- scoped_ptr<LayerTilingData> tiler_;
-
- DISALLOW_COPY_AND_ASSIGN(TiledLayerImpl);
-};
-
-} // namespace cc
-
-#endif // CC_LAYERS_TILED_LAYER_IMPL_H_
diff --git a/chromium/cc/layers/tiled_layer_impl_unittest.cc b/chromium/cc/layers/tiled_layer_impl_unittest.cc
deleted file mode 100644
index 6e662568bcd..00000000000
--- a/chromium/cc/layers/tiled_layer_impl_unittest.cc
+++ /dev/null
@@ -1,389 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/layers/tiled_layer_impl.h"
-
-#include "cc/layers/append_quads_data.h"
-#include "cc/quads/tile_draw_quad.h"
-#include "cc/test/fake_impl_proxy.h"
-#include "cc/test/fake_layer_tree_host_impl.h"
-#include "cc/test/fake_output_surface.h"
-#include "cc/test/layer_test_common.h"
-#include "cc/test/test_task_graph_runner.h"
-#include "cc/tiles/layer_tiling_data.h"
-#include "cc/trees/single_thread_proxy.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-namespace {
-
-class TiledLayerImplTest : public testing::Test {
- public:
- TiledLayerImplTest()
- : host_impl_(&proxy_, &shared_bitmap_manager_, &task_graph_runner_) {
- host_impl_.InitializeRenderer(FakeOutputSurface::Create3d());
- }
-
- scoped_ptr<TiledLayerImpl> CreateLayerNoTiles(
- const gfx::Size& tile_size,
- const gfx::Size& layer_size,
- LayerTilingData::BorderTexelOption border_texels) {
- scoped_ptr<TiledLayerImpl> layer =
- TiledLayerImpl::Create(host_impl_.active_tree(), 1);
- scoped_ptr<LayerTilingData> tiler =
- LayerTilingData::Create(tile_size, border_texels);
- tiler->SetTilingSize(layer_size);
- layer->SetTilingData(*tiler);
- layer->set_skips_draw(false);
- layer->draw_properties().visible_content_rect =
- gfx::Rect(layer_size);
- layer->draw_properties().opacity = 1;
- layer->SetBounds(layer_size);
- layer->SetContentBounds(layer_size);
- layer->SetHasRenderSurface(true);
- layer->draw_properties().render_target = layer.get();
- return layer.Pass();
- }
-
- // Create a default tiled layer with textures for all tiles and a default
- // visibility of the entire layer size.
- scoped_ptr<TiledLayerImpl> CreateLayer(
- const gfx::Size& tile_size,
- const gfx::Size& layer_size,
- LayerTilingData::BorderTexelOption border_texels) {
- scoped_ptr<TiledLayerImpl> layer =
- CreateLayerNoTiles(tile_size, layer_size, border_texels);
-
- for (int i = 0; i < layer->TilingForTesting()->num_tiles_x(); ++i) {
- for (int j = 0; j < layer->TilingForTesting()->num_tiles_y(); ++j) {
- ResourceProvider::ResourceId resource_id =
- host_impl_.resource_provider()->CreateResource(
- gfx::Size(1, 1), GL_CLAMP_TO_EDGE,
- ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888);
- layer->PushTileProperties(i, j, resource_id, false);
- }
- }
-
- return layer.Pass();
- }
-
- void GetQuads(RenderPass* render_pass,
- const gfx::Size& tile_size,
- const gfx::Size& layer_size,
- LayerTilingData::BorderTexelOption border_texel_option,
- const gfx::Rect& visible_content_rect) {
- scoped_ptr<TiledLayerImpl> layer =
- CreateLayer(tile_size, layer_size, border_texel_option);
- layer->draw_properties().visible_content_rect = visible_content_rect;
- layer->SetBounds(layer_size);
-
- AppendQuadsData data;
- layer->AppendQuads(render_pass, &data);
- }
-
- protected:
- FakeImplProxy proxy_;
- TestSharedBitmapManager shared_bitmap_manager_;
- TestTaskGraphRunner task_graph_runner_;
- FakeLayerTreeHostImpl host_impl_;
-};
-
-TEST_F(TiledLayerImplTest, EmptyQuadList) {
- gfx::Size tile_size(90, 90);
- int num_tiles_x = 8;
- int num_tiles_y = 4;
- gfx::Size layer_size(tile_size.width() * num_tiles_x,
- tile_size.height() * num_tiles_y);
-
- // Verify default layer does creates quads
- {
- scoped_ptr<TiledLayerImpl> layer =
- CreateLayer(tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS);
- scoped_ptr<RenderPass> render_pass = RenderPass::Create();
-
- AppendQuadsData data;
- EXPECT_TRUE(layer->WillDraw(DRAW_MODE_HARDWARE, nullptr));
- layer->AppendQuads(render_pass.get(), &data);
- layer->DidDraw(nullptr);
- unsigned num_tiles = num_tiles_x * num_tiles_y;
- EXPECT_EQ(render_pass->quad_list.size(), num_tiles);
- }
-
- // Layer with empty visible layer rect produces no quads
- {
- scoped_ptr<TiledLayerImpl> layer =
- CreateLayer(tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS);
- layer->draw_properties().visible_content_rect = gfx::Rect();
-
- scoped_ptr<RenderPass> render_pass = RenderPass::Create();
-
- EXPECT_FALSE(layer->WillDraw(DRAW_MODE_HARDWARE, nullptr));
- }
-
- // Layer with non-intersecting visible layer rect produces no quads
- {
- scoped_ptr<TiledLayerImpl> layer =
- CreateLayer(tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS);
-
- gfx::Rect outside_bounds(-100, -100, 50, 50);
- layer->draw_properties().visible_content_rect = outside_bounds;
-
- scoped_ptr<RenderPass> render_pass = RenderPass::Create();
-
- AppendQuadsData data;
- EXPECT_TRUE(layer->WillDraw(DRAW_MODE_HARDWARE, nullptr));
- layer->AppendQuads(render_pass.get(), &data);
- layer->DidDraw(nullptr);
- EXPECT_EQ(render_pass->quad_list.size(), 0u);
- }
-
- // Layer with skips draw produces no quads
- {
- scoped_ptr<TiledLayerImpl> layer =
- CreateLayer(tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS);
- layer->set_skips_draw(true);
-
- scoped_ptr<RenderPass> render_pass = RenderPass::Create();
-
- AppendQuadsData data;
- layer->AppendQuads(render_pass.get(), &data);
- EXPECT_EQ(render_pass->quad_list.size(), 0u);
- }
-}
-
-TEST_F(TiledLayerImplTest, Checkerboarding) {
- gfx::Size tile_size(10, 10);
- int num_tiles_x = 2;
- int num_tiles_y = 2;
- gfx::Size layer_size(tile_size.width() * num_tiles_x,
- tile_size.height() * num_tiles_y);
-
- scoped_ptr<TiledLayerImpl> layer =
- CreateLayer(tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS);
-
- // No checkerboarding
- {
- scoped_ptr<RenderPass> render_pass = RenderPass::Create();
-
- AppendQuadsData data;
- layer->AppendQuads(render_pass.get(), &data);
- EXPECT_EQ(render_pass->quad_list.size(), 4u);
- EXPECT_EQ(0u, data.num_missing_tiles);
-
- for (const auto& quad : render_pass->quad_list)
- EXPECT_EQ(quad->material, DrawQuad::TILED_CONTENT);
- }
-
- for (int i = 0; i < num_tiles_x; ++i)
- for (int j = 0; j < num_tiles_y; ++j)
- layer->PushTileProperties(i, j, 0, false);
-
- // All checkerboarding
- {
- scoped_ptr<RenderPass> render_pass = RenderPass::Create();
-
- AppendQuadsData data;
- layer->AppendQuads(render_pass.get(), &data);
- EXPECT_LT(0u, data.num_missing_tiles);
- EXPECT_EQ(render_pass->quad_list.size(), 4u);
- for (const auto& quad : render_pass->quad_list)
- EXPECT_NE(quad->material, DrawQuad::TILED_CONTENT);
- }
-}
-
-// Test with both border texels and without.
-#define WITH_AND_WITHOUT_BORDER_TEST(text_fixture_name) \
- TEST_F(TiledLayerImplBorderTest, text_fixture_name##NoBorders) { \
- text_fixture_name(LayerTilingData::NO_BORDER_TEXELS); \
- } \
- TEST_F(TiledLayerImplBorderTest, text_fixture_name##HasBorders) { \
- text_fixture_name(LayerTilingData::HAS_BORDER_TEXELS); \
- }
-
-class TiledLayerImplBorderTest : public TiledLayerImplTest {
- public:
- void CoverageVisibleRectOnTileBoundaries(
- LayerTilingData::BorderTexelOption borders) {
- gfx::Size layer_size(1000, 1000);
- scoped_ptr<RenderPass> render_pass = RenderPass::Create();
- GetQuads(render_pass.get(),
- gfx::Size(100, 100),
- layer_size,
- borders,
- gfx::Rect(layer_size));
- LayerTestCommon::VerifyQuadsExactlyCoverRect(render_pass->quad_list,
- gfx::Rect(layer_size));
- }
-
- void CoverageVisibleRectIntersectsTiles(
- LayerTilingData::BorderTexelOption borders) {
- // This rect intersects the middle 3x3 of the 5x5 tiles.
- gfx::Point top_left(65, 73);
- gfx::Point bottom_right(182, 198);
- gfx::Rect visible_content_rect = gfx::BoundingRect(top_left, bottom_right);
-
- gfx::Size layer_size(250, 250);
- scoped_ptr<RenderPass> render_pass = RenderPass::Create();
- GetQuads(render_pass.get(),
- gfx::Size(50, 50),
- gfx::Size(250, 250),
- LayerTilingData::NO_BORDER_TEXELS,
- visible_content_rect);
- LayerTestCommon::VerifyQuadsExactlyCoverRect(render_pass->quad_list,
- visible_content_rect);
- }
-
- void CoverageVisibleRectIntersectsBounds(
- LayerTilingData::BorderTexelOption borders) {
- gfx::Size layer_size(220, 210);
- gfx::Rect visible_content_rect(layer_size);
- scoped_ptr<RenderPass> render_pass = RenderPass::Create();
- GetQuads(render_pass.get(),
- gfx::Size(100, 100),
- layer_size,
- LayerTilingData::NO_BORDER_TEXELS,
- visible_content_rect);
- LayerTestCommon::VerifyQuadsExactlyCoverRect(render_pass->quad_list,
- visible_content_rect);
- }
-};
-WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectOnTileBoundaries);
-
-WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectIntersectsTiles);
-
-WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectIntersectsBounds);
-
-TEST_F(TiledLayerImplTest, TextureInfoForLayerNoBorders) {
- gfx::Size tile_size(50, 50);
- gfx::Size layer_size(250, 250);
- scoped_ptr<RenderPass> render_pass = RenderPass::Create();
- GetQuads(render_pass.get(),
- tile_size,
- layer_size,
- LayerTilingData::NO_BORDER_TEXELS,
- gfx::Rect(layer_size));
-
- for (auto iter = render_pass->quad_list.cbegin();
- iter != render_pass->quad_list.cend();
- ++iter) {
- const TileDrawQuad* quad = TileDrawQuad::MaterialCast(*iter);
-
- EXPECT_NE(0u, quad->resource_id) << LayerTestCommon::quad_string
- << iter.index();
- EXPECT_EQ(gfx::RectF(gfx::PointF(), tile_size), quad->tex_coord_rect)
- << LayerTestCommon::quad_string << iter.index();
- EXPECT_EQ(tile_size, quad->texture_size) << LayerTestCommon::quad_string
- << iter.index();
- }
-}
-
-TEST_F(TiledLayerImplTest, GPUMemoryUsage) {
- gfx::Size tile_size(20, 30);
- int num_tiles_x = 12;
- int num_tiles_y = 32;
- gfx::Size layer_size(tile_size.width() * num_tiles_x,
- tile_size.height() * num_tiles_y);
-
- scoped_ptr<TiledLayerImpl> layer = CreateLayerNoTiles(
- tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS);
-
- EXPECT_EQ(layer->GPUMemoryUsageInBytes(), 0u);
-
- ResourceProvider::ResourceId resource_id = 1;
- layer->PushTileProperties(0, 1, resource_id++, false);
- layer->PushTileProperties(2, 3, resource_id++, false);
- layer->PushTileProperties(2, 0, resource_id++, false);
-
- EXPECT_EQ(
- layer->GPUMemoryUsageInBytes(),
- static_cast<size_t>(3 * 4 * tile_size.width() * tile_size.height()));
-
- ResourceProvider::ResourceId empty_resource(0);
- layer->PushTileProperties(0, 1, empty_resource, false);
- layer->PushTileProperties(2, 3, empty_resource, false);
- layer->PushTileProperties(2, 0, empty_resource, false);
-
- EXPECT_EQ(layer->GPUMemoryUsageInBytes(), 0u);
-}
-
-TEST_F(TiledLayerImplTest, EmptyMask) {
- gfx::Size tile_size(20, 20);
- gfx::Size layer_size(0, 0);
- scoped_ptr<TiledLayerImpl> layer =
- CreateLayer(tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS);
-
- ResourceProvider::ResourceId mask_resource_id;
- gfx::Size mask_texture_size;
- layer->GetContentsResourceId(&mask_resource_id, &mask_texture_size);
- EXPECT_EQ(0u, mask_resource_id);
- EXPECT_EQ(0, layer->TilingForTesting()->num_tiles_x());
- EXPECT_EQ(0, layer->TilingForTesting()->num_tiles_y());
-}
-
-TEST_F(TiledLayerImplTest, Occlusion) {
- gfx::Size tile_size(100, 100);
- gfx::Size layer_bounds(1000, 1000);
- gfx::Size viewport_size(1000, 1000);
-
- LayerTestCommon::LayerImplTest impl;
-
- TiledLayerImpl* tiled_layer = impl.AddChildToRoot<TiledLayerImpl>();
- tiled_layer->SetBounds(layer_bounds);
- tiled_layer->SetContentBounds(layer_bounds);
- tiled_layer->SetDrawsContent(true);
- tiled_layer->set_skips_draw(false);
-
- scoped_ptr<LayerTilingData> tiler =
- LayerTilingData::Create(tile_size, LayerTilingData::NO_BORDER_TEXELS);
- tiler->SetTilingSize(layer_bounds);
- tiled_layer->SetTilingData(*tiler);
-
- for (int i = 0; i < tiled_layer->TilingForTesting()->num_tiles_x(); ++i) {
- for (int j = 0; j < tiled_layer->TilingForTesting()->num_tiles_y(); ++j) {
- ResourceProvider::ResourceId resource_id =
- impl.resource_provider()->CreateResource(
- gfx::Size(1, 1), GL_CLAMP_TO_EDGE,
- ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888);
- tiled_layer->PushTileProperties(i, j, resource_id, false);
- }
- }
-
- impl.CalcDrawProps(viewport_size);
-
- {
- SCOPED_TRACE("No occlusion");
- gfx::Rect occluded;
- impl.AppendQuadsWithOcclusion(tiled_layer, occluded);
-
- LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(),
- gfx::Rect(layer_bounds));
- EXPECT_EQ(100u, impl.quad_list().size());
- }
-
- {
- SCOPED_TRACE("Full occlusion");
- gfx::Rect occluded(tiled_layer->visible_content_rect());
- impl.AppendQuadsWithOcclusion(tiled_layer, occluded);
-
- LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect());
- EXPECT_EQ(impl.quad_list().size(), 0u);
- }
-
- {
- SCOPED_TRACE("Partial occlusion");
- gfx::Rect occluded(150, 0, 200, 1000);
- impl.AppendQuadsWithOcclusion(tiled_layer, occluded);
-
- size_t partially_occluded_count = 0;
- LayerTestCommon::VerifyQuadsAreOccluded(
- impl.quad_list(), occluded, &partially_occluded_count);
- // The layer outputs one quad, which is partially occluded.
- EXPECT_EQ(100u - 10u, impl.quad_list().size());
- EXPECT_EQ(10u + 10u, partially_occluded_count);
- }
-}
-
-} // namespace
-} // namespace cc
diff --git a/chromium/cc/layers/tiled_layer_unittest.cc b/chromium/cc/layers/tiled_layer_unittest.cc
deleted file mode 100644
index 7dbab998d1d..00000000000
--- a/chromium/cc/layers/tiled_layer_unittest.cc
+++ /dev/null
@@ -1,1762 +0,0 @@
-// Copyright 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/layers/tiled_layer.h"
-
-#include <limits>
-#include <vector>
-
-#include "base/location.h"
-#include "base/run_loop.h"
-#include "base/single_thread_task_runner.h"
-#include "base/thread_task_runner_handle.h"
-#include "cc/resources/bitmap_content_layer_updater.h"
-#include "cc/resources/layer_painter.h"
-#include "cc/resources/prioritized_resource_manager.h"
-#include "cc/resources/resource_update_controller.h"
-#include "cc/test/animation_test_common.h"
-#include "cc/test/fake_layer_tree_host_client.h"
-#include "cc/test/fake_layer_tree_host_impl.h"
-#include "cc/test/fake_output_surface.h"
-#include "cc/test/fake_output_surface_client.h"
-#include "cc/test/fake_proxy.h"
-#include "cc/test/geometry_test_utils.h"
-#include "cc/test/test_shared_bitmap_manager.h"
-#include "cc/test/tiled_layer_test_common.h"
-#include "cc/trees/occlusion_tracker.h"
-#include "cc/trees/single_thread_proxy.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-#include "ui/gfx/transform.h"
-
-namespace cc {
-namespace {
-
-class TestOcclusionTracker : public OcclusionTracker<Layer> {
- public:
- TestOcclusionTracker() : OcclusionTracker(gfx::Rect(0, 0, 1000, 1000)) {
- stack_.push_back(StackObject());
- }
-
- void SetRenderTarget(Layer* render_target) {
- stack_.back().target = render_target;
- }
-
- void SetOcclusion(const SimpleEnclosedRegion& occlusion) {
- stack_.back().occlusion_from_inside_target = occlusion;
- }
-};
-
-class SynchronousOutputSurfaceClient : public FakeLayerTreeHostClient {
- public:
- SynchronousOutputSurfaceClient()
- : FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D) {}
-
- bool EnsureOutputSurfaceCreated() {
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, run_loop_.QuitClosure(), base::TimeDelta::FromSeconds(5));
- run_loop_.Run();
- return output_surface_created_;
- }
-
- void DidInitializeOutputSurface() override {
- FakeLayerTreeHostClient::DidInitializeOutputSurface();
- output_surface_created_ = true;
- run_loop_.Quit();
- }
-
- void DidFailToInitializeOutputSurface() override {
- FakeLayerTreeHostClient::DidFailToInitializeOutputSurface();
- output_surface_created_ = false;
- run_loop_.Quit();
- }
-
- private:
- bool output_surface_created_;
- base::RunLoop run_loop_;
-};
-
-class TiledLayerTest : public testing::Test {
- public:
- TiledLayerTest()
- : proxy_(nullptr),
- output_surface_(FakeOutputSurface::Create3d()),
- queue_(make_scoped_ptr(new ResourceUpdateQueue)),
- impl_thread_("ImplThread"),
- occlusion_(nullptr) {
- settings_.max_partial_texture_updates = std::numeric_limits<size_t>::max();
- settings_.layer_transforms_should_scale_layer_contents = true;
- settings_.impl_side_painting = false;
- settings_.verify_property_trees = false;
- }
-
- void SetUp() override {
- impl_thread_.Start();
- shared_bitmap_manager_.reset(new TestSharedBitmapManager());
- LayerTreeHost::InitParams params;
- params.client = &synchronous_output_surface_client_;
- params.shared_bitmap_manager = shared_bitmap_manager_.get();
- params.settings = &settings_;
- params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
-
- layer_tree_host_ =
- LayerTreeHost::CreateThreaded(impl_thread_.task_runner(), &params);
- synchronous_output_surface_client_.SetLayerTreeHost(layer_tree_host_.get());
- proxy_ = layer_tree_host_->proxy();
- resource_manager_ = PrioritizedResourceManager::Create(proxy_);
- layer_tree_host_->SetLayerTreeHostClientReady();
- CHECK(synchronous_output_surface_client_.EnsureOutputSurfaceCreated());
-
- layer_tree_host_->SetRootLayer(Layer::Create());
-
- CHECK(output_surface_->BindToClient(&output_surface_client_));
-
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(proxy_);
- resource_provider_ = ResourceProvider::Create(output_surface_.get(),
- shared_bitmap_manager_.get(),
- nullptr,
- nullptr,
- 0,
- false,
- 1);
- host_impl_ = make_scoped_ptr(new FakeLayerTreeHostImpl(
- proxy_, shared_bitmap_manager_.get(), nullptr));
- }
-
- ~TiledLayerTest() override {
- ResourceManagerClearAllMemory(resource_manager_.get(),
- resource_provider_.get());
-
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(proxy_);
- resource_provider_ = nullptr;
- host_impl_ = nullptr;
- }
-
- void ResourceManagerClearAllMemory(
- PrioritizedResourceManager* resource_manager,
- ResourceProvider* resource_provider) {
- {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(proxy_);
- resource_manager->ClearAllMemory(resource_provider);
- resource_manager->ReduceMemory(resource_provider);
- }
- resource_manager->UnlinkAndClearEvictedBackings();
- }
-
- void UpdateTextures() {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(proxy_);
- DCHECK(queue_);
- scoped_ptr<ResourceUpdateController> update_controller =
- ResourceUpdateController::Create(nullptr,
- proxy_->ImplThreadTaskRunner(),
- queue_.Pass(),
- resource_provider_.get());
- update_controller->Finalize();
- queue_ = make_scoped_ptr(new ResourceUpdateQueue);
- }
-
- void LayerPushPropertiesTo(FakeTiledLayer* layer,
- FakeTiledLayerImpl* layer_impl) {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(proxy_);
- layer->PushPropertiesTo(layer_impl);
- layer->ResetNumDependentsNeedPushProperties();
- }
-
- void LayerUpdate(FakeTiledLayer* layer, TestOcclusionTracker* occluded) {
- DebugScopedSetMainThread main_thread(proxy_);
- layer->Update(queue_.get(), occluded);
- }
-
- void CalcDrawProps(RenderSurfaceLayerList* render_surface_layer_list) {
- if (occlusion_)
- occlusion_->SetRenderTarget(layer_tree_host_->root_layer());
-
- LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
- layer_tree_host_->root_layer(),
- layer_tree_host_->device_viewport_size(),
- render_surface_layer_list);
- inputs.device_scale_factor = layer_tree_host_->device_scale_factor();
- inputs.max_texture_size =
- layer_tree_host_->GetRendererCapabilities().max_texture_size;
- inputs.can_adjust_raster_scales = true;
- inputs.verify_property_trees = false;
- LayerTreeHostCommon::CalculateDrawProperties(&inputs);
- }
-
- bool UpdateAndPush(const scoped_refptr<FakeTiledLayer>& layer1,
- const scoped_ptr<FakeTiledLayerImpl>& layer_impl1) {
- scoped_refptr<FakeTiledLayer> layer2;
- scoped_ptr<FakeTiledLayerImpl> layer_impl2;
- return UpdateAndPush(layer1, layer_impl1, layer2, layer_impl2);
- }
-
- bool UpdateAndPush(const scoped_refptr<FakeTiledLayer>& layer1,
- const scoped_ptr<FakeTiledLayerImpl>& layer_impl1,
- const scoped_refptr<FakeTiledLayer>& layer2,
- const scoped_ptr<FakeTiledLayerImpl>& layer_impl2) {
- // Get textures
- resource_manager_->ClearPriorities();
- if (layer1.get())
- layer1->SetTexturePriorities(priority_calculator_);
- if (layer2.get())
- layer2->SetTexturePriorities(priority_calculator_);
- resource_manager_->PrioritizeTextures();
-
- // Save paint properties
- if (layer1.get())
- layer1->SavePaintProperties();
- if (layer2.get())
- layer2->SavePaintProperties();
-
- // Update content
- if (layer1.get())
- layer1->Update(queue_.get(), occlusion_);
- if (layer2.get())
- layer2->Update(queue_.get(), occlusion_);
-
- bool needs_update = false;
- if (layer1.get())
- needs_update |= layer1->NeedsIdlePaint();
- if (layer2.get())
- needs_update |= layer2->NeedsIdlePaint();
-
- // Update textures and push.
- UpdateTextures();
- if (layer1.get())
- LayerPushPropertiesTo(layer1.get(), layer_impl1.get());
- if (layer2.get())
- LayerPushPropertiesTo(layer2.get(), layer_impl2.get());
-
- return needs_update;
- }
-
- public:
- Proxy* proxy_;
- LayerTreeSettings settings_;
- FakeOutputSurfaceClient output_surface_client_;
- scoped_ptr<OutputSurface> output_surface_;
- scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
- scoped_ptr<ResourceProvider> resource_provider_;
- scoped_ptr<ResourceUpdateQueue> queue_;
- PriorityCalculator priority_calculator_;
- base::Thread impl_thread_;
- SynchronousOutputSurfaceClient synchronous_output_surface_client_;
- scoped_ptr<LayerTreeHost> layer_tree_host_;
- scoped_ptr<FakeLayerTreeHostImpl> host_impl_;
- scoped_ptr<PrioritizedResourceManager> resource_manager_;
- TestOcclusionTracker* occlusion_;
-};
-
-TEST_F(TiledLayerTest, PushDirtyTiles) {
- layer_tree_host_->SetViewportSize(gfx::Size(1000, 1000));
-
- scoped_refptr<FakeTiledLayer> layer =
- make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
- scoped_ptr<FakeTiledLayerImpl> layer_impl =
- make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
- RenderSurfaceLayerList render_surface_layer_list;
-
- layer_tree_host_->root_layer()->AddChild(layer);
-
- // The tile size is 100x100, so this invalidates and then paints two tiles.
- layer->SetBounds(gfx::Size(100, 200));
- CalcDrawProps(&render_surface_layer_list);
- UpdateAndPush(layer, layer_impl);
-
- // We should have both tiles on the impl side.
- EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
- EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
-
- // Invalidates both tiles, but then only update one of them.
- layer->InvalidateContentRect(gfx::Rect(0, 0, 100, 200));
- layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
- UpdateAndPush(layer, layer_impl);
-
- // We should only have the first tile since the other tile was invalidated but
- // not painted.
- EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
- EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
-}
-
-TEST_F(TiledLayerTest, Scale) {
- layer_tree_host_->SetViewportSize(gfx::Size(1000, 1000));
-
- layer_tree_host_->SetDeviceScaleFactor(1.5);
-
- scoped_refptr<FakeTiledLayer> layer =
- make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
- scoped_ptr<FakeTiledLayerImpl> layer_impl =
- make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
- RenderSurfaceLayerList render_surface_layer_list;
-
- layer_tree_host_->root_layer()->AddChild(layer);
-
- layer->SetBounds(gfx::Size(100, 200));
- CalcDrawProps(&render_surface_layer_list);
-
- // Change the width so that it doesn't divide cleanly by the scale.
- layer->SetBounds(gfx::Size(101, 200));
- UpdateAndPush(layer, layer_impl);
-
- EXPECT_EQ(1.5, layer->fake_layer_updater()->last_contents_width_scale());
-}
-
-TEST_F(TiledLayerTest, PushOccludedDirtyTiles) {
- scoped_refptr<FakeTiledLayer> layer =
- make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
- scoped_ptr<FakeTiledLayerImpl> layer_impl =
- make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
- TestOcclusionTracker occluded;
- occlusion_ = &occluded;
- layer_tree_host_->SetViewportSize(gfx::Size(1000, 1000));
-
- layer_tree_host_->root_layer()->AddChild(layer);
-
- {
- RenderSurfaceLayerList render_surface_layer_list;
-
- // The tile size is 100x100, so this invalidates and then paints two tiles.
- layer->SetBounds(gfx::Size(100, 200));
- CalcDrawProps(&render_surface_layer_list);
- UpdateAndPush(layer, layer_impl);
-
- // We should have both tiles on the impl side.
- EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
- EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
- }
-
- {
- RenderSurfaceLayerList render_surface_layer_list;
-
- // Invalidates part of the top tile...
- layer->InvalidateContentRect(gfx::Rect(0, 0, 50, 50));
- // ....but the area is occluded.
- occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(0, 0, 50, 50)));
- CalcDrawProps(&render_surface_layer_list);
- UpdateAndPush(layer, layer_impl);
-
- // We should still have both tiles, as part of the top tile is still
- // unoccluded.
- EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
- EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
- }
-}
-
-TEST_F(TiledLayerTest, PushDeletedTiles) {
- layer_tree_host_->SetViewportSize(gfx::Size(1000, 1000));
-
- scoped_refptr<FakeTiledLayer> layer =
- make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
- scoped_ptr<FakeTiledLayerImpl> layer_impl =
- make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
- RenderSurfaceLayerList render_surface_layer_list;
-
- layer_tree_host_->root_layer()->AddChild(layer);
-
- // The tile size is 100x100, so this invalidates and then paints two tiles.
- layer->SetBounds(gfx::Size(100, 200));
- CalcDrawProps(&render_surface_layer_list);
- UpdateAndPush(layer, layer_impl);
-
- // We should have both tiles on the impl side.
- EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
- EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
-
- resource_manager_->ClearPriorities();
- ResourceManagerClearAllMemory(resource_manager_.get(),
- resource_provider_.get());
- resource_manager_->SetMaxMemoryLimitBytes(4 * 1024 * 1024);
-
- // This should drop the tiles on the impl thread.
- LayerPushPropertiesTo(layer.get(), layer_impl.get());
-
- // We should now have no textures on the impl thread.
- EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 0));
- EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
-
- // This should recreate and update one of the deleted textures.
- layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
- UpdateAndPush(layer, layer_impl);
-
- // We should have one tiles on the impl side.
- EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
- EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
-}
-
-TEST_F(TiledLayerTest, PushIdlePaintTiles) {
- scoped_refptr<FakeTiledLayer> layer =
- make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
- scoped_ptr<FakeTiledLayerImpl> layer_impl =
- make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
- RenderSurfaceLayerList render_surface_layer_list;
-
- layer_tree_host_->root_layer()->AddChild(layer);
-
- // The tile size is 100x100. Setup 5x5 tiles with one visible tile in the
- // center. This paints 1 visible of the 25 invalid tiles.
- layer->SetBounds(gfx::Size(500, 500));
- CalcDrawProps(&render_surface_layer_list);
- layer->draw_properties().visible_content_rect = gfx::Rect(200, 200, 100, 100);
- bool needs_update = UpdateAndPush(layer, layer_impl);
- // We should need idle-painting for surrounding tiles.
- EXPECT_TRUE(needs_update);
-
- // We should have one tile on the impl side.
- EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(2, 2));
-
- // For the next four updates, we should detect we still need idle painting.
- for (int i = 0; i < 4; i++) {
- needs_update = UpdateAndPush(layer, layer_impl);
- EXPECT_TRUE(needs_update);
- }
-
- // We should always finish painting eventually.
- for (int i = 0; i < 20; i++)
- needs_update = UpdateAndPush(layer, layer_impl);
-
- // We should have pre-painted all of the surrounding tiles.
- for (int i = 0; i < 5; i++) {
- for (int j = 0; j < 5; j++)
- EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(i, j));
- }
-
- EXPECT_FALSE(needs_update);
-}
-
-TEST_F(TiledLayerTest, PredictivePainting) {
- scoped_refptr<FakeTiledLayer> layer =
- make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
- scoped_ptr<FakeTiledLayerImpl> layer_impl =
- make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
-
- layer_tree_host_->root_layer()->AddChild(layer);
-
- // Prepainting should occur in the scroll direction first, and the
- // visible rect should be extruded only along the dominant axis.
- gfx::Vector2d directions[6] = { gfx::Vector2d(-10, 0), gfx::Vector2d(10, 0),
- gfx::Vector2d(0, -10), gfx::Vector2d(0, 10),
- gfx::Vector2d(10, 20),
- gfx::Vector2d(-20, 10) };
- // We should push all tiles that touch the extruded visible rect.
- gfx::Rect pushed_visible_tiles[6] = {
- gfx::Rect(2, 2, 2, 1), gfx::Rect(1, 2, 2, 1), gfx::Rect(2, 2, 1, 2),
- gfx::Rect(2, 1, 1, 2), gfx::Rect(2, 1, 1, 2), gfx::Rect(2, 2, 2, 1)
- };
- // The first pre-paint should also paint first in the scroll
- // direction so we should find one additional tile in the scroll direction.
- gfx::Rect pushed_prepaint_tiles[6] = {
- gfx::Rect(2, 2, 3, 1), gfx::Rect(0, 2, 3, 1), gfx::Rect(2, 2, 1, 3),
- gfx::Rect(2, 0, 1, 3), gfx::Rect(2, 0, 1, 3), gfx::Rect(2, 2, 3, 1)
- };
- for (int k = 0; k < 6; k++) {
- // The tile size is 100x100. Setup 5x5 tiles with one visible tile
- // in the center.
- gfx::Size bounds = gfx::Size(500, 500);
- gfx::Rect visible_rect = gfx::Rect(200, 200, 100, 100);
- gfx::Rect previous_visible_rect =
- gfx::Rect(visible_rect.origin() + directions[k], visible_rect.size());
- gfx::Rect next_visible_rect =
- gfx::Rect(visible_rect.origin() - directions[k], visible_rect.size());
-
- // Setup. Use the previous_visible_rect to setup the prediction for next
- // frame.
- layer->SetBounds(bounds);
-
- RenderSurfaceLayerList render_surface_layer_list;
- CalcDrawProps(&render_surface_layer_list);
- layer->draw_properties().visible_content_rect = previous_visible_rect;
- bool needs_update = UpdateAndPush(layer, layer_impl);
-
- // Invalidate and move the visible_rect in the scroll direction.
- // Check that the correct tiles have been painted in the visible pass.
- layer->SetNeedsDisplay();
- layer->draw_properties().visible_content_rect = visible_rect;
- needs_update = UpdateAndPush(layer, layer_impl);
- for (int i = 0; i < 5; i++) {
- for (int j = 0; j < 5; j++)
- EXPECT_EQ(layer_impl->HasResourceIdForTileAt(i, j),
- pushed_visible_tiles[k].Contains(i, j));
- }
-
- // Move the transform in the same direction without invalidating.
- // Check that non-visible pre-painting occured in the correct direction.
- // Ignore diagonal scrolls here (k > 3) as these have new visible content
- // now.
- if (k <= 3) {
- layer->draw_properties().visible_content_rect = next_visible_rect;
- needs_update = UpdateAndPush(layer, layer_impl);
- for (int i = 0; i < 5; i++) {
- for (int j = 0; j < 5; j++)
- EXPECT_EQ(layer_impl->HasResourceIdForTileAt(i, j),
- pushed_prepaint_tiles[k].Contains(i, j));
- }
- }
-
- // We should always finish painting eventually.
- for (int i = 0; i < 20; i++)
- needs_update = UpdateAndPush(layer, layer_impl);
- EXPECT_FALSE(needs_update);
- }
-}
-
-TEST_F(TiledLayerTest, PushTilesAfterIdlePaintFailed) {
- // Start with 2mb of memory, but the test is going to try to use just more
- // than 1mb, so we reduce to 1mb later.
- resource_manager_->SetMaxMemoryLimitBytes(2 * 1024 * 1024);
- scoped_refptr<FakeTiledLayer> layer1 =
- make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
- scoped_ptr<FakeTiledLayerImpl> layer_impl1 =
- make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
- scoped_refptr<FakeTiledLayer> layer2 =
- make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
- scoped_ptr<FakeTiledLayerImpl> layer_impl2 =
- make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 2));
- RenderSurfaceLayerList render_surface_layer_list;
-
- layer_tree_host_->root_layer()->AddChild(layer1);
- layer_tree_host_->root_layer()->AddChild(layer2);
-
- // For this test we have two layers. layer1 exhausts most texture memory,
- // leaving room for 2 more tiles from layer2, but not all three tiles. First
- // we paint layer1, and one tile from layer2. Then when we idle paint layer2,
- // we will fail on the third tile of layer2, and this should not leave the
- // second tile in a bad state.
-
- // This uses 960000 bytes, leaving 88576 bytes of memory left, which is enough
- // for 2 tiles only in the other layer.
- gfx::Rect layer1_rect(0, 0, 100, 2400);
-
- // This requires 4*30000 bytes of memory.
- gfx::Rect layer2_rect(0, 0, 100, 300);
-
- // Paint a single tile in layer2 so that it will idle paint.
- layer1->SetBounds(layer1_rect.size());
- layer2->SetBounds(layer2_rect.size());
- CalcDrawProps(&render_surface_layer_list);
- layer1->draw_properties().visible_content_rect = layer1_rect;
- layer2->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
- bool needs_update = UpdateAndPush(layer1, layer_impl1, layer2, layer_impl2);
- // We should need idle-painting for both remaining tiles in layer2.
- EXPECT_TRUE(needs_update);
-
- // Reduce our memory limits to 1mb.
- resource_manager_->SetMaxMemoryLimitBytes(1024 * 1024);
-
- // Now idle paint layer2. We are going to run out of memory though!
- // Oh well, commit the frame and push.
- for (int i = 0; i < 4; i++) {
- needs_update = UpdateAndPush(layer1, layer_impl1, layer2, layer_impl2);
- }
-
- // Sanity check, we should have textures for the big layer.
- EXPECT_TRUE(layer_impl1->HasResourceIdForTileAt(0, 0));
- EXPECT_TRUE(layer_impl1->HasResourceIdForTileAt(0, 23));
-
- // We should only have the first two tiles from layer2 since
- // it failed to idle update the last tile.
- EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 0));
- EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 0));
- EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 1));
- EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 1));
-
- EXPECT_FALSE(needs_update);
- EXPECT_FALSE(layer_impl2->HasResourceIdForTileAt(0, 2));
-}
-
-TEST_F(TiledLayerTest, PushIdlePaintedOccludedTiles) {
- scoped_refptr<FakeTiledLayer> layer =
- make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
- scoped_ptr<FakeTiledLayerImpl> layer_impl =
- make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
- RenderSurfaceLayerList render_surface_layer_list;
- TestOcclusionTracker occluded;
- occlusion_ = &occluded;
-
- layer_tree_host_->root_layer()->AddChild(layer);
-
- // The tile size is 100x100, so this invalidates one occluded tile, culls it
- // during paint, but prepaints it.
- occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(0, 0, 100, 100)));
-
- layer->SetBounds(gfx::Size(100, 100));
- CalcDrawProps(&render_surface_layer_list);
- layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
- UpdateAndPush(layer, layer_impl);
-
- EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
-}
-
-TEST_F(TiledLayerTest, PushTilesMarkedDirtyDuringPaint) {
- scoped_refptr<FakeTiledLayer> layer =
- make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
- scoped_ptr<FakeTiledLayerImpl> layer_impl =
- make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
- RenderSurfaceLayerList render_surface_layer_list;
-
- layer_tree_host_->root_layer()->AddChild(layer);
-
- // The tile size is 100x100, so this invalidates and then paints two tiles.
- // However, during the paint, we invalidate one of the tiles. This should
- // not prevent the tile from being pushed.
- layer->fake_layer_updater()->SetRectToInvalidate(
- gfx::Rect(0, 50, 100, 50), layer.get());
- layer->SetBounds(gfx::Size(100, 200));
- CalcDrawProps(&render_surface_layer_list);
- layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
- UpdateAndPush(layer, layer_impl);
-
- // We should have both tiles on the impl side.
- EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
- EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
-}
-
-TEST_F(TiledLayerTest, PushTilesLayerMarkedDirtyDuringPaintOnNextLayer) {
- scoped_refptr<FakeTiledLayer> layer1 =
- make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
- scoped_refptr<FakeTiledLayer> layer2 =
- make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
- scoped_ptr<FakeTiledLayerImpl> layer1_impl =
- make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
- scoped_ptr<FakeTiledLayerImpl> layer2_impl =
- make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 2));
- RenderSurfaceLayerList render_surface_layer_list;
-
- layer_tree_host_->root_layer()->AddChild(layer1);
- layer_tree_host_->root_layer()->AddChild(layer2);
-
- // Invalidate a tile on layer1, during update of layer 2.
- layer2->fake_layer_updater()->SetRectToInvalidate(
- gfx::Rect(0, 50, 100, 50), layer1.get());
- layer1->SetBounds(gfx::Size(100, 200));
- layer2->SetBounds(gfx::Size(100, 200));
- CalcDrawProps(&render_surface_layer_list);
- layer1->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
- layer2->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
- UpdateAndPush(layer1, layer1_impl, layer2, layer2_impl);
-
- // We should have both tiles on the impl side for all layers.
- EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 0));
- EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 1));
- EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 0));
- EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 1));
-}
-
-TEST_F(TiledLayerTest, PushTilesLayerMarkedDirtyDuringPaintOnPreviousLayer) {
- scoped_refptr<FakeTiledLayer> layer1 =
- make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
- scoped_refptr<FakeTiledLayer> layer2 =
- make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
- scoped_ptr<FakeTiledLayerImpl> layer1_impl =
- make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
- scoped_ptr<FakeTiledLayerImpl> layer2_impl =
- make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 2));
- RenderSurfaceLayerList render_surface_layer_list;
-
- layer_tree_host_->root_layer()->AddChild(layer1);
- layer_tree_host_->root_layer()->AddChild(layer2);
-
- layer1->fake_layer_updater()->SetRectToInvalidate(
- gfx::Rect(0, 50, 100, 50), layer2.get());
- layer1->SetBounds(gfx::Size(100, 200));
- layer2->SetBounds(gfx::Size(100, 200));
- CalcDrawProps(&render_surface_layer_list);
- layer1->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
- layer2->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
- UpdateAndPush(layer1, layer1_impl, layer2, layer2_impl);
-
- // We should have both tiles on the impl side for all layers.
- EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 0));
- EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 1));
- EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 0));
- EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 1));
-}
-
-TEST_F(TiledLayerTest, PaintSmallAnimatedLayersImmediately) {
- // Create a LayerTreeHost that has the right viewportsize,
- // so the layer is considered small enough.
- bool run_out_of_memory[2] = { false, true };
- for (int i = 0; i < 2; i++) {
- // Create a layer with 5x5 tiles, with 4x4 size viewport.
- int viewport_width = 4 * FakeTiledLayer::tile_size().width();
- int viewport_height = 4 * FakeTiledLayer::tile_size().width();
- int layer_width = 5 * FakeTiledLayer::tile_size().width();
- int layer_height = 5 * FakeTiledLayer::tile_size().height();
- int memory_for_layer = layer_width * layer_height * 4;
- layer_tree_host_->SetViewportSize(
- gfx::Size(viewport_width, viewport_height));
-
- // Use 10x5 tiles to run out of memory.
- if (run_out_of_memory[i])
- layer_width *= 2;
-
- resource_manager_->SetMaxMemoryLimitBytes(memory_for_layer);
-
- scoped_refptr<FakeTiledLayer> layer =
- make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
- scoped_ptr<FakeTiledLayerImpl> layer_impl =
- make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
- RenderSurfaceLayerList render_surface_layer_list;
-
- layer_tree_host_->root_layer()->AddChild(layer);
-
- // Full size layer with half being visible.
- layer->SetBounds(gfx::Size(layer_width, layer_height));
- gfx::Rect visible_rect(0, 0, layer_width / 2, layer_height);
- CalcDrawProps(&render_surface_layer_list);
-
- // Pretend the layer is animating.
- layer->draw_properties().target_space_transform_is_animating = true;
- layer->draw_properties().visible_content_rect = visible_rect;
- layer->SetLayerTreeHost(layer_tree_host_.get());
-
- // The layer should paint its entire contents on the first paint
- // if it is close to the viewport size and has the available memory.
- layer->SetTexturePriorities(priority_calculator_);
- resource_manager_->PrioritizeTextures();
- layer->SavePaintProperties();
- layer->Update(queue_.get(), nullptr);
- UpdateTextures();
- LayerPushPropertiesTo(layer.get(), layer_impl.get());
-
- // We should have all the tiles for the small animated layer.
- // We should still have the visible tiles when we didn't
- // have enough memory for all the tiles.
- if (!run_out_of_memory[i]) {
- for (int i = 0; i < 5; ++i) {
- for (int j = 0; j < 5; ++j)
- EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(i, j));
- }
- } else {
- for (int i = 0; i < 10; ++i) {
- for (int j = 0; j < 5; ++j)
- EXPECT_EQ(layer_impl->HasResourceIdForTileAt(i, j), i < 5);
- }
- }
-
- layer->RemoveFromParent();
- }
-}
-
-TEST_F(TiledLayerTest, IdlePaintOutOfMemory) {
- scoped_refptr<FakeTiledLayer> layer =
- make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
- scoped_ptr<FakeTiledLayerImpl> layer_impl =
- make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
- RenderSurfaceLayerList render_surface_layer_list;
-
- layer_tree_host_->root_layer()->AddChild(layer);
-
- // We have enough memory for only the visible rect, so we will run out of
- // memory in first idle paint.
- int memory_limit = 4 * 100 * 100; // 1 tiles, 4 bytes per pixel.
- resource_manager_->SetMaxMemoryLimitBytes(memory_limit);
-
- // The tile size is 100x100, so this invalidates and then paints two tiles.
- bool needs_update = false;
- layer->SetBounds(gfx::Size(300, 300));
- CalcDrawProps(&render_surface_layer_list);
- layer->draw_properties().visible_content_rect = gfx::Rect(100, 100, 100, 100);
- for (int i = 0; i < 2; i++)
- needs_update = UpdateAndPush(layer, layer_impl);
-
- // Idle-painting should see no more priority tiles for painting.
- EXPECT_FALSE(needs_update);
-
- // We should have one tile on the impl side.
- EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(1, 1));
-}
-
-TEST_F(TiledLayerTest, IdlePaintZeroSizedLayer) {
- scoped_refptr<FakeTiledLayer> layer =
- make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
- scoped_ptr<FakeTiledLayerImpl> layer_impl =
- make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
-
- layer_tree_host_->root_layer()->AddChild(layer);
-
- bool animating[2] = { false, true };
- for (int i = 0; i < 2; i++) {
- // Pretend the layer is animating.
- layer->draw_properties().target_space_transform_is_animating = animating[i];
-
- // The layer's bounds are empty.
- // Empty layers don't paint or idle-paint.
- layer->SetBounds(gfx::Size());
-
- RenderSurfaceLayerList render_surface_layer_list;
- CalcDrawProps(&render_surface_layer_list);
- layer->draw_properties().visible_content_rect = gfx::Rect();
- bool needs_update = UpdateAndPush(layer, layer_impl);
-
- // Empty layers don't have tiles.
- EXPECT_EQ(0u, layer->NumPaintedTiles());
-
- // Empty layers don't need prepaint.
- EXPECT_FALSE(needs_update);
-
- // Empty layers don't have tiles.
- EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 0));
- }
-}
-
-TEST_F(TiledLayerTest, IdlePaintNonVisibleLayers) {
- scoped_refptr<FakeTiledLayer> layer =
- make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
- scoped_ptr<FakeTiledLayerImpl> layer_impl =
- make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
-
- // Alternate between not visible and visible.
- gfx::Rect v(0, 0, 100, 100);
- gfx::Rect nv(0, 0, 0, 0);
- gfx::Rect visible_rect[10] = { nv, nv, v, v, nv, nv, v, v, nv, nv };
- bool invalidate[10] = { true, true, true, true, true, true, true, true, false,
- false };
-
- // We should not have any tiles except for when the layer was visible
- // or after the layer was visible and we didn't invalidate.
- bool have_tile[10] = { false, false, true, true, false, false, true, true,
- true, true };
-
- layer_tree_host_->root_layer()->AddChild(layer);
-
- for (int i = 0; i < 10; i++) {
- layer->SetBounds(gfx::Size(100, 100));
-
- RenderSurfaceLayerList render_surface_layer_list;
- CalcDrawProps(&render_surface_layer_list);
- layer->draw_properties().visible_content_rect = visible_rect[i];
-
- if (invalidate[i])
- layer->InvalidateContentRect(gfx::Rect(0, 0, 100, 100));
- bool needs_update = UpdateAndPush(layer, layer_impl);
-
- // We should never signal idle paint, as we painted the entire layer
- // or the layer was not visible.
- EXPECT_FALSE(needs_update);
- EXPECT_EQ(layer_impl->HasResourceIdForTileAt(0, 0), have_tile[i]);
- }
-}
-
-TEST_F(TiledLayerTest, InvalidateFromPrepare) {
- scoped_refptr<FakeTiledLayer> layer =
- make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
- scoped_ptr<FakeTiledLayerImpl> layer_impl =
- make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
- RenderSurfaceLayerList render_surface_layer_list;
-
- layer_tree_host_->root_layer()->AddChild(layer);
-
- // The tile size is 100x100, so this invalidates and then paints two tiles.
- layer->SetBounds(gfx::Size(100, 200));
- CalcDrawProps(&render_surface_layer_list);
- layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
- UpdateAndPush(layer, layer_impl);
-
- // We should have both tiles on the impl side.
- EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
- EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
-
- layer->fake_layer_updater()->ClearPrepareCount();
- // Invoke update again. As the layer is valid update shouldn't be invoked on
- // the LayerUpdater.
- UpdateAndPush(layer, layer_impl);
- EXPECT_EQ(0, layer->fake_layer_updater()->prepare_count());
-
- // SetRectToInvalidate triggers InvalidateContentRect() being invoked from
- // update.
- layer->fake_layer_updater()->SetRectToInvalidate(
- gfx::Rect(25, 25, 50, 50), layer.get());
- layer->fake_layer_updater()->ClearPrepareCount();
- layer->InvalidateContentRect(gfx::Rect(0, 0, 50, 50));
- UpdateAndPush(layer, layer_impl);
- EXPECT_EQ(1, layer->fake_layer_updater()->prepare_count());
- layer->fake_layer_updater()->ClearPrepareCount();
-
- // The layer should still be invalid as update invoked invalidate.
- UpdateAndPush(layer, layer_impl); // visible
- EXPECT_EQ(1, layer->fake_layer_updater()->prepare_count());
-}
-
-TEST_F(TiledLayerTest, VerifyUpdateRectWhenContentBoundsAreScaled) {
- // The update rect (that indicates what was actually painted) should be in
- // layer space, not the content space.
- scoped_refptr<FakeTiledLayerWithScaledBounds> layer = make_scoped_refptr(
- new FakeTiledLayerWithScaledBounds(resource_manager_.get()));
-
- layer_tree_host_->root_layer()->AddChild(layer);
-
- gfx::Rect layer_bounds(0, 0, 300, 200);
- gfx::Rect content_bounds(0, 0, 150, 250);
-
- layer->SetBounds(layer_bounds.size());
- layer->SetContentBounds(content_bounds.size());
- layer->draw_properties().visible_content_rect = content_bounds;
- layer->draw_properties().contents_scale_x = .5f;
- layer->draw_properties().contents_scale_y = 1.25f;
-
- // On first update, the update_rect includes all tiles, even beyond the
- // boundaries of the layer.
- // However, it should still be in layer space, not content space.
- layer->InvalidateContentRect(content_bounds);
-
- layer->SetTexturePriorities(priority_calculator_);
- resource_manager_->PrioritizeTextures();
- layer->SavePaintProperties();
- layer->Update(queue_.get(), nullptr);
-
- // Update rect is 200x300 (tile size of 100x100). Scaled this gives 400x240.
- EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 400, 240), layer->update_rect());
- UpdateTextures();
-
- // After the tiles are updated once, another invalidate only needs to update
- // the bounds of the layer.
- layer->SetTexturePriorities(priority_calculator_);
- resource_manager_->PrioritizeTextures();
- layer->InvalidateContentRect(content_bounds);
- layer->SavePaintProperties();
- layer->Update(queue_.get(), nullptr);
- EXPECT_FLOAT_RECT_EQ(gfx::RectF(layer_bounds), layer->update_rect());
- UpdateTextures();
-
- // Partial re-paint should also be represented by the update rect in layer
- // space, not content space.
- gfx::Rect partial_damage(30, 100, 10, 10);
- layer->InvalidateContentRect(partial_damage);
- layer->SetTexturePriorities(priority_calculator_);
- resource_manager_->PrioritizeTextures();
- layer->SavePaintProperties();
- layer->Update(queue_.get(), nullptr);
- EXPECT_FLOAT_RECT_EQ(gfx::RectF(60, 80, 20, 8), layer->update_rect());
-}
-
-TEST_F(TiledLayerTest, VerifyInvalidationWhenContentsScaleChanges) {
- scoped_refptr<FakeTiledLayer> layer =
- make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
- scoped_ptr<FakeTiledLayerImpl> layer_impl =
- make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
- RenderSurfaceLayerList render_surface_layer_list;
-
- layer_tree_host_->root_layer()->AddChild(layer);
-
- // Create a layer with one tile.
- layer->SetBounds(gfx::Size(100, 100));
- CalcDrawProps(&render_surface_layer_list);
- layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
- layer->Update(queue_.get(), nullptr);
- UpdateTextures();
- EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 100, 100),
- layer->last_needs_display_rect());
-
- // Push the tiles to the impl side and check that there is exactly one.
- layer->SetTexturePriorities(priority_calculator_);
- resource_manager_->PrioritizeTextures();
- layer->SavePaintProperties();
- layer->Update(queue_.get(), nullptr);
- UpdateTextures();
- LayerPushPropertiesTo(layer.get(), layer_impl.get());
- EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
- EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
- EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 0));
- EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 1));
-
- layer->SetNeedsDisplayRect(gfx::Rect());
- EXPECT_FLOAT_RECT_EQ(gfx::RectF(), layer->last_needs_display_rect());
-
- // Change the contents scale.
- layer->UpdateContentsScale(2.f);
- layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 200, 200);
-
- // The impl side should get 2x2 tiles now.
- layer->SetTexturePriorities(priority_calculator_);
- resource_manager_->PrioritizeTextures();
- layer->SavePaintProperties();
- layer->Update(queue_.get(), nullptr);
- UpdateTextures();
- LayerPushPropertiesTo(layer.get(), layer_impl.get());
- EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
- EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
- EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(1, 0));
- EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(1, 1));
-
- // Verify that changing the contents scale caused invalidation, and
- // that the layer-space rectangle requiring painting is not scaled.
- EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 100, 100),
- layer->last_needs_display_rect());
-
- // Invalidate the entire layer again, but do not paint. All tiles should be
- // gone now from the impl side.
- layer->SetNeedsDisplay();
- layer->SetTexturePriorities(priority_calculator_);
- resource_manager_->PrioritizeTextures();
-
- LayerPushPropertiesTo(layer.get(), layer_impl.get());
- EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 0));
- EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
- EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 0));
- EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 1));
-}
-
-TEST_F(TiledLayerTest, SkipsDrawGetsReset) {
- // Create two 300 x 300 tiled layers.
- gfx::Size content_bounds(300, 300);
- gfx::Rect content_rect(content_bounds);
-
- // We have enough memory for only one of the two layers.
- int memory_limit = 4 * 300 * 300; // 4 bytes per pixel.
-
- scoped_refptr<FakeTiledLayer> root_layer = make_scoped_refptr(
- new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
- scoped_refptr<FakeTiledLayer> child_layer = make_scoped_refptr(
- new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
- root_layer->AddChild(child_layer);
-
- root_layer->SetBounds(content_bounds);
- root_layer->draw_properties().visible_content_rect = content_rect;
- root_layer->SetPosition(gfx::PointF(0, 0));
- child_layer->SetBounds(content_bounds);
- child_layer->draw_properties().visible_content_rect = content_rect;
- child_layer->SetPosition(gfx::PointF(0, 0));
- root_layer->InvalidateContentRect(content_rect);
- child_layer->InvalidateContentRect(content_rect);
-
- layer_tree_host_->SetRootLayer(root_layer);
- layer_tree_host_->SetViewportSize(gfx::Size(300, 300));
- layer_tree_host_->contents_texture_manager()->SetMaxMemoryLimitBytes(
- memory_limit);
-
- layer_tree_host_->UpdateLayers(queue_.get());
-
- // We'll skip the root layer.
- EXPECT_TRUE(root_layer->SkipsDraw());
- EXPECT_FALSE(child_layer->SkipsDraw());
-
- layer_tree_host_->CommitComplete();
-
- // Remove the child layer.
- root_layer->RemoveAllChildren();
-
- layer_tree_host_->UpdateLayers(queue_.get());
- EXPECT_FALSE(root_layer->SkipsDraw());
-
- ResourceManagerClearAllMemory(layer_tree_host_->contents_texture_manager(),
- resource_provider_.get());
- layer_tree_host_->SetRootLayer(nullptr);
-}
-
-TEST_F(TiledLayerTest, ResizeToSmaller) {
- scoped_refptr<FakeTiledLayer> layer =
- make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
-
- layer_tree_host_->root_layer()->AddChild(layer);
-
- layer->SetBounds(gfx::Size(700, 700));
- layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 700, 700);
- layer->InvalidateContentRect(gfx::Rect(0, 0, 700, 700));
-
- layer->SetTexturePriorities(priority_calculator_);
- resource_manager_->PrioritizeTextures();
- layer->SavePaintProperties();
- layer->Update(queue_.get(), nullptr);
-
- layer->SetBounds(gfx::Size(200, 200));
- layer->InvalidateContentRect(gfx::Rect(0, 0, 200, 200));
-}
-
-TEST_F(TiledLayerTest, HugeLayerUpdateCrash) {
- scoped_refptr<FakeTiledLayer> layer =
- make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
-
- layer_tree_host_->root_layer()->AddChild(layer);
-
- int size = 1 << 30;
- layer->SetBounds(gfx::Size(size, size));
- layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 700, 700);
- layer->InvalidateContentRect(gfx::Rect(0, 0, size, size));
-
- // Ensure no crash for bounds where size * size would overflow an int.
- layer->SetTexturePriorities(priority_calculator_);
- resource_manager_->PrioritizeTextures();
- layer->SavePaintProperties();
- layer->Update(queue_.get(), nullptr);
-}
-
-class TiledLayerPartialUpdateTest : public TiledLayerTest {
- public:
- TiledLayerPartialUpdateTest() { settings_.max_partial_texture_updates = 4; }
-};
-
-TEST_F(TiledLayerPartialUpdateTest, PartialUpdates) {
- // Create one 300 x 200 tiled layer with 3 x 2 tiles.
- gfx::Size content_bounds(300, 200);
- gfx::Rect content_rect(content_bounds);
-
- scoped_refptr<FakeTiledLayer> layer = make_scoped_refptr(
- new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
- layer->SetBounds(content_bounds);
- layer->SetPosition(gfx::PointF(0, 0));
- layer->draw_properties().visible_content_rect = content_rect;
- layer->InvalidateContentRect(content_rect);
-
- layer_tree_host_->SetRootLayer(layer);
- layer_tree_host_->SetViewportSize(gfx::Size(300, 200));
-
- // Full update of all 6 tiles.
- layer_tree_host_->UpdateLayers(queue_.get());
- {
- scoped_ptr<FakeTiledLayerImpl> layer_impl =
- make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
- EXPECT_EQ(6u, queue_->FullUploadSize());
- EXPECT_EQ(0u, queue_->PartialUploadSize());
- UpdateTextures();
- EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
- EXPECT_FALSE(queue_->HasMoreUpdates());
- layer->fake_layer_updater()->ClearUpdateCount();
- LayerPushPropertiesTo(layer.get(), layer_impl.get());
- }
- layer_tree_host_->CommitComplete();
-
- // Full update of 3 tiles and partial update of 3 tiles.
- layer->InvalidateContentRect(gfx::Rect(0, 0, 300, 150));
- layer_tree_host_->UpdateLayers(queue_.get());
- {
- scoped_ptr<FakeTiledLayerImpl> layer_impl =
- make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
- EXPECT_EQ(3u, queue_->FullUploadSize());
- EXPECT_EQ(3u, queue_->PartialUploadSize());
- UpdateTextures();
- EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
- EXPECT_FALSE(queue_->HasMoreUpdates());
- layer->fake_layer_updater()->ClearUpdateCount();
- LayerPushPropertiesTo(layer.get(), layer_impl.get());
- }
- layer_tree_host_->CommitComplete();
-
- // Partial update of 6 tiles.
- layer->InvalidateContentRect(gfx::Rect(50, 50, 200, 100));
- {
- scoped_ptr<FakeTiledLayerImpl> layer_impl =
- make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
- layer_tree_host_->UpdateLayers(queue_.get());
- EXPECT_EQ(2u, queue_->FullUploadSize());
- EXPECT_EQ(4u, queue_->PartialUploadSize());
- UpdateTextures();
- EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
- EXPECT_FALSE(queue_->HasMoreUpdates());
- layer->fake_layer_updater()->ClearUpdateCount();
- LayerPushPropertiesTo(layer.get(), layer_impl.get());
- }
- layer_tree_host_->CommitComplete();
-
- // Checkerboard all tiles.
- layer->InvalidateContentRect(gfx::Rect(0, 0, 300, 200));
- {
- scoped_ptr<FakeTiledLayerImpl> layer_impl =
- make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
- LayerPushPropertiesTo(layer.get(), layer_impl.get());
- }
- layer_tree_host_->CommitComplete();
-
- // Partial update of 6 checkerboard tiles.
- layer->InvalidateContentRect(gfx::Rect(50, 50, 200, 100));
- {
- scoped_ptr<FakeTiledLayerImpl> layer_impl =
- make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
- layer_tree_host_->UpdateLayers(queue_.get());
- EXPECT_EQ(6u, queue_->FullUploadSize());
- EXPECT_EQ(0u, queue_->PartialUploadSize());
- UpdateTextures();
- EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
- EXPECT_FALSE(queue_->HasMoreUpdates());
- layer->fake_layer_updater()->ClearUpdateCount();
- LayerPushPropertiesTo(layer.get(), layer_impl.get());
- }
- layer_tree_host_->CommitComplete();
-
- // Partial update of 4 tiles.
- layer->InvalidateContentRect(gfx::Rect(50, 50, 100, 100));
- {
- scoped_ptr<FakeTiledLayerImpl> layer_impl =
- make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
- layer_tree_host_->UpdateLayers(queue_.get());
- EXPECT_EQ(0u, queue_->FullUploadSize());
- EXPECT_EQ(4u, queue_->PartialUploadSize());
- UpdateTextures();
- EXPECT_EQ(4, layer->fake_layer_updater()->update_count());
- EXPECT_FALSE(queue_->HasMoreUpdates());
- layer->fake_layer_updater()->ClearUpdateCount();
- LayerPushPropertiesTo(layer.get(), layer_impl.get());
- }
- layer_tree_host_->CommitComplete();
-
- ResourceManagerClearAllMemory(layer_tree_host_->contents_texture_manager(),
- resource_provider_.get());
- layer_tree_host_->SetRootLayer(nullptr);
-}
-
-TEST_F(TiledLayerTest, TilesPaintedWithoutOcclusion) {
- layer_tree_host_->SetViewportSize(gfx::Size(1000, 1000));
-
- scoped_refptr<FakeTiledLayer> layer =
- make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
- RenderSurfaceLayerList render_surface_layer_list;
-
- layer_tree_host_->root_layer()->AddChild(layer);
-
- // The tile size is 100x100, so this invalidates and then paints two tiles.
- layer->SetBounds(gfx::Size(100, 200));
- CalcDrawProps(&render_surface_layer_list);
-
- layer->SetTexturePriorities(priority_calculator_);
- resource_manager_->PrioritizeTextures();
- layer->SavePaintProperties();
- layer->Update(queue_.get(), nullptr);
- EXPECT_EQ(2, layer->fake_layer_updater()->update_count());
-}
-
-TEST_F(TiledLayerTest, TilesPaintedWithOcclusion) {
- scoped_refptr<FakeTiledLayer> layer =
- make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
- RenderSurfaceLayerList render_surface_layer_list;
- TestOcclusionTracker occluded;
- occlusion_ = &occluded;
-
- layer_tree_host_->root_layer()->AddChild(layer);
-
- // The tile size is 100x100.
-
- layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
- layer->SetBounds(gfx::Size(600, 600));
- CalcDrawProps(&render_surface_layer_list);
-
- occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 100)));
- layer->draw_properties().drawable_content_rect =
- gfx::Rect(layer->content_bounds());
- layer->draw_properties().visible_content_rect =
- gfx::Rect(layer->content_bounds());
- layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
-
- layer->SetTexturePriorities(priority_calculator_);
- resource_manager_->PrioritizeTextures();
- layer->SavePaintProperties();
- layer->Update(queue_.get(), &occluded);
- EXPECT_EQ(36 - 3, layer->fake_layer_updater()->update_count());
-
- layer->fake_layer_updater()->ClearUpdateCount();
- layer->SetTexturePriorities(priority_calculator_);
- resource_manager_->PrioritizeTextures();
-
- occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(250, 200, 300, 100)));
- layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
- layer->SavePaintProperties();
- layer->Update(queue_.get(), &occluded);
- EXPECT_EQ(36 - 2, layer->fake_layer_updater()->update_count());
-
- layer->fake_layer_updater()->ClearUpdateCount();
- layer->SetTexturePriorities(priority_calculator_);
- resource_manager_->PrioritizeTextures();
-
- occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(250, 250, 300, 100)));
- layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
- layer->SavePaintProperties();
- layer->Update(queue_.get(), &occluded);
- EXPECT_EQ(36, layer->fake_layer_updater()->update_count());
-}
-
-TEST_F(TiledLayerTest, TilesPaintedWithOcclusionAndVisiblityConstraints) {
- scoped_refptr<FakeTiledLayer> layer =
- make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
- RenderSurfaceLayerList render_surface_layer_list;
- TestOcclusionTracker occluded;
- occlusion_ = &occluded;
-
- layer_tree_host_->root_layer()->AddChild(layer);
-
- // The tile size is 100x100.
-
- layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
- layer->SetBounds(gfx::Size(600, 600));
- CalcDrawProps(&render_surface_layer_list);
-
- // The partially occluded tiles (by the 150 occlusion height) are visible
- // beyond the occlusion, so not culled.
- occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 150)));
- layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 360);
- layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 360);
- layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
-
- layer->SetTexturePriorities(priority_calculator_);
- resource_manager_->PrioritizeTextures();
- layer->SavePaintProperties();
- layer->Update(queue_.get(), &occluded);
- EXPECT_EQ(24 - 3, layer->fake_layer_updater()->update_count());
-
- layer->fake_layer_updater()->ClearUpdateCount();
-
- // Now the visible region stops at the edge of the occlusion so the partly
- // visible tiles become fully occluded.
- occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 150)));
- layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 350);
- layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 350);
- layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
- layer->SetTexturePriorities(priority_calculator_);
- resource_manager_->PrioritizeTextures();
- layer->SavePaintProperties();
- layer->Update(queue_.get(), &occluded);
- EXPECT_EQ(24 - 6, layer->fake_layer_updater()->update_count());
-
- layer->fake_layer_updater()->ClearUpdateCount();
-
- // Now the visible region is even smaller than the occlusion, it should have
- // the same result.
- occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 150)));
- layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 340);
- layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 340);
- layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
- layer->SetTexturePriorities(priority_calculator_);
- resource_manager_->PrioritizeTextures();
- layer->SavePaintProperties();
- layer->Update(queue_.get(), &occluded);
- EXPECT_EQ(24 - 6, layer->fake_layer_updater()->update_count());
-}
-
-TEST_F(TiledLayerTest, TilesNotPaintedWithoutInvalidation) {
- scoped_refptr<FakeTiledLayer> layer =
- make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
- RenderSurfaceLayerList render_surface_layer_list;
- TestOcclusionTracker occluded;
- occlusion_ = &occluded;
-
- layer_tree_host_->root_layer()->AddChild(layer);
-
- // The tile size is 100x100.
-
- layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
- layer->SetBounds(gfx::Size(600, 600));
- CalcDrawProps(&render_surface_layer_list);
-
- occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 100)));
- layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 600);
- layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 600);
- layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
- layer->SetTexturePriorities(priority_calculator_);
- resource_manager_->PrioritizeTextures();
- layer->SavePaintProperties();
- layer->Update(queue_.get(), &occluded);
- EXPECT_EQ(36 - 3, layer->fake_layer_updater()->update_count());
- UpdateTextures();
-
- layer->fake_layer_updater()->ClearUpdateCount();
- layer->SetTexturePriorities(priority_calculator_);
- resource_manager_->PrioritizeTextures();
- layer->SavePaintProperties();
-
- // Repaint without marking it dirty. The 3 culled tiles will be pre-painted
- // now.
- layer->Update(queue_.get(), &occluded);
- EXPECT_EQ(3, layer->fake_layer_updater()->update_count());
-}
-
-TEST_F(TiledLayerTest, TilesPaintedWithOcclusionAndTransforms) {
- scoped_refptr<FakeTiledLayer> layer =
- make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
- RenderSurfaceLayerList render_surface_layer_list;
- TestOcclusionTracker occluded;
- occlusion_ = &occluded;
-
- layer_tree_host_->root_layer()->AddChild(layer);
-
- // The tile size is 100x100.
-
- // This makes sure the painting works when the occluded region (in screen
- // space) is transformed differently than the layer.
- layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
- layer->SetBounds(gfx::Size(600, 600));
- CalcDrawProps(&render_surface_layer_list);
- gfx::Transform screen_transform;
- screen_transform.Scale(0.5, 0.5);
- layer->draw_properties().screen_space_transform = screen_transform;
- layer->draw_properties().target_space_transform = screen_transform;
-
- occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(100, 100, 150, 50)));
- layer->draw_properties().drawable_content_rect =
- gfx::Rect(layer->content_bounds());
- layer->draw_properties().visible_content_rect =
- gfx::Rect(layer->content_bounds());
- layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
- layer->SetTexturePriorities(priority_calculator_);
- resource_manager_->PrioritizeTextures();
- layer->SavePaintProperties();
- layer->Update(queue_.get(), &occluded);
- EXPECT_EQ(36 - 3, layer->fake_layer_updater()->update_count());
-}
-
-TEST_F(TiledLayerTest, TilesPaintedWithOcclusionAndScaling) {
- scoped_refptr<FakeTiledLayer> layer =
- new FakeTiledLayer(resource_manager_.get());
- RenderSurfaceLayerList render_surface_layer_list;
- TestOcclusionTracker occluded;
- occlusion_ = &occluded;
-
- scoped_refptr<FakeTiledLayer> scale_layer =
- new FakeTiledLayer(resource_manager_.get());
- gfx::Transform scale_transform;
- scale_transform.Scale(2.0, 2.0);
- scale_layer->SetTransform(scale_transform);
-
- layer_tree_host_->root_layer()->AddChild(scale_layer);
-
- // The tile size is 100x100.
-
- // This makes sure the painting works when the content space is scaled to
- // a different layer space.
- layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
- layer->SetBounds(gfx::Size(300, 300));
- scale_layer->AddChild(layer);
- CalcDrawProps(&render_surface_layer_list);
- EXPECT_FLOAT_EQ(2.f, layer->contents_scale_x());
- EXPECT_FLOAT_EQ(2.f, layer->contents_scale_y());
- EXPECT_EQ(gfx::Size(600, 600).ToString(),
- layer->content_bounds().ToString());
-
- // No tiles are covered by the 300x50 occlusion.
- occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 50)));
- layer->draw_properties().drawable_content_rect =
- gfx::Rect(layer->bounds());
- layer->draw_properties().visible_content_rect =
- gfx::Rect(layer->content_bounds());
- layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
- layer->SetTexturePriorities(priority_calculator_);
- resource_manager_->PrioritizeTextures();
- layer->SavePaintProperties();
- layer->Update(queue_.get(), &occluded);
- int visible_tiles1 = 6 * 6;
- EXPECT_EQ(visible_tiles1, layer->fake_layer_updater()->update_count());
-
- layer->fake_layer_updater()->ClearUpdateCount();
-
- // The occlusion of 300x100 will be cover 3 tiles as tiles are 100x100 still.
- occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 100)));
- layer->draw_properties().drawable_content_rect =
- gfx::Rect(layer->bounds());
- layer->draw_properties().visible_content_rect =
- gfx::Rect(layer->content_bounds());
- layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
- layer->SetTexturePriorities(priority_calculator_);
- resource_manager_->PrioritizeTextures();
- layer->SavePaintProperties();
- layer->Update(queue_.get(), &occluded);
- int visible_tiles2 = 6 * 6 - 3;
- EXPECT_EQ(visible_tiles2, layer->fake_layer_updater()->update_count());
-
- layer->fake_layer_updater()->ClearUpdateCount();
-
- // This makes sure content scaling and transforms work together.
- // When the tiles are scaled down by half, they are 50x50 each in the
- // screen.
- gfx::Transform screen_transform;
- screen_transform.Scale(0.5, 0.5);
- layer->draw_properties().screen_space_transform = screen_transform;
- layer->draw_properties().target_space_transform = screen_transform;
-
- // An occlusion of 150x100 will cover 3*2 = 6 tiles.
- occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(100, 100, 150, 100)));
-
- gfx::Rect layer_bounds_rect(layer->bounds());
- layer->draw_properties().drawable_content_rect =
- gfx::ScaleToEnclosingRect(layer_bounds_rect, 0.5f);
- layer->draw_properties().visible_content_rect =
- gfx::Rect(layer->content_bounds());
- layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
- layer->SetTexturePriorities(priority_calculator_);
- resource_manager_->PrioritizeTextures();
- layer->SavePaintProperties();
- layer->Update(queue_.get(), &occluded);
- int visible_tiles3 = 6 * 6 - 6;
- EXPECT_EQ(visible_tiles3, layer->fake_layer_updater()->update_count());
-}
-
-TEST_F(TiledLayerTest, DontAllocateContentsWhenTargetSurfaceCantBeAllocated) {
- // Tile size is 100x100.
- gfx::Rect root_rect(0, 0, 300, 200);
- gfx::Rect child_rect(0, 0, 300, 100);
- gfx::Rect child2_rect(0, 100, 300, 100);
-
- scoped_refptr<FakeTiledLayer> root = make_scoped_refptr(
- new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
- scoped_refptr<Layer> surface = Layer::Create();
- scoped_refptr<FakeTiledLayer> child = make_scoped_refptr(
- new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
- scoped_refptr<FakeTiledLayer> child2 = make_scoped_refptr(
- new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
-
- root->SetBounds(root_rect.size());
- root->draw_properties().drawable_content_rect = root_rect;
- root->draw_properties().visible_content_rect = root_rect;
- root->AddChild(surface);
-
- surface->SetForceRenderSurface(true);
- surface->SetOpacity(0.5);
- surface->AddChild(child);
- surface->AddChild(child2);
-
- child->SetBounds(child_rect.size());
- child->SetPosition(child_rect.origin());
- child->draw_properties().visible_content_rect = child_rect;
- child->draw_properties().drawable_content_rect = root_rect;
-
- child2->SetBounds(child2_rect.size());
- child2->SetPosition(child2_rect.origin());
- child2->draw_properties().visible_content_rect = child2_rect;
- child2->draw_properties().drawable_content_rect = root_rect;
-
- layer_tree_host_->SetRootLayer(root);
- layer_tree_host_->SetViewportSize(root_rect.size());
-
- // With a huge memory limit, all layers should update and push their textures.
- root->InvalidateContentRect(root_rect);
- child->InvalidateContentRect(child_rect);
- child2->InvalidateContentRect(child2_rect);
- layer_tree_host_->UpdateLayers(queue_.get());
- {
- UpdateTextures();
- EXPECT_EQ(6, root->fake_layer_updater()->update_count());
- EXPECT_EQ(3, child->fake_layer_updater()->update_count());
- EXPECT_EQ(3, child2->fake_layer_updater()->update_count());
- EXPECT_FALSE(queue_->HasMoreUpdates());
-
- root->fake_layer_updater()->ClearUpdateCount();
- child->fake_layer_updater()->ClearUpdateCount();
- child2->fake_layer_updater()->ClearUpdateCount();
-
- scoped_ptr<FakeTiledLayerImpl> root_impl = make_scoped_ptr(
- new FakeTiledLayerImpl(host_impl_->active_tree(), root->id()));
- scoped_ptr<FakeTiledLayerImpl> child_impl = make_scoped_ptr(
- new FakeTiledLayerImpl(host_impl_->active_tree(), child->id()));
- scoped_ptr<FakeTiledLayerImpl> child2_impl = make_scoped_ptr(
- new FakeTiledLayerImpl(host_impl_->active_tree(), child2->id()));
- LayerPushPropertiesTo(child2.get(), child2_impl.get());
- LayerPushPropertiesTo(child.get(), child_impl.get());
- LayerPushPropertiesTo(root.get(), root_impl.get());
-
- for (unsigned i = 0; i < 3; ++i) {
- for (unsigned j = 0; j < 2; ++j)
- EXPECT_TRUE(root_impl->HasResourceIdForTileAt(i, j));
- EXPECT_TRUE(child_impl->HasResourceIdForTileAt(i, 0));
- EXPECT_TRUE(child2_impl->HasResourceIdForTileAt(i, 0));
- }
- }
- layer_tree_host_->CommitComplete();
-
- // With a memory limit that includes only the root layer (3x2 tiles) and half
- // the surface that the child layers draw into, the child layers will not be
- // allocated. If the surface isn't accounted for, then one of the children
- // would fit within the memory limit.
- root->InvalidateContentRect(root_rect);
- child->InvalidateContentRect(child_rect);
- child2->InvalidateContentRect(child2_rect);
-
- size_t memory_limit = (3 * 2 + 3 * 1) * (100 * 100) * 4;
- layer_tree_host_->contents_texture_manager()->SetMaxMemoryLimitBytes(
- memory_limit);
- layer_tree_host_->UpdateLayers(queue_.get());
- {
- UpdateTextures();
- EXPECT_EQ(6, root->fake_layer_updater()->update_count());
- EXPECT_EQ(0, child->fake_layer_updater()->update_count());
- EXPECT_EQ(0, child2->fake_layer_updater()->update_count());
- EXPECT_FALSE(queue_->HasMoreUpdates());
-
- root->fake_layer_updater()->ClearUpdateCount();
- child->fake_layer_updater()->ClearUpdateCount();
- child2->fake_layer_updater()->ClearUpdateCount();
-
- scoped_ptr<FakeTiledLayerImpl> root_impl = make_scoped_ptr(
- new FakeTiledLayerImpl(host_impl_->active_tree(), root->id()));
- scoped_ptr<FakeTiledLayerImpl> child_impl = make_scoped_ptr(
- new FakeTiledLayerImpl(host_impl_->active_tree(), child->id()));
- scoped_ptr<FakeTiledLayerImpl> child2_impl = make_scoped_ptr(
- new FakeTiledLayerImpl(host_impl_->active_tree(), child2->id()));
- LayerPushPropertiesTo(child2.get(), child2_impl.get());
- LayerPushPropertiesTo(child.get(), child_impl.get());
- LayerPushPropertiesTo(root.get(), root_impl.get());
-
- for (unsigned i = 0; i < 3; ++i) {
- for (unsigned j = 0; j < 2; ++j)
- EXPECT_TRUE(root_impl->HasResourceIdForTileAt(i, j));
- EXPECT_FALSE(child_impl->HasResourceIdForTileAt(i, 0));
- EXPECT_FALSE(child2_impl->HasResourceIdForTileAt(i, 0));
- }
- }
- layer_tree_host_->CommitComplete();
-
- // With a memory limit that includes only half the root layer, no contents
- // will be allocated. If render surface memory wasn't accounted for, there is
- // enough space for one of the children layers, but they draw into a surface
- // that can't be allocated.
- root->InvalidateContentRect(root_rect);
- child->InvalidateContentRect(child_rect);
- child2->InvalidateContentRect(child2_rect);
-
- memory_limit = (3 * 1) * (100 * 100) * 4;
- layer_tree_host_->contents_texture_manager()->SetMaxMemoryLimitBytes(
- memory_limit);
- layer_tree_host_->UpdateLayers(queue_.get());
- {
- UpdateTextures();
- EXPECT_EQ(0, root->fake_layer_updater()->update_count());
- EXPECT_EQ(0, child->fake_layer_updater()->update_count());
- EXPECT_EQ(0, child2->fake_layer_updater()->update_count());
- EXPECT_FALSE(queue_->HasMoreUpdates());
-
- root->fake_layer_updater()->ClearUpdateCount();
- child->fake_layer_updater()->ClearUpdateCount();
- child2->fake_layer_updater()->ClearUpdateCount();
-
- scoped_ptr<FakeTiledLayerImpl> root_impl = make_scoped_ptr(
- new FakeTiledLayerImpl(host_impl_->active_tree(), root->id()));
- scoped_ptr<FakeTiledLayerImpl> child_impl = make_scoped_ptr(
- new FakeTiledLayerImpl(host_impl_->active_tree(), child->id()));
- scoped_ptr<FakeTiledLayerImpl> child2_impl = make_scoped_ptr(
- new FakeTiledLayerImpl(host_impl_->active_tree(), child2->id()));
- LayerPushPropertiesTo(child2.get(), child2_impl.get());
- LayerPushPropertiesTo(child.get(), child_impl.get());
- LayerPushPropertiesTo(root.get(), root_impl.get());
-
- for (unsigned i = 0; i < 3; ++i) {
- for (unsigned j = 0; j < 2; ++j)
- EXPECT_FALSE(root_impl->HasResourceIdForTileAt(i, j));
- EXPECT_FALSE(child_impl->HasResourceIdForTileAt(i, 0));
- EXPECT_FALSE(child2_impl->HasResourceIdForTileAt(i, 0));
- }
- }
- layer_tree_host_->CommitComplete();
-
- ResourceManagerClearAllMemory(layer_tree_host_->contents_texture_manager(),
- resource_provider_.get());
- layer_tree_host_->SetRootLayer(nullptr);
-}
-
-class TrackingLayerPainter : public LayerPainter {
- public:
- static scoped_ptr<TrackingLayerPainter> Create() {
- return make_scoped_ptr(new TrackingLayerPainter());
- }
-
- void Paint(SkCanvas* canvas, const gfx::Rect& content_rect) override {
- painted_rect_ = content_rect;
- }
-
- gfx::Rect PaintedRect() const { return painted_rect_; }
- void ResetPaintedRect() { painted_rect_ = gfx::Rect(); }
-
- private:
- gfx::Rect painted_rect_;
-};
-
-class UpdateTrackingTiledLayer : public FakeTiledLayer {
- public:
- explicit UpdateTrackingTiledLayer(PrioritizedResourceManager* manager)
- : FakeTiledLayer(manager) {
- scoped_ptr<TrackingLayerPainter> painter(TrackingLayerPainter::Create());
- tracking_layer_painter_ = painter.get();
- layer_updater_ = BitmapContentLayerUpdater::Create(painter.Pass(), 0);
- }
-
- TrackingLayerPainter* tracking_layer_painter() const {
- return tracking_layer_painter_;
- }
-
- private:
- LayerUpdater* Updater() const override { return layer_updater_.get(); }
- ~UpdateTrackingTiledLayer() override {}
-
- TrackingLayerPainter* tracking_layer_painter_;
- scoped_refptr<BitmapContentLayerUpdater> layer_updater_;
-};
-
-TEST_F(TiledLayerTest, NonIntegerContentsScaleIsNotDistortedDuringPaint) {
- scoped_refptr<UpdateTrackingTiledLayer> layer =
- make_scoped_refptr(new UpdateTrackingTiledLayer(resource_manager_.get()));
-
- layer_tree_host_->root_layer()->AddChild(layer);
-
- gfx::Rect layer_rect(0, 0, 30, 31);
- layer->SetPosition(layer_rect.origin());
- layer->SetBounds(layer_rect.size());
- layer->UpdateContentsScale(1.5f);
-
- gfx::Rect content_rect(0, 0, 45, 47);
- EXPECT_EQ(content_rect.size(), layer->content_bounds());
- layer->draw_properties().visible_content_rect = content_rect;
- layer->draw_properties().drawable_content_rect = content_rect;
-
- layer->SetTexturePriorities(priority_calculator_);
- resource_manager_->PrioritizeTextures();
- layer->SavePaintProperties();
-
- // Update the whole tile.
- layer->Update(queue_.get(), nullptr);
- layer->tracking_layer_painter()->ResetPaintedRect();
-
- EXPECT_EQ(gfx::Rect(), layer->tracking_layer_painter()->PaintedRect());
- UpdateTextures();
-
- // Invalidate the entire layer in content space. When painting, the rect given
- // to webkit should match the layer's bounds.
- layer->InvalidateContentRect(content_rect);
- layer->Update(queue_.get(), nullptr);
-
- // Rounding leads to an extra pixel.
- gfx::Rect expanded_layer_rect(layer_rect);
- expanded_layer_rect.set_height(32);
- EXPECT_EQ(expanded_layer_rect,
- layer->tracking_layer_painter()->PaintedRect());
-}
-
-TEST_F(TiledLayerTest,
- NonIntegerContentsScaleIsNotDistortedDuringInvalidation) {
- scoped_refptr<UpdateTrackingTiledLayer> layer =
- make_scoped_refptr(new UpdateTrackingTiledLayer(resource_manager_.get()));
-
- layer_tree_host_->root_layer()->AddChild(layer);
-
- gfx::Rect layer_rect(0, 0, 30, 31);
- layer->SetPosition(layer_rect.origin());
- layer->SetBounds(layer_rect.size());
- layer->UpdateContentsScale(1.3f);
-
- gfx::Rect content_rect(layer->content_bounds());
- layer->draw_properties().visible_content_rect = content_rect;
- layer->draw_properties().drawable_content_rect = content_rect;
-
- layer->SetTexturePriorities(priority_calculator_);
- resource_manager_->PrioritizeTextures();
- layer->SavePaintProperties();
-
- // Update the whole tile.
- layer->Update(queue_.get(), nullptr);
- layer->tracking_layer_painter()->ResetPaintedRect();
-
- EXPECT_EQ(gfx::Rect(), layer->tracking_layer_painter()->PaintedRect());
- UpdateTextures();
-
- // Invalidate the entire layer in layer space. When painting, the rect given
- // to webkit should match the layer's bounds.
- layer->SetNeedsDisplayRect(layer_rect);
- layer->Update(queue_.get(), nullptr);
-
- // Rounding leads to an extra pixel.
- gfx::Rect expanded_layer_rect(layer_rect);
- expanded_layer_rect.set_height(32);
- EXPECT_EQ(expanded_layer_rect,
- layer->tracking_layer_painter()->PaintedRect());
-}
-
-} // namespace
-} // namespace cc
diff --git a/chromium/cc/layers/ui_resource_layer.cc b/chromium/cc/layers/ui_resource_layer.cc
index fd107b1ed07..87512ebd016 100644
--- a/chromium/cc/layers/ui_resource_layer.cc
+++ b/chromium/cc/layers/ui_resource_layer.cc
@@ -5,9 +5,6 @@
#include "cc/layers/ui_resource_layer.h"
#include "cc/layers/ui_resource_layer_impl.h"
-#include "cc/resources/prioritized_resource.h"
-#include "cc/resources/resource_update.h"
-#include "cc/resources/resource_update_queue.h"
#include "cc/resources/scoped_ui_resource.h"
#include "cc/resources/ui_resource_bitmap.h"
#include "cc/trees/layer_tree_host.h"
@@ -51,14 +48,13 @@ class SharedUIResourceHolder : public UIResourceLayer::UIResourceHolder {
UIResourceLayer::UIResourceHolder::~UIResourceHolder() {}
-scoped_refptr<UIResourceLayer> UIResourceLayer::Create() {
- return make_scoped_refptr(new UIResourceLayer());
+scoped_refptr<UIResourceLayer> UIResourceLayer::Create(
+ const LayerSettings& settings) {
+ return make_scoped_refptr(new UIResourceLayer(settings));
}
-UIResourceLayer::UIResourceLayer()
- : Layer(),
- uv_top_left_(0.f, 0.f),
- uv_bottom_right_(1.f, 1.f) {
+UIResourceLayer::UIResourceLayer(const LayerSettings& settings)
+ : Layer(settings), uv_top_left_(0.f, 0.f), uv_bottom_right_(1.f, 1.f) {
vertex_opacity_[0] = 1.0f;
vertex_opacity_[1] = 1.0f;
vertex_opacity_[2] = 1.0f;
diff --git a/chromium/cc/layers/ui_resource_layer.h b/chromium/cc/layers/ui_resource_layer.h
index dc2006e12bf..600f245dd6b 100644
--- a/chromium/cc/layers/ui_resource_layer.h
+++ b/chromium/cc/layers/ui_resource_layer.h
@@ -18,7 +18,7 @@ class ScopedUIResource;
class CC_EXPORT UIResourceLayer : public Layer {
public:
- static scoped_refptr<UIResourceLayer> Create();
+ static scoped_refptr<UIResourceLayer> Create(const LayerSettings& settings);
void PushPropertiesTo(LayerImpl* layer) override;
@@ -48,7 +48,7 @@ class CC_EXPORT UIResourceLayer : public Layer {
};
protected:
- UIResourceLayer();
+ explicit UIResourceLayer(const LayerSettings& settings);
~UIResourceLayer() override;
bool HasDrawableContent() const override;
diff --git a/chromium/cc/layers/ui_resource_layer_impl.cc b/chromium/cc/layers/ui_resource_layer_impl.cc
index 582ea9eb924..9fb703ef6fe 100644
--- a/chromium/cc/layers/ui_resource_layer_impl.cc
+++ b/chromium/cc/layers/ui_resource_layer_impl.cc
@@ -98,13 +98,13 @@ void UIResourceLayerImpl::AppendQuads(
render_pass->CreateAndAppendSharedQuadState();
PopulateSharedQuadState(shared_quad_state);
- AppendDebugBorderQuad(
- render_pass, content_bounds(), shared_quad_state, append_quads_data);
+ AppendDebugBorderQuad(render_pass, bounds(), shared_quad_state,
+ append_quads_data);
if (!ui_resource_id_)
return;
- ResourceProvider::ResourceId resource =
+ ResourceId resource =
layer_tree_impl()->ResourceIdForUIResource(ui_resource_id_);
if (!resource)
diff --git a/chromium/cc/layers/ui_resource_layer_impl_unittest.cc b/chromium/cc/layers/ui_resource_layer_impl_unittest.cc
index b725e6d44e9..e31d68ae6e5 100644
--- a/chromium/cc/layers/ui_resource_layer_impl_unittest.cc
+++ b/chromium/cc/layers/ui_resource_layer_impl_unittest.cc
@@ -13,6 +13,7 @@
#include "cc/test/fake_ui_resource_layer_tree_host_impl.h"
#include "cc/test/layer_test_common.h"
#include "cc/test/test_shared_bitmap_manager.h"
+#include "cc/test/test_task_graph_runner.h"
#include "cc/trees/single_thread_proxy.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -27,12 +28,11 @@ scoped_ptr<UIResourceLayerImpl> GenerateUIResourceLayer(
const gfx::Size& layer_size,
bool opaque,
UIResourceId uid) {
- gfx::Rect visible_content_rect(layer_size);
+ gfx::Rect visible_layer_rect(layer_size);
scoped_ptr<UIResourceLayerImpl> layer =
UIResourceLayerImpl::Create(host_impl->active_tree(), 1);
- layer->draw_properties().visible_content_rect = visible_content_rect;
+ layer->draw_properties().visible_layer_rect = visible_layer_rect;
layer->SetBounds(layer_size);
- layer->SetContentBounds(layer_size);
layer->SetHasRenderSurface(true);
layer->draw_properties().render_target = layer.get();
@@ -59,7 +59,9 @@ void QuadSizeTest(scoped_ptr<UIResourceLayerImpl> layer,
TEST(UIResourceLayerImplTest, VerifyDrawQuads) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeUIResourceLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
+ TestTaskGraphRunner task_graph_runner;
+ FakeUIResourceLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
host_impl.InitializeRenderer(FakeOutputSurface::Create3d());
// Make sure we're appending quads when there are valid values.
@@ -103,7 +105,9 @@ void OpaqueBoundsTest(scoped_ptr<UIResourceLayerImpl> layer,
TEST(UIResourceLayerImplTest, VerifySetOpaqueOnSkBitmap) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeUIResourceLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
+ TestTaskGraphRunner task_graph_runner;
+ FakeUIResourceLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
host_impl.InitializeRenderer(FakeOutputSurface::Create3d());
gfx::Size bitmap_size(100, 100);
@@ -131,7 +135,9 @@ TEST(UIResourceLayerImplTest, VerifySetOpaqueOnSkBitmap) {
TEST(UIResourceLayerImplTest, VerifySetOpaqueOnLayer) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeUIResourceLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
+ TestTaskGraphRunner task_graph_runner;
+ FakeUIResourceLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
host_impl.InitializeRenderer(FakeOutputSurface::Create3d());
gfx::Size bitmap_size(100, 100);
@@ -167,7 +173,6 @@ TEST(UIResourceLayerImplTest, Occlusion) {
UIResourceLayerImpl* ui_resource_layer_impl =
impl.AddChildToRoot<UIResourceLayerImpl>();
ui_resource_layer_impl->SetBounds(layer_size);
- ui_resource_layer_impl->SetContentBounds(layer_size);
ui_resource_layer_impl->SetDrawsContent(true);
ui_resource_layer_impl->SetUIResourceId(uid);
@@ -185,7 +190,7 @@ TEST(UIResourceLayerImplTest, Occlusion) {
{
SCOPED_TRACE("Full occlusion");
- gfx::Rect occluded(ui_resource_layer_impl->visible_content_rect());
+ gfx::Rect occluded(ui_resource_layer_impl->visible_layer_rect());
impl.AppendQuadsWithOcclusion(ui_resource_layer_impl, occluded);
LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect());
diff --git a/chromium/cc/layers/ui_resource_layer_unittest.cc b/chromium/cc/layers/ui_resource_layer_unittest.cc
index d0d356d6c5a..3d2681e74bd 100644
--- a/chromium/cc/layers/ui_resource_layer_unittest.cc
+++ b/chromium/cc/layers/ui_resource_layer_unittest.cc
@@ -5,17 +5,15 @@
#include "cc/layers/ui_resource_layer.h"
#include "base/thread_task_runner_handle.h"
-#include "cc/resources/prioritized_resource_manager.h"
#include "cc/resources/resource_provider.h"
-#include "cc/resources/resource_update_queue.h"
#include "cc/resources/scoped_ui_resource.h"
#include "cc/test/fake_layer_tree_host.h"
#include "cc/test/fake_layer_tree_host_client.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_output_surface_client.h"
#include "cc/test/geometry_test_utils.h"
+#include "cc/test/test_task_graph_runner.h"
#include "cc/trees/layer_tree_host.h"
-#include "cc/trees/occlusion_tracker.h"
#include "cc/trees/single_thread_proxy.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -31,8 +29,9 @@ namespace {
class TestUIResourceLayer : public UIResourceLayer {
public:
- static scoped_refptr<TestUIResourceLayer> Create() {
- return make_scoped_refptr(new TestUIResourceLayer());
+ static scoped_refptr<TestUIResourceLayer> Create(
+ const LayerSettings& settings) {
+ return make_scoped_refptr(new TestUIResourceLayer(settings));
}
UIResourceId GetUIResourceId() {
@@ -42,7 +41,10 @@ class TestUIResourceLayer : public UIResourceLayer {
}
protected:
- TestUIResourceLayer() : UIResourceLayer() { SetIsDrawable(true); }
+ explicit TestUIResourceLayer(const LayerSettings& settings)
+ : UIResourceLayer(settings) {
+ SetIsDrawable(true);
+ }
~TestUIResourceLayer() override {}
};
@@ -52,7 +54,8 @@ class UIResourceLayerTest : public testing::Test {
protected:
void SetUp() override {
- layer_tree_host_ = FakeLayerTreeHost::Create(&fake_client_);
+ layer_tree_host_ =
+ FakeLayerTreeHost::Create(&fake_client_, &task_graph_runner_);
layer_tree_host_->InitializeSingleThreaded(
&fake_client_, base::ThreadTaskRunnerHandle::Get(), nullptr);
}
@@ -62,11 +65,14 @@ class UIResourceLayerTest : public testing::Test {
}
FakeLayerTreeHostClient fake_client_;
+ TestTaskGraphRunner task_graph_runner_;
scoped_ptr<FakeLayerTreeHost> layer_tree_host_;
+ LayerSettings layer_settings_;
};
TEST_F(UIResourceLayerTest, SetBitmap) {
- scoped_refptr<UIResourceLayer> test_layer = TestUIResourceLayer::Create();
+ scoped_refptr<UIResourceLayer> test_layer =
+ TestUIResourceLayer::Create(layer_settings_);
ASSERT_TRUE(test_layer.get());
test_layer->SetBounds(gfx::Size(100, 100));
@@ -74,11 +80,8 @@ TEST_F(UIResourceLayerTest, SetBitmap) {
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get());
- ResourceUpdateQueue queue;
- gfx::Rect screen_space_clip_rect;
- OcclusionTracker<Layer> occlusion_tracker(screen_space_clip_rect);
test_layer->SavePaintProperties();
- test_layer->Update(&queue, &occlusion_tracker);
+ test_layer->Update();
EXPECT_FALSE(test_layer->DrawsContent());
@@ -87,13 +90,14 @@ TEST_F(UIResourceLayerTest, SetBitmap) {
bitmap.setImmutable();
test_layer->SetBitmap(bitmap);
- test_layer->Update(&queue, &occlusion_tracker);
+ test_layer->Update();
EXPECT_TRUE(test_layer->DrawsContent());
}
TEST_F(UIResourceLayerTest, SetUIResourceId) {
- scoped_refptr<TestUIResourceLayer> test_layer = TestUIResourceLayer::Create();
+ scoped_refptr<TestUIResourceLayer> test_layer =
+ TestUIResourceLayer::Create(layer_settings_);
ASSERT_TRUE(test_layer.get());
test_layer->SetBounds(gfx::Size(100, 100));
@@ -101,11 +105,8 @@ TEST_F(UIResourceLayerTest, SetUIResourceId) {
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get());
- ResourceUpdateQueue queue;
- gfx::Rect screen_space_clip_rect;
- OcclusionTracker<Layer> occlusion_tracker(screen_space_clip_rect);
test_layer->SavePaintProperties();
- test_layer->Update(&queue, &occlusion_tracker);
+ test_layer->Update();
EXPECT_FALSE(test_layer->DrawsContent());
@@ -113,7 +114,7 @@ TEST_F(UIResourceLayerTest, SetUIResourceId) {
scoped_ptr<ScopedUIResource> resource = ScopedUIResource::Create(
layer_tree_host_.get(), UIResourceBitmap(gfx::Size(10, 10), is_opaque));
test_layer->SetUIResourceId(resource->id());
- test_layer->Update(&queue, &occlusion_tracker);
+ test_layer->Update();
EXPECT_TRUE(test_layer->DrawsContent());
@@ -128,7 +129,8 @@ TEST_F(UIResourceLayerTest, SetUIResourceId) {
}
TEST_F(UIResourceLayerTest, BitmapClearedOnSetUIResourceId) {
- scoped_refptr<UIResourceLayer> test_layer = TestUIResourceLayer::Create();
+ scoped_refptr<UIResourceLayer> test_layer =
+ TestUIResourceLayer::Create(layer_settings_);
ASSERT_TRUE(test_layer.get());
test_layer->SetBounds(gfx::Size(100, 100));
diff --git a/chromium/cc/layers/video_frame_provider_client_impl.h b/chromium/cc/layers/video_frame_provider_client_impl.h
index 5429228b49b..e626b541405 100644
--- a/chromium/cc/layers/video_frame_provider_client_impl.h
+++ b/chromium/cc/layers/video_frame_provider_client_impl.h
@@ -59,6 +59,10 @@ class CC_EXPORT VideoFrameProviderClientImpl
void DidReceiveFrame() override;
void DidUpdateMatrix(const float* matrix) override;
+ const VideoFrameProvider* get_provider_for_testing() const {
+ return provider_;
+ }
+
private:
friend class base::RefCounted<VideoFrameProviderClientImpl>;
diff --git a/chromium/cc/layers/video_frame_provider_client_impl_unittest.cc b/chromium/cc/layers/video_frame_provider_client_impl_unittest.cc
new file mode 100644
index 00000000000..05385e46e56
--- /dev/null
+++ b/chromium/cc/layers/video_frame_provider_client_impl_unittest.cc
@@ -0,0 +1,166 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/layers/video_frame_provider_client_impl.h"
+#include "cc/layers/video_layer_impl.h"
+#include "cc/output/begin_frame_args.h"
+#include "cc/test/fake_video_frame_provider.h"
+#include "cc/test/layer_test_common.h"
+#include "media/base/video_frame.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::_;
+
+namespace cc {
+
+// NOTE: We cannot use DebugScopedSetImplThreadAndMainThreadBlocked in these
+// tests because it gets destroyed before the VideoLayerImpl is destroyed. This
+// causes a DCHECK in VideoLayerImpl's destructor to fail.
+static void DebugSetImplThreadAndMainThreadBlocked(Proxy* proxy) {
+#if DCHECK_IS_ON()
+ proxy->SetCurrentThreadIsImplThread(true);
+ proxy->SetMainThreadBlocked(true);
+#endif
+}
+
+class VideoFrameProviderClientImplTest : public testing::Test,
+ public VideoFrameControllerClient {
+ public:
+ VideoFrameProviderClientImplTest()
+ : client_impl_(VideoFrameProviderClientImpl::Create(&provider_, this)),
+ video_layer_impl_(nullptr),
+ test_frame_(media::VideoFrame::CreateFrame(media::VideoFrame::YV12,
+ gfx::Size(10, 10),
+ gfx::Rect(10, 10),
+ gfx::Size(10, 10),
+ base::TimeDelta())) {
+ DebugSetImplThreadAndMainThreadBlocked(impl_.proxy());
+ }
+
+ ~VideoFrameProviderClientImplTest() {
+ if (!client_impl_->Stopped()) {
+ client_impl_->Stop();
+ DCHECK(client_impl_->Stopped());
+ DCHECK(!client_impl_->ActiveVideoLayer());
+ }
+
+ provider_.SetVideoFrameProviderClient(nullptr);
+ }
+
+ void StartRendering() {
+ EXPECT_CALL(*this, AddVideoFrameController(_));
+ client_impl_->StartRendering();
+ }
+
+ void StopRendering() {
+ EXPECT_CALL(*this, RemoveVideoFrameController(_));
+ client_impl_->StopRendering();
+ }
+
+ void StartRenderingAndRenderFrame() {
+ EXPECT_FALSE(client_impl_->HasCurrentFrame());
+ provider_.set_frame(test_frame_);
+ EXPECT_TRUE(client_impl_->HasCurrentFrame());
+
+ // Start rendering and verify SetNeedsRedraw() was called for the new frame.
+ StartRendering();
+ EXPECT_EQ(gfx::Rect(), video_layer_impl_->update_rect());
+ client_impl_->OnBeginFrame(BeginFrameArgs());
+ EXPECT_NE(gfx::Rect(), video_layer_impl_->update_rect());
+ }
+
+ void CreateActiveVideoLayer() {
+ gfx::Size layer_size(100, 100);
+ video_layer_impl_ = impl_.AddChildToRoot<VideoLayerImpl>(
+ &provider_, media::VIDEO_ROTATION_0);
+ video_layer_impl_->SetBounds(layer_size);
+ video_layer_impl_->SetDrawsContent(true);
+ client_impl_->SetActiveVideoLayer(video_layer_impl_);
+ ASSERT_TRUE(client_impl_->ActiveVideoLayer());
+ }
+
+ MOCK_METHOD1(AddVideoFrameController, void(VideoFrameController*));
+ MOCK_METHOD1(RemoveVideoFrameController, void(VideoFrameController*));
+
+ protected:
+ FakeVideoFrameProvider provider_;
+ LayerTestCommon::LayerImplTest impl_;
+ scoped_refptr<VideoFrameProviderClientImpl> client_impl_;
+ VideoLayerImpl* video_layer_impl_;
+ scoped_refptr<media::VideoFrame> test_frame_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(VideoFrameProviderClientImplTest);
+};
+
+TEST_F(VideoFrameProviderClientImplTest, StartStopRendering) {
+ StartRendering();
+ StopRendering();
+}
+
+TEST_F(VideoFrameProviderClientImplTest, StopUsingProvider) {
+ ASSERT_TRUE(client_impl_->get_provider_for_testing());
+ StartRendering();
+ EXPECT_CALL(*this, RemoveVideoFrameController(_));
+ client_impl_->StopUsingProvider();
+ ASSERT_FALSE(client_impl_->get_provider_for_testing());
+}
+
+TEST_F(VideoFrameProviderClientImplTest, FrameAcquisition) {
+ CreateActiveVideoLayer();
+ StartRenderingAndRenderFrame();
+
+ // Verify GetCurrentFrame() and PutCurrentFrame() work correctly.
+ EXPECT_EQ(test_frame_, client_impl_->AcquireLockAndCurrentFrame());
+ EXPECT_EQ(0, provider_.put_current_frame_count());
+ client_impl_->PutCurrentFrame();
+ EXPECT_EQ(1, provider_.put_current_frame_count());
+
+ client_impl_->ReleaseLock();
+ StopRendering();
+}
+
+TEST_F(VideoFrameProviderClientImplTest, DidReceiveFrame) {
+ CreateActiveVideoLayer();
+ EXPECT_EQ(gfx::Rect(), video_layer_impl_->update_rect());
+ client_impl_->DidReceiveFrame();
+ EXPECT_NE(gfx::Rect(), video_layer_impl_->update_rect());
+}
+
+TEST_F(VideoFrameProviderClientImplTest, DidDrawFrameIssuesPutCurrentFrame) {
+ CreateActiveVideoLayer();
+ StartRenderingAndRenderFrame();
+ EXPECT_EQ(0, provider_.put_current_frame_count());
+ client_impl_->DidDrawFrame();
+ EXPECT_EQ(1, provider_.put_current_frame_count());
+ StopRendering();
+}
+
+TEST_F(VideoFrameProviderClientImplTest, StreamTextureMatrix) {
+ const float kIdentityMatrix[] = {
+ 1.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ };
+
+ EXPECT_FALSE(client_impl_->StreamTextureMatrix().IsIdentity());
+ client_impl_->DidUpdateMatrix(kIdentityMatrix);
+ EXPECT_TRUE(client_impl_->StreamTextureMatrix().IsIdentity());
+}
+
+} // namespace cc
diff --git a/chromium/cc/layers/video_layer.cc b/chromium/cc/layers/video_layer.cc
index fe37fbf47de..cae00aacf1d 100644
--- a/chromium/cc/layers/video_layer.cc
+++ b/chromium/cc/layers/video_layer.cc
@@ -9,14 +9,16 @@
namespace cc {
scoped_refptr<VideoLayer> VideoLayer::Create(
+ const LayerSettings& settings,
VideoFrameProvider* provider,
media::VideoRotation video_rotation) {
- return make_scoped_refptr(new VideoLayer(provider, video_rotation));
+ return make_scoped_refptr(new VideoLayer(settings, provider, video_rotation));
}
-VideoLayer::VideoLayer(VideoFrameProvider* provider,
+VideoLayer::VideoLayer(const LayerSettings& settings,
+ VideoFrameProvider* provider,
media::VideoRotation video_rotation)
- : provider_(provider), video_rotation_(video_rotation) {
+ : Layer(settings), provider_(provider), video_rotation_(video_rotation) {
DCHECK(provider_);
}
@@ -28,9 +30,8 @@ scoped_ptr<LayerImpl> VideoLayer::CreateLayerImpl(LayerTreeImpl* tree_impl) {
return impl.Pass();
}
-bool VideoLayer::Update(ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion) {
- bool updated = Layer::Update(queue, occlusion);
+bool VideoLayer::Update() {
+ bool updated = Layer::Update();
// Video layer doesn't update any resources from the main thread side,
// but repaint rects need to be sent to the VideoLayerImpl via commit.
diff --git a/chromium/cc/layers/video_layer.h b/chromium/cc/layers/video_layer.h
index bbcff36d52d..575de4664f0 100644
--- a/chromium/cc/layers/video_layer.h
+++ b/chromium/cc/layers/video_layer.h
@@ -20,16 +20,18 @@ class VideoLayerImpl;
// A Layer that contains a Video element.
class CC_EXPORT VideoLayer : public Layer {
public:
- static scoped_refptr<VideoLayer> Create(VideoFrameProvider* provider,
+ static scoped_refptr<VideoLayer> Create(const LayerSettings& settings,
+ VideoFrameProvider* provider,
media::VideoRotation video_rotation);
scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
- bool Update(ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion) override;
+ bool Update() override;
private:
- VideoLayer(VideoFrameProvider* provider, media::VideoRotation video_rotation);
+ VideoLayer(const LayerSettings& settings,
+ VideoFrameProvider* provider,
+ media::VideoRotation video_rotation);
~VideoLayer() override;
// This pointer is only for passing to VideoLayerImpl's constructor. It should
diff --git a/chromium/cc/layers/video_layer_impl.cc b/chromium/cc/layers/video_layer_impl.cc
index d73786d9bf4..2233583ed09 100644
--- a/chromium/cc/layers/video_layer_impl.cc
+++ b/chromium/cc/layers/video_layer_impl.cc
@@ -124,8 +124,11 @@ bool VideoLayerImpl::WillDraw(DrawMode draw_mode,
unsigned resource_id = resource_provider->CreateResourceFromTextureMailbox(
external_resources.mailboxes[i],
SingleReleaseCallbackImpl::Create(
- external_resources.release_callbacks[i]));
- frame_resources_.push_back(resource_id);
+ external_resources.release_callbacks[i]),
+ external_resources.read_lock_fences_enabled);
+ frame_resources_.push_back(FrameResource(
+ resource_id, external_resources.mailboxes[i].size_in_pixels(),
+ external_resources.mailboxes[i].allow_overlay()));
}
return true;
@@ -136,7 +139,7 @@ void VideoLayerImpl::AppendQuads(RenderPass* render_pass,
DCHECK(frame_.get());
gfx::Transform transform = draw_transform();
- gfx::Size rotated_size = content_bounds();
+ gfx::Size rotated_size = bounds();
switch (video_rotation_) {
case media::VIDEO_ROTATION_90:
@@ -158,7 +161,7 @@ void VideoLayerImpl::AppendQuads(RenderPass* render_pass,
SharedQuadState* shared_quad_state =
render_pass->CreateAndAppendSharedQuadState();
- shared_quad_state->SetAll(transform, rotated_size, visible_content_rect(),
+ shared_quad_state->SetAll(transform, rotated_size, visible_layer_rect(),
clip_rect(), is_clipped(), draw_opacity(),
draw_blend_mode(), sorting_context_id());
@@ -219,17 +222,22 @@ void VideoLayerImpl::AppendQuads(RenderPass* render_pass,
DCHECK_GE(frame_resources_.size(), 3u);
YUVVideoDrawQuad::ColorSpace color_space = YUVVideoDrawQuad::REC_601;
- if (frame_->format() == media::VideoFrame::YV12J) {
- color_space = YUVVideoDrawQuad::JPEG;
- } else if (frame_->format() == media::VideoFrame::YV12HD) {
- color_space = YUVVideoDrawQuad::REC_709;
+ int videoframe_color_space;
+ if (frame_->metadata()->GetInteger(media::VideoFrameMetadata::COLOR_SPACE,
+ &videoframe_color_space)) {
+ if (videoframe_color_space == media::VideoFrame::COLOR_SPACE_JPEG) {
+ color_space = YUVVideoDrawQuad::JPEG;
+ } else if (videoframe_color_space ==
+ media::VideoFrame::COLOR_SPACE_HD_REC709) {
+ color_space = YUVVideoDrawQuad::REC_709;
+ }
}
const gfx::Size ya_tex_size = coded_size;
gfx::Size uv_tex_size;
- if (frame_->format() == media::VideoFrame::NATIVE_TEXTURE) {
- DCHECK_EQ(media::VideoFrame::TEXTURE_YUV_420, frame_->texture_format());
+ if (frame_->HasTextures()) {
+ DCHECK_EQ(media::VideoFrame::I420, frame_->format());
DCHECK_EQ(3u, frame_resources_.size()); // Alpha is not supported yet.
DCHECK(visible_rect.origin().IsOrigin());
DCHECK(visible_rect.size() == coded_size);
@@ -266,8 +274,10 @@ void VideoLayerImpl::AppendQuads(RenderPass* render_pass,
yuv_video_quad->SetNew(
shared_quad_state, quad_rect, opaque_rect, visible_quad_rect,
ya_tex_coord_rect, uv_tex_coord_rect, ya_tex_size, uv_tex_size,
- frame_resources_[0], frame_resources_[1], frame_resources_[2],
- frame_resources_.size() > 3 ? frame_resources_[3] : 0, color_space);
+ frame_resources_[0].id, frame_resources_[1].id,
+ frame_resources_[2].id,
+ frame_resources_.size() > 3 ? frame_resources_[3].id : 0,
+ color_space);
ValidateQuadResources(yuv_video_quad);
break;
}
@@ -285,17 +295,10 @@ void VideoLayerImpl::AppendQuads(RenderPass* render_pass,
bool nearest_neighbor = false;
TextureDrawQuad* texture_quad =
render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
- texture_quad->SetNew(shared_quad_state,
- quad_rect,
- opaque_rect,
- visible_quad_rect,
- frame_resources_[0],
- premultiplied_alpha,
- uv_top_left,
- uv_bottom_right,
- SK_ColorTRANSPARENT,
- opacity,
- flipped,
+ texture_quad->SetNew(shared_quad_state, quad_rect, opaque_rect,
+ visible_quad_rect, frame_resources_[0].id,
+ premultiplied_alpha, uv_top_left, uv_bottom_right,
+ SK_ColorTRANSPARENT, opacity, flipped,
nearest_neighbor);
ValidateQuadResources(texture_quad);
break;
@@ -310,7 +313,8 @@ void VideoLayerImpl::AppendQuads(RenderPass* render_pass,
render_pass->CreateAndAppendDrawQuad<StreamVideoDrawQuad>();
stream_video_quad->SetNew(
shared_quad_state, quad_rect, opaque_rect, visible_quad_rect,
- frame_resources_[0],
+ frame_resources_[0].id, frame_resources_[0].size_in_pixels,
+ frame_resources_[0].allow_overlay,
scale * provider_client_impl_->StreamTextureMatrix());
ValidateQuadResources(stream_video_quad);
break;
@@ -321,12 +325,9 @@ void VideoLayerImpl::AppendQuads(RenderPass* render_pass,
break;
IOSurfaceDrawQuad* io_surface_quad =
render_pass->CreateAndAppendDrawQuad<IOSurfaceDrawQuad>();
- io_surface_quad->SetNew(shared_quad_state,
- quad_rect,
- opaque_rect,
- visible_quad_rect,
- visible_rect.size(),
- frame_resources_[0],
+ io_surface_quad->SetNew(shared_quad_state, quad_rect, opaque_rect,
+ visible_quad_rect, visible_rect.size(),
+ frame_resources_[0].id,
IOSurfaceDrawQuad::UNFLIPPED);
ValidateQuadResources(io_surface_quad);
break;
@@ -378,7 +379,7 @@ void VideoLayerImpl::DidDraw(ResourceProvider* resource_provider) {
software_release_callback_.Reset();
} else {
for (size_t i = 0; i < frame_resources_.size(); ++i)
- resource_provider->DeleteResource(frame_resources_[i]);
+ resource_provider->DeleteResource(frame_resources_[i].id);
frame_resources_.clear();
}
@@ -388,11 +389,11 @@ void VideoLayerImpl::DidDraw(ResourceProvider* resource_provider) {
provider_client_impl_->ReleaseLock();
}
-SimpleEnclosedRegion VideoLayerImpl::VisibleContentOpaqueRegion() const {
+SimpleEnclosedRegion VideoLayerImpl::VisibleOpaqueRegion() const {
// If we don't have a frame yet, then we don't have an opaque region.
if (!provider_client_impl_->HasCurrentFrame())
return SimpleEnclosedRegion();
- return LayerImpl::VisibleContentOpaqueRegion();
+ return LayerImpl::VisibleOpaqueRegion();
}
void VideoLayerImpl::ReleaseResources() {
diff --git a/chromium/cc/layers/video_layer_impl.h b/chromium/cc/layers/video_layer_impl.h
index aea38b5cbbe..6fab7f58dcb 100644
--- a/chromium/cc/layers/video_layer_impl.h
+++ b/chromium/cc/layers/video_layer_impl.h
@@ -38,7 +38,7 @@ class CC_EXPORT VideoLayerImpl : public LayerImpl {
void AppendQuads(RenderPass* render_pass,
AppendQuadsData* append_quads_data) override;
void DidDraw(ResourceProvider* resource_provider) override;
- SimpleEnclosedRegion VisibleContentOpaqueRegion() const override;
+ SimpleEnclosedRegion VisibleOpaqueRegion() const override;
void DidBecomeActive() override;
void ReleaseResources() override;
@@ -62,7 +62,16 @@ class CC_EXPORT VideoLayerImpl : public LayerImpl {
scoped_ptr<VideoResourceUpdater> updater_;
VideoFrameExternalResources::ResourceType frame_resource_type_;
- std::vector<ResourceProvider::ResourceId> frame_resources_;
+ struct FrameResource {
+ FrameResource(ResourceId id, gfx::Size size_in_pixels, bool allow_overlay)
+ : id(id),
+ size_in_pixels(size_in_pixels),
+ allow_overlay(allow_overlay) {}
+ ResourceId id;
+ gfx::Size size_in_pixels;
+ bool allow_overlay;
+ };
+ std::vector<FrameResource> frame_resources_;
// TODO(danakj): Remove these, hide software path inside ResourceProvider and
// ExternalResource (aka TextureMailbox) classes.
diff --git a/chromium/cc/layers/video_layer_impl_unittest.cc b/chromium/cc/layers/video_layer_impl_unittest.cc
index b0ecff95d39..da2de85d9ef 100644
--- a/chromium/cc/layers/video_layer_impl_unittest.cc
+++ b/chromium/cc/layers/video_layer_impl_unittest.cc
@@ -47,7 +47,6 @@ TEST(VideoLayerImplTest, Occlusion) {
VideoLayerImpl* video_layer_impl =
impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0);
video_layer_impl->SetBounds(layer_size);
- video_layer_impl->SetContentBounds(layer_size);
video_layer_impl->SetDrawsContent(true);
impl.CalcDrawProps(viewport_size);
@@ -64,7 +63,7 @@ TEST(VideoLayerImplTest, Occlusion) {
{
SCOPED_TRACE("Full occlusion");
- gfx::Rect occluded(video_layer_impl->visible_content_rect());
+ gfx::Rect occluded(video_layer_impl->visible_layer_rect());
impl.AppendQuadsWithOcclusion(video_layer_impl, occluded);
LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect());
@@ -98,7 +97,6 @@ TEST(VideoLayerImplTest, OccludesOtherLayers) {
scoped_ptr<LayerImpl> layer_impl = LayerImpl::Create(active_tree, 3);
layer_impl->SetHasRenderSurface(true);
layer_impl->SetBounds(layer_size);
- layer_impl->SetContentBounds(layer_size);
layer_impl->SetDrawsContent(true);
const auto& draw_properties = layer_impl->draw_properties();
@@ -106,13 +104,14 @@ TEST(VideoLayerImplTest, OccludesOtherLayers) {
scoped_ptr<VideoLayerImpl> video_layer_impl = VideoLayerImpl::Create(
active_tree, 4, &provider, media::VIDEO_ROTATION_0);
video_layer_impl->SetBounds(layer_size);
- video_layer_impl->SetContentBounds(layer_size);
video_layer_impl->SetDrawsContent(true);
video_layer_impl->SetContentsOpaque(true);
layer_impl->AddChild(video_layer_impl.Pass());
active_tree->SetRootLayer(layer_impl.Pass());
+ active_tree->BuildPropertyTreesForTesting();
+
active_tree->UpdateDrawProperties(false);
// We don't have a frame yet, so the video doesn't occlude the layer below it.
@@ -165,7 +164,6 @@ TEST(VideoLayerImplTest, Rotated0) {
VideoLayerImpl* video_layer_impl =
impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0);
video_layer_impl->SetBounds(layer_size);
- video_layer_impl->SetContentBounds(layer_size);
video_layer_impl->SetDrawsContent(true);
impl.CalcDrawProps(viewport_size);
@@ -176,8 +174,12 @@ TEST(VideoLayerImplTest, Rotated0) {
gfx::Point3F p1(0, impl.quad_list().front()->rect.height(), 0);
gfx::Point3F p2(impl.quad_list().front()->rect.width(), 0, 0);
- impl.quad_list().front()->quadTransform().TransformPoint(&p1);
- impl.quad_list().front()->quadTransform().TransformPoint(&p2);
+ impl.quad_list()
+ .front()
+ ->shared_quad_state->quad_to_target_transform.TransformPoint(&p1);
+ impl.quad_list()
+ .front()
+ ->shared_quad_state->quad_to_target_transform.TransformPoint(&p2);
EXPECT_EQ(gfx::Point3F(0, 50, 0), p1);
EXPECT_EQ(gfx::Point3F(100, 0, 0), p2);
}
@@ -201,7 +203,6 @@ TEST(VideoLayerImplTest, Rotated90) {
VideoLayerImpl* video_layer_impl =
impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_90);
video_layer_impl->SetBounds(layer_size);
- video_layer_impl->SetContentBounds(layer_size);
video_layer_impl->SetDrawsContent(true);
impl.CalcDrawProps(viewport_size);
@@ -212,8 +213,12 @@ TEST(VideoLayerImplTest, Rotated90) {
gfx::Point3F p1(0, impl.quad_list().front()->rect.height(), 0);
gfx::Point3F p2(impl.quad_list().front()->rect.width(), 0, 0);
- impl.quad_list().front()->quadTransform().TransformPoint(&p1);
- impl.quad_list().front()->quadTransform().TransformPoint(&p2);
+ impl.quad_list()
+ .front()
+ ->shared_quad_state->quad_to_target_transform.TransformPoint(&p1);
+ impl.quad_list()
+ .front()
+ ->shared_quad_state->quad_to_target_transform.TransformPoint(&p2);
EXPECT_EQ(gfx::Point3F(0, 0, 0), p1);
EXPECT_EQ(gfx::Point3F(100, 50, 0), p2);
}
@@ -237,7 +242,6 @@ TEST(VideoLayerImplTest, Rotated180) {
VideoLayerImpl* video_layer_impl =
impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_180);
video_layer_impl->SetBounds(layer_size);
- video_layer_impl->SetContentBounds(layer_size);
video_layer_impl->SetDrawsContent(true);
impl.CalcDrawProps(viewport_size);
@@ -248,8 +252,12 @@ TEST(VideoLayerImplTest, Rotated180) {
gfx::Point3F p1(0, impl.quad_list().front()->rect.height(), 0);
gfx::Point3F p2(impl.quad_list().front()->rect.width(), 0, 0);
- impl.quad_list().front()->quadTransform().TransformPoint(&p1);
- impl.quad_list().front()->quadTransform().TransformPoint(&p2);
+ impl.quad_list()
+ .front()
+ ->shared_quad_state->quad_to_target_transform.TransformPoint(&p1);
+ impl.quad_list()
+ .front()
+ ->shared_quad_state->quad_to_target_transform.TransformPoint(&p2);
EXPECT_EQ(gfx::Point3F(100, 0, 0), p1);
EXPECT_EQ(gfx::Point3F(0, 50, 0), p2);
}
@@ -273,7 +281,6 @@ TEST(VideoLayerImplTest, Rotated270) {
VideoLayerImpl* video_layer_impl =
impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_270);
video_layer_impl->SetBounds(layer_size);
- video_layer_impl->SetContentBounds(layer_size);
video_layer_impl->SetDrawsContent(true);
impl.CalcDrawProps(viewport_size);
@@ -284,8 +291,12 @@ TEST(VideoLayerImplTest, Rotated270) {
gfx::Point3F p1(0, impl.quad_list().front()->rect.height(), 0);
gfx::Point3F p2(impl.quad_list().front()->rect.width(), 0, 0);
- impl.quad_list().front()->quadTransform().TransformPoint(&p1);
- impl.quad_list().front()->quadTransform().TransformPoint(&p2);
+ impl.quad_list()
+ .front()
+ ->shared_quad_state->quad_to_target_transform.TransformPoint(&p1);
+ impl.quad_list()
+ .front()
+ ->shared_quad_state->quad_to_target_transform.TransformPoint(&p2);
EXPECT_EQ(gfx::Point3F(100, 50, 0), p1);
EXPECT_EQ(gfx::Point3F(0, 0, 0), p2);
}
@@ -313,7 +324,6 @@ TEST(VideoLayerImplTest, SoftwareVideoFrameGeneratesYUVQuad) {
VideoLayerImpl* video_layer_impl =
impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0);
video_layer_impl->SetBounds(layer_size);
- video_layer_impl->SetContentBounds(layer_size);
video_layer_impl->SetDrawsContent(true);
gfx::Rect occluded;
@@ -345,14 +355,15 @@ TEST(VideoLayerImplTest, NativeYUVFrameGeneratesYUVQuad) {
media::VideoFrame::WrapYUV420NativeTextures(
mailbox_holder, mailbox_holder, mailbox_holder,
base::Bind(EmptyCallback), gfx::Size(10, 10), gfx::Rect(10, 10),
- gfx::Size(10, 10), base::TimeDelta(), true);
+ gfx::Size(10, 10), base::TimeDelta());
+ video_frame->metadata()->SetBoolean(media::VideoFrameMetadata::ALLOW_OVERLAY,
+ true);
FakeVideoFrameProvider provider;
provider.set_frame(video_frame);
VideoLayerImpl* video_layer_impl =
impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0);
video_layer_impl->SetBounds(layer_size);
- video_layer_impl->SetContentBounds(layer_size);
video_layer_impl->SetDrawsContent(true);
gfx::Rect occluded;
diff --git a/chromium/cc/layers/viewport.cc b/chromium/cc/layers/viewport.cc
index 944f1bbd3cf..059e0a491a9 100644
--- a/chromium/cc/layers/viewport.cc
+++ b/chromium/cc/layers/viewport.cc
@@ -20,17 +20,26 @@ scoped_ptr<Viewport> Viewport::Create(
}
Viewport::Viewport(LayerTreeHostImpl* host_impl)
- : host_impl_(host_impl) {
+ : host_impl_(host_impl)
+ , pinch_zoom_active_(false) {
DCHECK(host_impl_);
}
+void Viewport::Pan(const gfx::Vector2dF& delta) {
+ gfx::Vector2dF pending_delta = delta;
+ float page_scale = host_impl_->active_tree()->current_page_scale_factor();
+ pending_delta.Scale(1 / page_scale);
+ InnerScrollLayer()->ScrollBy(pending_delta);
+}
+
Viewport::ScrollResult Viewport::ScrollBy(const gfx::Vector2dF& delta,
const gfx::Point& viewport_point,
- bool is_wheel_scroll) {
+ bool is_wheel_scroll,
+ bool affect_top_controls) {
gfx::Vector2dF content_delta = delta;
ScrollResult result;
- if (ShouldTopControlsConsumeScroll(delta)) {
+ if (affect_top_controls && ShouldTopControlsConsumeScroll(delta)) {
result.top_controls_applied_delta = ScrollTopControls(delta);
content_delta -= result.top_controls_applied_delta;
}
@@ -59,6 +68,70 @@ Viewport::ScrollResult Viewport::ScrollBy(const gfx::Vector2dF& delta,
return result;
}
+void Viewport::SnapPinchAnchorIfWithinMargin(const gfx::Point& anchor) {
+ gfx::SizeF viewport_size =
+ host_impl_->active_tree()->InnerViewportContainerLayer()->bounds();
+
+ if (anchor.x() < kPinchZoomSnapMarginDips)
+ pinch_anchor_adjustment_.set_x(-anchor.x());
+ else if (anchor.x() > viewport_size.width() - kPinchZoomSnapMarginDips)
+ pinch_anchor_adjustment_.set_x(viewport_size.width() - anchor.x());
+
+ if (anchor.y() < kPinchZoomSnapMarginDips)
+ pinch_anchor_adjustment_.set_y(-anchor.y());
+ else if (anchor.y() > viewport_size.height() - kPinchZoomSnapMarginDips)
+ pinch_anchor_adjustment_.set_y(viewport_size.height() - anchor.y());
+}
+
+void Viewport::PinchUpdate(float magnify_delta, const gfx::Point& anchor) {
+ if (!pinch_zoom_active_) {
+ // If this is the first pinch update and the pinch is within a margin-
+ // length of the screen edge, offset all updates by the amount so that we
+ // effectively snap the pinch zoom to the edge of the screen. This makes it
+ // easy to zoom in on position: fixed elements.
+ if (host_impl_->settings().invert_viewport_scroll_order)
+ SnapPinchAnchorIfWithinMargin(anchor);
+
+ pinch_zoom_active_ = true;
+ }
+
+ LayerTreeImpl* active_tree = host_impl_->active_tree();
+
+ // Keep the center-of-pinch anchor specified by (x, y) in a stable
+ // position over the course of the magnify.
+ gfx::Point adjusted_anchor = anchor + pinch_anchor_adjustment_;
+ float page_scale = active_tree->current_page_scale_factor();
+ gfx::PointF previous_scale_anchor =
+ gfx::ScalePoint(adjusted_anchor, 1.f / page_scale);
+ active_tree->SetPageScaleOnActiveTree(page_scale * magnify_delta);
+ page_scale = active_tree->current_page_scale_factor();
+ gfx::PointF new_scale_anchor =
+ gfx::ScalePoint(adjusted_anchor, 1.f / page_scale);
+ gfx::Vector2dF move = previous_scale_anchor - new_scale_anchor;
+
+ // Scale back to viewport space since that's the coordinate space ScrollBy
+ // uses.
+ move.Scale(page_scale);
+
+ // If clamping the inner viewport scroll offset causes a change, it should
+ // be accounted for from the intended move.
+ move -= InnerScrollLayer()->ClampScrollToMaxScrollOffset();
+
+ if (host_impl_->settings().invert_viewport_scroll_order) {
+ Pan(move);
+ } else {
+ gfx::Point viewport_point;
+ bool is_wheel_event = false;
+ bool affect_top_controls = false;
+ ScrollBy(move, viewport_point, is_wheel_event, affect_top_controls);
+ }
+}
+
+void Viewport::PinchEnd() {
+ pinch_anchor_adjustment_ = gfx::Vector2d();
+ pinch_zoom_active_ = false;
+}
+
gfx::Vector2dF Viewport::ScrollTopControls(const gfx::Vector2dF& delta) {
gfx::Vector2dF excess_delta =
host_impl_->top_controls_manager()->ScrollBy(delta);
diff --git a/chromium/cc/layers/viewport.h b/chromium/cc/layers/viewport.h
index 25528af02a4..01885d7774f 100644
--- a/chromium/cc/layers/viewport.h
+++ b/chromium/cc/layers/viewport.h
@@ -20,6 +20,11 @@ class LayerTreeHostImpl;
// class.
class CC_EXPORT Viewport {
public:
+ // If the pinch zoom anchor on the first PinchUpdate is within this length
+ // of the screen edge, "snap" the zoom to that edge. Experimentally
+ // determined.
+ static const int kPinchZoomSnapMarginDips = 100;
+
struct ScrollResult {
gfx::Vector2dF applied_delta;
gfx::Vector2dF unused_scroll_delta;
@@ -28,11 +33,19 @@ class CC_EXPORT Viewport {
static scoped_ptr<Viewport> Create(LayerTreeHostImpl* host_impl);
+ // Differs from scrolling in that only the visual viewport is moved, without
+ // affecting the top controls or outer viewport.
+ void Pan(const gfx::Vector2dF& delta);
+
// Scrolls the viewport, applying the unique bubbling between the inner and
// outer viewport. Scrolls can be consumed by top controls.
ScrollResult ScrollBy(const gfx::Vector2dF& delta,
const gfx::Point& viewport_point,
- bool is_wheel_scroll);
+ bool is_wheel_scroll,
+ bool affect_top_controls);
+
+ void PinchUpdate(float magnify_delta, const gfx::Point& anchor);
+ void PinchEnd();
private:
explicit Viewport(LayerTreeHostImpl* host_impl);
@@ -49,8 +62,16 @@ class CC_EXPORT Viewport {
LayerImpl* InnerScrollLayer() const;
LayerImpl* OuterScrollLayer() const;
+ void SnapPinchAnchorIfWithinMargin(const gfx::Point& anchor);
+
LayerTreeHostImpl* host_impl_;
+ bool pinch_zoom_active_;
+
+ // The pinch zoom anchor point is adjusted by this amount during a pinch. This
+ // is used to "snap" a pinch-zoom to the edge of the screen.
+ gfx::Vector2d pinch_anchor_adjustment_;
+
DISALLOW_COPY_AND_ASSIGN(Viewport);
};
diff --git a/chromium/cc/output/begin_frame_args.cc b/chromium/cc/output/begin_frame_args.cc
index 7a77be2bd52..216eb52587a 100644
--- a/chromium/cc/output/begin_frame_args.cc
+++ b/chromium/cc/output/begin_frame_args.cc
@@ -5,7 +5,6 @@
#include "cc/output/begin_frame_args.h"
#include "base/trace_event/trace_event_argument.h"
-#include "ui/gfx/frame_time.h"
namespace cc {
@@ -28,7 +27,8 @@ BeginFrameArgs::BeginFrameArgs()
: frame_time(base::TimeTicks()),
deadline(base::TimeTicks()),
interval(base::TimeDelta::FromMicroseconds(-1)),
- type(BeginFrameArgs::INVALID) {
+ type(BeginFrameArgs::INVALID),
+ on_critical_path(true) {
}
BeginFrameArgs::BeginFrameArgs(base::TimeTicks frame_time,
@@ -38,7 +38,8 @@ BeginFrameArgs::BeginFrameArgs(base::TimeTicks frame_time,
: frame_time(frame_time),
deadline(deadline),
interval(interval),
- type(type) {
+ type(type),
+ on_critical_path(true) {
}
BeginFrameArgs BeginFrameArgs::Create(BeginFrameArgs::CreationLocation location,
@@ -74,6 +75,7 @@ void BeginFrameArgs::AsValueInto(base::trace_event::TracedValue* state) const {
#ifndef NDEBUG
state->SetString("created_from", created_from.ToString());
#endif
+ state->SetBoolean("on_critical_path", on_critical_path);
}
// This is a hard-coded deadline adjustment that assumes 60Hz, to be used in
diff --git a/chromium/cc/output/begin_frame_args.h b/chromium/cc/output/begin_frame_args.h
index c22f7fdde97..1a7ae5f97a0 100644
--- a/chromium/cc/output/begin_frame_args.h
+++ b/chromium/cc/output/begin_frame_args.h
@@ -83,6 +83,7 @@ struct CC_EXPORT BeginFrameArgs {
base::TimeTicks deadline;
base::TimeDelta interval;
BeginFrameArgsType type;
+ bool on_critical_path;
private:
BeginFrameArgs(base::TimeTicks frame_time,
diff --git a/chromium/cc/output/begin_frame_args_unittest.cc b/chromium/cc/output/begin_frame_args_unittest.cc
index 877a857c632..c6f5a4203c9 100644
--- a/chromium/cc/output/begin_frame_args_unittest.cc
+++ b/chromium/cc/output/begin_frame_args_unittest.cc
@@ -8,7 +8,6 @@
#include "cc/test/begin_frame_args_test.h"
#include "testing/gtest/include/gtest/gtest-spi.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/frame_time.h"
namespace cc {
namespace {
@@ -33,7 +32,7 @@ TEST(BeginFrameArgsTest, Helpers) {
BeginFrameArgs args3 =
CreateExpiredBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
EXPECT_TRUE(args3.IsValid()) << args3;
- EXPECT_GT(gfx::FrameTime::Now(), args3.deadline);
+ EXPECT_GT(base::TimeTicks::Now(), args3.deadline);
EXPECT_EQ(BeginFrameArgs::NORMAL, args3.type);
BeginFrameArgs args4 = CreateBeginFrameArgsForTesting(
@@ -78,6 +77,7 @@ TEST(BeginFrameArgsTest, Create) {
// BeginFrames are not valid by default
BeginFrameArgs args1;
EXPECT_FALSE(args1.IsValid()) << args1;
+ EXPECT_TRUE(args1.on_critical_path);
BeginFrameArgs args2 = BeginFrameArgs::Create(
BEGINFRAME_FROM_HERE, base::TimeTicks::FromInternalValue(1),
diff --git a/chromium/cc/output/bsp_walk_action.cc b/chromium/cc/output/bsp_walk_action.cc
index 9ffc2998d5e..8a3369416ce 100644
--- a/chromium/cc/output/bsp_walk_action.cc
+++ b/chromium/cc/output/bsp_walk_action.cc
@@ -27,7 +27,9 @@ BspWalkActionDrawPolygon::BspWalkActionDrawPolygon(
void BspWalkActionDrawPolygon::operator()(DrawPolygon* item) {
gfx::Transform inverse_transform;
bool invertible =
- item->original_ref()->quadTransform().GetInverse(&inverse_transform);
+ item->original_ref()
+ ->shared_quad_state->quad_to_target_transform.GetInverse(
+ &inverse_transform);
DCHECK(invertible);
item->TransformToLayerSpace(inverse_transform);
renderer_->DoDrawPolygon(*item, frame_, render_pass_scissor_,
diff --git a/chromium/cc/output/context_provider.h b/chromium/cc/output/context_provider.h
index dfaab4a15b2..aa4367d97ff 100644
--- a/chromium/cc/output/context_provider.h
+++ b/chromium/cc/output/context_provider.h
@@ -58,9 +58,6 @@ class ContextProvider : public base::RefCountedThreadSafe<ContextProvider> {
// Returns the capabilities of the currently bound 3d context.
virtual Capabilities ContextCapabilities() = 0;
- // Checks if the context is currently known to be lost.
- virtual bool IsContextLost() = 0;
-
// Ask the provider to check if the contexts are valid or lost. If they are,
// this should invalidate the provider so that it can be replaced with a new
// one.
diff --git a/chromium/cc/output/delegating_renderer.cc b/chromium/cc/output/delegating_renderer.cc
index 7906afa77e6..a8fbbb70cde 100644
--- a/chromium/cc/output/delegating_renderer.cc
+++ b/chromium/cc/output/delegating_renderer.cc
@@ -66,13 +66,6 @@ const RendererCapabilitiesImpl& DelegatingRenderer::Capabilities() const {
return capabilities_;
}
-static ResourceProvider::ResourceId AppendToArray(
- ResourceProvider::ResourceIdArray* array,
- ResourceProvider::ResourceId id) {
- array->push_back(id);
- return id;
-}
-
void DelegatingRenderer::DrawFrame(RenderPassList* render_passes_in_draw_order,
float device_scale_factor,
const gfx::Rect& device_viewport_rect,
@@ -90,11 +83,11 @@ void DelegatingRenderer::DrawFrame(RenderPassList* render_passes_in_draw_order,
// Collect all resource ids in the render passes into a ResourceIdArray.
ResourceProvider::ResourceIdArray resources;
- DrawQuad::ResourceIteratorCallback append_to_array =
- base::Bind(&AppendToArray, &resources);
for (const auto& render_pass : out_data.render_pass_list) {
- for (const auto& quad : render_pass->quad_list)
- quad->IterateResources(append_to_array);
+ for (const auto& quad : render_pass->quad_list) {
+ for (ResourceId resource_id : quad->resources)
+ resources.push_back(resource_id);
+ }
}
resource_provider_->PrepareSendToParent(resources, &out_data.resource_list);
}
@@ -116,7 +109,6 @@ void DelegatingRenderer::DidChangeVisibility() {
ContextProvider* context_provider = output_surface_->context_provider();
if (!visible()) {
TRACE_EVENT0("cc", "DelegatingRenderer::SetVisible dropping resources");
- resource_provider_->ReleaseCachedData();
if (context_provider) {
context_provider->DeleteCachedResources();
context_provider->ContextGL()->Flush();
@@ -125,8 +117,13 @@ void DelegatingRenderer::DidChangeVisibility() {
// We loop visibility to the GPU process, since that's what manages memory.
// That will allow it to feed us with memory allocations that we can act
// upon.
- if (context_provider)
+ if (context_provider) {
context_provider->ContextSupport()->SetSurfaceVisible(visible());
+
+ // If we are not visible, we ask the context to aggressively free resources.
+ context_provider->ContextSupport()->SetAggressivelyFreeResources(
+ !visible());
+ }
}
} // namespace cc
diff --git a/chromium/cc/output/direct_renderer.cc b/chromium/cc/output/direct_renderer.cc
index 10bba297434..7ceaa00379f 100644
--- a/chromium/cc/output/direct_renderer.cc
+++ b/chromium/cc/output/direct_renderer.cc
@@ -10,6 +10,7 @@
#include "base/containers/hash_tables.h"
#include "base/containers/scoped_ptr_hash_map.h"
#include "base/metrics/histogram.h"
+#include "base/numerics/safe_conversions.h"
#include "base/trace_event/trace_event.h"
#include "cc/base/math_util.h"
#include "cc/output/bsp_tree.h"
@@ -132,8 +133,7 @@ DirectRenderer::DirectRenderer(RendererClient* client,
: Renderer(client, settings),
output_surface_(output_surface),
resource_provider_(resource_provider),
- overlay_processor_(
- new OverlayProcessor(output_surface, resource_provider)) {
+ overlay_processor_(new OverlayProcessor(output_surface)) {
overlay_processor_->Initialize();
}
@@ -193,8 +193,9 @@ void DirectRenderer::DrawFrame(RenderPassList* render_passes_in_draw_order,
const gfx::Rect& device_clip_rect,
bool disable_picture_quad_image_filtering) {
TRACE_EVENT0("cc", "DirectRenderer::DrawFrame");
- UMA_HISTOGRAM_COUNTS("Renderer4.renderPassCount",
- render_passes_in_draw_order->size());
+ UMA_HISTOGRAM_COUNTS(
+ "Renderer4.renderPassCount",
+ base::saturated_cast<int>(render_passes_in_draw_order->size()));
const RenderPass* root_render_pass = render_passes_in_draw_order->back();
DCHECK(root_render_pass);
@@ -309,8 +310,8 @@ bool DirectRenderer::ShouldSkipQuad(const DrawQuad& quad,
if (render_pass_scissor.IsEmpty())
return true;
- if (quad.isClipped()) {
- gfx::Rect r = quad.clipRect();
+ if (quad.shared_quad_state->is_clipped) {
+ gfx::Rect r = quad.shared_quad_state->clip_rect;
r.Intersect(render_pass_scissor);
return r.IsEmpty();
}
@@ -325,12 +326,12 @@ void DirectRenderer::SetScissorStateForQuad(
bool use_render_pass_scissor) {
if (use_render_pass_scissor) {
gfx::Rect quad_scissor_rect = render_pass_scissor;
- if (quad.isClipped())
- quad_scissor_rect.Intersect(quad.clipRect());
+ if (quad.shared_quad_state->is_clipped)
+ quad_scissor_rect.Intersect(quad.shared_quad_state->clip_rect);
SetScissorTestRectInDrawSpace(frame, quad_scissor_rect);
return;
- } else if (quad.isClipped()) {
- SetScissorTestRectInDrawSpace(frame, quad.clipRect());
+ } else if (quad.shared_quad_state->is_clipped) {
+ SetScissorTestRectInDrawSpace(frame, quad.shared_quad_state->clip_rect);
return;
}
@@ -461,7 +462,8 @@ void DirectRenderer::DrawRenderPass(DrawingFrame* frame,
// polygons to go into the BSP tree.
if (quad.shared_quad_state->sorting_context_id != 0) {
scoped_ptr<DrawPolygon> new_polygon(new DrawPolygon(
- *it, quad.visible_rect, quad.quadTransform(), next_polygon_id++));
+ *it, quad.visible_rect,
+ quad.shared_quad_state->quad_to_target_transform, next_polygon_id++));
if (new_polygon->points().size() > 2u) {
poly_list.push_back(new_polygon.Pass());
}
diff --git a/chromium/cc/output/gl_renderer.cc b/chromium/cc/output/gl_renderer.cc
index 69da9a74754..3ffc676a66d 100644
--- a/chromium/cc/output/gl_renderer.cc
+++ b/chromium/cc/output/gl_renderer.cc
@@ -394,6 +394,9 @@ void GLRenderer::DidChangeVisibility() {
EnforceMemoryPolicy();
context_support_->SetSurfaceVisible(visible());
+
+ // If we are not visible, we ask the context to aggressively free resources.
+ context_support_->SetAggressivelyFreeResources(!visible());
}
void GLRenderer::ReleaseRenderPassTextures() { render_pass_textures_.clear(); }
@@ -452,13 +455,6 @@ void GLRenderer::ClearFramebuffer(DrawingFrame* frame) {
}
}
-static ResourceProvider::ResourceId WaitOnResourceSyncPoints(
- ResourceProvider* resource_provider,
- ResourceProvider::ResourceId resource_id) {
- resource_provider->WaitSyncPointIfNeeded(resource_id);
- return resource_id;
-}
-
void GLRenderer::BeginDrawingFrame(DrawingFrame* frame) {
TRACE_EVENT0("cc", "GLRenderer::BeginDrawingFrame");
@@ -493,12 +489,12 @@ void GLRenderer::BeginDrawingFrame(DrawingFrame* frame) {
// Insert WaitSyncPointCHROMIUM on quad resources prior to drawing the frame,
// so that drawing can proceed without GL context switching interruptions.
- DrawQuad::ResourceIteratorCallback wait_on_resource_syncpoints_callback =
- base::Bind(&WaitOnResourceSyncPoints, resource_provider_);
-
+ ResourceProvider* resource_provider = resource_provider_;
for (const auto& pass : *frame->render_passes_in_draw_order) {
- for (const auto& quad : pass->quad_list)
- quad->IterateResources(wait_on_resource_syncpoints_callback);
+ for (const auto& quad : pass->quad_list) {
+ for (ResourceId resource_id : quad->resources)
+ resource_provider->WaitSyncPointIfNeeded(resource_id);
+ }
}
// TODO(enne): Do we need to reinitialize all of this state per frame?
@@ -604,12 +600,10 @@ void GLRenderer::DrawCheckerboardQuad(const DrawingFrame* frame,
gl_->Uniform1f(program->fragment_shader().frequency_location(), frequency);
- SetShaderOpacity(quad->opacity(),
+ SetShaderOpacity(quad->shared_quad_state->opacity,
program->fragment_shader().alpha_location());
- DrawQuadGeometry(frame,
- quad->quadTransform(),
- quad->rect,
- program->vertex_shader().matrix_location());
+ DrawQuadGeometry(frame, quad->shared_quad_state->quad_to_target_transform,
+ quad->rect, program->vertex_shader().matrix_location());
}
// This function does not handle 3D sorting right now, since the debug border
@@ -628,7 +622,9 @@ void GLRenderer::DrawDebugBorderQuad(const DrawingFrame* frame,
// partial swaps.
gfx::Rect layer_rect = quad->rect;
gfx::Transform render_matrix;
- QuadRectTransform(&render_matrix, quad->quadTransform(), layer_rect);
+ QuadRectTransform(&render_matrix,
+ quad->shared_quad_state->quad_to_target_transform,
+ layer_rect);
GLRenderer::ToGLMatrix(&gl_matrix[0],
frame->projection_matrix * render_matrix);
gl_->UniformMatrix4fv(program->vertex_shader().matrix_location(), 1, false,
@@ -720,15 +716,10 @@ static skia::RefPtr<SkImage> ApplyImageFilter(
canvas->drawSprite(source, 0, 0, &paint);
skia::RefPtr<SkImage> image = skia::AdoptRef(surface->newImageSnapshot());
- if (!image || !image->getTexture()) {
+ if (!image || !image->isTextureBacked()) {
return skia::RefPtr<SkImage>();
}
- // Flush the GrContext to ensure all buffered GL calls are drawn to the
- // backing store before we access and return it, and have cc begin using the
- // GL context again.
- canvas->flush();
-
return image;
}
@@ -938,7 +929,9 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
DCHECK(contents_texture->id());
gfx::Transform quad_rect_matrix;
- QuadRectTransform(&quad_rect_matrix, quad->quadTransform(), quad->rect);
+ QuadRectTransform(&quad_rect_matrix,
+ quad->shared_quad_state->quad_to_target_transform,
+ quad->rect);
gfx::Transform contents_device_transform =
frame->window_matrix * frame->projection_matrix * quad_rect_matrix;
contents_device_transform.FlattenTo2d();
@@ -948,13 +941,22 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
return;
gfx::QuadF surface_quad = SharedGeometryQuad();
- float edge[24];
- bool use_aa = settings_->allow_antialiasing &&
- ShouldAntialiasQuad(contents_device_transform, quad,
- settings_->force_antialiasing);
- SetupQuadForClippingAndAntialiasing(contents_device_transform, quad, use_aa,
- clip_region, &surface_quad, edge);
+ gfx::QuadF device_layer_quad;
+ bool use_aa = false;
+ if (settings_->allow_antialiasing) {
+ bool clipped = false;
+ device_layer_quad =
+ MathUtil::MapQuad(contents_device_transform, surface_quad, &clipped);
+ use_aa = ShouldAntialiasQuad(device_layer_quad, clipped,
+ settings_->force_antialiasing);
+ }
+
+ float edge[24];
+ const gfx::QuadF* aa_quad = use_aa ? &device_layer_quad : nullptr;
+ SetupRenderPassQuadForClippingAndAntialiasing(contents_device_transform, quad,
+ aa_quad, clip_region,
+ &surface_quad, edge);
SkXfermode::Mode blend_mode = quad->shared_quad_state->blend_mode;
bool use_shaders_for_blending =
!CanApplyBlendModeUsingBlendFunc(blend_mode) ||
@@ -963,6 +965,7 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
scoped_ptr<ScopedResource> background_texture;
skia::RefPtr<SkImage> background_image;
+ GLuint background_image_id = 0;
gfx::Rect background_rect;
if (use_shaders_for_blending) {
// Compute a bounding box around the pixels that will be visible through
@@ -987,16 +990,19 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
// pixels' coordinate space.
background_image =
ApplyBackgroundFilters(frame, quad, background_texture.get());
+ if (background_image)
+ background_image_id = background_image->getTextureHandle(true);
+ DCHECK(background_image_id);
}
}
if (!background_texture) {
// Something went wrong with reading the backdrop.
- DCHECK(!background_image);
+ DCHECK(!background_image_id);
use_shaders_for_blending = false;
- } else if (background_image) {
+ } else if (background_image_id) {
// Reset original background texture if there is not any mask
- if (!quad->mask_resource_id)
+ if (!quad->mask_resource_id())
background_texture.reset();
} else if (CanApplyBlendModeUsingBlendFunc(blend_mode) &&
ShouldApplyBackgroundFilters(frame, quad)) {
@@ -1007,9 +1013,9 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
}
// Need original background texture for mask?
bool mask_for_background =
- background_texture && // Have original background texture
- background_image && // Have filtered background texture
- quad->mask_resource_id; // Have mask texture
+ background_texture && // Have original background texture
+ background_image_id && // Have filtered background texture
+ quad->mask_resource_id(); // Have mask texture
SetBlendEnabled(
!use_shaders_for_blending &&
(quad->ShouldDrawWithBlending() || !IsDefaultBlendMode(blend_mode)));
@@ -1017,6 +1023,7 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
// TODO(senorblanco): Cache this value so that we don't have to do it for both
// the surface and its replica. Apply filters to the contents texture.
skia::RefPtr<SkImage> filter_image;
+ GLuint filter_image_id = 0;
SkScalar color_matrix[20];
bool use_color_matrix = false;
if (!quad->filters.IsEmpty()) {
@@ -1039,6 +1046,10 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
filter_image = ApplyImageFilter(
ScopedUseGrContext::Create(this, frame), resource_provider_,
quad->rect, quad->filters_scale, filter.get(), contents_texture);
+ if (filter_image) {
+ filter_image_id = filter_image->getTextureHandle(true);
+ DCHECK(filter_image_id);
+ }
}
}
}
@@ -1046,18 +1057,17 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
scoped_ptr<ResourceProvider::ScopedSamplerGL> mask_resource_lock;
unsigned mask_texture_id = 0;
SamplerType mask_sampler = SAMPLER_TYPE_NA;
- if (quad->mask_resource_id) {
+ if (quad->mask_resource_id()) {
mask_resource_lock.reset(new ResourceProvider::ScopedSamplerGL(
- resource_provider_, quad->mask_resource_id, GL_TEXTURE1, GL_LINEAR));
+ resource_provider_, quad->mask_resource_id(), GL_TEXTURE1, GL_LINEAR));
mask_texture_id = mask_resource_lock->texture_id();
mask_sampler = SamplerTypeFromTextureTarget(mask_resource_lock->target());
}
scoped_ptr<ResourceProvider::ScopedSamplerGL> contents_resource_lock;
- if (filter_image) {
- GrTexture* texture = filter_image->getTexture();
+ if (filter_image_id) {
DCHECK_EQ(GL_TEXTURE0, GetActiveTextureUnit(gl_));
- gl_->BindTexture(GL_TEXTURE_2D, texture->getTextureHandle());
+ gl_->BindTexture(GL_TEXTURE_2D, filter_image_id);
} else {
contents_resource_lock =
make_scoped_ptr(new ResourceProvider::ScopedSamplerGL(
@@ -1074,14 +1084,13 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
}
TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
- gl_,
- &highp_threshold_cache_,
- highp_threshold_min_,
- quad->shared_quad_state->visible_content_rect.bottom_right());
+ gl_, &highp_threshold_cache_, highp_threshold_min_,
+ quad->shared_quad_state->visible_quad_layer_rect.bottom_right());
ShaderLocations locations;
- DCHECK_EQ(background_texture || background_image, use_shaders_for_blending);
+ DCHECK_EQ(background_texture || background_image_id,
+ use_shaders_for_blending);
BlendMode shader_blend_mode = use_shaders_for_blending
? BlendModeFromSkXfermode(blend_mode)
: BLEND_MODE_NONE;
@@ -1220,7 +1229,7 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
scoped_ptr<ResourceProvider::ScopedSamplerGL> shader_background_sampler_lock;
if (locations.backdrop != -1) {
- DCHECK(background_texture || background_image);
+ DCHECK(background_texture || background_image_id);
DCHECK_NE(locations.backdrop, 0);
DCHECK_NE(locations.backdrop_rect, 0);
@@ -1230,10 +1239,9 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
background_rect.y(), background_rect.width(),
background_rect.height());
- if (background_image) {
- GrTexture* texture = background_image->getTexture();
+ if (background_image_id) {
gl_->ActiveTexture(GL_TEXTURE0 + last_texture_unit);
- gl_->BindTexture(GL_TEXTURE_2D, texture->getTextureHandle());
+ gl_->BindTexture(GL_TEXTURE_2D, background_image_id);
gl_->ActiveTexture(GL_TEXTURE0);
if (mask_for_background)
gl_->Uniform1i(locations.original_backdrop, ++last_texture_unit);
@@ -1249,14 +1257,14 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
}
}
- SetShaderOpacity(quad->opacity(), locations.alpha);
+ SetShaderOpacity(quad->shared_quad_state->opacity, locations.alpha);
SetShaderQuadF(surface_quad, locations.quad);
- DrawQuadGeometry(
- frame, quad->quadTransform(), quad->rect, locations.matrix);
+ DrawQuadGeometry(frame, quad->shared_quad_state->quad_to_target_transform,
+ quad->rect, locations.matrix);
// Flush the compositor context before the filter bitmap goes out of
// scope, so the draw gets processed before the filter texture gets deleted.
- if (filter_image)
+ if (filter_image_id)
gl_->Flush();
if (!use_shaders_for_blending)
@@ -1303,10 +1311,10 @@ bool is_bottom(const gfx::QuadF* clip_region, const DrawQuad* quad) {
return true;
return std::abs(clip_region->p3().y() -
- quad->shared_quad_state->content_bounds.height()) <
+ quad->shared_quad_state->quad_layer_bounds.height()) <
kAntiAliasingEpsilon &&
std::abs(clip_region->p4().y() -
- quad->shared_quad_state->content_bounds.height()) <
+ quad->shared_quad_state->quad_layer_bounds.height()) <
kAntiAliasingEpsilon;
}
@@ -1327,10 +1335,10 @@ bool is_right(const gfx::QuadF* clip_region, const DrawQuad* quad) {
return true;
return std::abs(clip_region->p2().x() -
- quad->shared_quad_state->content_bounds.width()) <
+ quad->shared_quad_state->quad_layer_bounds.width()) <
kAntiAliasingEpsilon &&
std::abs(clip_region->p3().x() -
- quad->shared_quad_state->content_bounds.width()) <
+ quad->shared_quad_state->quad_layer_bounds.width()) <
kAntiAliasingEpsilon;
}
} // anonymous namespace
@@ -1338,18 +1346,10 @@ bool is_right(const gfx::QuadF* clip_region, const DrawQuad* quad) {
static gfx::QuadF GetDeviceQuadWithAntialiasingOnExteriorEdges(
const LayerQuad& device_layer_edges,
const gfx::Transform& device_transform,
+ const gfx::QuadF& tile_quad,
const gfx::QuadF* clip_region,
const DrawQuad* quad) {
gfx::RectF tile_rect = quad->visible_rect;
- gfx::QuadF tile_quad(tile_rect);
-
- if (clip_region) {
- if (quad->material != DrawQuad::RENDER_PASS) {
- tile_quad = *clip_region;
- } else {
- GetScaledRegion(quad->rect, clip_region, &tile_quad);
- }
- }
gfx::PointF bottom_right = tile_quad.p3();
gfx::PointF bottom_left = tile_quad.p4();
@@ -1426,45 +1426,65 @@ void AlignQuadToBoundingBox(gfx::QuadF* clipped_quad) {
*clipped_quad = best_rotation;
}
-// static
-bool GLRenderer::ShouldAntialiasQuad(const gfx::Transform& device_transform,
- const DrawQuad* quad,
- bool force_antialiasing) {
- bool is_render_pass_quad = (quad->material == DrawQuad::RENDER_PASS);
- // For render pass quads, |device_transform| already contains quad's rect.
- // TODO(rosca@adobe.com): remove branching on is_render_pass_quad
- // crbug.com/429702
- if (!is_render_pass_quad && !quad->IsEdge())
- return false;
- gfx::RectF content_rect =
- is_render_pass_quad ? QuadVertexRect() : quad->visibleContentRect();
-
+// Map device space quad to local space. Device_transform has no 3d
+// component since it was flattened, so we don't need to project. We should
+// have already checked that the transform was uninvertible before this call.
+gfx::QuadF MapQuadToLocalSpace(const gfx::Transform& device_transform,
+ const gfx::QuadF& device_quad) {
+ gfx::Transform inverse_device_transform(gfx::Transform::kSkipInitialization);
+ DCHECK(device_transform.IsInvertible());
+ bool did_invert = device_transform.GetInverse(&inverse_device_transform);
+ DCHECK(did_invert);
bool clipped = false;
- gfx::QuadF device_layer_quad =
- MathUtil::MapQuad(device_transform, gfx::QuadF(content_rect), &clipped);
+ gfx::QuadF local_quad =
+ MathUtil::MapQuad(inverse_device_transform, device_quad, &clipped);
+ // We should not DCHECK(!clipped) here, because anti-aliasing inflation may
+ // cause device_quad to become clipped. To our knowledge this scenario does
+ // not need to be handled differently than the unclipped case.
+ return local_quad;
+}
+
+void InflateAntiAliasingDistances(const gfx::QuadF& quad,
+ LayerQuad* device_layer_edges,
+ float edge[24]) {
+ DCHECK(!quad.BoundingBox().IsEmpty());
+ LayerQuad device_layer_bounds(gfx::QuadF(quad.BoundingBox()));
+
+ device_layer_edges->InflateAntiAliasingDistance();
+ device_layer_edges->ToFloatArray(edge);
+
+ device_layer_bounds.InflateAntiAliasingDistance();
+ device_layer_bounds.ToFloatArray(&edge[12]);
+}
+// static
+bool GLRenderer::ShouldAntialiasQuad(const gfx::QuadF& device_layer_quad,
+ bool clipped,
+ bool force_aa) {
+ // AAing clipped quads is not supported by the code yet.
+ if (clipped)
+ return false;
if (device_layer_quad.BoundingBox().IsEmpty())
return false;
+ if (force_aa)
+ return true;
bool is_axis_aligned_in_target = device_layer_quad.IsRectilinear();
bool is_nearest_rect_within_epsilon =
is_axis_aligned_in_target &&
gfx::IsNearestRectWithinDistance(device_layer_quad.BoundingBox(),
kAntiAliasingEpsilon);
- // AAing clipped quads is not supported by the code yet.
- bool use_aa = !clipped && !is_nearest_rect_within_epsilon;
- return use_aa || force_antialiasing;
+ return !is_nearest_rect_within_epsilon;
}
// static
void GLRenderer::SetupQuadForClippingAndAntialiasing(
const gfx::Transform& device_transform,
const DrawQuad* quad,
- bool use_aa,
+ const gfx::QuadF* aa_quad,
const gfx::QuadF* clip_region,
gfx::QuadF* local_quad,
float edge[24]) {
- bool is_render_pass_quad = (quad->material == DrawQuad::RENDER_PASS);
gfx::QuadF rotated_clip;
const gfx::QuadF* local_clip_region = clip_region;
if (local_clip_region) {
@@ -1473,32 +1493,14 @@ void GLRenderer::SetupQuadForClippingAndAntialiasing(
local_clip_region = &rotated_clip;
}
- gfx::QuadF content_rect = is_render_pass_quad
- ? gfx::QuadF(QuadVertexRect())
- : gfx::QuadF(quad->visibleContentRect());
- if (!use_aa) {
- if (local_clip_region) {
- if (!is_render_pass_quad) {
- content_rect = *local_clip_region;
- } else {
- GetScaledRegion(quad->rect, local_clip_region, &content_rect);
- }
- *local_quad = content_rect;
- }
+ if (!aa_quad) {
+ if (local_clip_region)
+ *local_quad = *local_clip_region;
return;
}
- bool clipped = false;
- gfx::QuadF device_layer_quad =
- MathUtil::MapQuad(device_transform, content_rect, &clipped);
- LayerQuad device_layer_bounds(gfx::QuadF(device_layer_quad.BoundingBox()));
- device_layer_bounds.InflateAntiAliasingDistance();
-
- LayerQuad device_layer_edges(device_layer_quad);
- device_layer_edges.InflateAntiAliasingDistance();
-
- device_layer_edges.ToFloatArray(edge);
- device_layer_bounds.ToFloatArray(&edge[12]);
+ LayerQuad device_layer_edges(*aa_quad);
+ InflateAntiAliasingDistances(*aa_quad, &device_layer_edges, edge);
// If we have a clip region then we are split, and therefore
// by necessity, at least one of our edges is not an external
@@ -1511,26 +1513,60 @@ void GLRenderer::SetupQuadForClippingAndAntialiasing(
is_bottom(local_clip_region, quad) && is_right(local_clip_region, quad));
bool use_aa_on_all_four_edges =
- !local_clip_region &&
- (is_render_pass_quad || region_contains_all_outside_edges);
-
- gfx::QuadF device_quad =
- use_aa_on_all_four_edges
- ? device_layer_edges.ToQuadF()
- : GetDeviceQuadWithAntialiasingOnExteriorEdges(
- device_layer_edges, device_transform, local_clip_region, quad);
-
- // Map device space quad to local space. device_transform has no 3d
- // component since it was flattened, so we don't need to project. We should
- // have already checked that the transform was uninvertible above.
- gfx::Transform inverse_device_transform(gfx::Transform::kSkipInitialization);
- bool did_invert = device_transform.GetInverse(&inverse_device_transform);
- DCHECK(did_invert);
- *local_quad =
- MathUtil::MapQuad(inverse_device_transform, device_quad, &clipped);
- // We should not DCHECK(!clipped) here, because anti-aliasing inflation may
- // cause device_quad to become clipped. To our knowledge this scenario does
- // not need to be handled differently than the unclipped case.
+ !local_clip_region && region_contains_all_outside_edges;
+
+ gfx::QuadF device_quad;
+ if (use_aa_on_all_four_edges) {
+ device_quad = device_layer_edges.ToQuadF();
+ } else {
+ gfx::QuadF tile_quad(local_clip_region ? *local_clip_region
+ : gfx::QuadF(quad->visible_rect));
+ device_quad = GetDeviceQuadWithAntialiasingOnExteriorEdges(
+ device_layer_edges, device_transform, tile_quad, local_clip_region,
+ quad);
+ }
+
+ *local_quad = MapQuadToLocalSpace(device_transform, device_quad);
+}
+
+// static
+void GLRenderer::SetupRenderPassQuadForClippingAndAntialiasing(
+ const gfx::Transform& device_transform,
+ const RenderPassDrawQuad* quad,
+ const gfx::QuadF* aa_quad,
+ const gfx::QuadF* clip_region,
+ gfx::QuadF* local_quad,
+ float edge[24]) {
+ gfx::QuadF rotated_clip;
+ const gfx::QuadF* local_clip_region = clip_region;
+ if (local_clip_region) {
+ rotated_clip = *clip_region;
+ AlignQuadToBoundingBox(&rotated_clip);
+ local_clip_region = &rotated_clip;
+ }
+
+ if (!aa_quad) {
+ GetScaledRegion(quad->rect, local_clip_region, local_quad);
+ return;
+ }
+
+ LayerQuad device_layer_edges(*aa_quad);
+ InflateAntiAliasingDistances(*aa_quad, &device_layer_edges, edge);
+
+ gfx::QuadF device_quad;
+
+ // Apply anti-aliasing only to the edges that are not being clipped
+ if (local_clip_region) {
+ gfx::QuadF tile_quad(quad->visible_rect);
+ GetScaledRegion(quad->rect, local_clip_region, &tile_quad);
+ device_quad = GetDeviceQuadWithAntialiasingOnExteriorEdges(
+ device_layer_edges, device_transform, tile_quad, local_clip_region,
+ quad);
+ } else {
+ device_quad = device_layer_edges.ToQuadF();
+ }
+
+ *local_quad = MapQuadToLocalSpace(device_transform, device_quad);
}
void GLRenderer::DrawSolidColorQuad(const DrawingFrame* frame,
@@ -1539,7 +1575,7 @@ void GLRenderer::DrawSolidColorQuad(const DrawingFrame* frame,
gfx::Rect tile_rect = quad->visible_rect;
SkColor color = quad->color;
- float opacity = quad->opacity();
+ float opacity = quad->shared_quad_state->opacity;
float alpha = (SkColorGetA(color) * (1.0f / 255.0f)) * opacity;
// Early out if alpha is small enough that quad doesn't contribute to output.
@@ -1548,18 +1584,31 @@ void GLRenderer::DrawSolidColorQuad(const DrawingFrame* frame,
return;
gfx::Transform device_transform =
- frame->window_matrix * frame->projection_matrix * quad->quadTransform();
+ frame->window_matrix * frame->projection_matrix *
+ quad->shared_quad_state->quad_to_target_transform;
device_transform.FlattenTo2d();
if (!device_transform.IsInvertible())
return;
- bool force_aa = false;
gfx::QuadF local_quad = gfx::QuadF(gfx::RectF(tile_rect));
+
+ gfx::QuadF device_layer_quad;
+ bool use_aa = false;
+ bool allow_aa = settings_->allow_antialiasing &&
+ !quad->force_anti_aliasing_off && quad->IsEdge();
+
+ if (allow_aa) {
+ bool clipped = false;
+ bool force_aa = false;
+ device_layer_quad = MathUtil::MapQuad(
+ device_transform,
+ gfx::QuadF(quad->shared_quad_state->visible_quad_layer_rect), &clipped);
+ use_aa = ShouldAntialiasQuad(device_layer_quad, clipped, force_aa);
+ }
+
float edge[24];
- bool use_aa = settings_->allow_antialiasing &&
- !quad->force_anti_aliasing_off &&
- ShouldAntialiasQuad(device_transform, quad, force_aa);
- SetupQuadForClippingAndAntialiasing(device_transform, quad, use_aa,
+ const gfx::QuadF* aa_quad = use_aa ? &device_layer_quad : nullptr;
+ SetupQuadForClippingAndAntialiasing(device_transform, quad, aa_quad,
clip_region, &local_quad, edge);
SolidColorProgramUniforms uniforms;
@@ -1589,20 +1638,35 @@ void GLRenderer::DrawSolidColorQuad(const DrawingFrame* frame,
// to use antialiasing.
SetBlendEnabled(quad->ShouldDrawWithBlending() || use_aa);
- // Normalize to tile_rect.
- local_quad.Scale(1.0f / tile_rect.width(), 1.0f / tile_rect.height());
-
- SetShaderQuadF(local_quad, uniforms.quad_location);
+ // Antialising requires a normalized quad, but this could lead to floating
+ // point precision errors, so only normalize when antialising is on.
+ if (use_aa) {
+ // Normalize to tile_rect.
+ local_quad.Scale(1.0f / tile_rect.width(), 1.0f / tile_rect.height());
+
+ SetShaderQuadF(local_quad, uniforms.quad_location);
+
+ // The transform and vertex data are used to figure out the extents that the
+ // un-antialiased quad should have and which vertex this is and the float
+ // quad passed in via uniform is the actual geometry that gets used to draw
+ // it. This is why this centered rect is used and not the original
+ // quad_rect.
+ gfx::RectF centered_rect(
+ gfx::PointF(-0.5f * tile_rect.width(), -0.5f * tile_rect.height()),
+ tile_rect.size());
+ DrawQuadGeometry(frame, quad->shared_quad_state->quad_to_target_transform,
+ centered_rect, uniforms.matrix_location);
+ } else {
+ PrepareGeometry(SHARED_BINDING);
+ SetShaderQuadF(local_quad, uniforms.quad_location);
+ static float gl_matrix[16];
+ ToGLMatrix(&gl_matrix[0],
+ frame->projection_matrix *
+ quad->shared_quad_state->quad_to_target_transform);
+ gl_->UniformMatrix4fv(uniforms.matrix_location, 1, false, &gl_matrix[0]);
- // The transform and vertex data are used to figure out the extents that the
- // un-antialiased quad should have and which vertex this is and the float
- // quad passed in via uniform is the actual geometry that gets used to draw
- // it. This is why this centered rect is used and not the original quad_rect.
- gfx::RectF centered_rect(
- gfx::PointF(-0.5f * tile_rect.width(), -0.5f * tile_rect.height()),
- tile_rect.size());
- DrawQuadGeometry(
- frame, quad->quadTransform(), centered_rect, uniforms.matrix_location);
+ gl_->DrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
+ }
}
struct TileProgramUniforms {
@@ -1636,33 +1700,45 @@ static void TileUniformLocation(T program, TileProgramUniforms* uniforms) {
void GLRenderer::DrawTileQuad(const DrawingFrame* frame,
const TileDrawQuad* quad,
const gfx::QuadF* clip_region) {
- DrawContentQuad(frame, quad, quad->resource_id, clip_region);
+ DrawContentQuad(frame, quad, quad->resource_id(), clip_region);
}
void GLRenderer::DrawContentQuad(const DrawingFrame* frame,
const ContentDrawQuadBase* quad,
- ResourceProvider::ResourceId resource_id,
+ ResourceId resource_id,
const gfx::QuadF* clip_region) {
gfx::Transform device_transform =
- frame->window_matrix * frame->projection_matrix * quad->quadTransform();
+ frame->window_matrix * frame->projection_matrix *
+ quad->shared_quad_state->quad_to_target_transform;
device_transform.FlattenTo2d();
- bool use_aa = settings_->allow_antialiasing &&
- ShouldAntialiasQuad(device_transform, quad, false);
+ gfx::QuadF device_layer_quad;
+ bool use_aa = false;
+ bool allow_aa = settings_->allow_antialiasing && quad->IsEdge();
+ if (allow_aa) {
+ bool clipped = false;
+ bool force_aa = false;
+ device_layer_quad = MathUtil::MapQuad(
+ device_transform,
+ gfx::QuadF(quad->shared_quad_state->visible_quad_layer_rect), &clipped);
+ use_aa = ShouldAntialiasQuad(device_layer_quad, clipped, force_aa);
+ }
// TODO(timav): simplify coordinate transformations in DrawContentQuadAA
// similar to the way DrawContentQuadNoAA works and then consider
// combining DrawContentQuadAA and DrawContentQuadNoAA into one method.
if (use_aa)
- DrawContentQuadAA(frame, quad, resource_id, device_transform, clip_region);
+ DrawContentQuadAA(frame, quad, resource_id, device_transform,
+ device_layer_quad, clip_region);
else
DrawContentQuadNoAA(frame, quad, resource_id, clip_region);
}
void GLRenderer::DrawContentQuadAA(const DrawingFrame* frame,
const ContentDrawQuadBase* quad,
- ResourceProvider::ResourceId resource_id,
+ ResourceId resource_id,
const gfx::Transform& device_transform,
+ const gfx::QuadF& aa_quad,
const gfx::QuadF* clip_region) {
if (!device_transform.IsInvertible())
return;
@@ -1708,8 +1784,8 @@ void GLRenderer::DrawContentQuadAA(const DrawingFrame* frame,
gfx::QuadF local_quad = gfx::QuadF(gfx::RectF(tile_rect));
float edge[24];
- SetupQuadForClippingAndAntialiasing(device_transform, quad, true, clip_region,
- &local_quad, edge);
+ SetupQuadForClippingAndAntialiasing(device_transform, quad, &aa_quad,
+ clip_region, &local_quad, edge);
ResourceProvider::ScopedSamplerGL quad_resource_lock(
resource_provider_, resource_id,
quad->nearest_neighbor ? GL_NEAREST : GL_LINEAR);
@@ -1765,7 +1841,7 @@ void GLRenderer::DrawContentQuadAA(const DrawingFrame* frame,
// Normalize to tile_rect.
local_quad.Scale(1.0f / tile_rect.width(), 1.0f / tile_rect.height());
- SetShaderOpacity(quad->opacity(), uniforms.alpha_location);
+ SetShaderOpacity(quad->shared_quad_state->opacity, uniforms.alpha_location);
SetShaderQuadF(local_quad, uniforms.quad_location);
// The transform and vertex data are used to figure out the extents that the
@@ -1775,13 +1851,13 @@ void GLRenderer::DrawContentQuadAA(const DrawingFrame* frame,
gfx::RectF centered_rect(
gfx::PointF(-0.5f * tile_rect.width(), -0.5f * tile_rect.height()),
tile_rect.size());
- DrawQuadGeometry(
- frame, quad->quadTransform(), centered_rect, uniforms.matrix_location);
+ DrawQuadGeometry(frame, quad->shared_quad_state->quad_to_target_transform,
+ centered_rect, uniforms.matrix_location);
}
void GLRenderer::DrawContentQuadNoAA(const DrawingFrame* frame,
const ContentDrawQuadBase* quad,
- ResourceProvider::ResourceId resource_id,
+ ResourceId resource_id,
const gfx::QuadF* clip_region) {
gfx::RectF tex_coord_rect = MathUtil::ScaleRectProportional(
quad->tex_coord_rect, quad->rect, quad->visible_rect);
@@ -1790,11 +1866,12 @@ void GLRenderer::DrawContentQuadNoAA(const DrawingFrame* frame,
quad->rect.height() / quad->tex_coord_rect.height();
bool scaled = (tex_to_geom_scale_x != 1.f || tex_to_geom_scale_y != 1.f);
- GLenum filter =
- (scaled || !quad->quadTransform().IsIdentityOrIntegerTranslation()) &&
- !quad->nearest_neighbor
- ? GL_LINEAR
- : GL_NEAREST;
+ GLenum filter = (scaled ||
+ !quad->shared_quad_state->quad_to_target_transform
+ .IsIdentityOrIntegerTranslation()) &&
+ !quad->nearest_neighbor
+ ? GL_LINEAR
+ : GL_NEAREST;
ResourceProvider::ScopedSamplerGL quad_resource_lock(
resource_provider_, resource_id, filter);
@@ -1847,7 +1924,7 @@ void GLRenderer::DrawContentQuadNoAA(const DrawingFrame* frame,
SetBlendEnabled(quad->ShouldDrawWithBlending());
- SetShaderOpacity(quad->opacity(), uniforms.alpha_location);
+ SetShaderOpacity(quad->shared_quad_state->opacity, uniforms.alpha_location);
// Pass quad coordinates to the uniform in the same order as GeometryBinding
// does, then vertices will match the texture mapping in the vertex buffer.
@@ -1888,7 +1965,9 @@ void GLRenderer::DrawContentQuadNoAA(const DrawingFrame* frame,
gl_->Uniform2fv(uniforms.quad_location, 4, gl_quad);
static float gl_matrix[16];
- ToGLMatrix(&gl_matrix[0], frame->projection_matrix * quad->quadTransform());
+ ToGLMatrix(&gl_matrix[0],
+ frame->projection_matrix *
+ quad->shared_quad_state->quad_to_target_transform);
gl_->UniformMatrix4fv(uniforms.matrix_location, 1, false, &gl_matrix[0]);
gl_->DrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
@@ -1900,25 +1979,24 @@ void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame,
SetBlendEnabled(quad->ShouldDrawWithBlending());
TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
- gl_,
- &highp_threshold_cache_,
- highp_threshold_min_,
- quad->shared_quad_state->visible_content_rect.bottom_right());
+ gl_, &highp_threshold_cache_, highp_threshold_min_,
+ quad->shared_quad_state->visible_quad_layer_rect.bottom_right());
- bool use_alpha_plane = quad->a_plane_resource_id != 0;
+ bool use_alpha_plane = quad->a_plane_resource_id() != 0;
ResourceProvider::ScopedSamplerGL y_plane_lock(
- resource_provider_, quad->y_plane_resource_id, GL_TEXTURE1, GL_LINEAR);
+ resource_provider_, quad->y_plane_resource_id(), GL_TEXTURE1, GL_LINEAR);
ResourceProvider::ScopedSamplerGL u_plane_lock(
- resource_provider_, quad->u_plane_resource_id, GL_TEXTURE2, GL_LINEAR);
+ resource_provider_, quad->u_plane_resource_id(), GL_TEXTURE2, GL_LINEAR);
DCHECK_EQ(y_plane_lock.target(), u_plane_lock.target());
ResourceProvider::ScopedSamplerGL v_plane_lock(
- resource_provider_, quad->v_plane_resource_id, GL_TEXTURE3, GL_LINEAR);
+ resource_provider_, quad->v_plane_resource_id(), GL_TEXTURE3, GL_LINEAR);
DCHECK_EQ(y_plane_lock.target(), v_plane_lock.target());
scoped_ptr<ResourceProvider::ScopedSamplerGL> a_plane_lock;
if (use_alpha_plane) {
a_plane_lock.reset(new ResourceProvider::ScopedSamplerGL(
- resource_provider_, quad->a_plane_resource_id, GL_TEXTURE4, GL_LINEAR));
+ resource_provider_, quad->a_plane_resource_id(), GL_TEXTURE4,
+ GL_LINEAR));
DCHECK_EQ(y_plane_lock.target(), a_plane_lock->target());
}
@@ -2093,17 +2171,19 @@ void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame,
gl_->UniformMatrix3fv(yuv_matrix_location, 1, 0, yuv_to_rgb);
gl_->Uniform3fv(yuv_adj_location, 1, yuv_adjust);
- SetShaderOpacity(quad->opacity(), alpha_location);
+ SetShaderOpacity(quad->shared_quad_state->opacity, alpha_location);
if (!clip_region) {
- DrawQuadGeometry(frame, quad->quadTransform(), tile_rect, matrix_location);
+ DrawQuadGeometry(frame, quad->shared_quad_state->quad_to_target_transform,
+ tile_rect, matrix_location);
} else {
float uvs[8] = {0};
GetScaledUVs(quad->visible_rect, clip_region, uvs);
gfx::QuadF region_quad = *clip_region;
region_quad.Scale(1.0f / tile_rect.width(), 1.0f / tile_rect.height());
region_quad -= gfx::Vector2dF(0.5f, 0.5f);
- DrawQuadGeometryClippedByQuadF(frame, quad->quadTransform(), tile_rect,
- region_quad, matrix_location, uvs);
+ DrawQuadGeometryClippedByQuadF(
+ frame, quad->shared_quad_state->quad_to_target_transform, tile_rect,
+ region_quad, matrix_location, uvs);
}
}
@@ -2117,10 +2197,8 @@ void GLRenderer::DrawStreamVideoQuad(const DrawingFrame* frame,
DCHECK(capabilities_.using_egl_image);
TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
- gl_,
- &highp_threshold_cache_,
- highp_threshold_min_,
- quad->shared_quad_state->visible_content_rect.bottom_right());
+ gl_, &highp_threshold_cache_, highp_threshold_min_,
+ quad->shared_quad_state->visible_quad_layer_rect.bottom_right());
const VideoStreamTextureProgram* program =
GetVideoStreamTextureProgram(tex_coord_precision);
@@ -2131,17 +2209,17 @@ void GLRenderer::DrawStreamVideoQuad(const DrawingFrame* frame,
false, gl_matrix);
ResourceProvider::ScopedReadLockGL lock(resource_provider_,
- quad->resource_id);
+ quad->resource_id());
DCHECK_EQ(GL_TEXTURE0, GetActiveTextureUnit(gl_));
gl_->BindTexture(GL_TEXTURE_EXTERNAL_OES, lock.texture_id());
gl_->Uniform1i(program->fragment_shader().sampler_location(), 0);
- SetShaderOpacity(quad->opacity(),
+ SetShaderOpacity(quad->shared_quad_state->opacity,
program->fragment_shader().alpha_location());
if (!clip_region) {
- DrawQuadGeometry(frame, quad->quadTransform(), quad->rect,
- program->vertex_shader().matrix_location());
+ DrawQuadGeometry(frame, quad->shared_quad_state->quad_to_target_transform,
+ quad->rect, program->vertex_shader().matrix_location());
} else {
gfx::QuadF region_quad(*clip_region);
region_quad.Scale(1.0f / quad->rect.width(), 1.0f / quad->rect.height());
@@ -2149,8 +2227,8 @@ void GLRenderer::DrawStreamVideoQuad(const DrawingFrame* frame,
float uvs[8] = {0};
GetScaledUVs(quad->visible_rect, clip_region, uvs);
DrawQuadGeometryClippedByQuadF(
- frame, quad->quadTransform(), quad->rect, region_quad,
- program->vertex_shader().matrix_location(), uvs);
+ frame, quad->shared_quad_state->quad_to_target_transform, quad->rect,
+ region_quad, program->vertex_shader().matrix_location(), uvs);
}
}
@@ -2232,8 +2310,11 @@ void GLRenderer::FlushTextureQuadCache(BoundGeometry flush_binding) {
static_cast<int>(draw_cache_.vertex_opacity_data.size()),
static_cast<float*>(&draw_cache_.vertex_opacity_data.front()));
+ DCHECK_LE(draw_cache_.matrix_data.size(),
+ static_cast<size_t>(std::numeric_limits<int>::max()) / 6u);
// Draw the quads!
- gl_->DrawElements(GL_TRIANGLES, 6 * draw_cache_.matrix_data.size(),
+ gl_->DrawElements(GL_TRIANGLES,
+ 6 * static_cast<int>(draw_cache_.matrix_data.size()),
GL_UNSIGNED_SHORT, 0);
// Clear the cache.
@@ -2262,13 +2343,11 @@ void GLRenderer::EnqueueTextureQuad(const DrawingFrame* frame,
}
TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
- gl_,
- &highp_threshold_cache_,
- highp_threshold_min_,
- quad->shared_quad_state->visible_content_rect.bottom_right());
+ gl_, &highp_threshold_cache_, highp_threshold_min_,
+ quad->shared_quad_state->visible_quad_layer_rect.bottom_right());
ResourceProvider::ScopedReadLockGL lock(resource_provider_,
- quad->resource_id);
+ quad->resource_id());
const SamplerType sampler = SamplerTypeFromTextureTarget(lock.target());
// Choose the correct texture program binding
TexTransformTextureProgramBinding binding;
@@ -2288,7 +2367,7 @@ void GLRenderer::EnqueueTextureQuad(const DrawingFrame* frame,
}
}
- int resource_id = quad->resource_id;
+ int resource_id = quad->resource_id();
if (draw_cache_.program_id != binding.program_id ||
draw_cache_.resource_id != resource_id ||
@@ -2319,7 +2398,7 @@ void GLRenderer::EnqueueTextureQuad(const DrawingFrame* frame,
}
// Generate the vertex opacity
- const float opacity = quad->opacity();
+ const float opacity = quad->shared_quad_state->opacity;
draw_cache_.vertex_opacity_data.push_back(quad->vertex_opacity[0] * opacity);
draw_cache_.vertex_opacity_data.push_back(quad->vertex_opacity[1] * opacity);
draw_cache_.vertex_opacity_data.push_back(quad->vertex_opacity[2] * opacity);
@@ -2327,7 +2406,9 @@ void GLRenderer::EnqueueTextureQuad(const DrawingFrame* frame,
// Generate the transform matrix
gfx::Transform quad_rect_matrix;
- QuadRectTransform(&quad_rect_matrix, quad->quadTransform(), quad->rect);
+ QuadRectTransform(&quad_rect_matrix,
+ quad->shared_quad_state->quad_to_target_transform,
+ quad->rect);
quad_rect_matrix = frame->projection_matrix * quad_rect_matrix;
Float16 m;
@@ -2362,10 +2443,8 @@ void GLRenderer::DrawIOSurfaceQuad(const DrawingFrame* frame,
SetBlendEnabled(quad->ShouldDrawWithBlending());
TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
- gl_,
- &highp_threshold_cache_,
- highp_threshold_min_,
- quad->shared_quad_state->visible_content_rect.bottom_right());
+ gl_, &highp_threshold_cache_, highp_threshold_min_,
+ quad->shared_quad_state->visible_quad_layer_rect.bottom_right());
TexTransformTextureProgramBinding binding;
binding.Set(GetTextureIOSurfaceProgram(tex_coord_precision));
@@ -2382,23 +2461,26 @@ void GLRenderer::DrawIOSurfaceQuad(const DrawingFrame* frame,
quad->io_surface_size.height());
}
- const float vertex_opacity[] = {quad->opacity(), quad->opacity(),
- quad->opacity(), quad->opacity()};
+ const float vertex_opacity[] = {quad->shared_quad_state->opacity,
+ quad->shared_quad_state->opacity,
+ quad->shared_quad_state->opacity,
+ quad->shared_quad_state->opacity};
gl_->Uniform1fv(binding.vertex_opacity_location, 4, vertex_opacity);
ResourceProvider::ScopedReadLockGL lock(resource_provider_,
- quad->io_surface_resource_id);
+ quad->io_surface_resource_id());
DCHECK_EQ(GL_TEXTURE0, GetActiveTextureUnit(gl_));
gl_->BindTexture(GL_TEXTURE_RECTANGLE_ARB, lock.texture_id());
if (!clip_region) {
- DrawQuadGeometry(frame, quad->quadTransform(), quad->rect,
- binding.matrix_location);
+ DrawQuadGeometry(frame, quad->shared_quad_state->quad_to_target_transform,
+ quad->rect, binding.matrix_location);
} else {
float uvs[8] = {0};
GetScaledUVs(quad->visible_rect, clip_region, uvs);
- DrawQuadGeometryClippedByQuadF(frame, quad->quadTransform(), quad->rect,
- *clip_region, binding.matrix_location, uvs);
+ DrawQuadGeometryClippedByQuadF(
+ frame, quad->shared_quad_state->quad_to_target_transform, quad->rect,
+ *clip_region, binding.matrix_location, uvs);
}
gl_->BindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
@@ -2603,7 +2685,6 @@ void GLRenderer::EnforceMemoryPolicy() {
TRACE_EVENT0("cc", "GLRenderer::EnforceMemoryPolicy dropping resources");
ReleaseRenderPassTextures();
DiscardBackbuffer();
- resource_provider_->ReleaseCachedData();
output_surface_->context_provider()->DeleteCachedResources();
gl_->Flush();
}
@@ -3486,7 +3567,7 @@ void GLRenderer::RestoreFramebuffer(DrawingFrame* frame) {
}
bool GLRenderer::IsContextLost() {
- return output_surface_->context_provider()->IsContextLost();
+ return gl_->GetGraphicsResetStatusKHR() != GL_NO_ERROR;
}
void GLRenderer::ScheduleOverlays(DrawingFrame* frame) {
diff --git a/chromium/cc/output/gl_renderer.h b/chromium/cc/output/gl_renderer.h
index 324a7bd16e4..d80e1561502 100644
--- a/chromium/cc/output/gl_renderer.h
+++ b/chromium/cc/output/gl_renderer.h
@@ -122,9 +122,9 @@ class CC_EXPORT GLRenderer : public DirectRenderer {
void FinishDrawingQuadList() override;
// Returns true if quad requires antialiasing and false otherwise.
- static bool ShouldAntialiasQuad(const gfx::Transform& device_transform,
- const DrawQuad* quad,
- bool force_antialiasing);
+ static bool ShouldAntialiasQuad(const gfx::QuadF& device_layer_quad,
+ bool clipped,
+ bool force_aa);
// Inflate the quad and fill edge array for fragment shader.
// |local_quad| is set to inflated quad. |edge| array is filled with
@@ -132,7 +132,14 @@ class CC_EXPORT GLRenderer : public DirectRenderer {
static void SetupQuadForClippingAndAntialiasing(
const gfx::Transform& device_transform,
const DrawQuad* quad,
- bool use_aa,
+ const gfx::QuadF* device_layer_quad,
+ const gfx::QuadF* clip_region,
+ gfx::QuadF* local_quad,
+ float edge[24]);
+ static void SetupRenderPassQuadForClippingAndAntialiasing(
+ const gfx::Transform& device_transform,
+ const RenderPassDrawQuad* quad,
+ const gfx::QuadF* device_layer_quad,
const gfx::QuadF* clip_region,
gfx::QuadF* local_quad,
float edge[24]);
@@ -198,16 +205,17 @@ class CC_EXPORT GLRenderer : public DirectRenderer {
const gfx::QuadF* clip_region);
void DrawContentQuad(const DrawingFrame* frame,
const ContentDrawQuadBase* quad,
- ResourceProvider::ResourceId resource_id,
+ ResourceId resource_id,
const gfx::QuadF* clip_region);
void DrawContentQuadAA(const DrawingFrame* frame,
const ContentDrawQuadBase* quad,
- ResourceProvider::ResourceId resource_id,
+ ResourceId resource_id,
const gfx::Transform& device_transform,
+ const gfx::QuadF& aa_quad,
const gfx::QuadF* clip_region);
void DrawContentQuadNoAA(const DrawingFrame* frame,
const ContentDrawQuadBase* quad,
- ResourceProvider::ResourceId resource_id,
+ ResourceId resource_id,
const gfx::QuadF* clip_region);
void DrawYUVVideoQuad(const DrawingFrame* frame,
const YUVVideoDrawQuad* quad,
@@ -515,7 +523,7 @@ class CC_EXPORT GLRenderer : public DirectRenderer {
bool use_blend_equation_advanced_coherent_;
SkBitmap on_demand_tile_raster_bitmap_;
- ResourceProvider::ResourceId on_demand_tile_raster_resource_id_;
+ ResourceId on_demand_tile_raster_resource_id_;
BoundGeometry bound_geometry_;
DISALLOW_COPY_AND_ASSIGN(GLRenderer);
};
diff --git a/chromium/cc/output/gl_renderer_unittest.cc b/chromium/cc/output/gl_renderer_unittest.cc
index 09407f55ed7..4b133c930a5 100644
--- a/chromium/cc/output/gl_renderer_unittest.cc
+++ b/chromium/cc/output/gl_renderer_unittest.cc
@@ -22,6 +22,7 @@
#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_output_surface_client.h"
#include "cc/test/fake_renderer_client.h"
+#include "cc/test/fake_resource_provider.h"
#include "cc/test/pixel_test.h"
#include "cc/test/render_pass_test_common.h"
#include "cc/test/render_pass_test_utils.h"
@@ -334,13 +335,8 @@ class GLRendererWithDefaultHarnessTest : public GLRendererTest {
CHECK(output_surface_->BindToClient(&output_surface_client_));
shared_bitmap_manager_.reset(new TestSharedBitmapManager());
- resource_provider_ = ResourceProvider::Create(output_surface_.get(),
- shared_bitmap_manager_.get(),
- NULL,
- NULL,
- 0,
- false,
- 1).Pass();
+ resource_provider_ = FakeResourceProvider::Create(
+ output_surface_.get(), shared_bitmap_manager_.get());
renderer_ = make_scoped_ptr(new FakeRendererGL(&renderer_client_,
&settings_,
output_surface_.get(),
@@ -370,13 +366,8 @@ class GLRendererShaderTest : public GLRendererTest {
CHECK(output_surface_->BindToClient(&output_surface_client_));
shared_bitmap_manager_.reset(new TestSharedBitmapManager());
- resource_provider_ = ResourceProvider::Create(output_surface_.get(),
- shared_bitmap_manager_.get(),
- NULL,
- NULL,
- 0,
- false,
- 1).Pass();
+ resource_provider_ = FakeResourceProvider::Create(
+ output_surface_.get(), shared_bitmap_manager_.get());
renderer_.reset(new FakeRendererGL(&renderer_client_,
&settings_,
output_surface_.get(),
@@ -674,14 +665,8 @@ TEST_F(GLRendererTest, InitializationDoesNotMakeSynchronousCalls) {
scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
new TestSharedBitmapManager());
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager.get(),
- NULL,
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager.get());
RendererSettings settings;
FakeRendererClient renderer_client;
@@ -714,14 +699,8 @@ TEST_F(GLRendererTest, InitializationWithQuicklyLostContextDoesNotAssert) {
scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
new TestSharedBitmapManager());
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager.get(),
- NULL,
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager.get());
RendererSettings settings;
FakeRendererClient renderer_client;
@@ -753,14 +732,8 @@ TEST_F(GLRendererTest, OpaqueBackground) {
scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
new TestSharedBitmapManager());
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager.get(),
- NULL,
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager.get());
RendererSettings settings;
FakeRendererClient renderer_client;
@@ -805,14 +778,8 @@ TEST_F(GLRendererTest, TransparentBackground) {
scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
new TestSharedBitmapManager());
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager.get(),
- NULL,
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager.get());
RendererSettings settings;
FakeRendererClient renderer_client;
@@ -850,14 +817,8 @@ TEST_F(GLRendererTest, OffscreenOutputSurface) {
scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
new TestSharedBitmapManager());
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager.get(),
- NULL,
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager.get());
RendererSettings settings;
FakeRendererClient renderer_client;
@@ -935,14 +896,8 @@ TEST_F(GLRendererTest, VisibilityChangeIsLastCall) {
scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
new TestSharedBitmapManager());
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager.get(),
- NULL,
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager.get());
RendererSettings settings;
FakeRendererClient renderer_client;
@@ -1006,14 +961,8 @@ TEST_F(GLRendererTest, ActiveTextureState) {
scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
new TestSharedBitmapManager());
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager.get(),
- NULL,
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager.get());
RendererSettings settings;
FakeRendererClient renderer_client;
@@ -1097,14 +1046,8 @@ TEST_F(GLRendererTest, ShouldClearRootRenderPass) {
scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
new TestSharedBitmapManager());
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager.get(),
- NULL,
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager.get());
RendererSettings settings;
settings.should_clear_root_render_pass = false;
@@ -1195,14 +1138,8 @@ TEST_F(GLRendererTest, ScissorTestWhenClearing) {
scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
new TestSharedBitmapManager());
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager.get(),
- NULL,
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager.get());
RendererSettings settings;
FakeRendererClient renderer_client;
@@ -1293,14 +1230,8 @@ TEST_F(GLRendererTest, NoDiscardOnPartialUpdates) {
scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
new TestSharedBitmapManager());
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager.get(),
- NULL,
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager.get());
RendererSettings settings;
settings.partial_swap_enabled = true;
@@ -1464,14 +1395,8 @@ TEST_F(GLRendererTest, ScissorAndViewportWithinNonreshapableSurface) {
scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
new TestSharedBitmapManager());
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager.get(),
- NULL,
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager.get());
RendererSettings settings;
FakeRendererClient renderer_client;
@@ -1513,9 +1438,8 @@ TEST_F(GLRendererTest, DrawFramePreservesFramebuffer) {
scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
new TestSharedBitmapManager());
- scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
- output_surface.get(), shared_bitmap_manager.get(), NULL, NULL, 0, false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager.get());
RendererSettings settings;
FakeRendererClient renderer_client;
@@ -1558,7 +1482,7 @@ TEST_F(GLRendererShaderTest, DrawRenderPassQuadShaderPermutations) {
RenderPassId root_pass_id(1, 0);
TestRenderPass* root_pass;
- ResourceProvider::ResourceId mask = resource_provider_->CreateResource(
+ ResourceId mask = resource_provider_->CreateResource(
gfx::Size(20, 12), GL_CLAMP_TO_EDGE,
ResourceProvider::TEXTURE_HINT_IMMUTABLE,
resource_provider_->best_texture_format());
@@ -1933,13 +1857,8 @@ class MockOutputSurfaceTest : public GLRendererTest {
CHECK(output_surface_.BindToClient(&output_surface_client_));
shared_bitmap_manager_.reset(new TestSharedBitmapManager());
- resource_provider_ = ResourceProvider::Create(&output_surface_,
- shared_bitmap_manager_.get(),
- NULL,
- NULL,
- 0,
- false,
- 1).Pass();
+ resource_provider_ = FakeResourceProvider::Create(
+ &output_surface_, shared_bitmap_manager_.get());
renderer_.reset(new FakeRendererGL(&renderer_client_,
&settings_,
@@ -2110,9 +2029,8 @@ class TestOverlayProcessor : public OverlayProcessor {
OverlayCandidateList* candidates));
};
- TestOverlayProcessor(OutputSurface* surface,
- ResourceProvider* resource_provider)
- : OverlayProcessor(surface, resource_provider) {}
+ explicit TestOverlayProcessor(OutputSurface* surface)
+ : OverlayProcessor(surface) {}
~TestOverlayProcessor() override {}
void Initialize() override {
strategy_ = new Strategy();
@@ -2139,9 +2057,8 @@ TEST_F(GLRendererTest, DontOverlayWithCopyRequests) {
scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
new TestSharedBitmapManager());
- scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
- output_surface.get(), shared_bitmap_manager.get(), NULL, NULL, 0, false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager.get());
scoped_ptr<TextureMailboxDeleter> mailbox_deleter(
new TextureMailboxDeleter(base::ThreadTaskRunnerHandle::Get()));
@@ -2151,7 +2068,7 @@ TEST_F(GLRendererTest, DontOverlayWithCopyRequests) {
resource_provider.get(), mailbox_deleter.get());
TestOverlayProcessor* processor =
- new TestOverlayProcessor(output_surface.get(), resource_provider.get());
+ new TestOverlayProcessor(output_surface.get());
processor->Initialize();
renderer.SetOverlayProcessor(processor);
@@ -2166,12 +2083,10 @@ TEST_F(GLRendererTest, DontOverlayWithCopyRequests) {
unsigned sync_point = 0;
TextureMailbox mailbox =
TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
- mailbox.set_allow_overlay(true);
scoped_ptr<SingleReleaseCallbackImpl> release_callback =
SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased));
- ResourceProvider::ResourceId resource_id =
- resource_provider->CreateResourceFromTextureMailbox(
- mailbox, release_callback.Pass());
+ ResourceId resource_id = resource_provider->CreateResourceFromTextureMailbox(
+ mailbox, release_callback.Pass());
bool premultiplied_alpha = false;
bool flipped = false;
bool nearest_neighbor = false;
@@ -2184,6 +2099,7 @@ TEST_F(GLRendererTest, DontOverlayWithCopyRequests) {
premultiplied_alpha, gfx::PointF(0, 0),
gfx::PointF(1, 1), SK_ColorTRANSPARENT, vertex_opacity,
flipped, nearest_neighbor);
+ overlay_quad->set_allow_overlay(true);
// DirectRenderer::DrawFrame calls into OverlayProcessor::ProcessForOverlays.
// Attempt will be called for each strategy in OverlayProcessor. We have
@@ -2223,13 +2139,12 @@ class SingleOverlayOnTopProcessor : public OverlayProcessor {
}
};
- SingleOverlayOnTopProcessor(OutputSurface* surface,
- ResourceProvider* resource_provider)
- : OverlayProcessor(surface, resource_provider) {}
+ explicit SingleOverlayOnTopProcessor(OutputSurface* surface)
+ : OverlayProcessor(surface) {}
void Initialize() override {
- strategies_.push_back(scoped_ptr<Strategy>(
- new OverlayStrategySingleOnTop(&validator_, resource_provider_)));
+ strategies_.push_back(
+ scoped_ptr<Strategy>(new OverlayStrategySingleOnTop(&validator_)));
}
SingleOverlayValidator validator_;
@@ -2268,9 +2183,8 @@ TEST_F(GLRendererTest, OverlaySyncPointsAreProcessed) {
scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
new TestSharedBitmapManager());
- scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
- output_surface.get(), shared_bitmap_manager.get(), NULL, NULL, 0, false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager.get());
scoped_ptr<TextureMailboxDeleter> mailbox_deleter(
new TextureMailboxDeleter(base::ThreadTaskRunnerHandle::Get()));
@@ -2279,8 +2193,8 @@ TEST_F(GLRendererTest, OverlaySyncPointsAreProcessed) {
FakeRendererGL renderer(&renderer_client, &settings, output_surface.get(),
resource_provider.get(), mailbox_deleter.get());
- SingleOverlayOnTopProcessor* processor = new SingleOverlayOnTopProcessor(
- output_surface.get(), resource_provider.get());
+ SingleOverlayOnTopProcessor* processor =
+ new SingleOverlayOnTopProcessor(output_surface.get());
processor->Initialize();
renderer.SetOverlayProcessor(processor);
@@ -2293,12 +2207,10 @@ TEST_F(GLRendererTest, OverlaySyncPointsAreProcessed) {
unsigned sync_point = TestRenderPass::kSyncPointForMailboxTextureQuad;
TextureMailbox mailbox =
TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
- mailbox.set_allow_overlay(true);
scoped_ptr<SingleReleaseCallbackImpl> release_callback =
SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased));
- ResourceProvider::ResourceId resource_id =
- resource_provider->CreateResourceFromTextureMailbox(
- mailbox, release_callback.Pass());
+ ResourceId resource_id = resource_provider->CreateResourceFromTextureMailbox(
+ mailbox, release_callback.Pass());
bool premultiplied_alpha = false;
bool flipped = false;
bool nearest_neighbor = false;
@@ -2315,6 +2227,7 @@ TEST_F(GLRendererTest, OverlaySyncPointsAreProcessed) {
viewport_rect, resource_id, premultiplied_alpha,
uv_top_left, uv_bottom_right, SK_ColorTRANSPARENT,
vertex_opacity, flipped, nearest_neighbor);
+ overlay_quad->set_allow_overlay(true);
// Verify that overlay_quad actually gets turned into an overlay, and even
// though it's not drawn, that its sync point is waited on.
diff --git a/chromium/cc/output/latency_info_swap_promise.cc b/chromium/cc/output/latency_info_swap_promise.cc
index afc0f2d8502..5e08470fb07 100644
--- a/chromium/cc/output/latency_info_swap_promise.cc
+++ b/chromium/cc/output/latency_info_swap_promise.cc
@@ -5,6 +5,7 @@
#include "cc/output/latency_info_swap_promise.h"
#include "base/logging.h"
+#include "base/trace_event/trace_event.h"
namespace {
ui::LatencyComponentType DidNotSwapReasonToLatencyComponentType(
@@ -49,4 +50,11 @@ int64 LatencyInfoSwapPromise::TraceId() const {
return latency_.trace_id;
}
+// Trace the original LatencyInfo of a LatencyInfoSwapPromise
+void LatencyInfoSwapPromise::OnCommit() {
+ TRACE_EVENT_FLOW_STEP0("input,benchmark", "LatencyInfo.Flow",
+ TRACE_ID_DONT_MANGLE(TraceId()),
+ "HanldeInputEventMainCommit");
+}
+
} // namespace cc
diff --git a/chromium/cc/output/latency_info_swap_promise.h b/chromium/cc/output/latency_info_swap_promise.h
index 74810b8d1a2..9a4deb6e9c6 100644
--- a/chromium/cc/output/latency_info_swap_promise.h
+++ b/chromium/cc/output/latency_info_swap_promise.h
@@ -19,6 +19,7 @@ class CC_EXPORT LatencyInfoSwapPromise : public SwapPromise {
void DidActivate() override {}
void DidSwap(CompositorFrameMetadata* metadata) override;
void DidNotSwap(DidNotSwapReason reason) override;
+ void OnCommit() override;
int64 TraceId() const override;
diff --git a/chromium/cc/output/managed_memory_policy.cc b/chromium/cc/output/managed_memory_policy.cc
index 049d2b03f9f..d46790d5fef 100644
--- a/chromium/cc/output/managed_memory_policy.cc
+++ b/chromium/cc/output/managed_memory_policy.cc
@@ -5,7 +5,6 @@
#include "cc/output/managed_memory_policy.h"
#include "base/logging.h"
-#include "cc/resources/priority_calculator.h"
namespace cc {
@@ -43,23 +42,6 @@ bool ManagedMemoryPolicy::operator!=(const ManagedMemoryPolicy& other) const {
}
// static
-int ManagedMemoryPolicy::PriorityCutoffToValue(
- MemoryAllocation::PriorityCutoff priority_cutoff) {
- switch (priority_cutoff) {
- case MemoryAllocation::CUTOFF_ALLOW_NOTHING:
- return PriorityCalculator::AllowNothingCutoff();
- case MemoryAllocation::CUTOFF_ALLOW_REQUIRED_ONLY:
- return PriorityCalculator::AllowVisibleOnlyCutoff();
- case MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE:
- return PriorityCalculator::AllowVisibleAndNearbyCutoff();
- case MemoryAllocation::CUTOFF_ALLOW_EVERYTHING:
- return PriorityCalculator::AllowEverythingCutoff();
- }
- NOTREACHED();
- return PriorityCalculator::AllowNothingCutoff();
-}
-
-// static
TileMemoryLimitPolicy
ManagedMemoryPolicy::PriorityCutoffToTileMemoryLimitPolicy(
gpu::MemoryAllocation::PriorityCutoff priority_cutoff) {
diff --git a/chromium/cc/output/managed_memory_policy.h b/chromium/cc/output/managed_memory_policy.h
index a7273822a78..dee74ee1e8d 100644
--- a/chromium/cc/output/managed_memory_policy.h
+++ b/chromium/cc/output/managed_memory_policy.h
@@ -29,8 +29,6 @@ struct CC_EXPORT ManagedMemoryPolicy {
gpu::MemoryAllocation::PriorityCutoff priority_cutoff_when_visible;
size_t num_resources_limit;
- static int PriorityCutoffToValue(
- gpu::MemoryAllocation::PriorityCutoff priority_cutoff);
static TileMemoryLimitPolicy PriorityCutoffToTileMemoryLimitPolicy(
gpu::MemoryAllocation::PriorityCutoff priority_cutoff);
};
diff --git a/chromium/cc/output/output_surface.cc b/chromium/cc/output/output_surface.cc
index 670578ad6b0..a597a87d845 100644
--- a/chromium/cc/output/output_surface.cc
+++ b/chromium/cc/output/output_surface.cc
@@ -12,7 +12,9 @@
#include "cc/output/managed_memory_policy.h"
#include "cc/output/output_surface_client.h"
#include "gpu/GLES2/gl2extchromium.h"
+#include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/client/gles2_interface.h"
+#include "third_party/skia/include/gpu/GrContext.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
@@ -209,4 +211,34 @@ OverlayCandidateValidator* OutputSurface::GetOverlayCandidateValidator() const {
return nullptr;
}
+void OutputSurface::SetWorkerContextShouldAggressivelyFreeResources(
+ bool aggressively_free_resources) {
+ TRACE_EVENT1("cc",
+ "OutputSurface::SetWorkerContextShouldAggressivelyFreeResources",
+ "aggressively_free_resources", aggressively_free_resources);
+ if (auto* context_provider = worker_context_provider()) {
+ // The context lock must be held while accessing the worker context.
+ base::AutoLock context_lock(*context_provider->GetLock());
+
+ // Allow context to bind to current thread.
+ context_provider->DetachFromThread();
+
+ if (aggressively_free_resources) {
+ context_provider->DeleteCachedResources();
+ }
+
+ if (auto* context_support = context_provider->ContextSupport()) {
+ context_support->SetAggressivelyFreeResources(
+ aggressively_free_resources);
+ }
+
+ // Allow context to bind to other threads.
+ context_provider->DetachFromThread();
+ }
+}
+
+bool OutputSurface::SurfaceIsSuspendForRecycle() const {
+ return false;
+}
+
} // namespace cc
diff --git a/chromium/cc/output/output_surface.h b/chromium/cc/output/output_surface.h
index deaf97b4825..423dc6317c3 100644
--- a/chromium/cc/output/output_surface.h
+++ b/chromium/cc/output/output_surface.h
@@ -152,6 +152,13 @@ class CC_EXPORT OutputSurface {
// there's new content.
virtual void Invalidate() {}
+ // Updates the worker context provider's visibility, freeing GPU resources if
+ // appropriate.
+ virtual void SetWorkerContextShouldAggressivelyFreeResources(bool is_visible);
+
+ // If this returns true, then the surface will not attempt to draw.
+ virtual bool SurfaceIsSuspendForRecycle() const;
+
protected:
OutputSurfaceClient* client_;
diff --git a/chromium/cc/output/output_surface_unittest.cc b/chromium/cc/output/output_surface_unittest.cc
index 3b027027729..63373326507 100644
--- a/chromium/cc/output/output_surface_unittest.cc
+++ b/chromium/cc/output/output_surface_unittest.cc
@@ -15,7 +15,6 @@
#include "cc/test/test_web_graphics_context_3d.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/frame_time.h"
namespace cc {
namespace {
diff --git a/chromium/cc/output/overlay_candidate.h b/chromium/cc/output/overlay_candidate.h
index 36396358e65..b3e7fb359f1 100644
--- a/chromium/cc/output/overlay_candidate.h
+++ b/chromium/cc/output/overlay_candidate.h
@@ -34,6 +34,8 @@ class CC_EXPORT OverlayCandidate {
gfx::OverlayTransform transform;
// Format of the buffer to composite.
ResourceFormat format;
+ // Size of the resource, in pixels.
+ gfx::Size resource_size_in_pixels;
// Rect on the display to position the overlay to. Implementer must convert
// to integer coordinates if setting |overlay_handled| to true.
gfx::RectF display_rect;
diff --git a/chromium/cc/output/overlay_processor.cc b/chromium/cc/output/overlay_processor.cc
index 0f5ec560dd6..baae69dd10e 100644
--- a/chromium/cc/output/overlay_processor.cc
+++ b/chromium/cc/output/overlay_processor.cc
@@ -12,22 +12,19 @@
namespace cc {
-OverlayProcessor::OverlayProcessor(OutputSurface* surface,
- ResourceProvider* resource_provider)
- : surface_(surface), resource_provider_(resource_provider) {}
+OverlayProcessor::OverlayProcessor(OutputSurface* surface) : surface_(surface) {
+}
void OverlayProcessor::Initialize() {
DCHECK(surface_);
- if (!resource_provider_)
- return;
OverlayCandidateValidator* candidates =
surface_->GetOverlayCandidateValidator();
if (candidates) {
- strategies_.push_back(scoped_ptr<Strategy>(
- new OverlayStrategySingleOnTop(candidates, resource_provider_)));
- strategies_.push_back(scoped_ptr<Strategy>(
- new OverlayStrategyUnderlay(candidates, resource_provider_)));
+ strategies_.push_back(
+ scoped_ptr<Strategy>(new OverlayStrategySingleOnTop(candidates)));
+ strategies_.push_back(
+ scoped_ptr<Strategy>(new OverlayStrategyUnderlay(candidates)));
}
}
diff --git a/chromium/cc/output/overlay_processor.h b/chromium/cc/output/overlay_processor.h
index e50972e711d..e37816c9565 100644
--- a/chromium/cc/output/overlay_processor.h
+++ b/chromium/cc/output/overlay_processor.h
@@ -29,7 +29,7 @@ class CC_EXPORT OverlayProcessor {
};
typedef ScopedPtrVector<Strategy> StrategyList;
- OverlayProcessor(OutputSurface* surface, ResourceProvider* resource_provider);
+ explicit OverlayProcessor(OutputSurface* surface);
virtual ~OverlayProcessor();
// Virtual to allow testing different strategies.
virtual void Initialize();
@@ -40,7 +40,6 @@ class CC_EXPORT OverlayProcessor {
protected:
StrategyList strategies_;
OutputSurface* surface_;
- ResourceProvider* resource_provider_;
private:
DISALLOW_COPY_AND_ASSIGN(OverlayProcessor);
diff --git a/chromium/cc/output/overlay_strategy_common.cc b/chromium/cc/output/overlay_strategy_common.cc
index be352a5130a..33b45942398 100644
--- a/chromium/cc/output/overlay_strategy_common.cc
+++ b/chromium/cc/output/overlay_strategy_common.cc
@@ -9,6 +9,7 @@
#include "cc/quads/solid_color_draw_quad.h"
#include "cc/quads/stream_video_draw_quad.h"
#include "cc/quads/texture_draw_quad.h"
+#include "cc/resources/resource_provider.h"
#include "ui/gfx/geometry/point3_f.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/transform.h"
@@ -16,28 +17,42 @@
namespace cc {
OverlayStrategyCommon::OverlayStrategyCommon(
- OverlayCandidateValidator* capability_checker,
- ResourceProvider* resource_provider)
- : capability_checker_(capability_checker),
- resource_provider_(resource_provider) {
+ OverlayCandidateValidator* capability_checker)
+ : capability_checker_(capability_checker) {
}
OverlayStrategyCommon::~OverlayStrategyCommon() {
}
+bool OverlayStrategyCommon::Attempt(RenderPassList* render_passes_in_draw_order,
+ OverlayCandidateList* candidate_list) {
+ if (!capability_checker_)
+ return false;
+ RenderPass* root_render_pass = render_passes_in_draw_order->back();
+ DCHECK(root_render_pass);
+
+ QuadList& quad_list = root_render_pass->quad_list;
+ for (auto it = quad_list.begin(); it != quad_list.end(); ++it) {
+ OverlayCandidate candidate;
+ const DrawQuad* draw_quad = *it;
+ if (IsOverlayQuad(draw_quad) &&
+ GetCandidateQuadInfo(*draw_quad, &candidate) &&
+ TryOverlay(capability_checker_, render_passes_in_draw_order,
+ candidate_list, candidate, it))
+ return true;
+ }
+ return false;
+}
+
bool OverlayStrategyCommon::IsOverlayQuad(const DrawQuad* draw_quad) {
- unsigned int resource_id;
switch (draw_quad->material) {
case DrawQuad::TEXTURE_CONTENT:
- resource_id = TextureDrawQuad::MaterialCast(draw_quad)->resource_id;
- break;
+ return TextureDrawQuad::MaterialCast(draw_quad)->allow_overlay();
case DrawQuad::STREAM_VIDEO_CONTENT:
- resource_id = StreamVideoDrawQuad::MaterialCast(draw_quad)->resource_id;
- break;
+ return StreamVideoDrawQuad::MaterialCast(draw_quad)->allow_overlay();
default:
return false;
}
- return resource_provider_->AllowOverlay(resource_id);
}
bool OverlayStrategyCommon::IsInvisibleQuad(const DrawQuad* draw_quad) {
@@ -45,7 +60,7 @@ bool OverlayStrategyCommon::IsInvisibleQuad(const DrawQuad* draw_quad) {
const SolidColorDrawQuad* solid_quad =
SolidColorDrawQuad::MaterialCast(draw_quad);
SkColor color = solid_quad->color;
- float opacity = solid_quad->opacity();
+ float opacity = solid_quad->shared_quad_state->opacity;
float alpha = (SkColorGetA(color) * (1.0f / 255.0f)) * opacity;
return solid_quad->ShouldDrawWithBlending() &&
alpha < std::numeric_limits<float>::epsilon();
@@ -56,13 +71,14 @@ bool OverlayStrategyCommon::IsInvisibleQuad(const DrawQuad* draw_quad) {
bool OverlayStrategyCommon::GetTextureQuadInfo(const TextureDrawQuad& quad,
OverlayCandidate* quad_info) {
gfx::OverlayTransform overlay_transform =
- OverlayCandidate::GetOverlayTransform(quad.quadTransform(),
- quad.y_flipped);
+ OverlayCandidate::GetOverlayTransform(
+ quad.shared_quad_state->quad_to_target_transform, quad.y_flipped);
if (quad.background_color != SK_ColorTRANSPARENT ||
quad.premultiplied_alpha ||
overlay_transform == gfx::OVERLAY_TRANSFORM_INVALID)
return false;
- quad_info->resource_id = quad.resource_id;
+ quad_info->resource_id = quad.resource_id();
+ quad_info->resource_size_in_pixels = quad.resource_size_in_pixels();
quad_info->transform = overlay_transform;
quad_info->uv_rect = BoundingRect(quad.uv_top_left, quad.uv_bottom_right);
return true;
@@ -71,7 +87,8 @@ bool OverlayStrategyCommon::GetTextureQuadInfo(const TextureDrawQuad& quad,
bool OverlayStrategyCommon::GetVideoQuadInfo(const StreamVideoDrawQuad& quad,
OverlayCandidate* quad_info) {
gfx::OverlayTransform overlay_transform =
- OverlayCandidate::GetOverlayTransform(quad.quadTransform(), false);
+ OverlayCandidate::GetOverlayTransform(
+ quad.shared_quad_state->quad_to_target_transform, false);
if (overlay_transform == gfx::OVERLAY_TRANSFORM_INVALID)
return false;
if (!quad.matrix.IsScaleOrTranslation()) {
@@ -79,7 +96,8 @@ bool OverlayStrategyCommon::GetVideoQuadInfo(const StreamVideoDrawQuad& quad,
// coordinates yet.
return false;
}
- quad_info->resource_id = quad.resource_id;
+ quad_info->resource_id = quad.resource_id();
+ quad_info->resource_size_in_pixels = quad.resource_size_in_pixels();
quad_info->transform = overlay_transform;
gfx::Point3F uv0 = gfx::Point3F(0, 0, 0);
@@ -129,7 +147,7 @@ bool OverlayStrategyCommon::GetCandidateQuadInfo(const DrawQuad& draw_quad,
quad_info->format = RGBA_8888;
quad_info->display_rect = OverlayCandidate::GetOverlayRect(
- draw_quad.quadTransform(), draw_quad.rect);
+ draw_quad.shared_quad_state->quad_to_target_transform, draw_quad.rect);
return true;
}
diff --git a/chromium/cc/output/overlay_strategy_common.h b/chromium/cc/output/overlay_strategy_common.h
index 515a106e782..2b81b90ee40 100644
--- a/chromium/cc/output/overlay_strategy_common.h
+++ b/chromium/cc/output/overlay_strategy_common.h
@@ -17,10 +17,12 @@ class OverlayCandidate;
class CC_EXPORT OverlayStrategyCommon : public OverlayProcessor::Strategy {
public:
- OverlayStrategyCommon(OverlayCandidateValidator* capability_checker,
- ResourceProvider* resource_provider);
+ explicit OverlayStrategyCommon(OverlayCandidateValidator* capability_checker);
~OverlayStrategyCommon() override;
+ bool Attempt(RenderPassList* render_passes_in_draw_order,
+ OverlayCandidateList* candidate_list) override;
+
protected:
bool GetCandidateQuadInfo(const DrawQuad& draw_quad,
OverlayCandidate* quad_info);
@@ -38,10 +40,15 @@ class CC_EXPORT OverlayStrategyCommon : public OverlayProcessor::Strategy {
bool GetVideoQuadInfo(const StreamVideoDrawQuad& quad,
OverlayCandidate* quad_info);
- OverlayCandidateValidator* capability_checker_;
- ResourceProvider* resource_provider_;
+ virtual bool TryOverlay(OverlayCandidateValidator* capability_checker,
+ RenderPassList* render_passes_in_draw_order,
+ OverlayCandidateList* candidate_list,
+ const OverlayCandidate& candidate,
+ QuadList::Iterator iter) = 0;
private:
+ OverlayCandidateValidator* capability_checker_;
+
DISALLOW_COPY_AND_ASSIGN(OverlayStrategyCommon);
};
} // namespace cc
diff --git a/chromium/cc/output/overlay_strategy_single_on_top.cc b/chromium/cc/output/overlay_strategy_single_on_top.cc
index 65b039e6052..fd47e0f3b72 100644
--- a/chromium/cc/output/overlay_strategy_single_on_top.cc
+++ b/chromium/cc/output/overlay_strategy_single_on_top.cc
@@ -6,53 +6,38 @@
#include <limits>
+#include "cc/output/overlay_candidate_validator.h"
#include "cc/quads/draw_quad.h"
namespace cc {
OverlayStrategySingleOnTop::OverlayStrategySingleOnTop(
- OverlayCandidateValidator* capability_checker,
- ResourceProvider* resource_provider)
- : OverlayStrategyCommon(capability_checker, resource_provider) {
+ OverlayCandidateValidator* capability_checker)
+ : OverlayStrategyCommon(capability_checker) {
}
-bool OverlayStrategySingleOnTop::Attempt(
- RenderPassList* render_passes_in_draw_order,
- OverlayCandidateList* candidate_list) {
- // Only attempt to handle very simple case for now.
- if (!capability_checker_)
- return false;
+bool OverlayStrategySingleOnTop::TryOverlay(
+ OverlayCandidateValidator* capability_checker,
+ RenderPassList* render_passes_in_draw_order,
+ OverlayCandidateList* candidate_list,
+ const OverlayCandidate& candidate,
+ QuadList::Iterator candidate_iterator) {
RenderPass* root_render_pass = render_passes_in_draw_order->back();
- DCHECK(root_render_pass);
-
- OverlayCandidate candidate;
QuadList& quad_list = root_render_pass->quad_list;
- auto candidate_iterator = quad_list.end();
- for (auto it = quad_list.begin(); it != quad_list.end(); ++it) {
- const DrawQuad* draw_quad = *it;
- if (IsOverlayQuad(draw_quad)) {
- // Check that no prior quads overlap it.
- bool intersects = false;
- gfx::RectF rect = draw_quad->rect;
- draw_quad->quadTransform().TransformRect(&rect);
- for (auto overlap_iter = quad_list.cbegin(); overlap_iter != it;
- ++overlap_iter) {
- gfx::RectF overlap_rect = overlap_iter->rect;
- overlap_iter->quadTransform().TransformRect(&overlap_rect);
- if (rect.Intersects(overlap_rect) && !IsInvisibleQuad(*overlap_iter)) {
- intersects = true;
- break;
- }
- }
- if (intersects || !GetCandidateQuadInfo(*draw_quad, &candidate))
- continue;
- candidate_iterator = it;
- break;
- }
+ const DrawQuad* draw_quad = *candidate_iterator;
+ gfx::RectF rect = draw_quad->rect;
+ draw_quad->shared_quad_state->quad_to_target_transform.TransformRect(&rect);
+
+ // Check that no prior quads overlap it.
+ for (auto overlap_iter = quad_list.cbegin();
+ overlap_iter != candidate_iterator; ++overlap_iter) {
+ gfx::RectF overlap_rect = overlap_iter->rect;
+ overlap_iter->shared_quad_state->quad_to_target_transform.TransformRect(
+ &overlap_rect);
+ if (rect.Intersects(overlap_rect) && !IsInvisibleQuad(*overlap_iter))
+ return false;
}
- if (candidate_iterator == quad_list.end())
- return false;
// Add our primary surface.
OverlayCandidateList candidates;
@@ -61,11 +46,11 @@ bool OverlayStrategySingleOnTop::Attempt(
candidates.push_back(main_image);
// Add the overlay.
- candidate.plane_z_order = 1;
candidates.push_back(candidate);
+ candidates.back().plane_z_order = 1;
// Check for support.
- capability_checker_->CheckOverlaySupport(&candidates);
+ capability_checker->CheckOverlaySupport(&candidates);
// If the candidate can be handled by an overlay, create a pass for it.
if (candidates[1].overlay_handled) {
diff --git a/chromium/cc/output/overlay_strategy_single_on_top.h b/chromium/cc/output/overlay_strategy_single_on_top.h
index eeecd32fa4c..2b9cf4d04fd 100644
--- a/chromium/cc/output/overlay_strategy_single_on_top.h
+++ b/chromium/cc/output/overlay_strategy_single_on_top.h
@@ -19,10 +19,13 @@ class TextureDrawQuad;
class CC_EXPORT OverlayStrategySingleOnTop : public OverlayStrategyCommon {
public:
- OverlayStrategySingleOnTop(OverlayCandidateValidator* capability_checker,
- ResourceProvider* resource_provider);
- bool Attempt(RenderPassList* render_passes_in_draw_order,
- OverlayCandidateList* candidate_list) override;
+ explicit OverlayStrategySingleOnTop(
+ OverlayCandidateValidator* capability_checker);
+ bool TryOverlay(OverlayCandidateValidator* capability_checker,
+ RenderPassList* render_passes_in_draw_order,
+ OverlayCandidateList* candidate_list,
+ const OverlayCandidate& candidate,
+ QuadList::Iterator candidate_iterator) override;
private:
DISALLOW_COPY_AND_ASSIGN(OverlayStrategySingleOnTop);
diff --git a/chromium/cc/output/overlay_strategy_underlay.cc b/chromium/cc/output/overlay_strategy_underlay.cc
index 631ce03d95a..dd2b90f4814 100644
--- a/chromium/cc/output/overlay_strategy_underlay.cc
+++ b/chromium/cc/output/overlay_strategy_underlay.cc
@@ -4,37 +4,26 @@
#include "cc/output/overlay_strategy_underlay.h"
+#include "cc/output/overlay_candidate_validator.h"
#include "cc/quads/draw_quad.h"
#include "cc/quads/solid_color_draw_quad.h"
namespace cc {
OverlayStrategyUnderlay::OverlayStrategyUnderlay(
- OverlayCandidateValidator* capability_checker,
- ResourceProvider* resource_provider)
- : OverlayStrategyCommon(capability_checker, resource_provider) {
+ OverlayCandidateValidator* capability_checker)
+ : OverlayStrategyCommon(capability_checker) {
}
-bool OverlayStrategyUnderlay::Attempt(
- RenderPassList* render_passes_in_draw_order,
- OverlayCandidateList* candidate_list) {
- if (!capability_checker_)
- return false;
+bool OverlayStrategyUnderlay::TryOverlay(
+ OverlayCandidateValidator* capability_checker,
+ RenderPassList* render_passes_in_draw_order,
+ OverlayCandidateList* candidate_list,
+ const OverlayCandidate& candidate,
+ QuadList::Iterator candidate_iterator) {
RenderPass* root_render_pass = render_passes_in_draw_order->back();
- DCHECK(root_render_pass);
-
- OverlayCandidate candidate;
QuadList& quad_list = root_render_pass->quad_list;
- auto candidate_iterator = quad_list.end();
- for (auto it = quad_list.begin(); it != quad_list.end(); ++it) {
- if (IsOverlayQuad(*it) && GetCandidateQuadInfo(**it, &candidate)) {
- candidate_iterator = it;
- break;
- }
- }
- if (candidate_iterator == quad_list.end())
- return false;
// Add our primary surface.
OverlayCandidateList candidates;
@@ -43,11 +32,11 @@ bool OverlayStrategyUnderlay::Attempt(
candidates.push_back(main_image);
// Add the overlay.
- candidate.plane_z_order = -1;
candidates.push_back(candidate);
+ candidates.back().plane_z_order = -1;
// Check for support.
- capability_checker_->CheckOverlaySupport(&candidates);
+ capability_checker->CheckOverlaySupport(&candidates);
// If the candidate can be handled by an overlay, create a pass for it. We
// need to switch out the video quad with a black transparent one.
diff --git a/chromium/cc/output/overlay_strategy_underlay.h b/chromium/cc/output/overlay_strategy_underlay.h
index 881e170535f..fd55bef4319 100644
--- a/chromium/cc/output/overlay_strategy_underlay.h
+++ b/chromium/cc/output/overlay_strategy_underlay.h
@@ -18,10 +18,13 @@ class TextureDrawQuad;
// are fully opaque.
class CC_EXPORT OverlayStrategyUnderlay : public OverlayStrategyCommon {
public:
- OverlayStrategyUnderlay(OverlayCandidateValidator* capability_checker,
- ResourceProvider* resource_provider);
- bool Attempt(RenderPassList* render_passes_in_draw_order,
- OverlayCandidateList* candidate_list) override;
+ explicit OverlayStrategyUnderlay(
+ OverlayCandidateValidator* capability_checker);
+ bool TryOverlay(OverlayCandidateValidator* capability_checker,
+ RenderPassList* render_passes_in_draw_order,
+ OverlayCandidateList* candidate_list,
+ const OverlayCandidate& candidate,
+ QuadList::Iterator candidate_iterator) override;
private:
DISALLOW_COPY_AND_ASSIGN(OverlayStrategyUnderlay);
diff --git a/chromium/cc/output/overlay_unittest.cc b/chromium/cc/output/overlay_unittest.cc
index c9a2ae0c19a..6ac9b1c64c8 100644
--- a/chromium/cc/output/overlay_unittest.cc
+++ b/chromium/cc/output/overlay_unittest.cc
@@ -18,6 +18,7 @@
#include "cc/resources/resource_provider.h"
#include "cc/resources/texture_mailbox.h"
#include "cc/test/fake_output_surface_client.h"
+#include "cc/test/fake_resource_provider.h"
#include "cc/test/geometry_test_utils.h"
#include "cc/test/test_context_provider.h"
#include "cc/test/test_shared_bitmap_manager.h"
@@ -77,11 +78,9 @@ void SingleOverlayValidator::CheckOverlaySupport(
template <typename OverlayStrategyType>
class SingleOverlayProcessor : public OverlayProcessor {
public:
- SingleOverlayProcessor(OutputSurface* surface,
- ResourceProvider* resource_provider)
- : OverlayProcessor(surface, resource_provider) {
+ explicit SingleOverlayProcessor(OutputSurface* surface)
+ : OverlayProcessor(surface) {
EXPECT_EQ(surface, surface_);
- EXPECT_EQ(resource_provider, resource_provider_);
}
// Virtual to allow testing different strategies.
@@ -89,22 +88,20 @@ class SingleOverlayProcessor : public OverlayProcessor {
OverlayCandidateValidator* candidates =
surface_->GetOverlayCandidateValidator();
ASSERT_TRUE(candidates != NULL);
- strategies_.push_back(scoped_ptr<Strategy>(
- new OverlayStrategyType(candidates, resource_provider_)));
+ strategies_.push_back(
+ scoped_ptr<Strategy>(new OverlayStrategyType(candidates)));
}
};
class DefaultOverlayProcessor : public OverlayProcessor {
public:
- DefaultOverlayProcessor(OutputSurface* surface,
- ResourceProvider* resource_provider);
+ explicit DefaultOverlayProcessor(OutputSurface* surface);
size_t GetStrategyCount();
};
-DefaultOverlayProcessor::DefaultOverlayProcessor(
- OutputSurface* surface,
- ResourceProvider* resource_provider)
- : OverlayProcessor(surface, resource_provider) {}
+DefaultOverlayProcessor::DefaultOverlayProcessor(OutputSurface* surface)
+ : OverlayProcessor(surface) {
+}
size_t DefaultOverlayProcessor::GetStrategyCount() {
return strategies_.size();
@@ -152,12 +149,10 @@ scoped_ptr<RenderPass> CreateRenderPass() {
return pass.Pass();
}
-ResourceProvider::ResourceId CreateResource(
- ResourceProvider* resource_provider) {
+ResourceId CreateResource(ResourceProvider* resource_provider) {
unsigned sync_point = 0;
TextureMailbox mailbox =
TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
- mailbox.set_allow_overlay(true);
scoped_ptr<SingleReleaseCallbackImpl> release_callback =
SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased));
@@ -180,11 +175,13 @@ TextureDrawQuad* CreateCandidateQuadAt(ResourceProvider* resource_provider,
const SharedQuadState* shared_quad_state,
RenderPass* render_pass,
const gfx::Rect& rect) {
- ResourceProvider::ResourceId resource_id = CreateResource(resource_provider);
+ ResourceId resource_id = CreateResource(resource_provider);
bool premultiplied_alpha = false;
bool flipped = false;
bool nearest_neighbor = false;
float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ gfx::Size resource_size_in_pixels = gfx::Size(64, 64);
+ bool allow_overlay = true;
TextureDrawQuad* overlay_quad =
render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
@@ -200,6 +197,8 @@ TextureDrawQuad* CreateCandidateQuadAt(ResourceProvider* resource_provider,
vertex_opacity,
flipped,
nearest_neighbor);
+ overlay_quad->set_allow_overlay(allow_overlay);
+ overlay_quad->set_resource_size_in_pixels(resource_size_in_pixels);
return overlay_quad;
}
@@ -210,12 +209,14 @@ StreamVideoDrawQuad* CreateCandidateVideoQuadAt(
RenderPass* render_pass,
const gfx::Rect& rect,
const gfx::Transform& transform) {
- ResourceProvider::ResourceId resource_id = CreateResource(resource_provider);
+ ResourceId resource_id = CreateResource(resource_provider);
+ gfx::Size resource_size_in_pixels = gfx::Size(64, 64);
+ bool allow_overlay = true;
StreamVideoDrawQuad* overlay_quad =
render_pass->CreateAndAppendDrawQuad<StreamVideoDrawQuad>();
overlay_quad->SetNew(shared_quad_state, rect, rect, rect, resource_id,
- transform);
+ resource_size_in_pixels, allow_overlay, transform);
return overlay_quad;
}
@@ -277,8 +278,8 @@ static void CompareRenderPassLists(const RenderPassList& expected_list,
exp_iter != expected->quad_list.cend();
++exp_iter, ++act_iter) {
EXPECT_EQ(exp_iter->rect.ToString(), act_iter->rect.ToString());
- EXPECT_EQ(exp_iter->shared_quad_state->content_bounds.ToString(),
- act_iter->shared_quad_state->content_bounds.ToString());
+ EXPECT_EQ(exp_iter->shared_quad_state->quad_layer_bounds.ToString(),
+ act_iter->shared_quad_state->quad_layer_bounds.ToString());
}
}
}
@@ -302,11 +303,11 @@ TEST(OverlayTest, OverlaysProcessorHasStrategy) {
scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
new TestSharedBitmapManager());
- scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
- &output_surface, shared_bitmap_manager.get(), NULL, NULL, 0, false, 1));
+ scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
+ &output_surface, shared_bitmap_manager.get());
scoped_ptr<DefaultOverlayProcessor> overlay_processor(
- new DefaultOverlayProcessor(&output_surface, resource_provider.get()));
+ new DefaultOverlayProcessor(&output_surface));
overlay_processor->Initialize();
EXPECT_GE(2U, overlay_processor->GetStrategyCount());
}
@@ -322,16 +323,11 @@ class OverlayTest : public testing::Test {
EXPECT_TRUE(output_surface_->GetOverlayCandidateValidator() != NULL);
shared_bitmap_manager_.reset(new TestSharedBitmapManager());
- resource_provider_ = ResourceProvider::Create(output_surface_.get(),
- shared_bitmap_manager_.get(),
- NULL,
- NULL,
- 0,
- false,
- 1);
-
- overlay_processor_.reset(new SingleOverlayProcessor<OverlayStrategyType>(
- output_surface_.get(), resource_provider_.get()));
+ resource_provider_ = FakeResourceProvider::Create(
+ output_surface_.get(), shared_bitmap_manager_.get());
+
+ overlay_processor_.reset(
+ new SingleOverlayProcessor<OverlayStrategyType>(output_surface_.get()));
overlay_processor_->Initialize();
}
@@ -352,7 +348,7 @@ TEST_F(SingleOverlayOnTopTest, SuccessfullOverlay) {
CreateFullscreenCandidateQuad(resource_provider_.get(),
pass->shared_quad_state_list.back(),
pass.get());
- unsigned original_resource_id = original_quad->resource_id;
+ unsigned original_resource_id = original_quad->resource_id();
// Add something behind it.
CreateFullscreenCheckeredQuad(resource_provider_.get(),
@@ -550,7 +546,7 @@ TEST_F(SingleOverlayOnTopTest, RejectNonAxisAlignedTransform) {
pass->shared_quad_state_list.back(),
pass.get());
pass->shared_quad_state_list.back()
- ->content_to_target_transform.RotateAboutXAxis(45.f);
+ ->quad_to_target_transform.RotateAboutXAxis(45.f);
RenderPassList pass_list;
pass_list.push_back(pass.Pass());
@@ -567,8 +563,8 @@ TEST_F(SingleOverlayOnTopTest, AllowVerticalFlip) {
scoped_ptr<RenderPass> pass = CreateRenderPass();
CreateCandidateQuadAt(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass.get(), rect);
- pass->shared_quad_state_list.back()->content_to_target_transform.Scale(2.0f,
- -1.0f);
+ pass->shared_quad_state_list.back()->quad_to_target_transform.Scale(2.0f,
+ -1.0f);
RenderPassList pass_list;
pass_list.push_back(pass.Pass());
@@ -587,8 +583,8 @@ TEST_F(SingleOverlayOnTopTest, AllowHorizontalFlip) {
scoped_ptr<RenderPass> pass = CreateRenderPass();
CreateCandidateQuadAt(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass.get(), rect);
- pass->shared_quad_state_list.back()->content_to_target_transform.Scale(-1.0f,
- 2.0f);
+ pass->shared_quad_state_list.back()->quad_to_target_transform.Scale(-1.0f,
+ 2.0f);
RenderPassList pass_list;
pass_list.push_back(pass.Pass());
@@ -606,8 +602,8 @@ TEST_F(SingleOverlayOnTopTest, AllowPositiveScaleTransform) {
scoped_ptr<RenderPass> pass = CreateRenderPass();
CreateCandidateQuadAt(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass.get(), rect);
- pass->shared_quad_state_list.back()->content_to_target_transform.Scale(2.0f,
- 1.0f);
+ pass->shared_quad_state_list.back()->quad_to_target_transform.Scale(2.0f,
+ 1.0f);
RenderPassList pass_list;
pass_list.push_back(pass.Pass());
@@ -624,7 +620,7 @@ TEST_F(SingleOverlayOnTopTest, Allow90DegreeRotation) {
CreateCandidateQuadAt(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass.get(), rect);
pass->shared_quad_state_list.back()
- ->content_to_target_transform.RotateAboutZAxis(90.f);
+ ->quad_to_target_transform.RotateAboutZAxis(90.f);
RenderPassList pass_list;
pass_list.push_back(pass.Pass());
@@ -642,7 +638,7 @@ TEST_F(SingleOverlayOnTopTest, Allow180DegreeRotation) {
CreateCandidateQuadAt(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass.get(), rect);
pass->shared_quad_state_list.back()
- ->content_to_target_transform.RotateAboutZAxis(180.f);
+ ->quad_to_target_transform.RotateAboutZAxis(180.f);
RenderPassList pass_list;
pass_list.push_back(pass.Pass());
@@ -660,7 +656,7 @@ TEST_F(SingleOverlayOnTopTest, Allow270DegreeRotation) {
CreateCandidateQuadAt(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass.get(), rect);
pass->shared_quad_state_list.back()
- ->content_to_target_transform.RotateAboutZAxis(270.f);
+ ->quad_to_target_transform.RotateAboutZAxis(270.f);
RenderPassList pass_list;
pass_list.push_back(pass.Pass());
@@ -961,8 +957,8 @@ class GLRendererWithOverlaysTest : public testing::Test {
provider_ = TestContextProvider::Create();
output_surface_.reset(new OverlayOutputSurface(provider_));
CHECK(output_surface_->BindToClient(&output_surface_client_));
- resource_provider_ = ResourceProvider::Create(
- output_surface_.get(), NULL, NULL, NULL, 0, false, 1);
+ resource_provider_ =
+ FakeResourceProvider::Create(output_surface_.get(), nullptr);
provider_->support()->SetScheduleOverlayPlaneCallback(base::Bind(
&MockOverlayScheduler::Schedule, base::Unretained(&scheduler_)));
@@ -1104,10 +1100,8 @@ TEST_F(GLRendererWithOverlaysTest, ResourcesExportedAndReturned) {
Init(use_validator);
renderer_->set_expect_overlays(true);
- ResourceProvider::ResourceId resource1 =
- CreateResource(resource_provider_.get());
- ResourceProvider::ResourceId resource2 =
- CreateResource(resource_provider_.get());
+ ResourceId resource1 = CreateResource(resource_provider_.get());
+ ResourceId resource2 = CreateResource(resource_provider_.get());
scoped_ptr<RenderPass> pass = CreateRenderPass();
RenderPassList pass_list;
diff --git a/chromium/cc/output/program_binding.cc b/chromium/cc/output/program_binding.cc
index 7809e1085c7..c05447c7d65 100644
--- a/chromium/cc/output/program_binding.cc
+++ b/chromium/cc/output/program_binding.cc
@@ -6,6 +6,7 @@
#include "base/trace_event/trace_event.h"
#include "cc/output/geometry_binding.h"
+#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/gles2_interface.h"
using gpu::gles2::GLES2Interface;
@@ -129,4 +130,8 @@ void ProgramBindingBase::CleanupShaders(GLES2Interface* context) {
}
}
+bool ProgramBindingBase::IsContextLost(GLES2Interface* context) {
+ return context->GetGraphicsResetStatusKHR() != GL_NO_ERROR;
+}
+
} // namespace cc
diff --git a/chromium/cc/output/program_binding.h b/chromium/cc/output/program_binding.h
index 1d5132bdaea..8018cad76e3 100644
--- a/chromium/cc/output/program_binding.h
+++ b/chromium/cc/output/program_binding.h
@@ -42,6 +42,8 @@ class ProgramBindingBase {
unsigned fragment_shader);
void CleanupShaders(gpu::gles2::GLES2Interface* context);
+ bool IsContextLost(gpu::gles2::GLES2Interface* context);
+
unsigned program_;
unsigned vertex_shader_id_;
unsigned fragment_shader_id_;
@@ -79,7 +81,7 @@ class ProgramBinding : public ProgramBindingBase {
DCHECK(context_provider);
DCHECK(!initialized_);
- if (context_provider->IsContextLost())
+ if (IsContextLost(context_provider->ContextGL()))
return;
fragment_shader_.set_blend_mode(blend_mode);
@@ -89,7 +91,7 @@ class ProgramBinding : public ProgramBindingBase {
context_provider->ContextGL(),
vertex_shader_.GetShaderString(),
fragment_shader_.GetShaderString(precision, sampler))) {
- DCHECK(context_provider->IsContextLost());
+ DCHECK(IsContextLost(context_provider->ContextGL()));
return;
}
@@ -101,7 +103,7 @@ class ProgramBinding : public ProgramBindingBase {
// Link after binding uniforms
if (!Link(context_provider->ContextGL())) {
- DCHECK(context_provider->IsContextLost());
+ DCHECK(IsContextLost(context_provider->ContextGL()));
return;
}
diff --git a/chromium/cc/output/renderer_pixeltest.cc b/chromium/cc/output/renderer_pixeltest.cc
index 330c8bfd983..8472ff50613 100644
--- a/chromium/cc/output/renderer_pixeltest.cc
+++ b/chromium/cc/output/renderer_pixeltest.cc
@@ -47,48 +47,38 @@ scoped_ptr<RenderPass> CreateTestRenderPass(
}
SharedQuadState* CreateTestSharedQuadState(
- gfx::Transform content_to_target_transform,
+ gfx::Transform quad_to_target_transform,
const gfx::Rect& rect,
RenderPass* render_pass) {
- const gfx::Size content_bounds = rect.size();
- const gfx::Rect visible_content_rect = rect;
+ const gfx::Size layer_bounds = rect.size();
+ const gfx::Rect visible_layer_rect = rect;
const gfx::Rect clip_rect = rect;
const bool is_clipped = false;
const float opacity = 1.0f;
const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
int sorting_context_id = 0;
SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState();
- shared_state->SetAll(content_to_target_transform,
- content_bounds,
- visible_content_rect,
- clip_rect,
- is_clipped,
- opacity,
- blend_mode,
- sorting_context_id);
+ shared_state->SetAll(quad_to_target_transform, layer_bounds,
+ visible_layer_rect, clip_rect, is_clipped, opacity,
+ blend_mode, sorting_context_id);
return shared_state;
}
SharedQuadState* CreateTestSharedQuadStateClipped(
- gfx::Transform content_to_target_transform,
+ gfx::Transform quad_to_target_transform,
const gfx::Rect& rect,
const gfx::Rect& clip_rect,
RenderPass* render_pass) {
- const gfx::Size content_bounds = rect.size();
- const gfx::Rect visible_content_rect = clip_rect;
+ const gfx::Size layer_bounds = rect.size();
+ const gfx::Rect visible_layer_rect = clip_rect;
const bool is_clipped = true;
const float opacity = 1.0f;
const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
int sorting_context_id = 0;
SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState();
- shared_state->SetAll(content_to_target_transform,
- content_bounds,
- visible_content_rect,
- clip_rect,
- is_clipped,
- opacity,
- blend_mode,
- sorting_context_id);
+ shared_state->SetAll(quad_to_target_transform, layer_bounds,
+ visible_layer_rect, clip_rect, is_clipped, opacity,
+ blend_mode, sorting_context_id);
return shared_state;
}
@@ -137,12 +127,11 @@ void CreateTestTwoColoredTextureDrawQuad(const gfx::Rect& rect,
pixels[i * rect.width() + k] = pixel_stripe_color;
}
}
- ResourceProvider::ResourceId resource = resource_provider->CreateResource(
+ ResourceId resource = resource_provider->CreateResource(
rect.size(), GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
RGBA_8888);
- resource_provider->SetPixels(resource,
- reinterpret_cast<uint8_t*>(&pixels.front()),
- rect, rect, gfx::Vector2d());
+ resource_provider->CopyToResource(
+ resource, reinterpret_cast<uint8_t*>(&pixels.front()), rect.size());
float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
const gfx::PointF uv_top_left(0.0f, 0.0f);
@@ -172,7 +161,7 @@ void CreateTestTextureDrawQuad(const gfx::Rect& rect,
size_t num_pixels = static_cast<size_t>(rect.width()) * rect.height();
std::vector<uint32_t> pixels(num_pixels, pixel_color);
- ResourceProvider::ResourceId resource = resource_provider->CreateResource(
+ ResourceId resource = resource_provider->CreateResource(
rect.size(), GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
RGBA_8888);
resource_provider->CopyToResource(
@@ -202,10 +191,14 @@ void CreateTestYUVVideoDrawQuad_FromVideoFrame(
const gfx::Rect& visible_rect,
ResourceProvider* resource_provider) {
const bool with_alpha = (video_frame->format() == media::VideoFrame::YV12A);
- const YUVVideoDrawQuad::ColorSpace color_space =
- (video_frame->format() == media::VideoFrame::YV12J
- ? YUVVideoDrawQuad::JPEG
- : YUVVideoDrawQuad::REC_601);
+ YUVVideoDrawQuad::ColorSpace color_space = YUVVideoDrawQuad::REC_601;
+ int video_frame_color_space;
+ if (video_frame->metadata()->GetInteger(
+ media::VideoFrameMetadata::COLOR_SPACE, &video_frame_color_space) &&
+ video_frame_color_space == media::VideoFrame::COLOR_SPACE_JPEG) {
+ color_space = YUVVideoDrawQuad::JPEG;
+ }
+
const gfx::Rect opaque_rect(0, 0, 0, 0);
if (with_alpha) {
@@ -224,22 +217,19 @@ void CreateTestYUVVideoDrawQuad_FromVideoFrame(
EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
resources.release_callbacks.size());
- ResourceProvider::ResourceId y_resource =
- resource_provider->CreateResourceFromTextureMailbox(
- resources.mailboxes[media::VideoFrame::kYPlane],
- SingleReleaseCallbackImpl::Create(
- resources.release_callbacks[media::VideoFrame::kYPlane]));
- ResourceProvider::ResourceId u_resource =
- resource_provider->CreateResourceFromTextureMailbox(
- resources.mailboxes[media::VideoFrame::kUPlane],
- SingleReleaseCallbackImpl::Create(
- resources.release_callbacks[media::VideoFrame::kUPlane]));
- ResourceProvider::ResourceId v_resource =
- resource_provider->CreateResourceFromTextureMailbox(
- resources.mailboxes[media::VideoFrame::kVPlane],
- SingleReleaseCallbackImpl::Create(
- resources.release_callbacks[media::VideoFrame::kVPlane]));
- ResourceProvider::ResourceId a_resource = 0;
+ ResourceId y_resource = resource_provider->CreateResourceFromTextureMailbox(
+ resources.mailboxes[media::VideoFrame::kYPlane],
+ SingleReleaseCallbackImpl::Create(
+ resources.release_callbacks[media::VideoFrame::kYPlane]));
+ ResourceId u_resource = resource_provider->CreateResourceFromTextureMailbox(
+ resources.mailboxes[media::VideoFrame::kUPlane],
+ SingleReleaseCallbackImpl::Create(
+ resources.release_callbacks[media::VideoFrame::kUPlane]));
+ ResourceId v_resource = resource_provider->CreateResourceFromTextureMailbox(
+ resources.mailboxes[media::VideoFrame::kVPlane],
+ SingleReleaseCallbackImpl::Create(
+ resources.release_callbacks[media::VideoFrame::kVPlane]));
+ ResourceId a_resource = 0;
if (with_alpha) {
a_resource = resource_provider->CreateResourceFromTextureMailbox(
resources.mailboxes[media::VideoFrame::kAPlane],
@@ -327,6 +317,7 @@ void CreateTestYUVVideoDrawQuad_Striped(
void CreateTestYUVVideoDrawQuad_TwoColor(
const SharedQuadState* shared_state,
media::VideoFrame::Format format,
+ media::VideoFrame::ColorSpace color_space,
bool is_transparent,
const gfx::RectF& tex_coord_rect,
const gfx::Size& background_size,
@@ -346,6 +337,8 @@ void CreateTestYUVVideoDrawQuad_TwoColor(
scoped_refptr<media::VideoFrame> video_frame =
media::VideoFrame::CreateFrame(format, background_size, foreground_rect,
foreground_rect.size(), base::TimeDelta());
+ video_frame->metadata()->SetInteger(media::VideoFrameMetadata::COLOR_SPACE,
+ color_space);
int planes[] = {media::VideoFrame::kYPlane,
media::VideoFrame::kUPlane,
@@ -388,6 +381,7 @@ void CreateTestYUVVideoDrawQuad_TwoColor(
void CreateTestYUVVideoDrawQuad_Solid(
const SharedQuadState* shared_state,
media::VideoFrame::Format format,
+ media::VideoFrame::ColorSpace color_space,
bool is_transparent,
const gfx::RectF& tex_coord_rect,
uint8 y,
@@ -400,6 +394,8 @@ void CreateTestYUVVideoDrawQuad_Solid(
ResourceProvider* resource_provider) {
scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame(
format, rect.size(), rect, rect.size(), base::TimeDelta());
+ video_frame->metadata()->SetInteger(media::VideoFrameMetadata::COLOR_SPACE,
+ color_space);
// YUV values of a solid, constant, color. Useful for testing that color
// space/color range are being handled properly.
@@ -847,14 +843,16 @@ TYPED_TEST(IntersectingQuadGLPixelTest, YUVVideoQuads) {
(this->quad_rect_.height() / 2) & ~0xF);
CreateTestYUVVideoDrawQuad_TwoColor(
- this->front_quad_state_, media::VideoFrame::YV12J, false,
+ this->front_quad_state_, media::VideoFrame::YV12,
+ media::VideoFrame::COLOR_SPACE_JPEG, false,
gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), this->quad_rect_.size(),
this->quad_rect_, 0, 128, 128, inner_rect, 29, 255, 107,
this->render_pass_.get(), this->video_resource_updater_.get(),
this->resource_provider_.get());
CreateTestYUVVideoDrawQuad_TwoColor(
- this->back_quad_state_, media::VideoFrame::YV12J, false,
+ this->back_quad_state_, media::VideoFrame::YV12,
+ media::VideoFrame::COLOR_SPACE_JPEG, false,
gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), this->quad_rect_.size(),
this->quad_rect_, 149, 43, 21, inner_rect, 0, 128, 128,
this->render_pass_.get(), this->video_resource_updater2_.get(),
@@ -933,6 +931,7 @@ TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithBackground) {
class VideoGLRendererPixelTest : public GLRendererPixelTest {
protected:
void CreateEdgeBleedPass(media::VideoFrame::Format format,
+ media::VideoFrame::ColorSpace color_space,
RenderPassList* pass_list) {
gfx::Rect rect(200, 200);
@@ -961,9 +960,10 @@ class VideoGLRendererPixelTest : public GLRendererPixelTest {
// the final image. Bleeding will appear on all four sides of the video
// if the tex coords are not clamped.
CreateTestYUVVideoDrawQuad_TwoColor(
- shared_state, format, false, tex_coord_rect, background_size,
- gfx::Rect(background_size), 128, 128, 128, green_rect, 149, 43, 21,
- pass.get(), video_resource_updater_.get(), resource_provider_.get());
+ shared_state, format, color_space, false, tex_coord_rect,
+ background_size, gfx::Rect(background_size), 128, 128, 128, green_rect,
+ 149, 43, 21, pass.get(), video_resource_updater_.get(),
+ resource_provider_.get());
pass_list->push_back(pass.Pass());
}
@@ -1058,7 +1058,8 @@ TEST_F(VideoGLRendererPixelTest, SimpleYUVRectBlack) {
// In MPEG color range YUV values of (15,128,128) should produce black.
CreateTestYUVVideoDrawQuad_Solid(
- shared_state, media::VideoFrame::YV12, false,
+ shared_state, media::VideoFrame::YV12,
+ media::VideoFrame::COLOR_SPACE_UNSPECIFIED, false,
gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 15, 128, 128, pass.get(),
video_resource_updater_.get(), rect, rect, resource_provider_.get());
@@ -1083,7 +1084,8 @@ TEST_F(VideoGLRendererPixelTest, SimpleYUVJRect) {
// YUV of (149,43,21) should be green (0,255,0) in RGB.
CreateTestYUVVideoDrawQuad_Solid(
- shared_state, media::VideoFrame::YV12J, false,
+ shared_state, media::VideoFrame::YV12,
+ media::VideoFrame::COLOR_SPACE_JPEG, false,
gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 149, 43, 21, pass.get(),
video_resource_updater_.get(), rect, rect, resource_provider_.get());
@@ -1099,7 +1101,8 @@ TEST_F(VideoGLRendererPixelTest, SimpleYUVJRect) {
// tex coord rect is only a partial subrectangle of the coded contents.
TEST_F(VideoGLRendererPixelTest, YUVEdgeBleed) {
RenderPassList pass_list;
- CreateEdgeBleedPass(media::VideoFrame::YV12J, &pass_list);
+ CreateEdgeBleedPass(media::VideoFrame::YV12,
+ media::VideoFrame::COLOR_SPACE_JPEG, &pass_list);
EXPECT_TRUE(this->RunPixelTest(&pass_list,
base::FilePath(FILE_PATH_LITERAL("green.png")),
FuzzyPixelOffByOneComparator(true)));
@@ -1107,7 +1110,8 @@ TEST_F(VideoGLRendererPixelTest, YUVEdgeBleed) {
TEST_F(VideoGLRendererPixelTest, YUVAEdgeBleed) {
RenderPassList pass_list;
- CreateEdgeBleedPass(media::VideoFrame::YV12A, &pass_list);
+ CreateEdgeBleedPass(media::VideoFrame::YV12A,
+ media::VideoFrame::COLOR_SPACE_UNSPECIFIED, &pass_list);
EXPECT_TRUE(this->RunPixelTest(&pass_list,
base::FilePath(FILE_PATH_LITERAL("green.png")),
FuzzyPixelOffByOneComparator(true)));
@@ -1124,7 +1128,8 @@ TEST_F(VideoGLRendererPixelTest, SimpleYUVJRectGrey) {
// Dark grey in JPEG color range (in MPEG, this is black).
CreateTestYUVVideoDrawQuad_Solid(
- shared_state, media::VideoFrame::YV12J, false,
+ shared_state, media::VideoFrame::YV12,
+ media::VideoFrame::COLOR_SPACE_JPEG, false,
gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 15, 128, 128, pass.get(),
video_resource_updater_.get(), rect, rect, resource_provider_.get());
@@ -1204,9 +1209,9 @@ TYPED_TEST(RendererPixelTest, FastPassColorFilterAlpha) {
scoped_ptr<RenderPass> child_pass =
CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
- gfx::Transform content_to_target_transform;
+ gfx::Transform quad_to_target_transform;
SharedQuadState* shared_state = CreateTestSharedQuadState(
- content_to_target_transform, viewport_rect, child_pass.get());
+ quad_to_target_transform, viewport_rect, child_pass.get());
shared_state->opacity = 0.5f;
gfx::Rect blue_rect(0,
@@ -1225,7 +1230,7 @@ TYPED_TEST(RendererPixelTest, FastPassColorFilterAlpha) {
yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
SharedQuadState* blank_state = CreateTestSharedQuadState(
- content_to_target_transform, viewport_rect, child_pass.get());
+ quad_to_target_transform, viewport_rect, child_pass.get());
SolidColorDrawQuad* white =
child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
@@ -1296,9 +1301,9 @@ TYPED_TEST(RendererPixelTest, FastPassSaturateFilter) {
scoped_ptr<RenderPass> child_pass =
CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
- gfx::Transform content_to_target_transform;
+ gfx::Transform quad_to_target_transform;
SharedQuadState* shared_state = CreateTestSharedQuadState(
- content_to_target_transform, viewport_rect, child_pass.get());
+ quad_to_target_transform, viewport_rect, child_pass.get());
shared_state->opacity = 0.5f;
gfx::Rect blue_rect(0,
@@ -1317,7 +1322,7 @@ TYPED_TEST(RendererPixelTest, FastPassSaturateFilter) {
yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
SharedQuadState* blank_state = CreateTestSharedQuadState(
- content_to_target_transform, viewport_rect, child_pass.get());
+ quad_to_target_transform, viewport_rect, child_pass.get());
SolidColorDrawQuad* white =
child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
@@ -1367,9 +1372,9 @@ TYPED_TEST(RendererPixelTest, FastPassFilterChain) {
scoped_ptr<RenderPass> child_pass =
CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
- gfx::Transform content_to_target_transform;
+ gfx::Transform quad_to_target_transform;
SharedQuadState* shared_state = CreateTestSharedQuadState(
- content_to_target_transform, viewport_rect, child_pass.get());
+ quad_to_target_transform, viewport_rect, child_pass.get());
shared_state->opacity = 0.5f;
gfx::Rect blue_rect(0,
@@ -1388,7 +1393,7 @@ TYPED_TEST(RendererPixelTest, FastPassFilterChain) {
yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
SharedQuadState* blank_state = CreateTestSharedQuadState(
- content_to_target_transform, viewport_rect, child_pass.get());
+ quad_to_target_transform, viewport_rect, child_pass.get());
SolidColorDrawQuad* white =
child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
@@ -1440,9 +1445,9 @@ TYPED_TEST(RendererPixelTest, FastPassColorFilterAlphaTranslation) {
scoped_ptr<RenderPass> child_pass =
CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
- gfx::Transform content_to_target_transform;
+ gfx::Transform quad_to_target_transform;
SharedQuadState* shared_state = CreateTestSharedQuadState(
- content_to_target_transform, viewport_rect, child_pass.get());
+ quad_to_target_transform, viewport_rect, child_pass.get());
shared_state->opacity = 0.5f;
gfx::Rect blue_rect(0,
@@ -1461,7 +1466,7 @@ TYPED_TEST(RendererPixelTest, FastPassColorFilterAlphaTranslation) {
yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
SharedQuadState* blank_state = CreateTestSharedQuadState(
- content_to_target_transform, viewport_rect, child_pass.get());
+ quad_to_target_transform, viewport_rect, child_pass.get());
SolidColorDrawQuad* white =
child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
@@ -1536,9 +1541,9 @@ TYPED_TEST(RendererPixelTest, EnlargedRenderPassTexture) {
scoped_ptr<RenderPass> child_pass =
CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
- gfx::Transform content_to_target_transform;
+ gfx::Transform quad_to_target_transform;
SharedQuadState* shared_state = CreateTestSharedQuadState(
- content_to_target_transform, viewport_rect, child_pass.get());
+ quad_to_target_transform, viewport_rect, child_pass.get());
gfx::Rect blue_rect(0,
0,
@@ -1585,9 +1590,9 @@ TYPED_TEST(RendererPixelTest, EnlargedRenderPassTextureWithAntiAliasing) {
scoped_ptr<RenderPass> child_pass =
CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
- gfx::Transform content_to_target_transform;
+ gfx::Transform quad_to_target_transform;
SharedQuadState* shared_state = CreateTestSharedQuadState(
- content_to_target_transform, viewport_rect, child_pass.get());
+ quad_to_target_transform, viewport_rect, child_pass.get());
gfx::Rect blue_rect(0,
0,
@@ -1679,10 +1684,9 @@ TYPED_TEST(RendererPixelTest, RenderPassAndMaskWithPartialQuad) {
rect.Inset(6, 6, 4, 4);
}
- ResourceProvider::ResourceId mask_resource_id =
- this->resource_provider_->CreateResource(
- mask_rect.size(), GL_CLAMP_TO_EDGE,
- ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888);
+ ResourceId mask_resource_id = this->resource_provider_->CreateResource(
+ mask_rect.size(), GL_CLAMP_TO_EDGE,
+ ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888);
{
SkAutoLockPixels lock(bitmap);
this->resource_provider_->CopyToResource(
@@ -1743,41 +1747,32 @@ class RendererPixelTestWithBackgroundFilter
CreateTestRootRenderPass(root_id, device_viewport_rect);
root_pass->has_transparent_background = false;
- gfx::Transform identity_content_to_target_transform;
+ gfx::Transform identity_quad_to_target_transform;
RenderPassId filter_pass_id(2, 1);
gfx::Transform transform_to_root;
- scoped_ptr<RenderPass> filter_pass =
- CreateTestRenderPass(filter_pass_id,
- filter_pass_content_rect_,
- transform_to_root);
+ scoped_ptr<RenderPass> filter_pass = CreateTestRenderPass(
+ filter_pass_id, filter_pass_layer_rect_, transform_to_root);
// A non-visible quad in the filtering render pass.
{
SharedQuadState* shared_state =
- CreateTestSharedQuadState(identity_content_to_target_transform,
- filter_pass_content_rect_,
- filter_pass.get());
+ CreateTestSharedQuadState(identity_quad_to_target_transform,
+ filter_pass_layer_rect_, filter_pass.get());
SolidColorDrawQuad* color_quad =
filter_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
- color_quad->SetNew(shared_state,
- filter_pass_content_rect_,
- filter_pass_content_rect_,
- SK_ColorTRANSPARENT,
- false);
+ color_quad->SetNew(shared_state, filter_pass_layer_rect_,
+ filter_pass_layer_rect_, SK_ColorTRANSPARENT, false);
}
{
SharedQuadState* shared_state =
CreateTestSharedQuadState(filter_pass_to_target_transform_,
- filter_pass_content_rect_,
- filter_pass.get());
+ filter_pass_layer_rect_, filter_pass.get());
RenderPassDrawQuad* filter_pass_quad =
root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
- filter_pass_quad->SetNew(shared_state,
- filter_pass_content_rect_,
- filter_pass_content_rect_,
- filter_pass_id,
+ filter_pass_quad->SetNew(shared_state, filter_pass_layer_rect_,
+ filter_pass_layer_rect_, filter_pass_id,
0, // mask_resource_id
gfx::Vector2dF(), // mask_uv_scale
gfx::Size(), // mask_texture_size
@@ -1791,7 +1786,7 @@ class RendererPixelTestWithBackgroundFilter
gfx::Rect left_rect = gfx::Rect(0, 0, kColumnWidth, 20);
for (int i = 0; left_rect.y() < device_viewport_rect.height(); ++i) {
SharedQuadState* shared_state = CreateTestSharedQuadState(
- identity_content_to_target_transform, left_rect, root_pass.get());
+ identity_quad_to_target_transform, left_rect, root_pass.get());
SolidColorDrawQuad* color_quad =
root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
color_quad->SetNew(
@@ -1802,7 +1797,7 @@ class RendererPixelTestWithBackgroundFilter
gfx::Rect middle_rect = gfx::Rect(kColumnWidth+1, 0, kColumnWidth, 20);
for (int i = 0; middle_rect.y() < device_viewport_rect.height(); ++i) {
SharedQuadState* shared_state = CreateTestSharedQuadState(
- identity_content_to_target_transform, middle_rect, root_pass.get());
+ identity_quad_to_target_transform, middle_rect, root_pass.get());
SolidColorDrawQuad* color_quad =
root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
color_quad->SetNew(
@@ -1813,7 +1808,7 @@ class RendererPixelTestWithBackgroundFilter
gfx::Rect right_rect = gfx::Rect((kColumnWidth+1)*2, 0, kColumnWidth, 20);
for (int i = 0; right_rect.y() < device_viewport_rect.height(); ++i) {
SharedQuadState* shared_state = CreateTestSharedQuadState(
- identity_content_to_target_transform, right_rect, root_pass.get());
+ identity_quad_to_target_transform, right_rect, root_pass.get());
SolidColorDrawQuad* color_quad =
root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
color_quad->SetNew(
@@ -1822,9 +1817,8 @@ class RendererPixelTestWithBackgroundFilter
}
SharedQuadState* shared_state =
- CreateTestSharedQuadState(identity_content_to_target_transform,
- device_viewport_rect,
- root_pass.get());
+ CreateTestSharedQuadState(identity_quad_to_target_transform,
+ device_viewport_rect, root_pass.get());
SolidColorDrawQuad* background_quad =
root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
background_quad->SetNew(shared_state,
@@ -1840,7 +1834,7 @@ class RendererPixelTestWithBackgroundFilter
RenderPassList pass_list_;
FilterOperations background_filters_;
gfx::Transform filter_pass_to_target_transform_;
- gfx::Rect filter_pass_content_rect_;
+ gfx::Rect filter_pass_layer_rect_;
};
typedef ::testing::Types<GLRenderer, SoftwareRenderer>
@@ -1856,8 +1850,8 @@ TEST_F(GLRendererPixelTestWithBackgroundFilter, InvertFilter) {
this->background_filters_.Append(
FilterOperation::CreateInvertFilter(1.f));
- this->filter_pass_content_rect_ = gfx::Rect(this->device_viewport_size_);
- this->filter_pass_content_rect_.Inset(12, 14, 16, 18);
+ this->filter_pass_layer_rect_ = gfx::Rect(this->device_viewport_size_);
+ this->filter_pass_layer_rect_.Inset(12, 14, 16, 18);
this->SetUpRenderPassList();
EXPECT_TRUE(this->RunPixelTest(
@@ -1964,9 +1958,9 @@ TEST_F(ExternalStencilPixelTest, RenderSurfacesIgnoreStencil) {
scoped_ptr<RenderPass> child_pass =
CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
- gfx::Transform content_to_target_transform;
+ gfx::Transform quad_to_target_transform;
SharedQuadState* shared_state = CreateTestSharedQuadState(
- content_to_target_transform, viewport_rect, child_pass.get());
+ quad_to_target_transform, viewport_rect, child_pass.get());
gfx::Rect blue_rect(0,
0,
@@ -2021,26 +2015,26 @@ TEST_F(GLRendererPixelTest, AntiAliasing) {
RenderPassId id(1, 1);
scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
- gfx::Transform red_content_to_target_transform;
- red_content_to_target_transform.Rotate(10);
- SharedQuadState* red_shared_state = CreateTestSharedQuadState(
- red_content_to_target_transform, rect, pass.get());
+ gfx::Transform red_quad_to_target_transform;
+ red_quad_to_target_transform.Rotate(10);
+ SharedQuadState* red_shared_state =
+ CreateTestSharedQuadState(red_quad_to_target_transform, rect, pass.get());
SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false);
- gfx::Transform yellow_content_to_target_transform;
- yellow_content_to_target_transform.Rotate(5);
+ gfx::Transform yellow_quad_to_target_transform;
+ yellow_quad_to_target_transform.Rotate(5);
SharedQuadState* yellow_shared_state = CreateTestSharedQuadState(
- yellow_content_to_target_transform, rect, pass.get());
+ yellow_quad_to_target_transform, rect, pass.get());
SolidColorDrawQuad* yellow =
pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false);
- gfx::Transform blue_content_to_target_transform;
+ gfx::Transform blue_quad_to_target_transform;
SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
- blue_content_to_target_transform, rect, pass.get());
+ blue_quad_to_target_transform, rect, pass.get());
SolidColorDrawQuad* blue =
pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
@@ -2065,30 +2059,29 @@ TEST_F(GLRendererPixelTest, AxisAligned) {
scoped_ptr<RenderPass> pass =
CreateTestRenderPass(id, rect, transform_to_root);
- gfx::Transform red_content_to_target_transform;
- red_content_to_target_transform.Translate(50, 50);
- red_content_to_target_transform.Scale(
- 0.5f + 1.0f / (rect.width() * 2.0f),
- 0.5f + 1.0f / (rect.height() * 2.0f));
- SharedQuadState* red_shared_state = CreateTestSharedQuadState(
- red_content_to_target_transform, rect, pass.get());
+ gfx::Transform red_quad_to_target_transform;
+ red_quad_to_target_transform.Translate(50, 50);
+ red_quad_to_target_transform.Scale(0.5f + 1.0f / (rect.width() * 2.0f),
+ 0.5f + 1.0f / (rect.height() * 2.0f));
+ SharedQuadState* red_shared_state =
+ CreateTestSharedQuadState(red_quad_to_target_transform, rect, pass.get());
SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false);
- gfx::Transform yellow_content_to_target_transform;
- yellow_content_to_target_transform.Translate(25.5f, 25.5f);
- yellow_content_to_target_transform.Scale(0.5f, 0.5f);
+ gfx::Transform yellow_quad_to_target_transform;
+ yellow_quad_to_target_transform.Translate(25.5f, 25.5f);
+ yellow_quad_to_target_transform.Scale(0.5f, 0.5f);
SharedQuadState* yellow_shared_state = CreateTestSharedQuadState(
- yellow_content_to_target_transform, rect, pass.get());
+ yellow_quad_to_target_transform, rect, pass.get());
SolidColorDrawQuad* yellow =
pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false);
- gfx::Transform blue_content_to_target_transform;
+ gfx::Transform blue_quad_to_target_transform;
SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
- blue_content_to_target_transform, rect, pass.get());
+ blue_quad_to_target_transform, rect, pass.get());
SolidColorDrawQuad* blue =
pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
@@ -2113,22 +2106,21 @@ TEST_F(GLRendererPixelTest, ForceAntiAliasingOff) {
scoped_ptr<RenderPass> pass =
CreateTestRenderPass(id, rect, transform_to_root);
- gfx::Transform hole_content_to_target_transform;
- hole_content_to_target_transform.Translate(50, 50);
- hole_content_to_target_transform.Scale(
- 0.5f + 1.0f / (rect.width() * 2.0f),
- 0.5f + 1.0f / (rect.height() * 2.0f));
+ gfx::Transform hole_quad_to_target_transform;
+ hole_quad_to_target_transform.Translate(50, 50);
+ hole_quad_to_target_transform.Scale(0.5f + 1.0f / (rect.width() * 2.0f),
+ 0.5f + 1.0f / (rect.height() * 2.0f));
SharedQuadState* hole_shared_state = CreateTestSharedQuadState(
- hole_content_to_target_transform, rect, pass.get());
+ hole_quad_to_target_transform, rect, pass.get());
SolidColorDrawQuad* hole =
pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
hole->SetAll(
hole_shared_state, rect, rect, rect, false, SK_ColorTRANSPARENT, true);
- gfx::Transform green_content_to_target_transform;
+ gfx::Transform green_quad_to_target_transform;
SharedQuadState* green_shared_state = CreateTestSharedQuadState(
- green_content_to_target_transform, rect, pass.get());
+ green_quad_to_target_transform, rect, pass.get());
SolidColorDrawQuad* green =
pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
@@ -2150,13 +2142,11 @@ TEST_F(GLRendererPixelTest, AntiAliasingPerspective) {
CreateTestRootRenderPass(RenderPassId(1, 1), rect);
gfx::Rect red_rect(0, 0, 180, 500);
- gfx::Transform red_content_to_target_transform(
- 1.0f, 2.4520f, 10.6206f, 19.0f,
- 0.0f, 0.3528f, 5.9737f, 9.5f,
- 0.0f, -0.2250f, -0.9744f, 0.0f,
- 0.0f, 0.0225f, 0.0974f, 1.0f);
+ gfx::Transform red_quad_to_target_transform(
+ 1.0f, 2.4520f, 10.6206f, 19.0f, 0.0f, 0.3528f, 5.9737f, 9.5f, 0.0f,
+ -0.2250f, -0.9744f, 0.0f, 0.0f, 0.0225f, 0.0974f, 1.0f);
SharedQuadState* red_shared_state = CreateTestSharedQuadState(
- red_content_to_target_transform, red_rect, pass.get());
+ red_quad_to_target_transform, red_rect, pass.get());
SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
red->SetNew(red_shared_state, red_rect, red_rect, SK_ColorRED, false);
@@ -2213,16 +2203,14 @@ TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadIdentityScale) {
scoped_refptr<FakePicturePileImpl> blue_pile =
FakePicturePileImpl::CreateFromPile(blue_recording.get(), nullptr);
- gfx::Transform blue_content_to_target_transform;
+ gfx::Transform blue_quad_to_target_transform;
gfx::Vector2d offset(viewport.bottom_right() - blue_rect.bottom_right());
- blue_content_to_target_transform.Translate(offset.x(), offset.y());
+ blue_quad_to_target_transform.Translate(offset.x(), offset.y());
gfx::RectF blue_scissor_rect = blue_clip_rect;
- blue_content_to_target_transform.TransformRect(&blue_scissor_rect);
- SharedQuadState* blue_shared_state =
- CreateTestSharedQuadStateClipped(blue_content_to_target_transform,
- blue_rect,
- gfx::ToEnclosingRect(blue_scissor_rect),
- pass.get());
+ blue_quad_to_target_transform.TransformRect(&blue_scissor_rect);
+ SharedQuadState* blue_shared_state = CreateTestSharedQuadStateClipped(
+ blue_quad_to_target_transform, blue_rect,
+ gfx::ToEnclosingRect(blue_scissor_rect), pass.get());
PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
@@ -2242,9 +2230,9 @@ TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadIdentityScale) {
scoped_refptr<FakePicturePileImpl> green_pile =
FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
- gfx::Transform green_content_to_target_transform;
+ gfx::Transform green_quad_to_target_transform;
SharedQuadState* green_shared_state = CreateTestSharedQuadState(
- green_content_to_target_transform, viewport, pass.get());
+ green_quad_to_target_transform, viewport, pass.get());
PictureDrawQuad* green_quad =
pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
@@ -2284,9 +2272,9 @@ TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadOpacity) {
scoped_refptr<FakePicturePileImpl> green_pile =
FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
- gfx::Transform green_content_to_target_transform;
+ gfx::Transform green_quad_to_target_transform;
SharedQuadState* green_shared_state = CreateTestSharedQuadState(
- green_content_to_target_transform, viewport, pass.get());
+ green_quad_to_target_transform, viewport, pass.get());
green_shared_state->opacity = 0.5f;
PictureDrawQuad* green_quad =
@@ -2305,9 +2293,9 @@ TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadOpacity) {
scoped_refptr<FakePicturePileImpl> white_pile =
FakePicturePileImpl::CreateFromPile(white_recording.get(), nullptr);
- gfx::Transform white_content_to_target_transform;
+ gfx::Transform white_quad_to_target_transform;
SharedQuadState* white_shared_state = CreateTestSharedQuadState(
- white_content_to_target_transform, viewport, pass.get());
+ white_quad_to_target_transform, viewport, pass.get());
PictureDrawQuad* white_quad =
pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
@@ -2376,9 +2364,9 @@ TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadDisableImageFiltering) {
scoped_refptr<FakePicturePileImpl> pile =
FakePicturePileImpl::CreateFromPile(recording.get(), nullptr);
- gfx::Transform content_to_target_transform;
- SharedQuadState* shared_state = CreateTestSharedQuadState(
- content_to_target_transform, viewport, pass.get());
+ gfx::Transform quad_to_target_transform;
+ SharedQuadState* shared_state =
+ CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get());
PictureDrawQuad* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
quad->SetNew(shared_state, viewport, gfx::Rect(), viewport,
@@ -2428,9 +2416,9 @@ TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNearestNeighbor) {
scoped_refptr<FakePicturePileImpl> pile =
FakePicturePileImpl::CreateFromPile(recording.get(), nullptr);
- gfx::Transform content_to_target_transform;
- SharedQuadState* shared_state = CreateTestSharedQuadState(
- content_to_target_transform, viewport, pass.get());
+ gfx::Transform quad_to_target_transform;
+ SharedQuadState* shared_state =
+ CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get());
PictureDrawQuad* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
quad->SetNew(shared_state, viewport, gfx::Rect(), viewport,
@@ -2464,10 +2452,9 @@ TYPED_TEST(RendererPixelTest, TileDrawQuadNearestNeighbor) {
}
gfx::Size tile_size(2, 2);
- ResourceProvider::ResourceId resource =
- this->resource_provider_->CreateResource(
- tile_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
- RGBA_8888);
+ ResourceId resource = this->resource_provider_->CreateResource(
+ tile_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
+ RGBA_8888);
{
SkAutoLockPixels lock(bitmap);
@@ -2480,9 +2467,9 @@ TYPED_TEST(RendererPixelTest, TileDrawQuadNearestNeighbor) {
scoped_ptr<RenderPass> pass =
CreateTestRenderPass(id, viewport, transform_to_root);
- gfx::Transform content_to_target_transform;
- SharedQuadState* shared_state = CreateTestSharedQuadState(
- content_to_target_transform, viewport, pass.get());
+ gfx::Transform quad_to_target_transform;
+ SharedQuadState* shared_state =
+ CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get());
TileDrawQuad* quad = pass->CreateAndAppendDrawQuad<TileDrawQuad>();
quad->SetNew(shared_state, viewport, gfx::Rect(), viewport, resource,
@@ -2516,10 +2503,9 @@ TYPED_TEST(SoftwareRendererPixelTest, TextureDrawQuadNearestNeighbor) {
}
gfx::Size tile_size(2, 2);
- ResourceProvider::ResourceId resource =
- this->resource_provider_->CreateResource(
- tile_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
- RGBA_8888);
+ ResourceId resource = this->resource_provider_->CreateResource(
+ tile_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
+ RGBA_8888);
{
SkAutoLockPixels lock(bitmap);
@@ -2532,9 +2518,9 @@ TYPED_TEST(SoftwareRendererPixelTest, TextureDrawQuadNearestNeighbor) {
scoped_ptr<RenderPass> pass =
CreateTestRenderPass(id, viewport, transform_to_root);
- gfx::Transform content_to_target_transform;
- SharedQuadState* shared_state = CreateTestSharedQuadState(
- content_to_target_transform, viewport, pass.get());
+ gfx::Transform quad_to_target_transform;
+ SharedQuadState* shared_state =
+ CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get());
float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
TextureDrawQuad* quad = pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
@@ -2569,10 +2555,9 @@ TYPED_TEST(SoftwareRendererPixelTest, TextureDrawQuadLinear) {
}
gfx::Size tile_size(2, 2);
- ResourceProvider::ResourceId resource =
- this->resource_provider_->CreateResource(
- tile_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
- RGBA_8888);
+ ResourceId resource = this->resource_provider_->CreateResource(
+ tile_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
+ RGBA_8888);
{
SkAutoLockPixels lock(bitmap);
@@ -2585,9 +2570,9 @@ TYPED_TEST(SoftwareRendererPixelTest, TextureDrawQuadLinear) {
scoped_ptr<RenderPass> pass =
CreateTestRenderPass(id, viewport, transform_to_root);
- gfx::Transform content_to_target_transform;
- SharedQuadState* shared_state = CreateTestSharedQuadState(
- content_to_target_transform, viewport, pass.get());
+ gfx::Transform quad_to_target_transform;
+ SharedQuadState* shared_state =
+ CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get());
float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
TextureDrawQuad* quad = pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
@@ -2622,7 +2607,7 @@ TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNonIdentityScale) {
// a few extra "cleanup rects" need to be added to clobber the blending
// to make the output image more clean. This will also test subrects
// of the layer.
- gfx::Transform green_content_to_target_transform;
+ gfx::Transform green_quad_to_target_transform;
gfx::Rect green_rect1(gfx::Point(80, 0), gfx::Size(20, 100));
gfx::Rect green_rect2(gfx::Point(0, 80), gfx::Size(100, 20));
@@ -2641,8 +2626,8 @@ TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNonIdentityScale) {
FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
SharedQuadState* top_right_green_shared_quad_state =
- CreateTestSharedQuadState(
- green_content_to_target_transform, viewport, pass.get());
+ CreateTestSharedQuadState(green_quad_to_target_transform, viewport,
+ pass.get());
PictureDrawQuad* green_quad1 =
pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
@@ -2664,10 +2649,8 @@ TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNonIdentityScale) {
gfx::Point(viewport.width() / 2, viewport.height() / 2),
gfx::Size(viewport.width() / 2, viewport.height() / 2));
SharedQuadState* bottom_right_green_shared_state =
- CreateTestSharedQuadStateClipped(green_content_to_target_transform,
- viewport,
- bottom_right_rect,
- pass.get());
+ CreateTestSharedQuadStateClipped(green_quad_to_target_transform, viewport,
+ bottom_right_rect, pass.get());
SolidColorDrawQuad* bottom_right_color_quad =
pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
bottom_right_color_quad->SetNew(bottom_right_green_shared_state,
@@ -2717,11 +2700,11 @@ TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNonIdentityScale) {
// At a scale of 4x the rectangles with a width of 2.5 will take up 10 pixels,
// so scale an additional 10x to make them 100x100.
- gfx::Transform content_to_target_transform;
- content_to_target_transform.Scale(10.0, 10.0);
+ gfx::Transform quad_to_target_transform;
+ quad_to_target_transform.Scale(10.0, 10.0);
gfx::Rect quad_content_rect(gfx::Size(20, 20));
SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
- content_to_target_transform, quad_content_rect, pass.get());
+ quad_to_target_transform, quad_content_rect, pass.get());
PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
blue_quad->SetNew(blue_shared_state, quad_content_rect, gfx::Rect(),
@@ -2730,10 +2713,10 @@ TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNonIdentityScale) {
content_union_rect, contents_scale, pile.get());
// Fill left half of viewport with green.
- gfx::Transform half_green_content_to_target_transform;
+ gfx::Transform half_green_quad_to_target_transform;
gfx::Rect half_green_rect(gfx::Size(viewport.width() / 2, viewport.height()));
SharedQuadState* half_green_shared_state = CreateTestSharedQuadState(
- half_green_content_to_target_transform, half_green_rect, pass.get());
+ half_green_quad_to_target_transform, half_green_rect, pass.get());
SolidColorDrawQuad* half_color_quad =
pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
half_color_quad->SetNew(half_green_shared_state,
@@ -2768,9 +2751,9 @@ TEST_F(GLRendererPixelTestWithFlippedOutputSurface, ExplicitFlipTest) {
scoped_ptr<RenderPass> child_pass =
CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
- gfx::Transform content_to_target_transform;
+ gfx::Transform quad_to_target_transform;
SharedQuadState* shared_state = CreateTestSharedQuadState(
- content_to_target_transform, viewport_rect, child_pass.get());
+ quad_to_target_transform, viewport_rect, child_pass.get());
gfx::Rect blue_rect(0,
0,
@@ -2816,9 +2799,9 @@ TEST_F(GLRendererPixelTestWithFlippedOutputSurface, CheckChildPassUnflipped) {
scoped_ptr<RenderPass> child_pass =
CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
- gfx::Transform content_to_target_transform;
+ gfx::Transform quad_to_target_transform;
SharedQuadState* shared_state = CreateTestSharedQuadState(
- content_to_target_transform, viewport_rect, child_pass.get());
+ quad_to_target_transform, viewport_rect, child_pass.get());
gfx::Rect blue_rect(0,
0,
@@ -2865,9 +2848,9 @@ TEST_F(GLRendererPixelTest, CheckReadbackSubset) {
scoped_ptr<RenderPass> child_pass =
CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
- gfx::Transform content_to_target_transform;
+ gfx::Transform quad_to_target_transform;
SharedQuadState* shared_state = CreateTestSharedQuadState(
- content_to_target_transform, viewport_rect, child_pass.get());
+ quad_to_target_transform, viewport_rect, child_pass.get());
// Draw a green quad full-size with a blue quad in the lower-right corner.
gfx::Rect blue_rect(this->device_viewport_size_.width() * 3 / 4,
@@ -2929,10 +2912,9 @@ TYPED_TEST(RendererPixelTest, WrapModeRepeat) {
colors[2], colors[2], colors[3], colors[3],
colors[2], colors[2], colors[3], colors[3],
};
- ResourceProvider::ResourceId resource =
- this->resource_provider_->CreateResource(
- texture_size, GL_REPEAT, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
- RGBA_8888);
+ ResourceId resource = this->resource_provider_->CreateResource(
+ texture_size, GL_REPEAT, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
+ RGBA_8888);
this->resource_provider_->CopyToResource(
resource, reinterpret_cast<uint8_t*>(pixels), texture_size);
diff --git a/chromium/cc/output/renderer_settings.cc b/chromium/cc/output/renderer_settings.cc
index 2277af3ed3c..0c0a10d1e01 100644
--- a/chromium/cc/output/renderer_settings.cc
+++ b/chromium/cc/output/renderer_settings.cc
@@ -17,6 +17,7 @@ RendererSettings::RendererSettings()
partial_swap_enabled(false),
finish_rendering_on_resize(false),
should_clear_root_render_pass(true),
+ disable_gpu_vsync(false),
refresh_rate(60.0),
highp_threshold_min(0),
use_rgba_4444_textures(false),
diff --git a/chromium/cc/output/renderer_settings.h b/chromium/cc/output/renderer_settings.h
index 6da02383826..4757f8d5571 100644
--- a/chromium/cc/output/renderer_settings.h
+++ b/chromium/cc/output/renderer_settings.h
@@ -21,6 +21,7 @@ class CC_EXPORT RendererSettings {
bool partial_swap_enabled;
bool finish_rendering_on_resize;
bool should_clear_root_render_pass;
+ bool disable_gpu_vsync;
double refresh_rate;
int highp_threshold_min;
bool use_rgba_4444_textures;
diff --git a/chromium/cc/output/renderer_unittest.cc b/chromium/cc/output/renderer_unittest.cc
index a8f09ff9474..48545587759 100644
--- a/chromium/cc/output/renderer_unittest.cc
+++ b/chromium/cc/output/renderer_unittest.cc
@@ -7,6 +7,7 @@
#include "cc/output/output_surface.h"
#include "cc/test/fake_output_surface_client.h"
#include "cc/test/fake_renderer_client.h"
+#include "cc/test/fake_resource_provider.h"
#include "cc/test/test_context_provider.h"
#include "cc/test/test_web_graphics_context_3d.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -82,8 +83,8 @@ class RendererTest : public ::testing::Test {
new MockContextProvider(TestWebGraphicsContext3D::Create());
output_surface_.reset(new TestOutputSurface(context_provider_));
output_surface_->BindToClient(&output_surface_client_);
- resource_provider_ = ResourceProvider::Create(
- output_surface_.get(), NULL, NULL, NULL, 0, false, 1);
+ resource_provider_ =
+ FakeResourceProvider::Create(output_surface_.get(), nullptr);
renderer_ = CreateRenderer<T>(&renderer_client_,
&tree_settings_,
output_surface_.get(),
diff --git a/chromium/cc/output/software_renderer.cc b/chromium/cc/output/software_renderer.cc
index 80a5f0e53ca..a8110efb4dc 100644
--- a/chromium/cc/output/software_renderer.cc
+++ b/chromium/cc/output/software_renderer.cc
@@ -20,7 +20,7 @@
#include "cc/quads/solid_color_draw_quad.h"
#include "cc/quads/texture_draw_quad.h"
#include "cc/quads/tile_draw_quad.h"
-#include "skia/ext/opacity_draw_filter.h"
+#include "skia/ext/opacity_filter_canvas.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkImageFilter.h"
@@ -229,8 +229,7 @@ void SoftwareRenderer::PrepareSurfaceForPass(
}
}
-bool SoftwareRenderer::IsSoftwareResource(
- ResourceProvider::ResourceId resource_id) const {
+bool SoftwareRenderer::IsSoftwareResource(ResourceId resource_id) const {
switch (resource_provider_->GetResourceType(resource_id)) {
case ResourceProvider::RESOURCE_TYPE_GL_TEXTURE:
return false;
@@ -251,7 +250,9 @@ void SoftwareRenderer::DoDrawQuad(DrawingFrame* frame,
TRACE_EVENT0("cc", "SoftwareRenderer::DoDrawQuad");
gfx::Transform quad_rect_matrix;
- QuadRectTransform(&quad_rect_matrix, quad->quadTransform(), quad->rect);
+ QuadRectTransform(&quad_rect_matrix,
+ quad->shared_quad_state->quad_to_target_transform,
+ quad->rect);
gfx::Transform contents_device_transform =
frame->window_matrix * frame->projection_matrix * quad_rect_matrix;
contents_device_transform.FlattenTo2d();
@@ -277,7 +278,7 @@ void SoftwareRenderer::DoDrawQuad(DrawingFrame* frame,
if (quad->ShouldDrawWithBlending() ||
quad->shared_quad_state->blend_mode != SkXfermode::kSrcOver_Mode) {
- current_paint_.setAlpha(quad->opacity() * 255);
+ current_paint_.setAlpha(quad->shared_quad_state->opacity * 255);
current_paint_.setXfermodeMode(quad->shared_quad_state->blend_mode);
} else {
current_paint_.setXfermodeMode(SkXfermode::kSrc_Mode);
@@ -352,7 +353,7 @@ void SoftwareRenderer::DrawCheckerboardQuad(const DrawingFrame* frame,
gfx::RectF visible_quad_vertex_rect = MathUtil::ScaleRectProportional(
QuadVertexRect(), quad->rect, quad->visible_rect);
current_paint_.setColor(quad->color);
- current_paint_.setAlpha(quad->opacity());
+ current_paint_.setAlpha(quad->shared_quad_state->opacity);
current_canvas_->drawRect(gfx::RectFToSkRect(visible_quad_vertex_rect),
current_paint_);
}
@@ -369,7 +370,8 @@ void SoftwareRenderer::DrawDebugBorderQuad(const DrawingFrame* frame,
current_canvas_->resetMatrix();
current_paint_.setColor(quad->color);
- current_paint_.setAlpha(quad->opacity() * SkColorGetA(quad->color));
+ current_paint_.setAlpha(quad->shared_quad_state->opacity *
+ SkColorGetA(quad->color));
current_paint_.setStyle(SkPaint::kStroke_Style);
current_paint_.setStrokeWidth(quad->width);
current_canvas_->drawPoints(SkCanvas::kPolygon_PointMode,
@@ -385,23 +387,26 @@ void SoftwareRenderer::DrawPictureQuad(const DrawingFrame* frame,
SkMatrix::kFill_ScaleToFit);
current_canvas_->concat(content_matrix);
- // TODO(aelias): This isn't correct in all cases. We should detect these
- // cases and fall back to a persistent bitmap backing
- // (http://crbug.com/280374).
- skia::RefPtr<SkDrawFilter> opacity_filter =
- skia::AdoptRef(new skia::OpacityDrawFilter(
- quad->opacity(), frame->disable_picture_quad_image_filtering ||
- quad->nearest_neighbor));
- DCHECK(!current_canvas_->getDrawFilter());
- current_canvas_->setDrawFilter(opacity_filter.get());
-
- TRACE_EVENT0("cc",
- "SoftwareRenderer::DrawPictureQuad");
-
- quad->raster_source->PlaybackToSharedCanvas(
- current_canvas_, quad->content_rect, quad->contents_scale);
-
- current_canvas_->setDrawFilter(NULL);
+ const bool needs_transparency =
+ SkScalarRoundToInt(quad->shared_quad_state->opacity * 255) < 255;
+ const bool disable_image_filtering =
+ frame->disable_picture_quad_image_filtering || quad->nearest_neighbor;
+
+ TRACE_EVENT0("cc", "SoftwareRenderer::DrawPictureQuad");
+
+ if (needs_transparency || disable_image_filtering) {
+ // TODO(aelias): This isn't correct in all cases. We should detect these
+ // cases and fall back to a persistent bitmap backing
+ // (http://crbug.com/280374).
+ skia::OpacityFilterCanvas filtered_canvas(current_canvas_,
+ quad->shared_quad_state->opacity,
+ disable_image_filtering);
+ quad->raster_source->PlaybackToSharedCanvas(
+ &filtered_canvas, quad->content_rect, quad->contents_scale);
+ } else {
+ quad->raster_source->PlaybackToSharedCanvas(
+ current_canvas_, quad->content_rect, quad->contents_scale);
+ }
}
void SoftwareRenderer::DrawSolidColorQuad(const DrawingFrame* frame,
@@ -409,21 +414,22 @@ void SoftwareRenderer::DrawSolidColorQuad(const DrawingFrame* frame,
gfx::RectF visible_quad_vertex_rect = MathUtil::ScaleRectProportional(
QuadVertexRect(), quad->rect, quad->visible_rect);
current_paint_.setColor(quad->color);
- current_paint_.setAlpha(quad->opacity() * SkColorGetA(quad->color));
+ current_paint_.setAlpha(quad->shared_quad_state->opacity *
+ SkColorGetA(quad->color));
current_canvas_->drawRect(gfx::RectFToSkRect(visible_quad_vertex_rect),
current_paint_);
}
void SoftwareRenderer::DrawTextureQuad(const DrawingFrame* frame,
const TextureDrawQuad* quad) {
- if (!IsSoftwareResource(quad->resource_id)) {
+ if (!IsSoftwareResource(quad->resource_id())) {
DrawUnsupportedQuad(frame, quad);
return;
}
// TODO(skaslev): Add support for non-premultiplied alpha.
ResourceProvider::ScopedReadLockSoftware lock(resource_provider_,
- quad->resource_id);
+ quad->resource_id());
if (!lock.valid())
return;
const SkBitmap* bitmap = lock.sk_bitmap();
@@ -481,10 +487,10 @@ void SoftwareRenderer::DrawTileQuad(const DrawingFrame* frame,
// |resource_provider_| can be NULL in resourceless software draws, which
// should never produce tile quads in the first place.
DCHECK(resource_provider_);
- DCHECK(IsSoftwareResource(quad->resource_id));
+ DCHECK(IsSoftwareResource(quad->resource_id()));
ResourceProvider::ScopedReadLockSoftware lock(resource_provider_,
- quad->resource_id);
+ quad->resource_id());
if (!lock.valid())
return;
DCHECK_EQ(GL_CLAMP_TO_EDGE, lock.wrap_mode());
@@ -561,9 +567,9 @@ void SoftwareRenderer::DrawRenderPassQuad(const DrawingFrame* frame,
}
current_paint_.setShader(shader.get());
- if (quad->mask_resource_id) {
- ResourceProvider::ScopedReadLockSoftware mask_lock(resource_provider_,
- quad->mask_resource_id);
+ if (quad->mask_resource_id()) {
+ ResourceProvider::ScopedReadLockSoftware mask_lock(
+ resource_provider_, quad->mask_resource_id());
if (!lock.valid())
return;
SkShader::TileMode mask_tile_mode = WrapModeToTileMode(
@@ -608,7 +614,7 @@ void SoftwareRenderer::DrawUnsupportedQuad(const DrawingFrame* frame,
#else
current_paint_.setColor(SK_ColorMAGENTA);
#endif
- current_paint_.setAlpha(quad->opacity() * 255);
+ current_paint_.setAlpha(quad->shared_quad_state->opacity * 255);
current_canvas_->drawRect(gfx::RectFToSkRect(QuadVertexRect()),
current_paint_);
}
diff --git a/chromium/cc/output/software_renderer.h b/chromium/cc/output/software_renderer.h
index 74f328edc01..c3090429635 100644
--- a/chromium/cc/output/software_renderer.h
+++ b/chromium/cc/output/software_renderer.h
@@ -74,7 +74,7 @@ class CC_EXPORT SoftwareRenderer : public DirectRenderer {
void ClearCanvas(SkColor color);
void ClearFramebuffer(DrawingFrame* frame);
void SetClipRect(const gfx::Rect& rect);
- bool IsSoftwareResource(ResourceProvider::ResourceId resource_id) const;
+ bool IsSoftwareResource(ResourceId resource_id) const;
void DrawCheckerboardQuad(const DrawingFrame* frame,
const CheckerboardDrawQuad* quad);
diff --git a/chromium/cc/output/software_renderer_unittest.cc b/chromium/cc/output/software_renderer_unittest.cc
index 3b2c4bc2317..a7ef1a20f7d 100644
--- a/chromium/cc/output/software_renderer_unittest.cc
+++ b/chromium/cc/output/software_renderer_unittest.cc
@@ -16,6 +16,7 @@
#include "cc/test/animation_test_common.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_output_surface_client.h"
+#include "cc/test/fake_resource_provider.h"
#include "cc/test/geometry_test_utils.h"
#include "cc/test/render_pass_test_common.h"
#include "cc/test/render_pass_test_utils.h"
@@ -36,13 +37,8 @@ class SoftwareRendererTest : public testing::Test, public RendererClient {
CHECK(output_surface_->BindToClient(&output_surface_client_));
shared_bitmap_manager_.reset(new TestSharedBitmapManager());
- resource_provider_ = ResourceProvider::Create(output_surface_.get(),
- shared_bitmap_manager_.get(),
- NULL,
- NULL,
- 0,
- false,
- 1);
+ resource_provider_ = FakeResourceProvider::Create(
+ output_surface_.get(), shared_bitmap_manager_.get());
renderer_ = SoftwareRenderer::Create(
this, &settings_, output_surface_.get(), resource_provider());
}
@@ -134,8 +130,8 @@ TEST_F(SoftwareRendererTest, SolidColorQuad) {
gfx::Rect device_viewport_rect(outer_size);
scoped_ptr<SkBitmap> output =
DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect);
- EXPECT_EQ(outer_rect.width(), output->info().fWidth);
- EXPECT_EQ(outer_rect.height(), output->info().fHeight);
+ EXPECT_EQ(outer_rect.width(), output->info().width());
+ EXPECT_EQ(outer_rect.height(), output->info().height());
EXPECT_EQ(SK_ColorYELLOW, output->getColor(0, 0));
EXPECT_EQ(SK_ColorYELLOW,
@@ -153,14 +149,12 @@ TEST_F(SoftwareRendererTest, TileQuad) {
gfx::Rect inner_rect(gfx::Point(1, 1), inner_size);
InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice));
- ResourceProvider::ResourceId resource_yellow =
- resource_provider()->CreateResource(
- outer_size, GL_CLAMP_TO_EDGE,
- ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888);
- ResourceProvider::ResourceId resource_cyan =
- resource_provider()->CreateResource(
- inner_size, GL_CLAMP_TO_EDGE,
- ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888);
+ ResourceId resource_yellow = resource_provider()->CreateResource(
+ outer_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
+ RGBA_8888);
+ ResourceId resource_cyan = resource_provider()->CreateResource(
+ inner_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
+ RGBA_8888);
SkBitmap yellow_tile;
yellow_tile.allocN32Pixels(outer_size.width(), outer_size.height());
@@ -222,8 +216,8 @@ TEST_F(SoftwareRendererTest, TileQuad) {
gfx::Rect device_viewport_rect(outer_size);
scoped_ptr<SkBitmap> output =
DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect);
- EXPECT_EQ(outer_rect.width(), output->info().fWidth);
- EXPECT_EQ(outer_rect.height(), output->info().fHeight);
+ EXPECT_EQ(outer_rect.width(), output->info().width());
+ EXPECT_EQ(outer_rect.height(), output->info().height());
EXPECT_EQ(SK_ColorYELLOW, output->getColor(0, 0));
EXPECT_EQ(SK_ColorYELLOW,
@@ -240,10 +234,9 @@ TEST_F(SoftwareRendererTest, TileQuadVisibleRect) {
visible_rect.Inset(1, 2, 3, 4);
InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice));
- ResourceProvider::ResourceId resource_cyan =
- resource_provider()->CreateResource(
- tile_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
- RGBA_8888);
+ ResourceId resource_cyan = resource_provider()->CreateResource(
+ tile_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
+ RGBA_8888);
SkBitmap cyan_tile; // The lowest five rows are yellow.
cyan_tile.allocN32Pixels(tile_size.width(), tile_size.height());
@@ -292,8 +285,8 @@ TEST_F(SoftwareRendererTest, TileQuadVisibleRect) {
gfx::Rect device_viewport_rect(tile_size);
scoped_ptr<SkBitmap> output =
DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect);
- EXPECT_EQ(tile_rect.width(), output->info().fWidth);
- EXPECT_EQ(tile_rect.height(), output->info().fHeight);
+ EXPECT_EQ(tile_rect.width(), output->info().width());
+ EXPECT_EQ(tile_rect.height(), output->info().height());
// Check portion of tile not in visible rect isn't drawn.
const unsigned int kTransparent = SK_ColorTRANSPARENT;
@@ -334,8 +327,8 @@ TEST_F(SoftwareRendererTest, ShouldClearRootRenderPass) {
scoped_ptr<SkBitmap> output =
DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect);
- EXPECT_EQ(device_viewport_rect.width(), output->info().fWidth);
- EXPECT_EQ(device_viewport_rect.height(), output->info().fHeight);
+ EXPECT_EQ(device_viewport_rect.width(), output->info().width());
+ EXPECT_EQ(device_viewport_rect.height(), output->info().height());
EXPECT_EQ(SK_ColorGREEN, output->getColor(0, 0));
EXPECT_EQ(SK_ColorGREEN,
@@ -356,8 +349,8 @@ TEST_F(SoftwareRendererTest, ShouldClearRootRenderPass) {
renderer()->DecideRenderPassAllocationsForFrame(list);
output = DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect);
- EXPECT_EQ(device_viewport_rect.width(), output->info().fWidth);
- EXPECT_EQ(device_viewport_rect.height(), output->info().fHeight);
+ EXPECT_EQ(device_viewport_rect.width(), output->info().width());
+ EXPECT_EQ(device_viewport_rect.height(), output->info().height());
// If we didn't clear, the borders should still be green.
EXPECT_EQ(SK_ColorGREEN, output->getColor(0, 0));
@@ -401,8 +394,8 @@ TEST_F(SoftwareRendererTest, RenderPassVisibleRect) {
scoped_ptr<SkBitmap> output =
DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect);
- EXPECT_EQ(device_viewport_rect.width(), output->info().fWidth);
- EXPECT_EQ(device_viewport_rect.height(), output->info().fHeight);
+ EXPECT_EQ(device_viewport_rect.width(), output->info().width());
+ EXPECT_EQ(device_viewport_rect.height(), output->info().height());
EXPECT_EQ(SK_ColorGREEN, output->getColor(0, 0));
EXPECT_EQ(SK_ColorGREEN,
diff --git a/chromium/cc/output/swap_promise.h b/chromium/cc/output/swap_promise.h
index 45deee83401..cf0b88de9eb 100644
--- a/chromium/cc/output/swap_promise.h
+++ b/chromium/cc/output/swap_promise.h
@@ -54,6 +54,8 @@ class CC_EXPORT SwapPromise {
virtual void DidActivate() = 0;
virtual void DidSwap(CompositorFrameMetadata* metadata) = 0;
virtual void DidNotSwap(DidNotSwapReason reason) = 0;
+ // This is called when the main thread starts a (blocking) commit
+ virtual void OnCommit() {}
// A non-zero trace id identifies a trace flow object that is embedded in the
// swap promise. This can be used for registering additional flow steps to
diff --git a/chromium/cc/output/texture_mailbox_deleter.cc b/chromium/cc/output/texture_mailbox_deleter.cc
index aaf2a0ef223..7729c4ec7a1 100644
--- a/chromium/cc/output/texture_mailbox_deleter.cc
+++ b/chromium/cc/output/texture_mailbox_deleter.cc
@@ -65,9 +65,13 @@ scoped_ptr<SingleReleaseCallback> TextureMailboxDeleter::GetReleaseCallback(
// Provide a callback for the main thread that posts back to the impl
// thread.
- scoped_ptr<SingleReleaseCallback> main_callback =
- SingleReleaseCallback::Create(base::Bind(
- &PostTaskFromMainToImplThread, impl_task_runner_, run_impl_callback));
+ scoped_ptr<SingleReleaseCallback> main_callback;
+ if (impl_task_runner_) {
+ main_callback = SingleReleaseCallback::Create(base::Bind(
+ &PostTaskFromMainToImplThread, impl_task_runner_, run_impl_callback));
+ } else {
+ main_callback = SingleReleaseCallback::Create(run_impl_callback);
+ }
return main_callback.Pass();
}
diff --git a/chromium/cc/output/texture_mailbox_deleter.h b/chromium/cc/output/texture_mailbox_deleter.h
index 286512626d4..19760ea0a4c 100644
--- a/chromium/cc/output/texture_mailbox_deleter.h
+++ b/chromium/cc/output/texture_mailbox_deleter.h
@@ -19,6 +19,8 @@ class SingleReleaseCallback;
class CC_EXPORT TextureMailboxDeleter {
public:
+ // task_runner corresponds with the thread the delete task should be posted
+ // to. If null, the delete will happen on the calling thread.
explicit TextureMailboxDeleter(
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner);
~TextureMailboxDeleter();
diff --git a/chromium/cc/output/texture_mailbox_deleter_unittest.cc b/chromium/cc/output/texture_mailbox_deleter_unittest.cc
index 34d8595aa20..37b97123725 100644
--- a/chromium/cc/output/texture_mailbox_deleter_unittest.cc
+++ b/chromium/cc/output/texture_mailbox_deleter_unittest.cc
@@ -44,5 +44,31 @@ TEST(TextureMailboxDeleterTest, Destroy) {
cb->Run(0, false);
}
+TEST(TextureMailboxDeleterTest, NullTaskRunner) {
+ scoped_ptr<TextureMailboxDeleter> deleter(new TextureMailboxDeleter(nullptr));
+
+ scoped_refptr<TestContextProvider> context_provider =
+ TestContextProvider::Create();
+ context_provider->BindToCurrentThread();
+
+ GLuint texture_id = 0u;
+ context_provider->ContextGL()->GenTextures(1, &texture_id);
+
+ EXPECT_TRUE(context_provider->HasOneRef());
+ EXPECT_EQ(1u, context_provider->TestContext3d()->NumTextures());
+
+ scoped_ptr<SingleReleaseCallback> cb =
+ deleter->GetReleaseCallback(context_provider, texture_id);
+ EXPECT_FALSE(context_provider->HasOneRef());
+ EXPECT_EQ(1u, context_provider->TestContext3d()->NumTextures());
+
+ cb->Run(0, false);
+
+ // With no task runner the callback will immediately drops its ref on the
+ // ContextProvider and delete the texture.
+ EXPECT_TRUE(context_provider->HasOneRef());
+ EXPECT_EQ(0u, context_provider->TestContext3d()->NumTextures());
+}
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/output/vsync_parameter_observer.h b/chromium/cc/output/vsync_parameter_observer.h
deleted file mode 100644
index e586925e110..00000000000
--- a/chromium/cc/output/vsync_parameter_observer.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_OUTPUT_VSYNC_PARAMETER_OBSERVER_H_
-#define CC_OUTPUT_VSYNC_PARAMETER_OBSERVER_H_
-
-#include "base/time/time.h"
-
-// Interface for a class which observes the parameters regarding vsync
-// information.
-class VSyncParameterObserver {
- public:
- virtual void OnUpdateVSyncParameters(base::TimeTicks timebase,
- base::TimeDelta interval) = 0;
-};
-
-#endif // CC_OUTPUT_VSYNC_PARAMETER_OBSERVER_H_
diff --git a/chromium/cc/playback/clip_display_item.cc b/chromium/cc/playback/clip_display_item.cc
index a29787409c3..5941502860b 100644
--- a/chromium/cc/playback/clip_display_item.cc
+++ b/chromium/cc/playback/clip_display_item.cc
@@ -24,16 +24,16 @@ void ClipDisplayItem::SetNew(gfx::Rect clip_rect,
clip_rect_ = clip_rect;
rounded_clip_rects_ = rounded_clip_rects;
- size_t memory_usage = sizeof(gfx::Rect);
- for (size_t i = 0; i < rounded_clip_rects_.size(); ++i) {
- memory_usage += sizeof(rounded_clip_rects_[i]);
- }
+ size_t external_memory_usage =
+ rounded_clip_rects_.capacity() * sizeof(rounded_clip_rects_[0]);
+
DisplayItem::SetNew(true /* suitable_for_gpu_raster */, 1 /* op_count */,
- memory_usage);
+ external_memory_usage);
}
void ClipDisplayItem::Raster(SkCanvas* canvas,
- SkDrawPictureCallback* callback) const {
+ const gfx::Rect& canvas_target_playback_rect,
+ SkPicture::AbortCallback* callback) const {
canvas->save();
canvas->clipRect(SkRect::MakeXYWH(clip_rect_.x(), clip_rect_.y(),
clip_rect_.width(), clip_rect_.height()));
@@ -76,14 +76,15 @@ void ClipDisplayItem::AsValueInto(base::trace_event::TracedValue* array) const {
EndClipDisplayItem::EndClipDisplayItem() {
DisplayItem::SetNew(true /* suitable_for_gpu_raster */, 0 /* op_count */,
- 0 /* memory_usage */);
+ 0 /* external_memory_usage */);
}
EndClipDisplayItem::~EndClipDisplayItem() {
}
void EndClipDisplayItem::Raster(SkCanvas* canvas,
- SkDrawPictureCallback* callback) const {
+ const gfx::Rect& canvas_target_playback_rect,
+ SkPicture::AbortCallback* callback) const {
canvas->restore();
}
diff --git a/chromium/cc/playback/clip_display_item.h b/chromium/cc/playback/clip_display_item.h
index a4acc9f9893..83e0b6bf21a 100644
--- a/chromium/cc/playback/clip_display_item.h
+++ b/chromium/cc/playback/clip_display_item.h
@@ -14,7 +14,6 @@
#include "ui/gfx/geometry/rect.h"
class SkCanvas;
-class SkDrawPictureCallback;
namespace cc {
@@ -26,7 +25,9 @@ class CC_EXPORT ClipDisplayItem : public DisplayItem {
void SetNew(gfx::Rect clip_rect,
const std::vector<SkRRect>& rounded_clip_rects);
- void Raster(SkCanvas* canvas, SkDrawPictureCallback* callback) const override;
+ void Raster(SkCanvas* canvas,
+ const gfx::Rect& canvas_target_playback_rect,
+ SkPicture::AbortCallback* callback) const override;
void AsValueInto(base::trace_event::TracedValue* array) const override;
private:
@@ -39,7 +40,9 @@ class CC_EXPORT EndClipDisplayItem : public DisplayItem {
EndClipDisplayItem();
~EndClipDisplayItem() override;
- void Raster(SkCanvas* canvas, SkDrawPictureCallback* callback) const override;
+ void Raster(SkCanvas* canvas,
+ const gfx::Rect& canvas_target_playback_rect,
+ SkPicture::AbortCallback* callback) const override;
void AsValueInto(base::trace_event::TracedValue* array) const override;
};
diff --git a/chromium/cc/playback/clip_path_display_item.cc b/chromium/cc/playback/clip_path_display_item.cc
index 7be8922fca7..f7fd60626e5 100644
--- a/chromium/cc/playback/clip_path_display_item.cc
+++ b/chromium/cc/playback/clip_path_display_item.cc
@@ -23,13 +23,15 @@ void ClipPathDisplayItem::SetNew(const SkPath& clip_path,
clip_op_ = clip_op;
antialias_ = antialias;
- size_t memory_usage = sizeof(SkPath) + sizeof(SkRegion::Op) + sizeof(bool);
+ // The size of SkPath's external storage is not currently accounted for (and
+ // may well be shared anyway).
DisplayItem::SetNew(true /* suitable_for_gpu_raster */, 1 /* op_count */,
- memory_usage);
+ 0 /* external_memory_usage */);
}
void ClipPathDisplayItem::Raster(SkCanvas* canvas,
- SkDrawPictureCallback* callback) const {
+ const gfx::Rect& canvas_target_playback_rect,
+ SkPicture::AbortCallback* callback) const {
canvas->save();
canvas->clipPath(clip_path_, clip_op_, antialias_);
}
@@ -42,14 +44,16 @@ void ClipPathDisplayItem::AsValueInto(
EndClipPathDisplayItem::EndClipPathDisplayItem() {
DisplayItem::SetNew(true /* suitable_for_gpu_raster */, 0 /* op_count */,
- 0 /* memory_usage */);
+ 0 /* external_memory_usage */);
}
EndClipPathDisplayItem::~EndClipPathDisplayItem() {
}
-void EndClipPathDisplayItem::Raster(SkCanvas* canvas,
- SkDrawPictureCallback* callback) const {
+void EndClipPathDisplayItem::Raster(
+ SkCanvas* canvas,
+ const gfx::Rect& canvas_target_playback_rect,
+ SkPicture::AbortCallback* callback) const {
canvas->restore();
}
diff --git a/chromium/cc/playback/clip_path_display_item.h b/chromium/cc/playback/clip_path_display_item.h
index 19d4a7ced39..732087b9789 100644
--- a/chromium/cc/playback/clip_path_display_item.h
+++ b/chromium/cc/playback/clip_path_display_item.h
@@ -12,7 +12,6 @@
#include "third_party/skia/include/core/SkRegion.h"
class SkCanvas;
-class SkDrawPictureCallback;
namespace cc {
@@ -23,7 +22,9 @@ class CC_EXPORT ClipPathDisplayItem : public DisplayItem {
void SetNew(const SkPath& path, SkRegion::Op clip_op, bool antialias);
- void Raster(SkCanvas* canvas, SkDrawPictureCallback* callback) const override;
+ void Raster(SkCanvas* canvas,
+ const gfx::Rect& canvas_target_playback_rect,
+ SkPicture::AbortCallback* callback) const override;
void AsValueInto(base::trace_event::TracedValue* array) const override;
private:
@@ -41,7 +42,9 @@ class CC_EXPORT EndClipPathDisplayItem : public DisplayItem {
return make_scoped_ptr(new EndClipPathDisplayItem());
}
- void Raster(SkCanvas* canvas, SkDrawPictureCallback* callback) const override;
+ void Raster(SkCanvas* canvas,
+ const gfx::Rect& canvas_target_playback_rect,
+ SkPicture::AbortCallback* callback) const override;
void AsValueInto(base::trace_event::TracedValue* array) const override;
};
diff --git a/chromium/cc/playback/compositing_display_item.cc b/chromium/cc/playback/compositing_display_item.cc
index bee1fb15dcb..31365b5881c 100644
--- a/chromium/cc/playback/compositing_display_item.cc
+++ b/chromium/cc/playback/compositing_display_item.cc
@@ -31,14 +31,15 @@ void CompositingDisplayItem::SetNew(uint8_t alpha,
color_filter_ = cf;
// TODO(pdr): Include color_filter's memory here.
- size_t memory_usage =
- sizeof(float) + sizeof(bool) + sizeof(SkRect) + sizeof(SkXfermode::Mode);
+ size_t external_memory_usage = 0;
DisplayItem::SetNew(true /* suitable_for_gpu_raster */, 1 /* op_count */,
- memory_usage);
+ external_memory_usage);
}
-void CompositingDisplayItem::Raster(SkCanvas* canvas,
- SkDrawPictureCallback* callback) const {
+void CompositingDisplayItem::Raster(
+ SkCanvas* canvas,
+ const gfx::Rect& canvas_target_playback_rect,
+ SkPicture::AbortCallback* callback) const {
SkPaint paint;
paint.setXfermodeMode(xfermode_);
paint.setAlpha(alpha_);
@@ -59,14 +60,16 @@ void CompositingDisplayItem::AsValueInto(
EndCompositingDisplayItem::EndCompositingDisplayItem() {
DisplayItem::SetNew(true /* suitable_for_gpu_raster */, 0 /* op_count */,
- 0 /* memory_usage */);
+ 0 /* external_memory_usage */);
}
EndCompositingDisplayItem::~EndCompositingDisplayItem() {
}
-void EndCompositingDisplayItem::Raster(SkCanvas* canvas,
- SkDrawPictureCallback* callback) const {
+void EndCompositingDisplayItem::Raster(
+ SkCanvas* canvas,
+ const gfx::Rect& canvas_target_playback_rect,
+ SkPicture::AbortCallback* callback) const {
canvas->restore();
}
diff --git a/chromium/cc/playback/compositing_display_item.h b/chromium/cc/playback/compositing_display_item.h
index d2af8d5ceb7..91cd3e71f8e 100644
--- a/chromium/cc/playback/compositing_display_item.h
+++ b/chromium/cc/playback/compositing_display_item.h
@@ -15,7 +15,6 @@
#include "ui/gfx/geometry/rect_f.h"
class SkCanvas;
-class SkDrawPictureCallback;
namespace cc {
@@ -29,7 +28,9 @@ class CC_EXPORT CompositingDisplayItem : public DisplayItem {
SkRect* bounds,
skia::RefPtr<SkColorFilter> color_filter);
- void Raster(SkCanvas* canvas, SkDrawPictureCallback* callback) const override;
+ void Raster(SkCanvas* canvas,
+ const gfx::Rect& canvas_target_playback_rect,
+ SkPicture::AbortCallback* callback) const override;
void AsValueInto(base::trace_event::TracedValue* array) const override;
private:
@@ -49,7 +50,9 @@ class CC_EXPORT EndCompositingDisplayItem : public DisplayItem {
return make_scoped_ptr(new EndCompositingDisplayItem());
}
- void Raster(SkCanvas* canvas, SkDrawPictureCallback* callback) const override;
+ void Raster(SkCanvas* canvas,
+ const gfx::Rect& canvas_target_playback_rect,
+ SkPicture::AbortCallback* callback) const override;
void AsValueInto(base::trace_event::TracedValue* array) const override;
};
diff --git a/chromium/cc/playback/display_item.h b/chromium/cc/playback/display_item.h
index 2eedb91b5f3..d89807dd3ce 100644
--- a/chromium/cc/playback/display_item.h
+++ b/chromium/cc/playback/display_item.h
@@ -8,10 +8,10 @@
#include "base/memory/scoped_ptr.h"
#include "cc/base/cc_export.h"
#include "cc/debug/traced_value.h"
+#include "third_party/skia/include/core/SkPicture.h"
#include "ui/gfx/geometry/rect.h"
class SkCanvas;
-class SkDrawPictureCallback;
namespace cc {
@@ -21,29 +21,32 @@ class CC_EXPORT DisplayItem {
void SetNew(bool is_suitable_for_gpu_rasterization,
int approximate_op_count,
- size_t picture_memory_usage) {
+ size_t external_memory_usage) {
is_suitable_for_gpu_rasterization_ = is_suitable_for_gpu_rasterization;
approximate_op_count_ = approximate_op_count;
- picture_memory_usage_ =
- picture_memory_usage + sizeof(bool) + sizeof(int) + sizeof(size_t);
+ external_memory_usage_ = external_memory_usage;
}
virtual void Raster(SkCanvas* canvas,
- SkDrawPictureCallback* callback) const = 0;
+ const gfx::Rect& canvas_target_playback_rect,
+ SkPicture::AbortCallback* callback) const = 0;
virtual void AsValueInto(base::trace_event::TracedValue* array) const = 0;
bool is_suitable_for_gpu_rasterization() const {
return is_suitable_for_gpu_rasterization_;
}
int approximate_op_count() const { return approximate_op_count_; }
- size_t picture_memory_usage() const { return picture_memory_usage_; }
+ size_t external_memory_usage() const { return external_memory_usage_; }
protected:
DisplayItem();
bool is_suitable_for_gpu_rasterization_;
int approximate_op_count_;
- size_t picture_memory_usage_;
+
+ // The size, in bytes, of the memory owned by this display item but not
+ // allocated within it (e.g. held through scoped_ptr or vector).
+ size_t external_memory_usage_;
};
} // namespace cc
diff --git a/chromium/cc/playback/display_item_list.cc b/chromium/cc/playback/display_item_list.cc
index 656ade1deff..08fe71d26e6 100644
--- a/chromium/cc/playback/display_item_list.cc
+++ b/chromium/cc/playback/display_item_list.cc
@@ -6,15 +6,17 @@
#include <string>
+#include "base/numerics/safe_conversions.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"
#include "cc/base/math_util.h"
#include "cc/debug/picture_debug_util.h"
+#include "cc/debug/traced_display_item_list.h"
#include "cc/debug/traced_picture.h"
#include "cc/debug/traced_value.h"
+#include "cc/playback/display_item_list_settings.h"
#include "cc/playback/largest_display_item.h"
#include "third_party/skia/include/core/SkCanvas.h"
-#include "third_party/skia/include/core/SkDrawPictureCallback.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
#include "third_party/skia/include/utils/SkPictureUtils.h"
#include "ui/gfx/skia_util.h"
@@ -23,12 +25,10 @@ namespace cc {
namespace {
-bool PictureTracingEnabled() {
+bool DisplayItemsTracingEnabled() {
bool tracing_enabled;
TRACE_EVENT_CATEGORY_GROUP_ENABLED(
- TRACE_DISABLED_BY_DEFAULT("cc.debug.picture") ","
- TRACE_DISABLED_BY_DEFAULT("devtools.timeline.picture"),
- &tracing_enabled);
+ TRACE_DISABLED_BY_DEFAULT("cc.debug.display_items"), &tracing_enabled);
return tracing_enabled;
}
@@ -37,15 +37,19 @@ const int kDefaultNumDisplayItemsToReserve = 100;
} // namespace
DisplayItemList::DisplayItemList(gfx::Rect layer_rect,
- bool use_cached_picture,
+ const DisplayItemListSettings& settings,
bool retain_individual_display_items)
- : items_(LargestDisplayItemSize(), kDefaultNumDisplayItemsToReserve),
- use_cached_picture_(use_cached_picture),
+ : items_(LargestDisplayItemSize(),
+ settings.max_sidecar_size,
+ kDefaultNumDisplayItemsToReserve,
+ settings.sidecar_destroyer),
+ use_cached_picture_(settings.use_cached_picture),
retain_individual_display_items_(retain_individual_display_items),
layer_rect_(layer_rect),
- is_suitable_for_gpu_rasterization_(true),
+ all_items_are_suitable_for_gpu_rasterization_(true),
approximate_op_count_(0),
- picture_memory_usage_(0) {
+ picture_memory_usage_(0),
+ external_memory_usage_(0) {
#if DCHECK_IS_ON()
needs_process_ = false;
#endif
@@ -59,31 +63,47 @@ DisplayItemList::DisplayItemList(gfx::Rect layer_rect,
}
}
-DisplayItemList::DisplayItemList(gfx::Rect layer_rect, bool use_cached_picture)
- : DisplayItemList(layer_rect,
- use_cached_picture,
- !use_cached_picture || PictureTracingEnabled()) {
+DisplayItemList::DisplayItemList(gfx::Rect layer_rect,
+ const DisplayItemListSettings& settings)
+ : DisplayItemList(
+ layer_rect,
+ settings,
+ !settings.use_cached_picture || DisplayItemsTracingEnabled()) {
+}
+
+scoped_refptr<DisplayItemList> DisplayItemList::CreateWithoutCachedPicture(
+ const DisplayItemListSettings& settings) {
+ DCHECK(!settings.use_cached_picture);
+ return Create(gfx::Rect(), settings);
}
scoped_refptr<DisplayItemList> DisplayItemList::Create(
gfx::Rect layer_rect,
bool use_cached_picture) {
- return make_scoped_refptr(
- new DisplayItemList(layer_rect, use_cached_picture));
+ DisplayItemListSettings settings;
+ settings.use_cached_picture = use_cached_picture;
+ return Create(layer_rect, settings);
+}
+
+scoped_refptr<DisplayItemList> DisplayItemList::Create(
+ gfx::Rect layer_rect,
+ const DisplayItemListSettings& settings) {
+ return make_scoped_refptr(new DisplayItemList(layer_rect, settings));
}
DisplayItemList::~DisplayItemList() {
}
void DisplayItemList::Raster(SkCanvas* canvas,
- SkDrawPictureCallback* callback,
+ SkPicture::AbortCallback* callback,
+ const gfx::Rect& canvas_target_playback_rect,
float contents_scale) const {
DCHECK(ProcessAppendedItemsCalled());
if (!use_cached_picture_) {
canvas->save();
canvas->scale(contents_scale, contents_scale);
for (auto* item : items_)
- item->Raster(canvas, callback);
+ item->Raster(canvas, canvas_target_playback_rect, callback);
canvas->restore();
} else {
DCHECK(picture_);
@@ -121,20 +141,20 @@ void DisplayItemList::ProcessAppendedItems() {
#if DCHECK_IS_ON()
needs_process_ = false;
#endif
- for (DisplayItem* item : items_) {
- is_suitable_for_gpu_rasterization_ &=
+ for (const DisplayItem* item : items_) {
+ all_items_are_suitable_for_gpu_rasterization_ &=
item->is_suitable_for_gpu_rasterization();
approximate_op_count_ += item->approximate_op_count();
if (use_cached_picture_) {
DCHECK(canvas_);
- item->Raster(canvas_.get(), NULL);
+ item->Raster(canvas_.get(), gfx::Rect(), NULL);
}
if (retain_individual_display_items_) {
// Warning: this double-counts SkPicture data if use_cached_picture_ is
// also true.
- picture_memory_usage_ += item->picture_memory_usage();
+ external_memory_usage_ += item->external_memory_usage();
}
}
@@ -142,24 +162,55 @@ void DisplayItemList::ProcessAppendedItems() {
items_.clear();
}
-void DisplayItemList::CreateAndCacheSkPicture() {
- DCHECK(ProcessAppendedItemsCalled());
- // Convert to an SkPicture for faster rasterization.
- DCHECK(use_cached_picture_);
- DCHECK(!picture_);
- picture_ = skia::AdoptRef(recorder_->endRecordingAsPicture());
- DCHECK(picture_);
- picture_memory_usage_ += SkPictureUtils::ApproximateBytesUsed(picture_.get());
- recorder_.reset();
- canvas_.clear();
+void DisplayItemList::RasterIntoCanvas(const DisplayItem& item) {
+ DCHECK(canvas_);
+ DCHECK(!retain_individual_display_items_);
+ all_items_are_suitable_for_gpu_rasterization_ &=
+ item.is_suitable_for_gpu_rasterization();
+ approximate_op_count_ += item.approximate_op_count();
+
+ item.Raster(canvas_.get(), gfx::Rect(), NULL);
+}
+
+bool DisplayItemList::RetainsIndividualDisplayItems() const {
+ return retain_individual_display_items_;
+}
+
+void DisplayItemList::RemoveLast() {
+ // We cannot remove the last item if it has been squashed into a picture.
+ // The last item should not have been handled by ProcessAppendedItems, so we
+ // don't need to remove it from approximate_op_count_, etc.
+ DCHECK(retain_individual_display_items_);
+ DCHECK(!use_cached_picture_);
+ items_.RemoveLast();
+}
+
+void DisplayItemList::Finalize() {
+ ProcessAppendedItems();
+
+ if (use_cached_picture_) {
+ // Convert to an SkPicture for faster rasterization.
+ DCHECK(use_cached_picture_);
+ DCHECK(!picture_);
+ picture_ = skia::AdoptRef(recorder_->endRecordingAsPicture());
+ DCHECK(picture_);
+ picture_memory_usage_ =
+ SkPictureUtils::ApproximateBytesUsed(picture_.get());
+ recorder_.reset();
+ canvas_.clear();
+ }
}
bool DisplayItemList::IsSuitableForGpuRasterization() const {
DCHECK(ProcessAppendedItemsCalled());
+ if (use_cached_picture_)
+ return picture_->suitableForGpuRasterization(NULL);
+
// This is more permissive than Picture's implementation, since none of the
// items might individually trigger a veto even though they collectively have
- // enough "bad" operations that a corresponding Picture would get vetoed.
- return is_suitable_for_gpu_rasterization_;
+ // enough "bad" operations that a corresponding Picture would get vetoed. See
+ // crbug.com/513016.
+ return all_items_are_suitable_for_gpu_rasterization_;
}
int DisplayItemList::ApproximateOpCount() const {
@@ -167,42 +218,58 @@ int DisplayItemList::ApproximateOpCount() const {
return approximate_op_count_;
}
-size_t DisplayItemList::PictureMemoryUsage() const {
+size_t DisplayItemList::ApproximateMemoryUsage() const {
DCHECK(ProcessAppendedItemsCalled());
// We double-count in this case. Produce zero to avoid being misleading.
if (use_cached_picture_ && retain_individual_display_items_)
return 0;
DCHECK_IMPLIES(use_cached_picture_, picture_);
- return picture_memory_usage_;
+
+ size_t memory_usage = sizeof(*this);
+
+ // Memory outside this class due to |items_|.
+ memory_usage += items_.GetCapacityInBytes() + external_memory_usage_;
+
+ // Memory outside this class due to |picture|.
+ memory_usage += picture_memory_usage_;
+
+ // TODO(jbroman): Does anything else owned by this class substantially
+ // contribute to memory usage?
+
+ return memory_usage;
}
scoped_refptr<base::trace_event::ConvertableToTraceFormat>
-DisplayItemList::AsValue() const {
+DisplayItemList::AsValue(bool include_items) const {
DCHECK(ProcessAppendedItemsCalled());
scoped_refptr<base::trace_event::TracedValue> state =
new base::trace_event::TracedValue();
- state->SetInteger("length", items_.size());
- state->BeginArray("params.items");
- for (const DisplayItem* item : items_) {
- item->AsValueInto(state.get());
+ if (include_items) {
+ state->BeginArray("params.items");
+ for (const DisplayItem* item : items_) {
+ item->AsValueInto(state.get());
+ }
+ state->EndArray();
}
- state->EndArray();
- state->SetValue("params.layer_rect", MathUtil::AsValue(layer_rect_));
- SkPictureRecorder recorder;
- SkCanvas* canvas =
- recorder.beginRecording(layer_rect_.width(), layer_rect_.height());
- canvas->translate(-layer_rect_.x(), -layer_rect_.y());
- canvas->clipRect(gfx::RectToSkRect(layer_rect_));
- Raster(canvas, NULL, 1.f);
- skia::RefPtr<SkPicture> picture =
- skia::AdoptRef(recorder.endRecordingAsPicture());
+ state->SetValue("params.layer_rect", MathUtil::AsValue(layer_rect_));
- std::string b64_picture;
- PictureDebugUtil::SerializeAsBase64(picture.get(), &b64_picture);
- state->SetString("skp64", b64_picture);
+ if (!layer_rect_.IsEmpty()) {
+ SkPictureRecorder recorder;
+ SkCanvas* canvas =
+ recorder.beginRecording(layer_rect_.width(), layer_rect_.height());
+ canvas->translate(-layer_rect_.x(), -layer_rect_.y());
+ canvas->clipRect(gfx::RectToSkRect(layer_rect_));
+ Raster(canvas, NULL, gfx::Rect(), 1.f);
+ skia::RefPtr<SkPicture> picture =
+ skia::AdoptRef(recorder.endRecordingAsPicture());
+
+ std::string b64_picture;
+ PictureDebugUtil::SerializeAsBase64(picture.get(), &b64_picture);
+ state->SetString("skp64", b64_picture);
+ }
return state;
}
@@ -210,9 +277,12 @@ DisplayItemList::AsValue() const {
void DisplayItemList::EmitTraceSnapshot() const {
DCHECK(ProcessAppendedItemsCalled());
TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
+ TRACE_DISABLED_BY_DEFAULT("cc.debug.display_items") ","
TRACE_DISABLED_BY_DEFAULT("cc.debug.picture") ","
TRACE_DISABLED_BY_DEFAULT("devtools.timeline.picture"),
- "cc::DisplayItemList", this, AsValue());
+ "cc::DisplayItemList", this,
+ TracedDisplayItemList::AsTraceableDisplayItemList(this,
+ DisplayItemsTracingEnabled()));
}
void DisplayItemList::GatherPixelRefs(const gfx::Size& grid_cell_size) {
@@ -226,4 +296,9 @@ void DisplayItemList::GatherPixelRefs(const gfx::Size& grid_cell_size) {
pixel_refs_->GatherPixelRefsFromPicture(picture_.get());
}
+
+void* DisplayItemList::GetSidecar(DisplayItem* display_item) {
+ return items_.GetSidecar(display_item);
+}
+
} // namespace cc
diff --git a/chromium/cc/playback/display_item_list.h b/chromium/cc/playback/display_item_list.h
index 84b41683720..35bcb8cc4b6 100644
--- a/chromium/cc/playback/display_item_list.h
+++ b/chromium/cc/playback/display_item_list.h
@@ -11,30 +11,45 @@
#include "base/trace_event/trace_event.h"
#include "cc/base/cc_export.h"
#include "cc/base/scoped_ptr_vector.h"
+#include "cc/base/sidecar_list_container.h"
#include "cc/playback/display_item.h"
#include "cc/playback/pixel_ref_map.h"
-// TODO(danakj): Move ListContainer out of cc/quads/
-#include "cc/quads/list_container.h"
#include "skia/ext/refptr.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "ui/gfx/geometry/rect.h"
class SkCanvas;
-class SkDrawPictureCallback;
class SkPictureRecorder;
namespace cc {
+class DisplayItemListSettings;
+
class CC_EXPORT DisplayItemList
: public base::RefCountedThreadSafe<DisplayItemList> {
public:
+ static scoped_refptr<DisplayItemList> CreateWithoutCachedPicture(
+ const DisplayItemListSettings& settings);
+
+ // Creates a display item list with the given cull rect (if picture caching
+ // is used). The resulting display list will not support sidecar data.
static scoped_refptr<DisplayItemList> Create(gfx::Rect layer_rect,
bool use_cached_picture);
+ static scoped_refptr<DisplayItemList> Create(
+ gfx::Rect layer_rect,
+ const DisplayItemListSettings& settings);
+
void Raster(SkCanvas* canvas,
- SkDrawPictureCallback* callback,
+ SkPicture::AbortCallback* callback,
+ const gfx::Rect& canvas_target_playback_rect,
float contents_scale) const;
+ // This is a fast path for use only if canvas_ is set and
+ // retain_individual_display_items_ is false. This method also updates
+ // is_suitable_for_gpu_rasterization_ and approximate_op_count_.
+ void RasterIntoCanvas(const DisplayItem& display_item);
+
template <typename DisplayItemType>
DisplayItemType* CreateAndAppendItem() {
#if DCHECK_IS_ON()
@@ -44,29 +59,43 @@ class CC_EXPORT DisplayItemList
return items_.AllocateAndConstruct<DisplayItemType>();
}
- void ProcessAppendedItems();
- void CreateAndCacheSkPicture();
+ // Removes the last item. This cannot be called on lists with cached pictures
+ // (since the data may already have been incorporated into cached picture
+ // sizes, etc).
+ void RemoveLast();
+
+ // Called after all items are appended, to process the items and, if
+ // applicable, create an internally cached SkPicture.
+ void Finalize();
bool IsSuitableForGpuRasterization() const;
int ApproximateOpCount() const;
- size_t PictureMemoryUsage() const;
+ size_t ApproximateMemoryUsage() const;
- scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValue() const;
+ bool RetainsIndividualDisplayItems() const;
+
+ scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValue(
+ bool include_items) const;
void EmitTraceSnapshot() const;
void GatherPixelRefs(const gfx::Size& grid_cell_size);
+ // Finds the sidecar for a display item in this list.
+ void* GetSidecar(DisplayItem* display_item);
+
private:
DisplayItemList(gfx::Rect layer_rect,
- bool use_cached_picture,
+ const DisplayItemListSettings& display_list_settings,
bool retain_individual_display_items);
- DisplayItemList(gfx::Rect layer_rect, bool use_cached_picture);
+ DisplayItemList(gfx::Rect layer_rect,
+ const DisplayItemListSettings& display_list_settings);
~DisplayItemList();
// While appending new items, if they are not being retained, this can process
// periodically to avoid retaining all the items and processing at the end.
void ProcessAppendedItemsOnTheFly();
+ void ProcessAppendedItems();
#if DCHECK_IS_ON()
bool ProcessAppendedItemsCalled() const { return !needs_process_; }
bool needs_process_;
@@ -74,7 +103,7 @@ class CC_EXPORT DisplayItemList
bool ProcessAppendedItemsCalled() const { return true; }
#endif
- ListContainer<DisplayItem> items_;
+ SidecarListContainer<DisplayItem> items_;
skia::RefPtr<SkPicture> picture_;
scoped_ptr<SkPictureRecorder> recorder_;
@@ -83,15 +112,20 @@ class CC_EXPORT DisplayItemList
bool retain_individual_display_items_;
gfx::Rect layer_rect_;
- bool is_suitable_for_gpu_rasterization_;
+ bool all_items_are_suitable_for_gpu_rasterization_;
int approximate_op_count_;
+
+ // Memory usage due to the cached SkPicture.
size_t picture_memory_usage_;
+ // Memory usage due to external data held by display items.
+ size_t external_memory_usage_;
+
scoped_ptr<PixelRefMap> pixel_refs_;
friend class base::RefCountedThreadSafe<DisplayItemList>;
friend class PixelRefMap::Iterator;
- FRIEND_TEST_ALL_PREFIXES(DisplayItemListTest, PictureMemoryUsage);
+ FRIEND_TEST_ALL_PREFIXES(DisplayItemListTest, ApproximateMemoryUsage);
DISALLOW_COPY_AND_ASSIGN(DisplayItemList);
};
diff --git a/chromium/cc/playback/display_item_list_settings.cc b/chromium/cc/playback/display_item_list_settings.cc
new file mode 100644
index 00000000000..e471d7e54ca
--- /dev/null
+++ b/chromium/cc/playback/display_item_list_settings.cc
@@ -0,0 +1,18 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/playback/display_item_list_settings.h"
+
+namespace cc {
+
+DisplayItemListSettings::DisplayItemListSettings()
+ : use_cached_picture(false),
+ max_sidecar_size(0),
+ sidecar_destroyer([](void* sidecar) {}) {
+}
+
+DisplayItemListSettings::~DisplayItemListSettings() {
+}
+
+} // namespace cc
diff --git a/chromium/cc/playback/display_item_list_settings.h b/chromium/cc/playback/display_item_list_settings.h
new file mode 100644
index 00000000000..277a2ea8da9
--- /dev/null
+++ b/chromium/cc/playback/display_item_list_settings.h
@@ -0,0 +1,29 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_PLAYBACK_DISPLAY_ITEM_LIST_SETTINGS_H_
+#define CC_PLAYBACK_DISPLAY_ITEM_LIST_SETTINGS_H_
+
+#include <cstddef>
+
+#include "cc/base/cc_export.h"
+
+namespace cc {
+
+class CC_EXPORT DisplayItemListSettings {
+ public:
+ DisplayItemListSettings();
+ ~DisplayItemListSettings();
+
+ // If set, a picture will be cached inside the DisplayItemList.
+ bool use_cached_picture;
+
+ // Settings that control sidecar data.
+ size_t max_sidecar_size;
+ void (*sidecar_destroyer)(void* sidecar);
+};
+
+} // namespace cc
+
+#endif // CC_PLAYBACK_DISPLAY_ITEM_LIST_SETTINGS_H_
diff --git a/chromium/cc/playback/display_item_list_unittest.cc b/chromium/cc/playback/display_item_list_unittest.cc
index 6a5bbf61ae8..89d4970da8a 100644
--- a/chromium/cc/playback/display_item_list_unittest.cc
+++ b/chromium/cc/playback/display_item_list_unittest.cc
@@ -9,6 +9,7 @@
#include "cc/output/filter_operation.h"
#include "cc/output/filter_operations.h"
#include "cc/playback/clip_display_item.h"
+#include "cc/playback/display_item_list_settings.h"
#include "cc/playback/drawing_display_item.h"
#include "cc/playback/filter_display_item.h"
#include "cc/playback/transform_display_item.h"
@@ -50,8 +51,7 @@ TEST(DisplayItemListTest, SingleDrawingItem) {
picture = skia::AdoptRef(recorder.endRecordingAsPicture());
auto* item = list->CreateAndAppendItem<DrawingDisplayItem>();
item->SetNew(picture);
- list->ProcessAppendedItems();
- list->CreateAndCacheSkPicture();
+ list->Finalize();
DrawDisplayList(pixels, layer_rect, list);
SkBitmap expected_bitmap;
@@ -110,8 +110,7 @@ TEST(DisplayItemListTest, ClipItem) {
item3->SetNew(picture.Pass());
list->CreateAndAppendItem<EndClipDisplayItem>();
- list->ProcessAppendedItems();
- list->CreateAndCacheSkPicture();
+ list->Finalize();
DrawDisplayList(pixels, layer_rect, list);
@@ -173,8 +172,7 @@ TEST(DisplayItemListTest, TransformItem) {
item3->SetNew(picture);
list->CreateAndAppendItem<EndTransformDisplayItem>();
- list->ProcessAppendedItems();
- list->CreateAndCacheSkPicture();
+ list->Finalize();
DrawDisplayList(pixels, layer_rect, list);
@@ -228,8 +226,7 @@ TEST(DisplayItemListTest, FilterItem) {
auto* item = list->CreateAndAppendItem<FilterDisplayItem>();
item->SetNew(filters, filter_bounds);
list->CreateAndAppendItem<EndFilterDisplayItem>();
- list->ProcessAppendedItems();
- list->CreateAndCacheSkPicture();
+ list->Finalize();
DrawDisplayList(pixels, layer_rect, list);
@@ -272,7 +269,7 @@ TEST(DisplayItemListTest, CompactingItems) {
picture = skia::AdoptRef(recorder.endRecordingAsPicture());
auto* item1 = list_without_caching->CreateAndAppendItem<DrawingDisplayItem>();
item1->SetNew(picture);
- list_without_caching->ProcessAppendedItems();
+ list_without_caching->Finalize();
DrawDisplayList(pixels, layer_rect, list_without_caching);
unsigned char expected_pixels[4 * 100 * 100] = {0};
@@ -281,14 +278,141 @@ TEST(DisplayItemListTest, CompactingItems) {
DisplayItemList::Create(layer_rect, use_cached_picture);
auto* item2 = list_with_caching->CreateAndAppendItem<DrawingDisplayItem>();
item2->SetNew(picture);
- list_with_caching->ProcessAppendedItems();
- list_with_caching->CreateAndCacheSkPicture();
+ list_with_caching->Finalize();
DrawDisplayList(expected_pixels, layer_rect, list_with_caching);
EXPECT_EQ(0, memcmp(pixels, expected_pixels, 4 * 100 * 100));
}
-TEST(DisplayItemListTest, PictureMemoryUsage) {
+TEST(DisplayItemListTest, IsSuitableForGpuRasterizationWithCachedPicture) {
+ gfx::Rect layer_rect(1000, 1000);
+ SkPictureRecorder recorder;
+ skia::RefPtr<SkCanvas> canvas;
+ skia::RefPtr<SkPicture> picture;
+
+ bool use_cached_picture = true;
+ scoped_refptr<DisplayItemList> list =
+ DisplayItemList::Create(layer_rect, use_cached_picture);
+ canvas =
+ skia::SharePtr(recorder.beginRecording(gfx::RectToSkRect(layer_rect)));
+
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(0, 100);
+ path.lineTo(50, 50);
+ path.lineTo(100, 100);
+ path.lineTo(100, 0);
+ path.close();
+
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ canvas->drawPath(path, paint);
+
+ picture = skia::AdoptRef(recorder.endRecordingAsPicture());
+ DrawingDisplayItem* item = list->CreateAndAppendItem<DrawingDisplayItem>();
+ item->SetNew(picture);
+ list->Finalize();
+
+ // A single DrawingDisplayItem with a large AA concave path shouldn't trigger
+ // a veto.
+ EXPECT_TRUE(list->IsSuitableForGpuRasterization());
+
+ list = DisplayItemList::Create(layer_rect, use_cached_picture);
+ canvas =
+ skia::SharePtr(recorder.beginRecording(gfx::RectToSkRect(layer_rect)));
+ for (int i = 0; i < 10; ++i)
+ canvas->drawPath(path, paint);
+ picture = skia::AdoptRef(recorder.endRecordingAsPicture());
+ item = list->CreateAndAppendItem<DrawingDisplayItem>();
+ item->SetNew(picture);
+ list->Finalize();
+
+ // A single DrawingDisplayItem with several large AA concave paths should
+ // trigger a veto.
+ EXPECT_FALSE(list->IsSuitableForGpuRasterization());
+
+ list = DisplayItemList::Create(layer_rect, use_cached_picture);
+ for (int i = 0; i < 10; ++i) {
+ canvas =
+ skia::SharePtr(recorder.beginRecording(gfx::RectToSkRect(layer_rect)));
+ canvas->drawPath(path, paint);
+ picture = skia::AdoptRef(recorder.endRecordingAsPicture());
+ item = list->CreateAndAppendItem<DrawingDisplayItem>();
+ item->SetNew(picture);
+ }
+ list->Finalize();
+
+ // Having several DrawingDisplayItems that each contain a large AA concave
+ // path should trigger a veto.
+ EXPECT_FALSE(list->IsSuitableForGpuRasterization());
+}
+
+TEST(DisplayItemListTest, IsSuitableForGpuRasterizationWithoutCachedPicture) {
+ gfx::Rect layer_rect(1000, 1000);
+ SkPictureRecorder recorder;
+ skia::RefPtr<SkCanvas> canvas;
+ skia::RefPtr<SkPicture> picture;
+
+ bool use_cached_picture = false;
+ scoped_refptr<DisplayItemList> list =
+ DisplayItemList::Create(layer_rect, use_cached_picture);
+ canvas =
+ skia::SharePtr(recorder.beginRecording(gfx::RectToSkRect(layer_rect)));
+
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(0, 100);
+ path.lineTo(50, 50);
+ path.lineTo(100, 100);
+ path.lineTo(100, 0);
+ path.close();
+
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ canvas->drawPath(path, paint);
+
+ picture = skia::AdoptRef(recorder.endRecordingAsPicture());
+ DrawingDisplayItem* item = list->CreateAndAppendItem<DrawingDisplayItem>();
+ item->SetNew(picture);
+ list->Finalize();
+
+ // A single DrawingDisplayItem with a large AA concave path shouldn't trigger
+ // a veto.
+ EXPECT_TRUE(list->IsSuitableForGpuRasterization());
+
+ list = DisplayItemList::Create(layer_rect, use_cached_picture);
+ canvas =
+ skia::SharePtr(recorder.beginRecording(gfx::RectToSkRect(layer_rect)));
+ for (int i = 0; i < 10; ++i)
+ canvas->drawPath(path, paint);
+ picture = skia::AdoptRef(recorder.endRecordingAsPicture());
+ item = list->CreateAndAppendItem<DrawingDisplayItem>();
+ item->SetNew(picture);
+ list->Finalize();
+
+ // A single DrawingDisplayItem with several large AA concave paths should
+ // trigger a veto.
+ EXPECT_FALSE(list->IsSuitableForGpuRasterization());
+
+ list = DisplayItemList::Create(layer_rect, use_cached_picture);
+ for (int i = 0; i < 10; ++i) {
+ canvas =
+ skia::SharePtr(recorder.beginRecording(gfx::RectToSkRect(layer_rect)));
+ canvas->drawPath(path, paint);
+ picture = skia::AdoptRef(recorder.endRecordingAsPicture());
+ item = list->CreateAndAppendItem<DrawingDisplayItem>();
+ item->SetNew(picture);
+ }
+ list->Finalize();
+
+ // Without a cached picture, having several DrawingDisplayItems that each
+ // contain a single large AA concave will not trigger a veto, since each item
+ // is individually suitable for GPU rasterization.
+ EXPECT_TRUE(list->IsSuitableForGpuRasterization());
+}
+
+TEST(DisplayItemListTest, ApproximateMemoryUsage) {
+ const int kNumCommandsInTestSkPicture = 1000;
scoped_refptr<DisplayItemList> list;
size_t memory_usage;
@@ -298,21 +422,19 @@ TEST(DisplayItemListTest, PictureMemoryUsage) {
SkPaint blue_paint;
blue_paint.setColor(SK_ColorBLUE);
SkCanvas* canvas = recorder.beginRecording(gfx::RectFToSkRect(layer_rect));
- for (int i = 0; i < 100; i++)
+ for (int i = 0; i < kNumCommandsInTestSkPicture; i++)
canvas->drawPaint(blue_paint);
skia::RefPtr<SkPicture> picture =
skia::AdoptRef(recorder.endRecordingAsPicture());
size_t picture_size = SkPictureUtils::ApproximateBytesUsed(picture.get());
- ASSERT_GE(picture_size, 100 * sizeof(SkPaint));
- ASSERT_LE(picture_size, 200 * sizeof(SkPaint));
+ ASSERT_GE(picture_size, kNumCommandsInTestSkPicture * sizeof(blue_paint));
// Using a cached picture, we should get about the right size.
list = DisplayItemList::Create(layer_rect, true);
auto* item = list->CreateAndAppendItem<DrawingDisplayItem>();
item->SetNew(picture);
- list->ProcessAppendedItems();
- list->CreateAndCacheSkPicture();
- memory_usage = list->PictureMemoryUsage();
+ list->Finalize();
+ memory_usage = list->ApproximateMemoryUsage();
EXPECT_GE(memory_usage, picture_size);
EXPECT_LE(memory_usage, 2 * picture_size);
@@ -320,20 +442,21 @@ TEST(DisplayItemListTest, PictureMemoryUsage) {
list = DisplayItemList::Create(layer_rect, false);
item = list->CreateAndAppendItem<DrawingDisplayItem>();
item->SetNew(picture);
- list->ProcessAppendedItems();
- memory_usage = list->PictureMemoryUsage();
+ list->Finalize();
+ memory_usage = list->ApproximateMemoryUsage();
EXPECT_GE(memory_usage, picture_size);
EXPECT_LE(memory_usage, 2 * picture_size);
// To avoid double counting, we expect zero size to be computed if both the
// picture and items are retained (currently this only happens due to certain
// categories being traced).
- list = new DisplayItemList(layer_rect, true, true);
+ DisplayItemListSettings settings;
+ settings.use_cached_picture = true;
+ list = new DisplayItemList(layer_rect, settings, true);
item = list->CreateAndAppendItem<DrawingDisplayItem>();
item->SetNew(picture);
- list->ProcessAppendedItems();
- list->CreateAndCacheSkPicture();
- memory_usage = list->PictureMemoryUsage();
+ list->Finalize();
+ memory_usage = list->ApproximateMemoryUsage();
EXPECT_EQ(static_cast<size_t>(0), memory_usage);
}
diff --git a/chromium/cc/playback/display_list_raster_source.cc b/chromium/cc/playback/display_list_raster_source.cc
index 0dcd025f3c9..4911e846029 100644
--- a/chromium/cc/playback/display_list_raster_source.cc
+++ b/chromium/cc/playback/display_list_raster_source.cc
@@ -14,16 +14,6 @@
#include "third_party/skia/include/core/SkPictureRecorder.h"
#include "ui/gfx/geometry/rect_conversions.h"
-namespace {
-
-#ifdef NDEBUG
-const bool kDefaultClearCanvasSetting = false;
-#else
-const bool kDefaultClearCanvasSetting = true;
-#endif
-
-} // namespace
-
namespace cc {
scoped_refptr<DisplayListRasterSource>
@@ -40,7 +30,7 @@ DisplayListRasterSource::DisplayListRasterSource()
can_use_lcd_text_(true),
is_solid_color_(false),
solid_color_(SK_ColorTRANSPARENT),
- clear_canvas_with_debug_color_(kDefaultClearCanvasSetting),
+ clear_canvas_with_debug_color_(false),
slow_down_raster_scale_factor_for_debug_(0),
should_attempt_to_use_distance_field_text_(false) {
}
@@ -56,7 +46,7 @@ DisplayListRasterSource::DisplayListRasterSource(
solid_color_(other->solid_color_),
recorded_viewport_(other->recorded_viewport_),
size_(other->size_),
- clear_canvas_with_debug_color_(kDefaultClearCanvasSetting),
+ clear_canvas_with_debug_color_(other->clear_canvas_with_debug_color_),
slow_down_raster_scale_factor_for_debug_(
other->slow_down_raster_scale_factor_for_debug_),
should_attempt_to_use_distance_field_text_(false) {
@@ -73,7 +63,7 @@ DisplayListRasterSource::DisplayListRasterSource(
solid_color_(other->solid_color_),
recorded_viewport_(other->recorded_viewport_),
size_(other->size_),
- clear_canvas_with_debug_color_(kDefaultClearCanvasSetting),
+ clear_canvas_with_debug_color_(other->clear_canvas_with_debug_color_),
slow_down_raster_scale_factor_for_debug_(
other->slow_down_raster_scale_factor_for_debug_),
should_attempt_to_use_distance_field_text_(
@@ -87,38 +77,47 @@ void DisplayListRasterSource::PlaybackToSharedCanvas(
SkCanvas* canvas,
const gfx::Rect& canvas_rect,
float contents_scale) const {
- RasterCommon(canvas, NULL, canvas_rect, contents_scale);
+ RasterCommon(canvas, NULL, canvas_rect, canvas_rect, contents_scale);
}
void DisplayListRasterSource::RasterForAnalysis(skia::AnalysisCanvas* canvas,
const gfx::Rect& canvas_rect,
float contents_scale) const {
- RasterCommon(canvas, canvas, canvas_rect, contents_scale);
+ RasterCommon(canvas, canvas, canvas_rect, canvas_rect, contents_scale);
}
-void DisplayListRasterSource::PlaybackToCanvas(SkCanvas* canvas,
- const gfx::Rect& canvas_rect,
- float contents_scale) const {
+void DisplayListRasterSource::PlaybackToCanvas(
+ SkCanvas* canvas,
+ const gfx::Rect& canvas_bitmap_rect,
+ const gfx::Rect& canvas_playback_rect,
+ float contents_scale) const {
RasterSourceHelper::PrepareForPlaybackToCanvas(
- canvas, canvas_rect, gfx::Rect(size_), contents_scale, background_color_,
- clear_canvas_with_debug_color_, requires_clear_);
+ canvas, canvas_bitmap_rect, canvas_playback_rect, gfx::Rect(size_),
+ contents_scale, background_color_, clear_canvas_with_debug_color_,
+ requires_clear_);
- RasterCommon(canvas, NULL, canvas_rect, contents_scale);
+ RasterCommon(canvas, NULL, canvas_bitmap_rect, canvas_playback_rect,
+ contents_scale);
}
-void DisplayListRasterSource::RasterCommon(SkCanvas* canvas,
- SkDrawPictureCallback* callback,
- const gfx::Rect& canvas_rect,
- float contents_scale) const {
- canvas->translate(-canvas_rect.x(), -canvas_rect.y());
+void DisplayListRasterSource::RasterCommon(
+ SkCanvas* canvas,
+ SkPicture::AbortCallback* callback,
+ const gfx::Rect& canvas_bitmap_rect,
+ const gfx::Rect& canvas_playback_rect,
+ float contents_scale) const {
+ canvas->translate(-canvas_bitmap_rect.x(), -canvas_bitmap_rect.y());
gfx::Rect content_rect =
gfx::ToEnclosingRect(gfx::ScaleRect(gfx::Rect(size_), contents_scale));
- content_rect.Intersect(canvas_rect);
+ content_rect.Intersect(canvas_playback_rect);
canvas->clipRect(gfx::RectToSkRect(content_rect), SkRegion::kIntersect_Op);
DCHECK(display_list_.get());
- display_list_->Raster(canvas, callback, contents_scale);
+ gfx::Rect canvas_target_playback_rect =
+ canvas_playback_rect - canvas_bitmap_rect.OffsetFromOrigin();
+ display_list_->Raster(canvas, callback, canvas_target_playback_rect,
+ contents_scale);
}
skia::RefPtr<SkPicture> DisplayListRasterSource::GetFlattenedPicture() {
@@ -129,7 +128,7 @@ skia::RefPtr<SkPicture> DisplayListRasterSource::GetFlattenedPicture() {
SkCanvas* canvas = recorder.beginRecording(display_list_rect.width(),
display_list_rect.height());
if (!display_list_rect.IsEmpty())
- PlaybackToCanvas(canvas, display_list_rect, 1.0);
+ PlaybackToCanvas(canvas, display_list_rect, display_list_rect, 1.0);
skia::RefPtr<SkPicture> picture =
skia::AdoptRef(recorder.endRecordingAsPicture());
@@ -139,7 +138,7 @@ skia::RefPtr<SkPicture> DisplayListRasterSource::GetFlattenedPicture() {
size_t DisplayListRasterSource::GetPictureMemoryUsage() const {
if (!display_list_)
return 0;
- return display_list_->PictureMemoryUsage();
+ return display_list_->ApproximateMemoryUsage();
}
void DisplayListRasterSource::PerformSolidColorAnalysis(
diff --git a/chromium/cc/playback/display_list_raster_source.h b/chromium/cc/playback/display_list_raster_source.h
index e9010e59261..24faa33c7fc 100644
--- a/chromium/cc/playback/display_list_raster_source.h
+++ b/chromium/cc/playback/display_list_raster_source.h
@@ -27,7 +27,8 @@ class CC_EXPORT DisplayListRasterSource : public RasterSource {
// RasterSource overrides.
void PlaybackToCanvas(SkCanvas* canvas,
- const gfx::Rect& canvas_rect,
+ const gfx::Rect& canvas_bitmap_rect,
+ const gfx::Rect& canvas_playback_rect,
float contents_scale) const override;
void PlaybackToSharedCanvas(SkCanvas* canvas,
const gfx::Rect& canvas_rect,
@@ -80,14 +81,15 @@ class CC_EXPORT DisplayListRasterSource : public RasterSource {
private:
// Called when analyzing a tile. We can use AnalysisCanvas as
- // SkDrawPictureCallback, which allows us to early out from analysis.
+ // SkPicture::AbortCallback, which allows us to early out from analysis.
void RasterForAnalysis(skia::AnalysisCanvas* canvas,
const gfx::Rect& canvas_rect,
float contents_scale) const;
void RasterCommon(SkCanvas* canvas,
- SkDrawPictureCallback* callback,
- const gfx::Rect& canvas_rect,
+ SkPicture::AbortCallback* callback,
+ const gfx::Rect& canvas_bitmap_rect,
+ const gfx::Rect& canvas_playback_rect,
float contents_scale) const;
DISALLOW_COPY_AND_ASSIGN(DisplayListRasterSource);
diff --git a/chromium/cc/playback/display_list_raster_source_unittest.cc b/chromium/cc/playback/display_list_raster_source_unittest.cc
new file mode 100644
index 00000000000..d936af51f9c
--- /dev/null
+++ b/chromium/cc/playback/display_list_raster_source_unittest.cc
@@ -0,0 +1,556 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/memory/scoped_ptr.h"
+#include "cc/playback/display_list_raster_source.h"
+#include "cc/test/fake_display_list_recording_source.h"
+#include "cc/test/skia_common.h"
+#include "skia/ext/refptr.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/skia/include/core/SkPixelRef.h"
+#include "third_party/skia/include/core/SkShader.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/size_conversions.h"
+
+namespace cc {
+namespace {
+
+TEST(DisplayListRasterSourceTest, AnalyzeIsSolidUnscaled) {
+ gfx::Size layer_bounds(400, 400);
+
+ scoped_ptr<FakeDisplayListRecordingSource> recording_source =
+ FakeDisplayListRecordingSource::CreateFilledRecordingSource(layer_bounds);
+
+ SkPaint solid_paint;
+ SkColor solid_color = SkColorSetARGB(255, 12, 23, 34);
+ solid_paint.setColor(solid_color);
+
+ SkColor non_solid_color = SkColorSetARGB(128, 45, 56, 67);
+ SkPaint non_solid_paint;
+ non_solid_paint.setColor(non_solid_color);
+
+ recording_source->add_draw_rect_with_paint(gfx::Rect(layer_bounds),
+ solid_paint);
+ recording_source->Rerecord();
+
+ scoped_refptr<DisplayListRasterSource> raster =
+ DisplayListRasterSource::CreateFromDisplayListRecordingSource(
+ recording_source.get(), false);
+
+ // Ensure everything is solid.
+ for (int y = 0; y <= 300; y += 100) {
+ for (int x = 0; x <= 300; x += 100) {
+ RasterSource::SolidColorAnalysis analysis;
+ gfx::Rect rect(x, y, 100, 100);
+ raster->PerformSolidColorAnalysis(rect, 1.0, &analysis);
+ EXPECT_TRUE(analysis.is_solid_color) << rect.ToString();
+ EXPECT_EQ(solid_color, analysis.solid_color) << rect.ToString();
+ }
+ }
+
+ // Add one non-solid pixel and recreate the raster source.
+ recording_source->add_draw_rect_with_paint(gfx::Rect(50, 50, 1, 1),
+ non_solid_paint);
+ recording_source->Rerecord();
+ raster = DisplayListRasterSource::CreateFromDisplayListRecordingSource(
+ recording_source.get(), false);
+
+ RasterSource::SolidColorAnalysis analysis;
+ raster->PerformSolidColorAnalysis(gfx::Rect(0, 0, 100, 100), 1.0, &analysis);
+ EXPECT_FALSE(analysis.is_solid_color);
+
+ raster->PerformSolidColorAnalysis(gfx::Rect(100, 0, 100, 100), 1.0,
+ &analysis);
+ EXPECT_TRUE(analysis.is_solid_color);
+ EXPECT_EQ(solid_color, analysis.solid_color);
+
+ // Boundaries should be clipped.
+ analysis.is_solid_color = false;
+ raster->PerformSolidColorAnalysis(gfx::Rect(350, 0, 100, 100), 1.0,
+ &analysis);
+ EXPECT_TRUE(analysis.is_solid_color);
+ EXPECT_EQ(solid_color, analysis.solid_color);
+
+ analysis.is_solid_color = false;
+ raster->PerformSolidColorAnalysis(gfx::Rect(0, 350, 100, 100), 1.0,
+ &analysis);
+ EXPECT_TRUE(analysis.is_solid_color);
+ EXPECT_EQ(solid_color, analysis.solid_color);
+
+ analysis.is_solid_color = false;
+ raster->PerformSolidColorAnalysis(gfx::Rect(350, 350, 100, 100), 1.0,
+ &analysis);
+ EXPECT_TRUE(analysis.is_solid_color);
+ EXPECT_EQ(solid_color, analysis.solid_color);
+}
+
+TEST(DisplayListRasterSourceTest, AnalyzeIsSolidScaled) {
+ gfx::Size layer_bounds(400, 400);
+
+ scoped_ptr<FakeDisplayListRecordingSource> recording_source =
+ FakeDisplayListRecordingSource::CreateFilledRecordingSource(layer_bounds);
+
+ SkColor solid_color = SkColorSetARGB(255, 12, 23, 34);
+ SkPaint solid_paint;
+ solid_paint.setColor(solid_color);
+
+ SkColor non_solid_color = SkColorSetARGB(128, 45, 56, 67);
+ SkPaint non_solid_paint;
+ non_solid_paint.setColor(non_solid_color);
+
+ recording_source->add_draw_rect_with_paint(gfx::Rect(0, 0, 400, 400),
+ solid_paint);
+ recording_source->Rerecord();
+
+ scoped_refptr<DisplayListRasterSource> raster =
+ DisplayListRasterSource::CreateFromDisplayListRecordingSource(
+ recording_source.get(), false);
+
+ // Ensure everything is solid.
+ for (int y = 0; y <= 30; y += 10) {
+ for (int x = 0; x <= 30; x += 10) {
+ RasterSource::SolidColorAnalysis analysis;
+ gfx::Rect rect(x, y, 10, 10);
+ raster->PerformSolidColorAnalysis(rect, 0.1f, &analysis);
+ EXPECT_TRUE(analysis.is_solid_color) << rect.ToString();
+ EXPECT_EQ(analysis.solid_color, solid_color) << rect.ToString();
+ }
+ }
+
+ // Add one non-solid pixel and recreate the raster source.
+ recording_source->add_draw_rect_with_paint(gfx::Rect(50, 50, 1, 1),
+ non_solid_paint);
+ recording_source->Rerecord();
+ raster = DisplayListRasterSource::CreateFromDisplayListRecordingSource(
+ recording_source.get(), false);
+
+ RasterSource::SolidColorAnalysis analysis;
+ raster->PerformSolidColorAnalysis(gfx::Rect(0, 0, 10, 10), 0.1f, &analysis);
+ EXPECT_FALSE(analysis.is_solid_color);
+
+ raster->PerformSolidColorAnalysis(gfx::Rect(10, 0, 10, 10), 0.1f, &analysis);
+ EXPECT_TRUE(analysis.is_solid_color);
+ EXPECT_EQ(analysis.solid_color, solid_color);
+
+ // Boundaries should be clipped.
+ analysis.is_solid_color = false;
+ raster->PerformSolidColorAnalysis(gfx::Rect(35, 0, 10, 10), 0.1f, &analysis);
+ EXPECT_TRUE(analysis.is_solid_color);
+ EXPECT_EQ(analysis.solid_color, solid_color);
+
+ analysis.is_solid_color = false;
+ raster->PerformSolidColorAnalysis(gfx::Rect(0, 35, 10, 10), 0.1f, &analysis);
+ EXPECT_TRUE(analysis.is_solid_color);
+ EXPECT_EQ(analysis.solid_color, solid_color);
+
+ analysis.is_solid_color = false;
+ raster->PerformSolidColorAnalysis(gfx::Rect(35, 35, 10, 10), 0.1f, &analysis);
+ EXPECT_TRUE(analysis.is_solid_color);
+ EXPECT_EQ(analysis.solid_color, solid_color);
+}
+
+TEST(DisplayListRasterSourceTest, AnalyzeIsSolidEmpty) {
+ gfx::Size layer_bounds(400, 400);
+
+ scoped_ptr<FakeDisplayListRecordingSource> recording_source =
+ FakeDisplayListRecordingSource::CreateFilledRecordingSource(layer_bounds);
+ recording_source->Rerecord();
+
+ scoped_refptr<DisplayListRasterSource> raster =
+ DisplayListRasterSource::CreateFromDisplayListRecordingSource(
+ recording_source.get(), false);
+ RasterSource::SolidColorAnalysis analysis;
+ EXPECT_FALSE(analysis.is_solid_color);
+
+ raster->PerformSolidColorAnalysis(gfx::Rect(0, 0, 400, 400), 1.f, &analysis);
+
+ EXPECT_TRUE(analysis.is_solid_color);
+ EXPECT_EQ(analysis.solid_color, SkColorSetARGB(0, 0, 0, 0));
+}
+
+TEST(DisplayListRasterSourceTest, PixelRefIteratorDiscardableRefsOneTile) {
+ gfx::Size layer_bounds(512, 512);
+
+ scoped_ptr<FakeDisplayListRecordingSource> recording_source =
+ FakeDisplayListRecordingSource::CreateFilledRecordingSource(layer_bounds);
+
+ SkBitmap discardable_bitmap[2][2];
+ CreateBitmap(gfx::Size(32, 32), "discardable", &discardable_bitmap[0][0]);
+ CreateBitmap(gfx::Size(32, 32), "discardable", &discardable_bitmap[0][1]);
+ CreateBitmap(gfx::Size(32, 32), "discardable", &discardable_bitmap[1][1]);
+
+ // Discardable pixel refs are found in the following cells:
+ // |---|---|
+ // | x | x |
+ // |---|---|
+ // | | x |
+ // |---|---|
+ recording_source->add_draw_bitmap(discardable_bitmap[0][0], gfx::Point(0, 0));
+ recording_source->add_draw_bitmap(discardable_bitmap[0][1],
+ gfx::Point(260, 0));
+ recording_source->add_draw_bitmap(discardable_bitmap[1][1],
+ gfx::Point(260, 260));
+ recording_source->SetGatherPixelRefs(true);
+ recording_source->Rerecord();
+
+ scoped_refptr<DisplayListRasterSource> raster =
+ DisplayListRasterSource::CreateFromDisplayListRecordingSource(
+ recording_source.get(), false);
+
+ // Tile sized iterators. These should find only one pixel ref.
+ {
+ std::vector<SkPixelRef*> pixel_refs;
+ raster->GatherPixelRefs(gfx::Rect(0, 0, 256, 256), 1.0, &pixel_refs);
+ EXPECT_EQ(1u, pixel_refs.size());
+ EXPECT_EQ(discardable_bitmap[0][0].pixelRef(), pixel_refs[0]);
+ }
+ {
+ std::vector<SkPixelRef*> pixel_refs;
+ raster->GatherPixelRefs(gfx::Rect(0, 0, 512, 512), 2.0, &pixel_refs);
+ EXPECT_EQ(1u, pixel_refs.size());
+ EXPECT_EQ(discardable_bitmap[0][0].pixelRef(), pixel_refs[0]);
+ }
+ {
+ std::vector<SkPixelRef*> pixel_refs;
+ raster->GatherPixelRefs(gfx::Rect(0, 0, 128, 128), 0.5, &pixel_refs);
+ EXPECT_EQ(1u, pixel_refs.size());
+ EXPECT_EQ(discardable_bitmap[0][0].pixelRef(), pixel_refs[0]);
+ }
+ // Shifted tile sized iterators. These should find only one pixel ref.
+ {
+ std::vector<SkPixelRef*> pixel_refs;
+ raster->GatherPixelRefs(gfx::Rect(260, 260, 256, 256), 1.0, &pixel_refs);
+ EXPECT_EQ(1u, pixel_refs.size());
+ EXPECT_EQ(discardable_bitmap[1][1].pixelRef(), pixel_refs[0]);
+ }
+ {
+ std::vector<SkPixelRef*> pixel_refs;
+ raster->GatherPixelRefs(gfx::Rect(520, 520, 512, 512), 2.0, &pixel_refs);
+ EXPECT_EQ(1u, pixel_refs.size());
+ EXPECT_EQ(discardable_bitmap[1][1].pixelRef(), pixel_refs[0]);
+ }
+ {
+ std::vector<SkPixelRef*> pixel_refs;
+ raster->GatherPixelRefs(gfx::Rect(130, 130, 128, 128), 0.5, &pixel_refs);
+ EXPECT_EQ(1u, pixel_refs.size());
+ EXPECT_EQ(discardable_bitmap[1][1].pixelRef(), pixel_refs[0]);
+ }
+ // Ensure there's no discardable pixel refs in the empty cell
+ {
+ std::vector<SkPixelRef*> pixel_refs;
+ raster->GatherPixelRefs(gfx::Rect(0, 256, 256, 256), 1.0, &pixel_refs);
+ EXPECT_EQ(0u, pixel_refs.size());
+ }
+ // Layer sized iterators. These should find three pixel ref.
+ {
+ std::vector<SkPixelRef*> pixel_refs;
+ raster->GatherPixelRefs(gfx::Rect(0, 0, 512, 512), 1.0, &pixel_refs);
+ EXPECT_EQ(3u, pixel_refs.size());
+ EXPECT_EQ(discardable_bitmap[0][0].pixelRef(), pixel_refs[0]);
+ EXPECT_EQ(discardable_bitmap[0][1].pixelRef(), pixel_refs[1]);
+ EXPECT_EQ(discardable_bitmap[1][1].pixelRef(), pixel_refs[2]);
+ }
+ {
+ std::vector<SkPixelRef*> pixel_refs;
+ raster->GatherPixelRefs(gfx::Rect(0, 0, 1024, 1024), 2.0, &pixel_refs);
+ EXPECT_EQ(3u, pixel_refs.size());
+ EXPECT_EQ(discardable_bitmap[0][0].pixelRef(), pixel_refs[0]);
+ EXPECT_EQ(discardable_bitmap[0][1].pixelRef(), pixel_refs[1]);
+ EXPECT_EQ(discardable_bitmap[1][1].pixelRef(), pixel_refs[2]);
+ }
+ {
+ std::vector<SkPixelRef*> pixel_refs;
+ raster->GatherPixelRefs(gfx::Rect(0, 0, 256, 256), 0.5, &pixel_refs);
+ EXPECT_EQ(3u, pixel_refs.size());
+ EXPECT_EQ(discardable_bitmap[0][0].pixelRef(), pixel_refs[0]);
+ EXPECT_EQ(discardable_bitmap[0][1].pixelRef(), pixel_refs[1]);
+ EXPECT_EQ(discardable_bitmap[1][1].pixelRef(), pixel_refs[2]);
+ }
+}
+
+TEST(DisplayListRasterSourceTest, RasterFullContents) {
+ gfx::Size layer_bounds(3, 5);
+ float contents_scale = 1.5f;
+ float raster_divisions = 2.f;
+
+ scoped_ptr<FakeDisplayListRecordingSource> recording_source =
+ FakeDisplayListRecordingSource::CreateFilledRecordingSource(layer_bounds);
+ recording_source->SetBackgroundColor(SK_ColorBLACK);
+ recording_source->SetClearCanvasWithDebugColor(false);
+
+ // Because the caller sets content opaque, it also promises that it
+ // has at least filled in layer_bounds opaquely.
+ SkPaint white_paint;
+ white_paint.setColor(SK_ColorWHITE);
+ recording_source->add_draw_rect_with_paint(gfx::Rect(layer_bounds),
+ white_paint);
+ recording_source->Rerecord();
+
+ scoped_refptr<DisplayListRasterSource> raster =
+ DisplayListRasterSource::CreateFromDisplayListRecordingSource(
+ recording_source.get(), false);
+
+ gfx::Size content_bounds(
+ gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale)));
+
+ // Simulate drawing into different tiles at different offsets.
+ int step_x = std::ceil(content_bounds.width() / raster_divisions);
+ int step_y = std::ceil(content_bounds.height() / raster_divisions);
+ for (int offset_x = 0; offset_x < content_bounds.width();
+ offset_x += step_x) {
+ for (int offset_y = 0; offset_y < content_bounds.height();
+ offset_y += step_y) {
+ gfx::Rect content_rect(offset_x, offset_y, step_x, step_y);
+ content_rect.Intersect(gfx::Rect(content_bounds));
+
+ // Simulate a canvas rect larger than the content rect. Every pixel
+ // up to one pixel outside the content rect is guaranteed to be opaque.
+ // Outside of that is undefined.
+ gfx::Rect canvas_rect(content_rect);
+ canvas_rect.Inset(0, 0, -1, -1);
+
+ SkBitmap bitmap;
+ bitmap.allocN32Pixels(canvas_rect.width(), canvas_rect.height());
+ SkCanvas canvas(bitmap);
+ canvas.clear(SK_ColorTRANSPARENT);
+
+ raster->PlaybackToCanvas(&canvas, canvas_rect, canvas_rect,
+ contents_scale);
+
+ SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels());
+ int num_pixels = bitmap.width() * bitmap.height();
+ bool all_white = true;
+ for (int i = 0; i < num_pixels; ++i) {
+ EXPECT_EQ(SkColorGetA(pixels[i]), 255u);
+ all_white &= (SkColorGetR(pixels[i]) == 255);
+ all_white &= (SkColorGetG(pixels[i]) == 255);
+ all_white &= (SkColorGetB(pixels[i]) == 255);
+ }
+
+ // If the canvas doesn't extend past the edge of the content,
+ // it should be entirely white. Otherwise, the edge of the content
+ // will be non-white.
+ EXPECT_EQ(all_white, gfx::Rect(content_bounds).Contains(canvas_rect));
+ }
+ }
+}
+
+TEST(DisplayListRasterSourceTest, RasterPartialContents) {
+ gfx::Size layer_bounds(3, 5);
+ float contents_scale = 1.5f;
+
+ scoped_ptr<FakeDisplayListRecordingSource> recording_source =
+ FakeDisplayListRecordingSource::CreateFilledRecordingSource(layer_bounds);
+ recording_source->SetBackgroundColor(SK_ColorGREEN);
+ recording_source->SetClearCanvasWithDebugColor(false);
+
+ // First record everything as white.
+ SkPaint white_paint;
+ white_paint.setColor(SK_ColorWHITE);
+ recording_source->add_draw_rect_with_paint(gfx::Rect(layer_bounds),
+ white_paint);
+ recording_source->Rerecord();
+
+ scoped_refptr<DisplayListRasterSource> raster =
+ DisplayListRasterSource::CreateFromDisplayListRecordingSource(
+ recording_source.get(), false);
+
+ gfx::Size content_bounds(
+ gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale)));
+
+ SkBitmap bitmap;
+ bitmap.allocN32Pixels(content_bounds.width(), content_bounds.height());
+ SkCanvas canvas(bitmap);
+ canvas.clear(SK_ColorTRANSPARENT);
+
+ // Playback the full rect which should make everything white.
+ gfx::Rect raster_full_rect(content_bounds);
+ gfx::Rect playback_rect(content_bounds);
+ raster->PlaybackToCanvas(&canvas, raster_full_rect, playback_rect,
+ contents_scale);
+
+ {
+ SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels());
+ for (int i = 0; i < bitmap.width(); ++i) {
+ for (int j = 0; j < bitmap.height(); ++j) {
+ SCOPED_TRACE(i);
+ SCOPED_TRACE(j);
+ EXPECT_EQ(255u, SkColorGetA(pixels[i + j * bitmap.width()]));
+ EXPECT_EQ(255u, SkColorGetR(pixels[i + j * bitmap.width()]));
+ EXPECT_EQ(255u, SkColorGetG(pixels[i + j * bitmap.width()]));
+ EXPECT_EQ(255u, SkColorGetB(pixels[i + j * bitmap.width()]));
+ }
+ }
+ }
+
+ // Re-record everything as black.
+ SkPaint black_paint;
+ black_paint.setColor(SK_ColorBLACK);
+ recording_source->add_draw_rect_with_paint(gfx::Rect(layer_bounds),
+ black_paint);
+ recording_source->Rerecord();
+
+ // Make a new RasterSource from the new recording.
+ raster = DisplayListRasterSource::CreateFromDisplayListRecordingSource(
+ recording_source.get(), false);
+
+ // We're going to playback from "everything is black" into a smaller area,
+ // that touches the edge pixels of the recording.
+ playback_rect.Inset(1, 2, 0, 1);
+ raster->PlaybackToCanvas(&canvas, raster_full_rect, playback_rect,
+ contents_scale);
+
+ SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels());
+ int num_black = 0;
+ int num_white = 0;
+ for (int i = 0; i < bitmap.width(); ++i) {
+ for (int j = 0; j < bitmap.height(); ++j) {
+ SCOPED_TRACE(j);
+ SCOPED_TRACE(i);
+ bool expect_black = playback_rect.Contains(i, j);
+ if (expect_black) {
+ EXPECT_EQ(255u, SkColorGetA(pixels[i + j * bitmap.width()]));
+ EXPECT_EQ(0u, SkColorGetR(pixels[i + j * bitmap.width()]));
+ EXPECT_EQ(0u, SkColorGetG(pixels[i + j * bitmap.width()]));
+ EXPECT_EQ(0u, SkColorGetB(pixels[i + j * bitmap.width()]));
+ ++num_black;
+ } else {
+ EXPECT_EQ(255u, SkColorGetA(pixels[i + j * bitmap.width()]));
+ EXPECT_EQ(255u, SkColorGetR(pixels[i + j * bitmap.width()]));
+ EXPECT_EQ(255u, SkColorGetG(pixels[i + j * bitmap.width()]));
+ EXPECT_EQ(255u, SkColorGetB(pixels[i + j * bitmap.width()]));
+ ++num_white;
+ }
+ }
+ }
+ EXPECT_GT(num_black, 0);
+ EXPECT_GT(num_white, 0);
+}
+
+TEST(DisplayListRasterSourceTest, RasterPartialClear) {
+ gfx::Size layer_bounds(3, 5);
+ gfx::Size partial_bounds(2, 4);
+ float contents_scale = 1.5f;
+
+ scoped_ptr<FakeDisplayListRecordingSource> recording_source =
+ FakeDisplayListRecordingSource::CreateFilledRecordingSource(layer_bounds);
+ recording_source->SetBackgroundColor(SK_ColorGREEN);
+ recording_source->SetRequiresClear(true);
+ recording_source->SetClearCanvasWithDebugColor(false);
+
+ // First record everything as white.
+ const unsigned alpha_dark = 10u;
+ SkPaint white_paint;
+ white_paint.setColor(SK_ColorWHITE);
+ white_paint.setAlpha(alpha_dark);
+ recording_source->add_draw_rect_with_paint(gfx::Rect(layer_bounds),
+ white_paint);
+ recording_source->Rerecord();
+
+ scoped_refptr<DisplayListRasterSource> raster =
+ DisplayListRasterSource::CreateFromDisplayListRecordingSource(
+ recording_source.get(), false);
+
+ gfx::Size content_bounds(
+ gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale)));
+
+ SkBitmap bitmap;
+ bitmap.allocN32Pixels(content_bounds.width(), content_bounds.height());
+ SkCanvas canvas(bitmap);
+ canvas.clear(SK_ColorTRANSPARENT);
+
+ // Playback the full rect which should make everything light gray (alpha=10).
+ gfx::Rect raster_full_rect(content_bounds);
+ gfx::Rect playback_rect(content_bounds);
+ raster->PlaybackToCanvas(&canvas, raster_full_rect, playback_rect,
+ contents_scale);
+
+ {
+ SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels());
+ for (int i = 0; i < bitmap.width(); ++i) {
+ for (int j = 0; j < bitmap.height(); ++j) {
+ SCOPED_TRACE(i);
+ SCOPED_TRACE(j);
+ EXPECT_EQ(alpha_dark, SkColorGetA(pixels[i + j * bitmap.width()]));
+ EXPECT_EQ(alpha_dark, SkColorGetR(pixels[i + j * bitmap.width()]));
+ EXPECT_EQ(alpha_dark, SkColorGetG(pixels[i + j * bitmap.width()]));
+ EXPECT_EQ(alpha_dark, SkColorGetB(pixels[i + j * bitmap.width()]));
+ }
+ }
+ }
+
+ scoped_ptr<FakeDisplayListRecordingSource> recording_source_light =
+ FakeDisplayListRecordingSource::CreateFilledRecordingSource(layer_bounds);
+ recording_source_light->SetBackgroundColor(SK_ColorGREEN);
+ recording_source_light->SetRequiresClear(true);
+ recording_source_light->SetClearCanvasWithDebugColor(false);
+
+ // Record everything as a slightly lighter white.
+ const unsigned alpha_light = 18u;
+ white_paint.setAlpha(alpha_light);
+ recording_source_light->add_draw_rect_with_paint(gfx::Rect(layer_bounds),
+ white_paint);
+ recording_source_light->Rerecord();
+
+ // Make a new RasterSource from the new recording.
+ raster = DisplayListRasterSource::CreateFromDisplayListRecordingSource(
+ recording_source_light.get(), false);
+
+ // We're going to playback from alpha(18) white rectangle into a smaller area
+ // of the recording resulting in a smaller lighter white rectangle over a
+ // darker white background rectangle.
+ playback_rect = gfx::Rect(
+ gfx::ToCeiledSize(gfx::ScaleSize(partial_bounds, contents_scale)));
+ raster->PlaybackToCanvas(&canvas, raster_full_rect, playback_rect,
+ contents_scale);
+
+ // Test that the whole playback_rect was cleared and repainted with new alpha.
+ SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels());
+ for (int i = 0; i < playback_rect.width(); ++i) {
+ for (int j = 0; j < playback_rect.height(); ++j) {
+ SCOPED_TRACE(j);
+ SCOPED_TRACE(i);
+ EXPECT_EQ(alpha_light, SkColorGetA(pixels[i + j * bitmap.width()]));
+ EXPECT_EQ(alpha_light, SkColorGetR(pixels[i + j * bitmap.width()]));
+ EXPECT_EQ(alpha_light, SkColorGetG(pixels[i + j * bitmap.width()]));
+ EXPECT_EQ(alpha_light, SkColorGetB(pixels[i + j * bitmap.width()]));
+ }
+ }
+}
+
+TEST(DisplayListRasterSourceTest, RasterContentsTransparent) {
+ gfx::Size layer_bounds(5, 3);
+ float contents_scale = 0.5f;
+
+ scoped_ptr<FakeDisplayListRecordingSource> recording_source =
+ FakeDisplayListRecordingSource::CreateFilledRecordingSource(layer_bounds);
+ recording_source->SetBackgroundColor(SK_ColorTRANSPARENT);
+ recording_source->SetRequiresClear(true);
+ recording_source->SetClearCanvasWithDebugColor(false);
+ recording_source->Rerecord();
+
+ scoped_refptr<DisplayListRasterSource> raster =
+ DisplayListRasterSource::CreateFromDisplayListRecordingSource(
+ recording_source.get(), false);
+ gfx::Size content_bounds(
+ gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale)));
+
+ gfx::Rect canvas_rect(content_bounds);
+ canvas_rect.Inset(0, 0, -1, -1);
+
+ SkBitmap bitmap;
+ bitmap.allocN32Pixels(canvas_rect.width(), canvas_rect.height());
+ SkCanvas canvas(bitmap);
+
+ raster->PlaybackToCanvas(&canvas, canvas_rect, canvas_rect, contents_scale);
+
+ SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels());
+ int num_pixels = bitmap.width() * bitmap.height();
+ for (int i = 0; i < num_pixels; ++i) {
+ EXPECT_EQ(SkColorGetA(pixels[i]), 0u);
+ }
+}
+
+} // namespace
+} // namespace cc
diff --git a/chromium/cc/playback/display_list_recording_source.cc b/chromium/cc/playback/display_list_recording_source.cc
index 9d6e31f26c7..e88343cb6b7 100644
--- a/chromium/cc/playback/display_list_recording_source.cc
+++ b/chromium/cc/playback/display_list_recording_source.cc
@@ -6,6 +6,7 @@
#include <algorithm>
+#include "cc/base/histograms.h"
#include "cc/base/region.h"
#include "cc/layers/content_layer_client.h"
#include "cc/playback/display_item_list.h"
@@ -22,18 +23,34 @@ const int kPixelDistanceToRecord = 8000;
// operations.
const int kOpCountThatIsOkToAnalyze = 10;
+// This is the distance, in layer space, by which the recorded viewport has to
+// change before causing a paint of the new content. For example, it means
+// that one has to scroll a very large page by 512 pixels before we will
+// re-record a new DisplayItemList for an updated recorded viewport.
+const int kMinimumDistanceBeforeUpdatingRecordedViewport = 512;
+
+#ifdef NDEBUG
+const bool kDefaultClearCanvasSetting = false;
+#else
+const bool kDefaultClearCanvasSetting = true;
+#endif
+
+DEFINE_SCOPED_UMA_HISTOGRAM_AREA_TIMER(
+ ScopedDisplayListRecordingSourceUpdateTimer,
+ "Compositing.DisplayListRecordingSource.UpdateUs",
+ "Compositing.DisplayListRecordingSource.UpdateInvalidatedAreaPerMs");
+
} // namespace
namespace cc {
DisplayListRecordingSource::DisplayListRecordingSource(
- const gfx::Size& grid_cell_size,
- bool use_cached_picture)
- : use_cached_picture_(use_cached_picture),
- slow_down_raster_scale_factor_for_debug_(0),
+ const gfx::Size& grid_cell_size)
+ : slow_down_raster_scale_factor_for_debug_(0),
gather_pixel_refs_(false),
requires_clear_(false),
is_solid_color_(false),
+ clear_canvas_with_debug_color_(kDefaultClearCanvasSetting),
solid_color_(SK_ColorTRANSPARENT),
background_color_(SK_ColorTRANSPARENT),
pixel_record_distance_(kPixelDistanceToRecord),
@@ -44,6 +61,54 @@ DisplayListRecordingSource::DisplayListRecordingSource(
DisplayListRecordingSource::~DisplayListRecordingSource() {
}
+// This method only really makes sense to call if the size of the layer didn't
+// change.
+bool DisplayListRecordingSource::ExposesEnoughNewArea(
+ const gfx::Rect& current_recorded_viewport,
+ const gfx::Rect& potential_new_recorded_viewport,
+ const gfx::Size& layer_size) {
+ // If both are empty, nothing to do.
+ if (current_recorded_viewport.IsEmpty() &&
+ potential_new_recorded_viewport.IsEmpty())
+ return false;
+
+ // Re-record when going from empty to not-empty, to cover cases where
+ // the layer is recorded for the first time, or otherwise becomes visible.
+ if (current_recorded_viewport.IsEmpty())
+ return true;
+
+ // Re-record if the new viewport includes area outside of a skirt around the
+ // existing viewport.
+ gfx::Rect expanded_viewport(current_recorded_viewport);
+ expanded_viewport.Inset(-kMinimumDistanceBeforeUpdatingRecordedViewport,
+ -kMinimumDistanceBeforeUpdatingRecordedViewport);
+ if (!expanded_viewport.Contains(potential_new_recorded_viewport))
+ return true;
+
+ // Even if the new viewport doesn't include enough new area to satisfy the
+ // condition above, re-record anyway if touches a layer edge not touched by
+ // the existing viewport. Viewports are clipped to layer boundaries, so if the
+ // new viewport touches a layer edge not touched by the existing viewport,
+ // the new viewport must expose new area that touches this layer edge. Since
+ // this new area touches a layer edge, it's impossible to expose more area in
+ // that direction, so recording cannot be deferred until the exposed new area
+ // satisfies the condition above.
+ if (potential_new_recorded_viewport.x() == 0 &&
+ current_recorded_viewport.x() != 0)
+ return true;
+ if (potential_new_recorded_viewport.y() == 0 &&
+ current_recorded_viewport.y() != 0)
+ return true;
+ if (potential_new_recorded_viewport.right() == layer_size.width() &&
+ current_recorded_viewport.right() != layer_size.width())
+ return true;
+ if (potential_new_recorded_viewport.bottom() == layer_size.height() &&
+ current_recorded_viewport.bottom() != layer_size.height())
+ return true;
+
+ return false;
+}
+
bool DisplayListRecordingSource::UpdateAndExpandInvalidation(
ContentLayerClient* painter,
Region* invalidation,
@@ -51,6 +116,7 @@ bool DisplayListRecordingSource::UpdateAndExpandInvalidation(
const gfx::Rect& visible_layer_rect,
int frame_number,
RecordingMode recording_mode) {
+ ScopedDisplayListRecordingSourceUpdateTimer timer;
bool updated = false;
if (size_ != layer_size) {
@@ -58,12 +124,20 @@ bool DisplayListRecordingSource::UpdateAndExpandInvalidation(
updated = true;
}
- gfx::Rect old_recorded_viewport = recorded_viewport_;
- recorded_viewport_ = visible_layer_rect;
- recorded_viewport_.Inset(-pixel_record_distance_, -pixel_record_distance_);
- recorded_viewport_.Intersect(gfx::Rect(GetSize()));
+ // The recorded viewport is the visible layer rect, expanded
+ // by the pixel record distance, up to a maximum of the total
+ // layer size.
+ gfx::Rect potential_new_recorded_viewport = visible_layer_rect;
+ potential_new_recorded_viewport.Inset(-pixel_record_distance_,
+ -pixel_record_distance_);
+ potential_new_recorded_viewport.Intersect(gfx::Rect(GetSize()));
+
+ if (updated ||
+ ExposesEnoughNewArea(recorded_viewport_, potential_new_recorded_viewport,
+ GetSize())) {
+ gfx::Rect old_recorded_viewport = recorded_viewport_;
+ recorded_viewport_ = potential_new_recorded_viewport;
- if (recorded_viewport_ != old_recorded_viewport) {
// Invalidate newly-exposed and no-longer-exposed areas.
Region newly_exposed_region(recorded_viewport_);
newly_exposed_region.Subtract(old_recorded_viewport);
@@ -76,6 +150,12 @@ bool DisplayListRecordingSource::UpdateAndExpandInvalidation(
updated = true;
}
+ // Count the area that is being invalidated.
+ Region recorded_invalidation(*invalidation);
+ recorded_invalidation.Intersect(recorded_viewport_);
+ for (Region::Iterator it(recorded_invalidation); it.has_rect(); it.next())
+ timer.AddArea(it.rect().size().GetArea());
+
if (!updated && !invalidation->Intersects(recorded_viewport_))
return false;
@@ -105,15 +185,11 @@ bool DisplayListRecordingSource::UpdateAndExpandInvalidation(
repeat_count = slow_down_raster_scale_factor_for_debug_;
painting_control = ContentLayerClient::DISPLAY_LIST_CACHING_DISABLED;
}
+
for (int i = 0; i < repeat_count; ++i) {
- display_list_ =
- DisplayItemList::Create(recorded_viewport_, use_cached_picture_);
- painter->PaintContentsToDisplayList(display_list_.get(), recorded_viewport_,
- painting_control);
+ display_list_ = painter->PaintContentsToDisplayList(recorded_viewport_,
+ painting_control);
}
- display_list_->ProcessAppendedItems();
- if (use_cached_picture_)
- display_list_->CreateAndCacheSkPicture();
is_suitable_for_gpu_rasterization_ =
display_list_->IsSuitableForGpuRasterization();
@@ -179,7 +255,7 @@ void DisplayListRecordingSource::DetermineIfSolidColor() {
gfx::Size layer_size = GetSize();
skia::AnalysisCanvas canvas(layer_size.width(), layer_size.height());
- display_list_->Raster(&canvas, nullptr, 1.f);
+ display_list_->Raster(&canvas, nullptr, gfx::Rect(), 1.f);
is_solid_color_ = canvas.GetColorIfSolid(&solid_color_);
}
diff --git a/chromium/cc/playback/display_list_recording_source.h b/chromium/cc/playback/display_list_recording_source.h
index 8d652fa67de..8d4e52f0cc3 100644
--- a/chromium/cc/playback/display_list_recording_source.h
+++ b/chromium/cc/playback/display_list_recording_source.h
@@ -14,8 +14,7 @@ class DisplayListRasterSource;
class CC_EXPORT DisplayListRecordingSource : public RecordingSource {
public:
- DisplayListRecordingSource(const gfx::Size& grid_cell_size,
- bool use_cached_picture);
+ explicit DisplayListRecordingSource(const gfx::Size& grid_cell_size);
~DisplayListRecordingSource() override;
// RecordingSource overrides.
@@ -36,18 +35,25 @@ class CC_EXPORT DisplayListRecordingSource : public RecordingSource {
bool IsSuitableForGpuRasterization() const override;
void SetUnsuitableForGpuRasterizationForTesting() override;
gfx::Size GetTileGridSizeForTesting() const override;
+ // Returns true if the new recorded viewport exposes enough new area to be
+ // worth re-recording.
+ static bool ExposesEnoughNewArea(
+ const gfx::Rect& current_recorded_viewport,
+ const gfx::Rect& potential_new_recorded_viewport,
+ const gfx::Size& layer_size);
+
+ gfx::Rect recorded_viewport() const { return recorded_viewport_; }
protected:
void Clear();
- const bool use_cached_picture_;
-
gfx::Rect recorded_viewport_;
gfx::Size size_;
int slow_down_raster_scale_factor_for_debug_;
bool gather_pixel_refs_;
bool requires_clear_;
bool is_solid_color_;
+ bool clear_canvas_with_debug_color_;
SkColor solid_color_;
SkColor background_color_;
int pixel_record_distance_;
diff --git a/chromium/cc/playback/display_list_recording_source_unittest.cc b/chromium/cc/playback/display_list_recording_source_unittest.cc
index 0d7ec7c74f1..0ddfb6fc5c8 100644
--- a/chromium/cc/playback/display_list_recording_source_unittest.cc
+++ b/chromium/cc/playback/display_list_recording_source_unittest.cc
@@ -4,7 +4,9 @@
#include <vector>
+#include "cc/base/region.h"
#include "cc/playback/display_list_raster_source.h"
+#include "cc/test/fake_content_layer_client.h"
#include "cc/test/fake_display_list_recording_source.h"
#include "cc/test/skia_common.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -12,12 +14,18 @@
namespace cc {
namespace {
-TEST(DisplayListRecordingSourceTest, DiscardablePixelRefsWithTransform) {
+class DisplayListRecordingSourceTest : public testing::Test {
+ public:
+ void SetUp() override {}
+};
+
+TEST_F(DisplayListRecordingSourceTest, DiscardablePixelRefsWithTransform) {
gfx::Size grid_cell_size(128, 128);
- gfx::Rect recorded_viewport(0, 0, 256, 256);
+ gfx::Rect recorded_viewport(256, 256);
scoped_ptr<FakeDisplayListRecordingSource> recording_source =
- FakeDisplayListRecordingSource::CreateRecordingSource(recorded_viewport);
+ FakeDisplayListRecordingSource::CreateFilledRecordingSource(
+ recorded_viewport.size());
recording_source->SetGridCellSize(grid_cell_size);
SkBitmap discardable_bitmap[2][2];
gfx::Transform identity_transform;
@@ -161,5 +169,137 @@ TEST(DisplayListRecordingSourceTest, DiscardablePixelRefsWithTransform) {
}
}
+TEST_F(DisplayListRecordingSourceTest, ExposesEnoughNewAreaEmpty) {
+ gfx::Size layer_size(1000, 1000);
+
+ // Both empty means there is nothing to do.
+ EXPECT_FALSE(DisplayListRecordingSource::ExposesEnoughNewArea(
+ gfx::Rect(), gfx::Rect(), layer_size));
+ // Going from empty to non-empty means we must re-record because it could be
+ // the first frame after construction or Clear.
+ EXPECT_TRUE(DisplayListRecordingSource::ExposesEnoughNewArea(
+ gfx::Rect(), gfx::Rect(1, 1), layer_size));
+
+ // Going from non-empty to empty is not special-cased.
+ EXPECT_FALSE(DisplayListRecordingSource::ExposesEnoughNewArea(
+ gfx::Rect(1, 1), gfx::Rect(), layer_size));
+}
+
+TEST_F(DisplayListRecordingSourceTest, ExposesEnoughNewAreaNotBigEnough) {
+ gfx::Size layer_size(1000, 1000);
+ gfx::Rect current_recorded_viewport(100, 100, 100, 100);
+ EXPECT_FALSE(DisplayListRecordingSource::ExposesEnoughNewArea(
+ current_recorded_viewport, gfx::Rect(100, 100, 90, 90), layer_size));
+ EXPECT_FALSE(DisplayListRecordingSource::ExposesEnoughNewArea(
+ current_recorded_viewport, gfx::Rect(100, 100, 100, 100), layer_size));
+ EXPECT_FALSE(DisplayListRecordingSource::ExposesEnoughNewArea(
+ current_recorded_viewport, gfx::Rect(1, 1, 200, 200), layer_size));
+}
+
+TEST_F(DisplayListRecordingSourceTest,
+ ExposesEnoughNewAreaNotBigEnoughButNewAreaTouchesEdge) {
+ gfx::Size layer_size(500, 500);
+ gfx::Rect current_recorded_viewport(100, 100, 100, 100);
+
+ // Top edge.
+ EXPECT_TRUE(DisplayListRecordingSource::ExposesEnoughNewArea(
+ current_recorded_viewport, gfx::Rect(100, 0, 100, 200), layer_size));
+
+ // Left edge.
+ EXPECT_TRUE(DisplayListRecordingSource::ExposesEnoughNewArea(
+ current_recorded_viewport, gfx::Rect(0, 100, 200, 100), layer_size));
+
+ // Bottom edge.
+ EXPECT_TRUE(DisplayListRecordingSource::ExposesEnoughNewArea(
+ current_recorded_viewport, gfx::Rect(100, 100, 100, 400), layer_size));
+
+ // Right edge.
+ EXPECT_TRUE(DisplayListRecordingSource::ExposesEnoughNewArea(
+ current_recorded_viewport, gfx::Rect(100, 100, 400, 100), layer_size));
+}
+
+// Verifies that having a current viewport that touches a layer edge does not
+// force re-recording.
+TEST_F(DisplayListRecordingSourceTest,
+ ExposesEnoughNewAreaCurrentViewportTouchesEdge) {
+ gfx::Size layer_size(500, 500);
+ gfx::Rect potential_new_viewport(100, 100, 300, 300);
+
+ // Top edge.
+ EXPECT_FALSE(DisplayListRecordingSource::ExposesEnoughNewArea(
+ gfx::Rect(100, 0, 100, 100), potential_new_viewport, layer_size));
+
+ // Left edge.
+ EXPECT_FALSE(DisplayListRecordingSource::ExposesEnoughNewArea(
+ gfx::Rect(0, 100, 100, 100), potential_new_viewport, layer_size));
+
+ // Bottom edge.
+ EXPECT_FALSE(DisplayListRecordingSource::ExposesEnoughNewArea(
+ gfx::Rect(300, 400, 100, 100), potential_new_viewport, layer_size));
+
+ // Right edge.
+ EXPECT_FALSE(DisplayListRecordingSource::ExposesEnoughNewArea(
+ gfx::Rect(400, 300, 100, 100), potential_new_viewport, layer_size));
+}
+
+TEST_F(DisplayListRecordingSourceTest, ExposesEnoughNewAreaScrollScenarios) {
+ gfx::Size layer_size(1000, 1000);
+ gfx::Rect current_recorded_viewport(100, 100, 100, 100);
+
+ gfx::Rect new_recorded_viewport(current_recorded_viewport);
+ new_recorded_viewport.Offset(512, 0);
+ EXPECT_FALSE(DisplayListRecordingSource::ExposesEnoughNewArea(
+ current_recorded_viewport, new_recorded_viewport, layer_size));
+ new_recorded_viewport.Offset(0, 512);
+ EXPECT_FALSE(DisplayListRecordingSource::ExposesEnoughNewArea(
+ current_recorded_viewport, new_recorded_viewport, layer_size));
+
+ new_recorded_viewport.Offset(1, 0);
+ EXPECT_TRUE(DisplayListRecordingSource::ExposesEnoughNewArea(
+ current_recorded_viewport, new_recorded_viewport, layer_size));
+
+ new_recorded_viewport.Offset(-1, 1);
+ EXPECT_TRUE(DisplayListRecordingSource::ExposesEnoughNewArea(
+ current_recorded_viewport, new_recorded_viewport, layer_size));
+}
+
+// Verifies that UpdateAndExpandInvalidation calls ExposesEnoughNewArea with the
+// right arguments.
+TEST_F(DisplayListRecordingSourceTest,
+ ExposesEnoughNewAreaCalledWithCorrectArguments) {
+ gfx::Size grid_cell_size(128, 128);
+ DisplayListRecordingSource recording_source(grid_cell_size);
+ FakeContentLayerClient client;
+ Region invalidation;
+ gfx::Size layer_size(9000, 9000);
+ gfx::Rect visible_rect(0, 0, 256, 256);
+
+ recording_source.UpdateAndExpandInvalidation(
+ &client, &invalidation, layer_size, visible_rect, 0,
+ RecordingSource::RECORD_NORMALLY);
+ EXPECT_EQ(gfx::Rect(0, 0, 8256, 8256), recording_source.recorded_viewport());
+
+ visible_rect.Offset(0, 512);
+ recording_source.UpdateAndExpandInvalidation(
+ &client, &invalidation, layer_size, visible_rect, 0,
+ RecordingSource::RECORD_NORMALLY);
+ EXPECT_EQ(gfx::Rect(0, 0, 8256, 8256), recording_source.recorded_viewport());
+
+ // Move past the threshold for enough exposed new area.
+ visible_rect.Offset(0, 1);
+ recording_source.UpdateAndExpandInvalidation(
+ &client, &invalidation, layer_size, visible_rect, 0,
+ RecordingSource::RECORD_NORMALLY);
+ EXPECT_EQ(gfx::Rect(0, 0, 8256, 8769), recording_source.recorded_viewport());
+
+ // Make the bottom of the potential new recorded viewport coincide with the
+ // layer's bottom edge.
+ visible_rect.Offset(0, 231);
+ recording_source.UpdateAndExpandInvalidation(
+ &client, &invalidation, layer_size, visible_rect, 0,
+ RecordingSource::RECORD_NORMALLY);
+ EXPECT_EQ(gfx::Rect(0, 0, 8256, 9000), recording_source.recorded_viewport());
+}
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/playback/drawing_display_item.cc b/chromium/cc/playback/drawing_display_item.cc
index 51cd42edf41..6cebed2ae00 100644
--- a/chromium/cc/playback/drawing_display_item.cc
+++ b/chromium/cc/playback/drawing_display_item.cc
@@ -10,10 +10,10 @@
#include "base/trace_event/trace_event_argument.h"
#include "cc/debug/picture_debug_util.h"
#include "third_party/skia/include/core/SkCanvas.h"
-#include "third_party/skia/include/core/SkDrawPictureCallback.h"
#include "third_party/skia/include/core/SkMatrix.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/utils/SkPictureUtils.h"
+#include "ui/gfx/skia_util.h"
namespace cc {
@@ -31,7 +31,18 @@ void DrawingDisplayItem::SetNew(skia::RefPtr<SkPicture> picture) {
}
void DrawingDisplayItem::Raster(SkCanvas* canvas,
- SkDrawPictureCallback* callback) const {
+ const gfx::Rect& canvas_target_playback_rect,
+ SkPicture::AbortCallback* callback) const {
+ // The canvas_playback_rect can be empty to signify no culling is desired.
+ if (!canvas_target_playback_rect.IsEmpty()) {
+ const SkMatrix& matrix = canvas->getTotalMatrix();
+ const SkRect& cull_rect = picture_->cullRect();
+ SkRect target_rect;
+ matrix.mapRect(&target_rect, cull_rect);
+ if (!target_rect.intersect(gfx::RectToSkRect(canvas_target_playback_rect)))
+ return;
+ }
+
// SkPicture always does a wrapping save/restore on the canvas, so it is not
// necessary here.
if (callback)
diff --git a/chromium/cc/playback/drawing_display_item.h b/chromium/cc/playback/drawing_display_item.h
index 81ddbce4f11..f94e7c9ca6e 100644
--- a/chromium/cc/playback/drawing_display_item.h
+++ b/chromium/cc/playback/drawing_display_item.h
@@ -12,7 +12,6 @@
#include "ui/gfx/geometry/point_f.h"
class SkCanvas;
-class SkDrawPictureCallback;
class SkPicture;
namespace cc {
@@ -24,7 +23,9 @@ class CC_EXPORT DrawingDisplayItem : public DisplayItem {
void SetNew(skia::RefPtr<SkPicture> picture);
- void Raster(SkCanvas* canvas, SkDrawPictureCallback* callback) const override;
+ void Raster(SkCanvas* canvas,
+ const gfx::Rect& canvas_playback_rect,
+ SkPicture::AbortCallback* callback) const override;
void AsValueInto(base::trace_event::TracedValue* array) const override;
void CloneTo(DrawingDisplayItem* item) const;
diff --git a/chromium/cc/playback/filter_display_item.cc b/chromium/cc/playback/filter_display_item.cc
index 8e849cf6009..fbed01509c8 100644
--- a/chromium/cc/playback/filter_display_item.cc
+++ b/chromium/cc/playback/filter_display_item.cc
@@ -27,14 +27,16 @@ void FilterDisplayItem::SetNew(const FilterOperations& filters,
filters_ = filters;
bounds_ = bounds;
- size_t memory_usage =
- sizeof(skia::RefPtr<SkImageFilter>) + sizeof(gfx::RectF);
+ // FilterOperations doesn't expose its capacity, but size is probably good
+ // enough.
+ size_t external_memory_usage = filters_.size() * sizeof(filters_.at(0));
DisplayItem::SetNew(true /* suitable_for_gpu_raster */, 1 /* op_count */,
- memory_usage);
+ external_memory_usage);
}
void FilterDisplayItem::Raster(SkCanvas* canvas,
- SkDrawPictureCallback* callback) const {
+ const gfx::Rect& canvas_target_playback_rect,
+ SkPicture::AbortCallback* callback) const {
canvas->save();
canvas->translate(bounds_.x(), bounds_.y());
@@ -61,14 +63,15 @@ void FilterDisplayItem::AsValueInto(
EndFilterDisplayItem::EndFilterDisplayItem() {
DisplayItem::SetNew(true /* suitable_for_gpu_raster */, 0 /* op_count */,
- 0 /* memory_usage */);
+ 0 /* external_memory_usage */);
}
EndFilterDisplayItem::~EndFilterDisplayItem() {
}
void EndFilterDisplayItem::Raster(SkCanvas* canvas,
- SkDrawPictureCallback* callback) const {
+ const gfx::Rect& canvas_target_playback_rect,
+ SkPicture::AbortCallback* callback) const {
canvas->restore();
canvas->restore();
}
diff --git a/chromium/cc/playback/filter_display_item.h b/chromium/cc/playback/filter_display_item.h
index a999b3883bf..9672878752a 100644
--- a/chromium/cc/playback/filter_display_item.h
+++ b/chromium/cc/playback/filter_display_item.h
@@ -12,7 +12,6 @@
#include "ui/gfx/geometry/rect_f.h"
class SkCanvas;
-class SkDrawPictureCallback;
namespace cc {
@@ -23,7 +22,9 @@ class CC_EXPORT FilterDisplayItem : public DisplayItem {
void SetNew(const FilterOperations& filters, const gfx::RectF& bounds);
- void Raster(SkCanvas* canvas, SkDrawPictureCallback* callback) const override;
+ void Raster(SkCanvas* canvas,
+ const gfx::Rect& canvas_target_playback_rect,
+ SkPicture::AbortCallback* callback) const override;
void AsValueInto(base::trace_event::TracedValue* array) const override;
private:
@@ -40,7 +41,9 @@ class CC_EXPORT EndFilterDisplayItem : public DisplayItem {
return make_scoped_ptr(new EndFilterDisplayItem());
}
- void Raster(SkCanvas* canvas, SkDrawPictureCallback* callback) const override;
+ void Raster(SkCanvas* canvas,
+ const gfx::Rect& canvas_target_playback_rect,
+ SkPicture::AbortCallback* callback) const override;
void AsValueInto(base::trace_event::TracedValue* array) const override;
};
diff --git a/chromium/cc/playback/float_clip_display_item.cc b/chromium/cc/playback/float_clip_display_item.cc
index 0f368a65770..8b29fc214c5 100644
--- a/chromium/cc/playback/float_clip_display_item.cc
+++ b/chromium/cc/playback/float_clip_display_item.cc
@@ -20,13 +20,13 @@ FloatClipDisplayItem::~FloatClipDisplayItem() {
void FloatClipDisplayItem::SetNew(const gfx::RectF& clip_rect) {
clip_rect_ = clip_rect;
- size_t memory_usage = sizeof(gfx::RectF);
DisplayItem::SetNew(true /* suitable_for_gpu_raster */, 1 /* op_count */,
- memory_usage);
+ 0 /* external_memory_usage */);
}
void FloatClipDisplayItem::Raster(SkCanvas* canvas,
- SkDrawPictureCallback* callback) const {
+ const gfx::Rect& canvas_target_playback_rect,
+ SkPicture::AbortCallback* callback) const {
canvas->save();
canvas->clipRect(gfx::RectFToSkRect(clip_rect_));
}
@@ -39,14 +39,16 @@ void FloatClipDisplayItem::AsValueInto(
EndFloatClipDisplayItem::EndFloatClipDisplayItem() {
DisplayItem::SetNew(true /* suitable_for_gpu_raster */, 0 /* op_count */,
- 0 /* memory_usage */);
+ 0 /* external_memory_usage */);
}
EndFloatClipDisplayItem::~EndFloatClipDisplayItem() {
}
-void EndFloatClipDisplayItem::Raster(SkCanvas* canvas,
- SkDrawPictureCallback* callback) const {
+void EndFloatClipDisplayItem::Raster(
+ SkCanvas* canvas,
+ const gfx::Rect& canvas_target_playback_rect,
+ SkPicture::AbortCallback* callback) const {
canvas->restore();
}
diff --git a/chromium/cc/playback/float_clip_display_item.h b/chromium/cc/playback/float_clip_display_item.h
index 2812189ff61..13d637f85a3 100644
--- a/chromium/cc/playback/float_clip_display_item.h
+++ b/chromium/cc/playback/float_clip_display_item.h
@@ -13,7 +13,6 @@
#include "ui/gfx/geometry/rect_f.h"
class SkCanvas;
-class SkDrawPictureCallback;
namespace cc {
@@ -24,7 +23,9 @@ class CC_EXPORT FloatClipDisplayItem : public DisplayItem {
void SetNew(const gfx::RectF& clip_rect);
- void Raster(SkCanvas* canvas, SkDrawPictureCallback* callback) const override;
+ void Raster(SkCanvas* canvas,
+ const gfx::Rect& canvas_target_playback_rect,
+ SkPicture::AbortCallback* callback) const override;
void AsValueInto(base::trace_event::TracedValue* array) const override;
private:
@@ -40,7 +41,9 @@ class CC_EXPORT EndFloatClipDisplayItem : public DisplayItem {
return make_scoped_ptr(new EndFloatClipDisplayItem());
}
- void Raster(SkCanvas* canvas, SkDrawPictureCallback* callback) const override;
+ void Raster(SkCanvas* canvas,
+ const gfx::Rect& canvas_target_playback_rect,
+ SkPicture::AbortCallback* callback) const override;
void AsValueInto(base::trace_event::TracedValue* array) const override;
};
diff --git a/chromium/cc/playback/picture.cc b/chromium/cc/playback/picture.cc
index 4537bf72107..8ce9c66ff8f 100644
--- a/chromium/cc/playback/picture.cc
+++ b/chromium/cc/playback/picture.cc
@@ -12,14 +12,12 @@
#include "base/trace_event/trace_event_argument.h"
#include "base/values.h"
#include "cc/base/math_util.h"
-#include "cc/base/util.h"
#include "cc/debug/picture_debug_util.h"
#include "cc/debug/traced_picture.h"
#include "cc/debug/traced_value.h"
#include "cc/layers/content_layer_client.h"
#include "skia/ext/pixel_ref_utils.h"
#include "third_party/skia/include/core/SkCanvas.h"
-#include "third_party/skia/include/core/SkDrawPictureCallback.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
#include "third_party/skia/include/core/SkStream.h"
diff --git a/chromium/cc/playback/picture_pile.cc b/chromium/cc/playback/picture_pile.cc
index b7b2822195b..55a5f80997a 100644
--- a/chromium/cc/playback/picture_pile.cc
+++ b/chromium/cc/playback/picture_pile.cc
@@ -8,6 +8,7 @@
#include <limits>
#include <vector>
+#include "cc/base/histograms.h"
#include "cc/base/region.h"
#include "cc/playback/picture_pile_impl.h"
#include "skia/ext/analysis_canvas.h"
@@ -149,6 +150,11 @@ const bool kDefaultClearCanvasSetting = false;
const bool kDefaultClearCanvasSetting = true;
#endif
+DEFINE_SCOPED_UMA_HISTOGRAM_AREA_TIMER(
+ ScopedPicturePileUpdateTimer,
+ "Compositing.PicturePile.UpdateUs",
+ "Compositing.PicturePile.UpdateInvalidatedAreaPerMs");
+
} // namespace
namespace cc {
@@ -181,6 +187,8 @@ bool PicturePile::UpdateAndExpandInvalidation(
const gfx::Rect& visible_layer_rect,
int frame_number,
RecordingSource::RecordingMode recording_mode) {
+ ScopedPicturePileUpdateTimer timer;
+
gfx::Rect interest_rect = visible_layer_rect;
interest_rect.Inset(-pixel_record_distance_, -pixel_record_distance_);
recorded_viewport_ = interest_rect;
@@ -188,6 +196,13 @@ bool PicturePile::UpdateAndExpandInvalidation(
bool updated = ApplyInvalidationAndResize(interest_rect, invalidation,
layer_size, frame_number);
+
+ // Count the area that is being invalidated.
+ Region recorded_invalidation(*invalidation);
+ recorded_invalidation.Intersect(recorded_viewport_);
+ for (Region::Iterator it(recorded_invalidation); it.has_rect(); it.next())
+ timer.AddArea(it.rect().size().GetArea());
+
std::vector<gfx::Rect> invalid_tiles;
GetInvalidTileRects(interest_rect, &invalid_tiles);
std::vector<gfx::Rect> record_rects;
diff --git a/chromium/cc/playback/picture_pile_impl.cc b/chromium/cc/playback/picture_pile_impl.cc
index 96c6f63addb..345c24c7093 100644
--- a/chromium/cc/playback/picture_pile_impl.cc
+++ b/chromium/cc/playback/picture_pile_impl.cc
@@ -100,12 +100,14 @@ void PicturePileImpl::RasterForAnalysis(skia::AnalysisCanvas* canvas,
}
void PicturePileImpl::PlaybackToCanvas(SkCanvas* canvas,
- const gfx::Rect& canvas_rect,
+ const gfx::Rect& canvas_bitmap_rect,
+ const gfx::Rect& canvas_playback_rect,
float contents_scale) const {
RasterSourceHelper::PrepareForPlaybackToCanvas(
- canvas, canvas_rect, gfx::Rect(tiling_.tiling_size()), contents_scale,
- background_color_, clear_canvas_with_debug_color_, requires_clear_);
- RasterCommon(canvas, NULL, canvas_rect, contents_scale);
+ canvas, canvas_bitmap_rect, canvas_bitmap_rect,
+ gfx::Rect(tiling_.tiling_size()), contents_scale, background_color_,
+ clear_canvas_with_debug_color_, requires_clear_);
+ RasterCommon(canvas, NULL, canvas_bitmap_rect, contents_scale);
}
void PicturePileImpl::CoalesceRasters(const gfx::Rect& canvas_rect,
@@ -202,7 +204,7 @@ void PicturePileImpl::CoalesceRasters(const gfx::Rect& canvas_rect,
}
void PicturePileImpl::RasterCommon(SkCanvas* canvas,
- SkDrawPictureCallback* callback,
+ SkPicture::AbortCallback* callback,
const gfx::Rect& canvas_rect,
float contents_scale) const {
DCHECK(contents_scale >= min_contents_scale_);
@@ -266,7 +268,7 @@ skia::RefPtr<SkPicture> PicturePileImpl::GetFlattenedPicture() {
SkCanvas* canvas =
recorder.beginRecording(tiling_rect.width(), tiling_rect.height());
if (!tiling_rect.IsEmpty())
- PlaybackToCanvas(canvas, tiling_rect, 1.0);
+ PlaybackToCanvas(canvas, tiling_rect, tiling_rect, 1.0);
skia::RefPtr<SkPicture> picture =
skia::AdoptRef(recorder.endRecordingAsPicture());
diff --git a/chromium/cc/playback/picture_pile_impl.h b/chromium/cc/playback/picture_pile_impl.h
index e8be323225a..0e1164b2dff 100644
--- a/chromium/cc/playback/picture_pile_impl.h
+++ b/chromium/cc/playback/picture_pile_impl.h
@@ -39,7 +39,8 @@ class CC_EXPORT PicturePileImpl : public RasterSource {
// reported rasterize time (in stats_instrumentation) is the minimum measured
// value over all runs.
void PlaybackToCanvas(SkCanvas* canvas,
- const gfx::Rect& canvas_rect,
+ const gfx::Rect& canvas_bitmap_rect,
+ const gfx::Rect& canvas_playback_rect,
float contents_scale) const override;
void PlaybackToSharedCanvas(SkCanvas* canvas,
const gfx::Rect& canvas_rect,
@@ -130,7 +131,7 @@ class CC_EXPORT PicturePileImpl : public RasterSource {
typedef std::map<const Picture*, Region> PictureRegionMap;
// Called when analyzing a tile. We can use AnalysisCanvas as
- // SkDrawPictureCallback, which allows us to early out from analysis.
+ // SkPicture::AbortCallback, which allows us to early out from analysis.
void RasterForAnalysis(skia::AnalysisCanvas* canvas,
const gfx::Rect& canvas_rect,
float contents_scale) const;
@@ -141,7 +142,7 @@ class CC_EXPORT PicturePileImpl : public RasterSource {
PictureRegionMap* result) const;
void RasterCommon(SkCanvas* canvas,
- SkDrawPictureCallback* callback,
+ SkPicture::AbortCallback* callback,
const gfx::Rect& canvas_rect,
float contents_scale) const;
diff --git a/chromium/cc/playback/picture_pile_impl_perftest.cc b/chromium/cc/playback/picture_pile_impl_perftest.cc
index a70fe68ebde..e1560400f22 100644
--- a/chromium/cc/playback/picture_pile_impl_perftest.cc
+++ b/chromium/cc/playback/picture_pile_impl_perftest.cc
@@ -55,7 +55,8 @@ class PicturePileImplPerfTest : public testing::Test {
timer_.Reset();
do {
- pile->PlaybackToCanvas(&canvas, content_rect, contents_scale);
+ pile->PlaybackToCanvas(&canvas, content_rect, content_rect,
+ contents_scale);
timer_.NextLap();
} while (!timer_.HasTimeLimitExpired());
diff --git a/chromium/cc/playback/picture_pile_impl_unittest.cc b/chromium/cc/playback/picture_pile_impl_unittest.cc
index 14b06eecd5d..81c2aec4713 100644
--- a/chromium/cc/playback/picture_pile_impl_unittest.cc
+++ b/chromium/cc/playback/picture_pile_impl_unittest.cc
@@ -345,7 +345,7 @@ TEST(PicturePileImplTest, RasterFullContents) {
SkCanvas canvas(bitmap);
canvas.clear(SK_ColorTRANSPARENT);
- pile->PlaybackToCanvas(&canvas, canvas_rect, contents_scale);
+ pile->PlaybackToCanvas(&canvas, canvas_rect, canvas_rect, contents_scale);
SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels());
int num_pixels = bitmap.width() * bitmap.height();
@@ -390,7 +390,7 @@ TEST(PicturePileImpl, RasterContentsTransparent) {
bitmap.allocN32Pixels(canvas_rect.width(), canvas_rect.height());
SkCanvas canvas(bitmap);
- pile->PlaybackToCanvas(&canvas, canvas_rect, contents_scale);
+ pile->PlaybackToCanvas(&canvas, canvas_rect, canvas_rect, contents_scale);
SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels());
int num_pixels = bitmap.width() * bitmap.height();
@@ -437,7 +437,8 @@ TEST_P(OverlapTest, NoOverlap) {
bitmap.allocN32Pixels(content_bounds.width(), content_bounds.height());
SkCanvas canvas(bitmap);
- pile->PlaybackToCanvas(&canvas, gfx::Rect(content_bounds), contents_scale);
+ pile->PlaybackToCanvas(&canvas, gfx::Rect(content_bounds),
+ gfx::Rect(content_bounds), contents_scale);
for (int y = 0; y < bitmap.height(); y++) {
for (int x = 0; x < bitmap.width(); x++) {
diff --git a/chromium/cc/playback/pixel_ref_map.cc b/chromium/cc/playback/pixel_ref_map.cc
index bb5a84c37b5..a5c8f05f453 100644
--- a/chromium/cc/playback/pixel_ref_map.cc
+++ b/chromium/cc/playback/pixel_ref_map.cc
@@ -7,7 +7,7 @@
#include <algorithm>
#include <limits>
-#include "cc/base/util.h"
+#include "cc/base/math_util.h"
#include "cc/playback/display_item_list.h"
#include "cc/playback/picture.h"
#include "skia/ext/pixel_ref_utils.h"
@@ -33,15 +33,16 @@ void PixelRefMap::GatherPixelRefsFromPicture(SkPicture* picture) {
skia::PixelRefUtils::GatherDiscardablePixelRefs(picture, &pixel_refs);
for (skia::DiscardablePixelRefList::const_iterator it = pixel_refs.begin();
it != pixel_refs.end(); ++it) {
- gfx::Point min(
- RoundDown(static_cast<int>(it->pixel_ref_rect.x()), cell_size_.width()),
- RoundDown(static_cast<int>(it->pixel_ref_rect.y()),
- cell_size_.height()));
- gfx::Point max(
- RoundDown(static_cast<int>(std::ceil(it->pixel_ref_rect.right())),
- cell_size_.width()),
- RoundDown(static_cast<int>(std::ceil(it->pixel_ref_rect.bottom())),
- cell_size_.height()));
+ gfx::Point min(MathUtil::RoundDown(static_cast<int>(it->pixel_ref_rect.x()),
+ cell_size_.width()),
+ MathUtil::RoundDown(static_cast<int>(it->pixel_ref_rect.y()),
+ cell_size_.height()));
+ gfx::Point max(MathUtil::RoundDown(
+ static_cast<int>(std::ceil(it->pixel_ref_rect.right())),
+ cell_size_.width()),
+ MathUtil::RoundDown(
+ static_cast<int>(std::ceil(it->pixel_ref_rect.bottom())),
+ cell_size_.height()));
for (int y = min.y(); y <= max.y(); y += cell_size_.height()) {
for (int x = min.x(); x <= max.x(); x += cell_size_.width()) {
@@ -147,11 +148,12 @@ void PixelRefMap::Iterator::PointToFirstPixelRef(const gfx::Rect& rect) {
gfx::Size cell_size(target_pixel_ref_map_->cell_size_);
// We have to find a cell_size aligned point that corresponds to
// query_rect. Point is a multiple of cell_size.
- min_point_ = gfx::Point(RoundDown(query_rect.x(), cell_size.width()),
- RoundDown(query_rect.y(), cell_size.height()));
- max_point_ =
- gfx::Point(RoundDown(query_rect.right() - 1, cell_size.width()),
- RoundDown(query_rect.bottom() - 1, cell_size.height()));
+ min_point_ =
+ gfx::Point(MathUtil::RoundDown(query_rect.x(), cell_size.width()),
+ MathUtil::RoundDown(query_rect.y(), cell_size.height()));
+ max_point_ = gfx::Point(
+ MathUtil::RoundDown(query_rect.right() - 1, cell_size.width()),
+ MathUtil::RoundDown(query_rect.bottom() - 1, cell_size.height()));
// Limit the points to known pixel ref boundaries.
min_point_ = gfx::Point(
diff --git a/chromium/cc/playback/raster_source.h b/chromium/cc/playback/raster_source.h
index c0a484aa8d9..8d0356fae38 100644
--- a/chromium/cc/playback/raster_source.h
+++ b/chromium/cc/playback/raster_source.h
@@ -41,7 +41,8 @@ class CC_EXPORT RasterSource : public base::RefCountedThreadSafe<RasterSource> {
// It is assumed that the canvas passed here will only be rasterized by
// this raster source via this call.
virtual void PlaybackToCanvas(SkCanvas* canvas,
- const gfx::Rect& canvas_rect,
+ const gfx::Rect& canvas_bitmap_rect,
+ const gfx::Rect& canvas_playback_rect,
float contents_scale) const = 0;
// Similar to above, except that the canvas passed here can (or was already)
diff --git a/chromium/cc/playback/raster_source_helper.cc b/chromium/cc/playback/raster_source_helper.cc
index 6510b3c0e78..bd5edda07c3 100644
--- a/chromium/cc/playback/raster_source_helper.cc
+++ b/chromium/cc/playback/raster_source_helper.cc
@@ -14,16 +14,28 @@ namespace cc {
void RasterSourceHelper::PrepareForPlaybackToCanvas(
SkCanvas* canvas,
- const gfx::Rect& canvas_rect,
+ const gfx::Rect& canvas_bitmap_rect,
+ const gfx::Rect& canvas_playback_rect,
const gfx::Rect& source_rect,
float contents_scale,
SkColor background_color,
bool clear_canvas_with_debug_color,
bool requires_clear) {
- canvas->discard();
+ bool partial_update = canvas_bitmap_rect != canvas_playback_rect;
+
+ if (!partial_update)
+ canvas->discard();
if (clear_canvas_with_debug_color) {
// Any non-painted areas in the content bounds will be left in this color.
- canvas->clear(DebugColors::NonPaintedFillColor());
+ if (!partial_update) {
+ canvas->clear(DebugColors::NonPaintedFillColor());
+ } else {
+ canvas->save();
+ canvas->clipRect(gfx::RectToSkRect(
+ canvas_playback_rect - canvas_bitmap_rect.OffsetFromOrigin()));
+ canvas->drawColor(DebugColors::NonPaintedFillColor());
+ canvas->restore();
+ }
}
// If this raster source has opaque contents, it is guaranteeing that it will
@@ -33,7 +45,15 @@ void RasterSourceHelper::PrepareForPlaybackToCanvas(
TRACE_EVENT_INSTANT0("cc", "SkCanvas::clear", TRACE_EVENT_SCOPE_THREAD);
// Clearing is about ~4x faster than drawing a rect even if the content
// isn't covering a majority of the canvas.
- canvas->clear(SK_ColorTRANSPARENT);
+ if (!partial_update) {
+ canvas->clear(SK_ColorTRANSPARENT);
+ } else {
+ canvas->save();
+ canvas->clipRect(gfx::RectToSkRect(
+ canvas_playback_rect - canvas_bitmap_rect.OffsetFromOrigin()));
+ canvas->drawColor(SK_ColorTRANSPARENT, SkXfermode::kClear_Mode);
+ canvas->restore();
+ }
} else {
// Even if completely covered, for rasterizations that touch the edge of the
// layer, we also need to raster the background color underneath the last
@@ -47,14 +67,15 @@ void RasterSourceHelper::PrepareForPlaybackToCanvas(
// covered by content.
gfx::Rect deflated_content_rect = content_rect;
deflated_content_rect.Inset(0, 0, 1, 1);
- if (!deflated_content_rect.Contains(canvas_rect)) {
+ deflated_content_rect.Intersect(canvas_playback_rect);
+ if (!deflated_content_rect.Contains(canvas_playback_rect)) {
if (clear_canvas_with_debug_color) {
// Any non-painted areas outside of the content bounds are left in
// this color. If this is seen then it means that cc neglected to
// rerasterize a tile that used to intersect with the content rect
// after the content bounds grew.
canvas->save();
- canvas->translate(-canvas_rect.x(), -canvas_rect.y());
+ canvas->translate(-canvas_bitmap_rect.x(), -canvas_bitmap_rect.y());
canvas->clipRect(gfx::RectToSkRect(content_rect),
SkRegion::kDifference_Op);
canvas->drawColor(DebugColors::MissingResizeInvalidations(),
@@ -65,9 +86,12 @@ void RasterSourceHelper::PrepareForPlaybackToCanvas(
// Drawing at most 2 x 2 x (canvas width + canvas height) texels is 2-3X
// faster than clearing, so special case this.
canvas->save();
- canvas->translate(-canvas_rect.x(), -canvas_rect.y());
+ canvas->translate(-canvas_bitmap_rect.x(), -canvas_bitmap_rect.y());
gfx::Rect inflated_content_rect = content_rect;
+ // Only clear edges that will be inside the canvas_playback_rect, else we
+ // clear things that are still valid from a previous raster.
inflated_content_rect.Inset(0, 0, -1, -1);
+ inflated_content_rect.Intersect(canvas_playback_rect);
canvas->clipRect(gfx::RectToSkRect(inflated_content_rect),
SkRegion::kReplace_Op);
canvas->clipRect(gfx::RectToSkRect(deflated_content_rect),
diff --git a/chromium/cc/playback/raster_source_helper.h b/chromium/cc/playback/raster_source_helper.h
index 30513030351..9918703cd1f 100644
--- a/chromium/cc/playback/raster_source_helper.h
+++ b/chromium/cc/playback/raster_source_helper.h
@@ -16,7 +16,8 @@ namespace cc {
class CC_EXPORT RasterSourceHelper {
public:
static void PrepareForPlaybackToCanvas(SkCanvas* canvas,
- const gfx::Rect& canvas_rect,
+ const gfx::Rect& canvas_bitmap_rect,
+ const gfx::Rect& canvas_playback_rect,
const gfx::Rect& source_rect,
float contents_scale,
SkColor background_color,
diff --git a/chromium/cc/playback/recording_source_unittest.cc b/chromium/cc/playback/recording_source_unittest.cc
index 01a89a19ba3..f1506e32ec8 100644
--- a/chromium/cc/playback/recording_source_unittest.cc
+++ b/chromium/cc/playback/recording_source_unittest.cc
@@ -8,7 +8,6 @@
#include "cc/test/fake_display_list_recording_source.h"
#include "cc/test/fake_picture_pile.h"
#include "cc/test/fake_picture_pile_impl.h"
-#include "cc/test/impl_side_painting_settings.h"
#include "cc/test/skia_common.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -30,8 +29,10 @@ template <>
scoped_ptr<FakeDisplayListRecordingSource> CreateRecordingSource<
FakeDisplayListRecordingSource>(const gfx::Rect& viewport,
const gfx::Size& grid_cell_size) {
+ gfx::Rect layer_rect(viewport.right(), viewport.bottom());
scoped_ptr<FakeDisplayListRecordingSource> recording_source =
- FakeDisplayListRecordingSource::CreateRecordingSource(viewport);
+ FakeDisplayListRecordingSource::CreateRecordingSource(viewport,
+ layer_rect.size());
recording_source->SetGridCellSize(grid_cell_size);
return recording_source.Pass();
diff --git a/chromium/cc/playback/transform_display_item.cc b/chromium/cc/playback/transform_display_item.cc
index 1f4e5dbd733..df7ca1b8e56 100644
--- a/chromium/cc/playback/transform_display_item.cc
+++ b/chromium/cc/playback/transform_display_item.cc
@@ -20,13 +20,13 @@ TransformDisplayItem::~TransformDisplayItem() {
void TransformDisplayItem::SetNew(const gfx::Transform& transform) {
transform_ = transform;
- size_t memory_usage = sizeof(gfx::Transform);
DisplayItem::SetNew(true /* suitable_for_gpu_raster */, 1 /* op_count */,
- memory_usage);
+ 0 /* external_memory_usage */);
}
void TransformDisplayItem::Raster(SkCanvas* canvas,
- SkDrawPictureCallback* callback) const {
+ const gfx::Rect& canvas_target_playback_rect,
+ SkPicture::AbortCallback* callback) const {
canvas->save();
if (!transform_.IsIdentity())
canvas->concat(transform_.matrix());
@@ -40,14 +40,16 @@ void TransformDisplayItem::AsValueInto(
EndTransformDisplayItem::EndTransformDisplayItem() {
DisplayItem::SetNew(true /* suitable_for_gpu_raster */, 0 /* op_count */,
- 0 /* memory_usage */);
+ 0 /* external_memory_usage */);
}
EndTransformDisplayItem::~EndTransformDisplayItem() {
}
-void EndTransformDisplayItem::Raster(SkCanvas* canvas,
- SkDrawPictureCallback* callback) const {
+void EndTransformDisplayItem::Raster(
+ SkCanvas* canvas,
+ const gfx::Rect& canvas_target_playback_rect,
+ SkPicture::AbortCallback* callback) const {
canvas->restore();
}
diff --git a/chromium/cc/playback/transform_display_item.h b/chromium/cc/playback/transform_display_item.h
index 731249d338e..9d3f9c6da46 100644
--- a/chromium/cc/playback/transform_display_item.h
+++ b/chromium/cc/playback/transform_display_item.h
@@ -11,7 +11,6 @@
#include "ui/gfx/transform.h"
class SkCanvas;
-class SkDrawPictureCallback;
namespace cc {
@@ -22,7 +21,9 @@ class CC_EXPORT TransformDisplayItem : public DisplayItem {
void SetNew(const gfx::Transform& transform);
- void Raster(SkCanvas* canvas, SkDrawPictureCallback* callback) const override;
+ void Raster(SkCanvas* canvas,
+ const gfx::Rect& canvas_target_playback_rect,
+ SkPicture::AbortCallback* callback) const override;
void AsValueInto(base::trace_event::TracedValue* array) const override;
private:
@@ -38,7 +39,9 @@ class CC_EXPORT EndTransformDisplayItem : public DisplayItem {
return make_scoped_ptr(new EndTransformDisplayItem());
}
- void Raster(SkCanvas* canvas, SkDrawPictureCallback* callback) const override;
+ void Raster(SkCanvas* canvas,
+ const gfx::Rect& canvas_target_playback_rect,
+ SkPicture::AbortCallback* callback) const override;
void AsValueInto(base::trace_event::TracedValue* array) const override;
};
diff --git a/chromium/cc/quads/checkerboard_draw_quad.cc b/chromium/cc/quads/checkerboard_draw_quad.cc
index db6ad1ea356..4cd3c2aa18b 100644
--- a/chromium/cc/quads/checkerboard_draw_quad.cc
+++ b/chromium/cc/quads/checkerboard_draw_quad.cc
@@ -39,9 +39,6 @@ void CheckerboardDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
this->scale = scale;
}
-void CheckerboardDrawQuad::IterateResources(
- const ResourceIteratorCallback& callback) {}
-
const CheckerboardDrawQuad* CheckerboardDrawQuad::MaterialCast(
const DrawQuad* quad) {
DCHECK(quad->material == DrawQuad::CHECKERBOARD);
diff --git a/chromium/cc/quads/checkerboard_draw_quad.h b/chromium/cc/quads/checkerboard_draw_quad.h
index 9ecf4f0fe23..fe793675a27 100644
--- a/chromium/cc/quads/checkerboard_draw_quad.h
+++ b/chromium/cc/quads/checkerboard_draw_quad.h
@@ -33,8 +33,6 @@ class CC_EXPORT CheckerboardDrawQuad : public DrawQuad {
SkColor color;
float scale;
- void IterateResources(const ResourceIteratorCallback& callback) override;
-
static const CheckerboardDrawQuad* MaterialCast(const DrawQuad*);
private:
diff --git a/chromium/cc/quads/debug_border_draw_quad.cc b/chromium/cc/quads/debug_border_draw_quad.cc
index f91bf3b84bf..529075aa9de 100644
--- a/chromium/cc/quads/debug_border_draw_quad.cc
+++ b/chromium/cc/quads/debug_border_draw_quad.cc
@@ -41,9 +41,6 @@ void DebugBorderDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
this->width = width;
}
-void DebugBorderDrawQuad::IterateResources(
- const ResourceIteratorCallback& callback) {}
-
const DebugBorderDrawQuad* DebugBorderDrawQuad::MaterialCast(
const DrawQuad* quad) {
DCHECK(quad->material == DrawQuad::DEBUG_BORDER);
diff --git a/chromium/cc/quads/debug_border_draw_quad.h b/chromium/cc/quads/debug_border_draw_quad.h
index 7ee0d82f2d9..7023ab23b5d 100644
--- a/chromium/cc/quads/debug_border_draw_quad.h
+++ b/chromium/cc/quads/debug_border_draw_quad.h
@@ -33,8 +33,6 @@ class CC_EXPORT DebugBorderDrawQuad : public DrawQuad {
SkColor color;
int width;
- void IterateResources(const ResourceIteratorCallback& callback) override;
-
static const DebugBorderDrawQuad* MaterialCast(const DrawQuad*);
private:
diff --git a/chromium/cc/quads/draw_polygon.cc b/chromium/cc/quads/draw_polygon.cc
index 6544b641acb..cdb94d0e33b 100644
--- a/chromium/cc/quads/draw_polygon.cc
+++ b/chromium/cc/quads/draw_polygon.cc
@@ -52,7 +52,7 @@ DrawPolygon::DrawPolygon(const DrawQuad* original,
// a visible content rect to make the 4 corner points from, and a transformation
// to move it and its normal into screen space.
DrawPolygon::DrawPolygon(const DrawQuad* original_ref,
- const gfx::RectF& visible_content_rect,
+ const gfx::RectF& visible_layer_rect,
const gfx::Transform& transform,
int draw_order_index)
: normal_(0.0f, 0.0f, 1.0f),
@@ -61,7 +61,7 @@ DrawPolygon::DrawPolygon(const DrawQuad* original_ref,
is_split_(false) {
gfx::Point3F points[8];
int num_vertices_in_clipped_quad;
- gfx::QuadF send_quad(visible_content_rect);
+ gfx::QuadF send_quad(visible_layer_rect);
// Doing this mapping here is very important, since we can't just transform
// the points without clipping and not run into strange geometry issues when
diff --git a/chromium/cc/quads/draw_polygon.h b/chromium/cc/quads/draw_polygon.h
index b94ff1ef777..93c36024fc2 100644
--- a/chromium/cc/quads/draw_polygon.h
+++ b/chromium/cc/quads/draw_polygon.h
@@ -29,7 +29,7 @@ class CC_EXPORT DrawPolygon {
const gfx::Vector3dF& normal,
int draw_order_index = 0);
DrawPolygon(const DrawQuad* original_ref,
- const gfx::RectF& visible_content_rect,
+ const gfx::RectF& visible_layer_rect,
const gfx::Transform& transform,
int draw_order_index = 0);
diff --git a/chromium/cc/quads/draw_quad.cc b/chromium/cc/quads/draw_quad.cc
index ac1b43e6c20..606d7ab6058 100644
--- a/chromium/cc/quads/draw_quad.cc
+++ b/chromium/cc/quads/draw_quad.cc
@@ -62,10 +62,9 @@ void DrawQuad::AsValueInto(base::trace_event::TracedValue* value) const {
MathUtil::AddToTracedValue("content_space_rect", rect, value);
bool rect_is_clipped;
- gfx::QuadF rect_as_target_space_quad = MathUtil::MapQuad(
- shared_quad_state->content_to_target_transform,
- gfx::QuadF(rect),
- &rect_is_clipped);
+ gfx::QuadF rect_as_target_space_quad =
+ MathUtil::MapQuad(shared_quad_state->quad_to_target_transform,
+ gfx::QuadF(rect), &rect_is_clipped);
MathUtil::AddToTracedValue("rect_as_target_space_quad",
rect_as_target_space_quad, value);
@@ -74,10 +73,9 @@ void DrawQuad::AsValueInto(base::trace_event::TracedValue* value) const {
MathUtil::AddToTracedValue("content_space_opaque_rect", opaque_rect, value);
bool opaque_rect_is_clipped;
- gfx::QuadF opaque_rect_as_target_space_quad = MathUtil::MapQuad(
- shared_quad_state->content_to_target_transform,
- gfx::QuadF(opaque_rect),
- &opaque_rect_is_clipped);
+ gfx::QuadF opaque_rect_as_target_space_quad =
+ MathUtil::MapQuad(shared_quad_state->quad_to_target_transform,
+ gfx::QuadF(opaque_rect), &opaque_rect_is_clipped);
MathUtil::AddToTracedValue("opaque_rect_as_target_space_quad",
opaque_rect_as_target_space_quad, value);
@@ -86,10 +84,9 @@ void DrawQuad::AsValueInto(base::trace_event::TracedValue* value) const {
MathUtil::AddToTracedValue("content_space_visible_rect", visible_rect, value);
bool visible_rect_is_clipped;
- gfx::QuadF visible_rect_as_target_space_quad = MathUtil::MapQuad(
- shared_quad_state->content_to_target_transform,
- gfx::QuadF(visible_rect),
- &visible_rect_is_clipped);
+ gfx::QuadF visible_rect_as_target_space_quad =
+ MathUtil::MapQuad(shared_quad_state->quad_to_target_transform,
+ gfx::QuadF(visible_rect), &visible_rect_is_clipped);
MathUtil::AddToTracedValue("visible_rect_as_target_space_quad",
visible_rect_as_target_space_quad, value);
@@ -101,4 +98,9 @@ void DrawQuad::AsValueInto(base::trace_event::TracedValue* value) const {
ExtendValue(value);
}
+DrawQuad::Resources::Resources() : count(0) {
+ for (size_t i = 0; i < kMaxResourceIdCount; ++i)
+ ids[i] = 0;
+}
+
} // namespace cc
diff --git a/chromium/cc/quads/draw_quad.h b/chromium/cc/quads/draw_quad.h
index 3897d1d1ce8..df3bc1213f5 100644
--- a/chromium/cc/quads/draw_quad.h
+++ b/chromium/cc/quads/draw_quad.h
@@ -7,8 +7,8 @@
#include "base/callback.h"
#include "cc/base/cc_export.h"
+#include "cc/base/resource_id.h"
#include "cc/quads/shared_quad_state.h"
-#include "cc/resources/resource_provider.h"
namespace base {
namespace trace_event {
@@ -27,10 +27,10 @@ namespace cc {
// Note: quads contain rects and sizes, which live in different spaces. There is
// the "content space", which is the arbitrary space in which the quad's
// geometry is defined (generally related to the layer that produced the quad,
-// e.g. the content space for TiledLayerImpls, or the geometry space for
-// PictureLayerImpls). There is also the "target space", which is the space, in
-// "physical" pixels, of the render target where the quads is drawn. The quad's
-// transform maps the content space to the target space.
+// e.g. the geometry space for PictureLayerImpls or the layer's coordinate space
+// for most other layers). There is also the "target space", which is the space,
+// in "physical" pixels, of the render target where the quads is drawn. The
+// quad's transform maps the content space to the target space.
class CC_EXPORT DrawQuad {
public:
enum Material {
@@ -51,17 +51,6 @@ class CC_EXPORT DrawQuad {
virtual ~DrawQuad();
- // TODO(danakj): Chromify or remove these SharedQuadState helpers.
- const gfx::Transform& quadTransform() const {
- return shared_quad_state->content_to_target_transform;
- }
- gfx::Rect visibleContentRect() const {
- return shared_quad_state->visible_content_rect;
- }
- gfx::Rect clipRect() const { return shared_quad_state->clip_rect; }
- bool isClipped() const { return shared_quad_state->is_clipped; }
- float opacity() const { return shared_quad_state->opacity; }
-
Material material;
// This rect, after applying the quad_transform(), gives the geometry that
@@ -96,10 +85,6 @@ class CC_EXPORT DrawQuad {
return !opaque_rect.Contains(visible_rect);
}
- typedef ResourceProvider::ResourceId ResourceId;
- typedef base::Callback<ResourceId(ResourceId)> ResourceIteratorCallback;
- virtual void IterateResources(const ResourceIteratorCallback& callback) = 0;
-
// Is the left edge of this tile aligned with the originating layer's
// left edge?
bool IsLeftEdge() const { return !rect.x(); }
@@ -111,13 +96,13 @@ class CC_EXPORT DrawQuad {
// Is the right edge of this tile aligned with the originating layer's
// right edge?
bool IsRightEdge() const {
- return rect.right() == shared_quad_state->content_bounds.width();
+ return rect.right() == shared_quad_state->quad_layer_bounds.width();
}
// Is the bottom edge of this tile aligned with the originating layer's
// bottom edge?
bool IsBottomEdge() const {
- return rect.bottom() == shared_quad_state->content_bounds.height();
+ return rect.bottom() == shared_quad_state->quad_layer_bounds.height();
}
// Is any edge of this tile aligned with the originating layer's
@@ -128,6 +113,22 @@ class CC_EXPORT DrawQuad {
void AsValueInto(base::trace_event::TracedValue* value) const;
+ struct CC_EXPORT Resources {
+ enum : size_t { kMaxResourceIdCount = 4 };
+ Resources();
+
+ ResourceId* begin() { return ids; }
+ ResourceId* end() {
+ DCHECK_LE(count, kMaxResourceIdCount);
+ return ids + count;
+ }
+
+ size_t count;
+ ResourceId ids[kMaxResourceIdCount];
+ };
+
+ Resources resources;
+
protected:
DrawQuad();
diff --git a/chromium/cc/quads/draw_quad_perftest.cc b/chromium/cc/quads/draw_quad_perftest.cc
new file mode 100644
index 00000000000..08ce6d07b29
--- /dev/null
+++ b/chromium/cc/quads/draw_quad_perftest.cc
@@ -0,0 +1,113 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <vector>
+
+#include "base/bind.h"
+#include "base/time/time.h"
+#include "cc/debug/lap_timer.h"
+#include "cc/quads/draw_quad.h"
+#include "cc/quads/render_pass.h"
+#include "cc/quads/texture_draw_quad.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/perf/perf_test.h"
+
+namespace cc {
+namespace {
+
+static const int kTimeLimitMillis = 2000;
+static const int kWarmupRuns = 5;
+static const int kTimeCheckInterval = 10;
+
+SharedQuadState* CreateSharedQuadState(RenderPass* render_pass) {
+ gfx::Transform quad_transform = gfx::Transform(1.0, 0.0, 0.5, 1.0, 0.5, 0.0);
+ gfx::Size content_bounds(26, 28);
+ gfx::Rect visible_layer_rect(10, 12, 14, 16);
+ gfx::Rect clip_rect(19, 21, 23, 25);
+ bool is_clipped = false;
+ float opacity = 1.f;
+ int sorting_context_id = 65536;
+ SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
+
+ SharedQuadState* state = render_pass->CreateAndAppendSharedQuadState();
+ state->SetAll(quad_transform, content_bounds, visible_layer_rect, clip_rect,
+ is_clipped, opacity, blend_mode, sorting_context_id);
+ return state;
+}
+
+class DrawQuadPerfTest : public testing::Test {
+ public:
+ DrawQuadPerfTest()
+ : timer_(kWarmupRuns,
+ base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
+ kTimeCheckInterval) {}
+
+ void CreateRenderPass() {
+ render_pass_ = RenderPass::Create();
+ SharedQuadState* new_shared_state(
+ CreateSharedQuadState(render_pass_.get()));
+ shared_state_ = render_pass_->CreateAndAppendSharedQuadState();
+ shared_state_->CopyFrom(new_shared_state);
+ }
+
+ void CleanUpRenderPass() {
+ render_pass_.reset();
+ shared_state_ = nullptr;
+ }
+
+ void GenerateTextureDrawQuads(int count, std::vector<DrawQuad*>* quads) {
+ for (int i = 0; i < count; ++i) {
+ TextureDrawQuad* quad =
+ render_pass_->CreateAndAppendDrawQuad<TextureDrawQuad>();
+ gfx::Rect rect(0, 0, 100, 100);
+ ResourceId resource_id = 1;
+ bool premultiplied_alpha = true;
+ gfx::PointF uv_top_left(0, 0);
+ gfx::PointF uv_bottom_right(1, 1);
+ SkColor background_color = SK_ColorRED;
+ float vertex_opacity[4] = {1.f, 1.f, 1.f, 1.f};
+ bool y_flipped = false;
+ bool nearest_neighbor = true;
+
+ quad->SetNew(shared_state_, rect, rect, rect, resource_id,
+ premultiplied_alpha, uv_top_left, uv_bottom_right,
+ background_color, vertex_opacity, y_flipped,
+ nearest_neighbor);
+ quads->push_back(quad);
+ }
+ }
+
+ void RunIterateResourceTest(const std::string& test_name, int quad_count) {
+ CreateRenderPass();
+ std::vector<DrawQuad*> quads;
+ GenerateTextureDrawQuads(quad_count, &quads);
+
+ timer_.Reset();
+ do {
+ for (auto* quad : quads) {
+ for (ResourceId& resource_id : quad->resources)
+ ++resource_id;
+ }
+ timer_.NextLap();
+ } while (!timer_.HasTimeLimitExpired());
+
+ perf_test::PrintResult("draw_quad_iterate_resources", "", test_name,
+ timer_.LapsPerSecond(), "runs/s", true);
+ CleanUpRenderPass();
+ }
+
+ private:
+ scoped_ptr<RenderPass> render_pass_;
+ SharedQuadState* shared_state_;
+ LapTimer timer_;
+};
+
+TEST_F(DrawQuadPerfTest, IterateResources) {
+ RunIterateResourceTest("10_quads", 10);
+ RunIterateResourceTest("100_quads", 100);
+ RunIterateResourceTest("500_quads", 500);
+}
+
+} // namespace
+} // namespace cc
diff --git a/chromium/cc/quads/draw_quad_unittest.cc b/chromium/cc/quads/draw_quad_unittest.cc
index 968a1d059fc..833f388aafb 100644
--- a/chromium/cc/quads/draw_quad_unittest.cc
+++ b/chromium/cc/quads/draw_quad_unittest.cc
@@ -34,8 +34,8 @@ namespace {
TEST(DrawQuadTest, CopySharedQuadState) {
gfx::Transform quad_transform = gfx::Transform(1.0, 0.0, 0.5, 1.0, 0.5, 0.0);
- gfx::Size content_bounds(26, 28);
- gfx::Rect visible_content_rect(10, 12, 14, 16);
+ gfx::Size layer_bounds(26, 28);
+ gfx::Rect visible_layer_rect(10, 12, 14, 16);
gfx::Rect clip_rect(19, 21, 23, 25);
bool is_clipped = true;
float opacity = 0.25f;
@@ -43,19 +43,13 @@ TEST(DrawQuadTest, CopySharedQuadState) {
int sorting_context_id = 65536;
scoped_ptr<SharedQuadState> state(new SharedQuadState);
- state->SetAll(quad_transform,
- content_bounds,
- visible_content_rect,
- clip_rect,
- is_clipped,
- opacity,
- blend_mode,
- sorting_context_id);
+ state->SetAll(quad_transform, layer_bounds, visible_layer_rect, clip_rect,
+ is_clipped, opacity, blend_mode, sorting_context_id);
scoped_ptr<SharedQuadState> copy(new SharedQuadState);
copy->CopyFrom(state.get());
- EXPECT_EQ(quad_transform, copy->content_to_target_transform);
- EXPECT_EQ(visible_content_rect, copy->visible_content_rect);
+ EXPECT_EQ(quad_transform, copy->quad_to_target_transform);
+ EXPECT_EQ(visible_layer_rect, copy->visible_quad_layer_rect);
EXPECT_EQ(opacity, copy->opacity);
EXPECT_EQ(clip_rect, copy->clip_rect);
EXPECT_EQ(is_clipped, copy->is_clipped);
@@ -64,8 +58,8 @@ TEST(DrawQuadTest, CopySharedQuadState) {
SharedQuadState* CreateSharedQuadState(RenderPass* render_pass) {
gfx::Transform quad_transform = gfx::Transform(1.0, 0.0, 0.5, 1.0, 0.5, 0.0);
- gfx::Size content_bounds(26, 28);
- gfx::Rect visible_content_rect(10, 12, 14, 16);
+ gfx::Size layer_bounds(26, 28);
+ gfx::Rect visible_layer_rect(10, 12, 14, 16);
gfx::Rect clip_rect(19, 21, 23, 25);
bool is_clipped = false;
float opacity = 1.f;
@@ -73,14 +67,8 @@ SharedQuadState* CreateSharedQuadState(RenderPass* render_pass) {
SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
SharedQuadState* state = render_pass->CreateAndAppendSharedQuadState();
- state->SetAll(quad_transform,
- content_bounds,
- visible_content_rect,
- clip_rect,
- is_clipped,
- opacity,
- blend_mode,
- sorting_context_id);
+ state->SetAll(quad_transform, layer_bounds, visible_layer_rect, clip_rect,
+ is_clipped, opacity, blend_mode, sorting_context_id);
return state;
}
@@ -330,6 +318,15 @@ void CompareDrawQuad(DrawQuad* quad,
} \
SETUP_AND_COPY_QUAD_NEW(Type, quad_new);
+#define CREATE_QUAD_10_ALL(Type, a, b, c, d, e, f, g, h, i, j) \
+ Type* quad_all = render_pass->CreateAndAppendDrawQuad<Type>(); \
+ { \
+ QUAD_DATA quad_all->SetAll(shared_state, quad_rect, quad_opaque_rect, \
+ quad_visible_rect, needs_blending, a, b, c, d, \
+ e, f, g, h, i, j); \
+ } \
+ SETUP_AND_COPY_QUAD_ALL(Type, quad_all);
+
#define CREATE_QUAD_11_NEW(Type, a, b, c, d, e, f, g, h, i, j, k) \
Type* quad_new = render_pass->CreateAndAppendDrawQuad<Type>(); \
{ \
@@ -404,7 +401,7 @@ TEST(DrawQuadTest, CopyIOSurfaceDrawQuad) {
gfx::Rect opaque_rect(33, 47, 10, 12);
gfx::Rect visible_rect(40, 50, 30, 20);
gfx::Size size(58, 95);
- ResourceProvider::ResourceId resource_id = 72;
+ ResourceId resource_id = 72;
IOSurfaceDrawQuad::Orientation orientation = IOSurfaceDrawQuad::UNFLIPPED;
CREATE_SHARED_STATE();
@@ -418,20 +415,20 @@ TEST(DrawQuadTest, CopyIOSurfaceDrawQuad) {
EXPECT_EQ(visible_rect, copy_quad->visible_rect);
EXPECT_EQ(opaque_rect, copy_quad->opaque_rect);
EXPECT_EQ(size, copy_quad->io_surface_size);
- EXPECT_EQ(resource_id, copy_quad->io_surface_resource_id);
+ EXPECT_EQ(resource_id, copy_quad->io_surface_resource_id());
EXPECT_EQ(orientation, copy_quad->orientation);
CREATE_QUAD_3_ALL(IOSurfaceDrawQuad, size, resource_id, orientation);
EXPECT_EQ(DrawQuad::IO_SURFACE_CONTENT, copy_quad->material);
EXPECT_EQ(size, copy_quad->io_surface_size);
- EXPECT_EQ(resource_id, copy_quad->io_surface_resource_id);
+ EXPECT_EQ(resource_id, copy_quad->io_surface_resource_id());
EXPECT_EQ(orientation, copy_quad->orientation);
}
TEST(DrawQuadTest, CopyRenderPassDrawQuad) {
gfx::Rect visible_rect(40, 50, 30, 20);
RenderPassId render_pass_id(22, 64);
- ResourceProvider::ResourceId mask_resource_id = 78;
+ ResourceId mask_resource_id = 78;
gfx::Vector2dF mask_uv_scale(33.f, 19.f);
gfx::Size mask_texture_size(128, 134);
FilterOperations filters;
@@ -457,7 +454,7 @@ TEST(DrawQuadTest, CopyRenderPassDrawQuad) {
EXPECT_EQ(DrawQuad::RENDER_PASS, copy_quad->material);
EXPECT_EQ(visible_rect, copy_quad->visible_rect);
EXPECT_EQ(copied_render_pass_id, copy_quad->render_pass_id);
- EXPECT_EQ(mask_resource_id, copy_quad->mask_resource_id);
+ EXPECT_EQ(mask_resource_id, copy_quad->mask_resource_id());
EXPECT_EQ(mask_uv_scale.ToString(), copy_quad->mask_uv_scale.ToString());
EXPECT_EQ(mask_texture_size.ToString(),
copy_quad->mask_texture_size.ToString());
@@ -476,7 +473,7 @@ TEST(DrawQuadTest, CopyRenderPassDrawQuad) {
copied_render_pass_id);
EXPECT_EQ(DrawQuad::RENDER_PASS, copy_quad->material);
EXPECT_EQ(copied_render_pass_id, copy_quad->render_pass_id);
- EXPECT_EQ(mask_resource_id, copy_quad->mask_resource_id);
+ EXPECT_EQ(mask_resource_id, copy_quad->mask_resource_id());
EXPECT_EQ(mask_uv_scale.ToString(), copy_quad->mask_uv_scale.ToString());
EXPECT_EQ(mask_texture_size.ToString(),
copy_quad->mask_texture_size.ToString());
@@ -507,21 +504,28 @@ TEST(DrawQuadTest, CopySolidColorDrawQuad) {
TEST(DrawQuadTest, CopyStreamVideoDrawQuad) {
gfx::Rect opaque_rect(33, 47, 10, 12);
gfx::Rect visible_rect(40, 50, 30, 20);
- ResourceProvider::ResourceId resource_id = 64;
+ ResourceId resource_id = 64;
+ gfx::Size resource_size_in_pixels = gfx::Size(40, 41);
+ bool allow_overlay = true;
gfx::Transform matrix = gfx::Transform(0.5, 0.25, 1, 0.75, 0, 1);
CREATE_SHARED_STATE();
- CREATE_QUAD_4_NEW(
- StreamVideoDrawQuad, opaque_rect, visible_rect, resource_id, matrix);
+ CREATE_QUAD_6_NEW(StreamVideoDrawQuad, opaque_rect, visible_rect, resource_id,
+ resource_size_in_pixels, allow_overlay, matrix);
EXPECT_EQ(DrawQuad::STREAM_VIDEO_CONTENT, copy_quad->material);
EXPECT_EQ(visible_rect, copy_quad->visible_rect);
EXPECT_EQ(opaque_rect, copy_quad->opaque_rect);
- EXPECT_EQ(resource_id, copy_quad->resource_id);
+ EXPECT_EQ(resource_id, copy_quad->resource_id());
+ EXPECT_EQ(allow_overlay, copy_quad->allow_overlay());
+ EXPECT_EQ(resource_size_in_pixels, copy_quad->resource_size_in_pixels());
EXPECT_EQ(matrix, copy_quad->matrix);
- CREATE_QUAD_2_ALL(StreamVideoDrawQuad, resource_id, matrix);
+ CREATE_QUAD_4_ALL(StreamVideoDrawQuad, resource_id, resource_size_in_pixels,
+ allow_overlay, matrix);
EXPECT_EQ(DrawQuad::STREAM_VIDEO_CONTENT, copy_quad->material);
- EXPECT_EQ(resource_id, copy_quad->resource_id);
+ EXPECT_EQ(resource_id, copy_quad->resource_id());
+ EXPECT_EQ(allow_overlay, copy_quad->allow_overlay());
+ EXPECT_EQ(resource_size_in_pixels, copy_quad->resource_size_in_pixels());
EXPECT_EQ(matrix, copy_quad->matrix);
}
@@ -545,6 +549,8 @@ TEST(DrawQuadTest, CopyTextureDrawQuad) {
gfx::Rect opaque_rect(33, 47, 10, 12);
gfx::Rect visible_rect(40, 50, 30, 20);
unsigned resource_id = 82;
+ gfx::Size resource_size_in_pixels = gfx::Size(40, 41);
+ bool allow_overlay = true;
bool premultiplied_alpha = true;
gfx::PointF uv_top_left(0.5f, 224.f);
gfx::PointF uv_bottom_right(51.5f, 260.f);
@@ -567,7 +573,7 @@ TEST(DrawQuadTest, CopyTextureDrawQuad) {
EXPECT_EQ(DrawQuad::TEXTURE_CONTENT, copy_quad->material);
EXPECT_EQ(visible_rect, copy_quad->visible_rect);
EXPECT_EQ(opaque_rect, copy_quad->opaque_rect);
- EXPECT_EQ(resource_id, copy_quad->resource_id);
+ EXPECT_EQ(resource_id, copy_quad->resource_id());
EXPECT_EQ(premultiplied_alpha, copy_quad->premultiplied_alpha);
EXPECT_EQ(uv_top_left, copy_quad->uv_top_left);
EXPECT_EQ(uv_bottom_right, copy_quad->uv_bottom_right);
@@ -575,17 +581,14 @@ TEST(DrawQuadTest, CopyTextureDrawQuad) {
EXPECT_EQ(y_flipped, copy_quad->y_flipped);
EXPECT_EQ(nearest_neighbor, copy_quad->nearest_neighbor);
- CREATE_QUAD_8_ALL(TextureDrawQuad,
- resource_id,
- premultiplied_alpha,
- uv_top_left,
- uv_bottom_right,
- SK_ColorTRANSPARENT,
- vertex_opacity,
- y_flipped,
- nearest_neighbor);
+ CREATE_QUAD_10_ALL(TextureDrawQuad, resource_id, resource_size_in_pixels,
+ allow_overlay, premultiplied_alpha, uv_top_left,
+ uv_bottom_right, SK_ColorTRANSPARENT, vertex_opacity,
+ y_flipped, nearest_neighbor);
EXPECT_EQ(DrawQuad::TEXTURE_CONTENT, copy_quad->material);
- EXPECT_EQ(resource_id, copy_quad->resource_id);
+ EXPECT_EQ(resource_id, copy_quad->resource_id());
+ EXPECT_EQ(allow_overlay, copy_quad->allow_overlay());
+ EXPECT_EQ(resource_size_in_pixels, copy_quad->resource_size_in_pixels());
EXPECT_EQ(premultiplied_alpha, copy_quad->premultiplied_alpha);
EXPECT_EQ(uv_top_left, copy_quad->uv_top_left);
EXPECT_EQ(uv_bottom_right, copy_quad->uv_bottom_right);
@@ -615,7 +618,7 @@ TEST(DrawQuadTest, CopyTileDrawQuad) {
EXPECT_EQ(DrawQuad::TILED_CONTENT, copy_quad->material);
EXPECT_EQ(opaque_rect, copy_quad->opaque_rect);
EXPECT_EQ(visible_rect, copy_quad->visible_rect);
- EXPECT_EQ(resource_id, copy_quad->resource_id);
+ EXPECT_EQ(resource_id, copy_quad->resource_id());
EXPECT_EQ(tex_coord_rect, copy_quad->tex_coord_rect);
EXPECT_EQ(texture_size, copy_quad->texture_size);
EXPECT_EQ(swizzle_contents, copy_quad->swizzle_contents);
@@ -628,7 +631,7 @@ TEST(DrawQuadTest, CopyTileDrawQuad) {
swizzle_contents,
nearest_neighbor);
EXPECT_EQ(DrawQuad::TILED_CONTENT, copy_quad->material);
- EXPECT_EQ(resource_id, copy_quad->resource_id);
+ EXPECT_EQ(resource_id, copy_quad->resource_id());
EXPECT_EQ(tex_coord_rect, copy_quad->tex_coord_rect);
EXPECT_EQ(texture_size, copy_quad->texture_size);
EXPECT_EQ(swizzle_contents, copy_quad->swizzle_contents);
@@ -642,10 +645,10 @@ TEST(DrawQuadTest, CopyYUVVideoDrawQuad) {
gfx::RectF uv_tex_coord_rect(20, 25, 15, 10);
gfx::Size ya_tex_size(32, 68);
gfx::Size uv_tex_size(41, 51);
- ResourceProvider::ResourceId y_plane_resource_id = 45;
- ResourceProvider::ResourceId u_plane_resource_id = 532;
- ResourceProvider::ResourceId v_plane_resource_id = 4;
- ResourceProvider::ResourceId a_plane_resource_id = 63;
+ ResourceId y_plane_resource_id = 45;
+ ResourceId u_plane_resource_id = 532;
+ ResourceId v_plane_resource_id = 4;
+ ResourceId a_plane_resource_id = 63;
YUVVideoDrawQuad::ColorSpace color_space = YUVVideoDrawQuad::JPEG;
CREATE_SHARED_STATE();
@@ -660,10 +663,10 @@ TEST(DrawQuadTest, CopyYUVVideoDrawQuad) {
EXPECT_EQ(uv_tex_coord_rect, copy_quad->uv_tex_coord_rect);
EXPECT_EQ(ya_tex_size, copy_quad->ya_tex_size);
EXPECT_EQ(uv_tex_size, copy_quad->uv_tex_size);
- EXPECT_EQ(y_plane_resource_id, copy_quad->y_plane_resource_id);
- EXPECT_EQ(u_plane_resource_id, copy_quad->u_plane_resource_id);
- EXPECT_EQ(v_plane_resource_id, copy_quad->v_plane_resource_id);
- EXPECT_EQ(a_plane_resource_id, copy_quad->a_plane_resource_id);
+ EXPECT_EQ(y_plane_resource_id, copy_quad->y_plane_resource_id());
+ EXPECT_EQ(u_plane_resource_id, copy_quad->u_plane_resource_id());
+ EXPECT_EQ(v_plane_resource_id, copy_quad->v_plane_resource_id());
+ EXPECT_EQ(a_plane_resource_id, copy_quad->a_plane_resource_id());
EXPECT_EQ(color_space, copy_quad->color_space);
CREATE_QUAD_9_ALL(YUVVideoDrawQuad, ya_tex_coord_rect, uv_tex_coord_rect,
@@ -675,10 +678,10 @@ TEST(DrawQuadTest, CopyYUVVideoDrawQuad) {
EXPECT_EQ(uv_tex_coord_rect, copy_quad->uv_tex_coord_rect);
EXPECT_EQ(ya_tex_size, copy_quad->ya_tex_size);
EXPECT_EQ(uv_tex_size, copy_quad->uv_tex_size);
- EXPECT_EQ(y_plane_resource_id, copy_quad->y_plane_resource_id);
- EXPECT_EQ(u_plane_resource_id, copy_quad->u_plane_resource_id);
- EXPECT_EQ(v_plane_resource_id, copy_quad->v_plane_resource_id);
- EXPECT_EQ(a_plane_resource_id, copy_quad->a_plane_resource_id);
+ EXPECT_EQ(y_plane_resource_id, copy_quad->y_plane_resource_id());
+ EXPECT_EQ(u_plane_resource_id, copy_quad->u_plane_resource_id());
+ EXPECT_EQ(v_plane_resource_id, copy_quad->v_plane_resource_id());
+ EXPECT_EQ(a_plane_resource_id, copy_quad->a_plane_resource_id());
EXPECT_EQ(color_space, copy_quad->color_space);
}
@@ -725,16 +728,12 @@ TEST(DrawQuadTest, CopyPictureDrawQuad) {
class DrawQuadIteratorTest : public testing::Test {
protected:
- ResourceProvider::ResourceId IncrementResourceId(
- ResourceProvider::ResourceId id) {
- ++num_resources_;
- return id + 1;
- }
-
int IterateAndCount(DrawQuad* quad) {
num_resources_ = 0;
- quad->IterateResources(base::Bind(
- &DrawQuadIteratorTest::IncrementResourceId, base::Unretained(this)));
+ for (ResourceId& resource_id : quad->resources) {
+ ++num_resources_;
+ ++resource_id;
+ }
return num_resources_;
}
@@ -766,7 +765,7 @@ TEST_F(DrawQuadIteratorTest, IOSurfaceDrawQuad) {
gfx::Rect opaque_rect(33, 47, 10, 12);
gfx::Rect visible_rect(40, 50, 30, 20);
gfx::Size size(58, 95);
- ResourceProvider::ResourceId resource_id = 72;
+ ResourceId resource_id = 72;
IOSurfaceDrawQuad::Orientation orientation = IOSurfaceDrawQuad::UNFLIPPED;
CREATE_SHARED_STATE();
@@ -776,15 +775,15 @@ TEST_F(DrawQuadIteratorTest, IOSurfaceDrawQuad) {
size,
resource_id,
orientation);
- EXPECT_EQ(resource_id, quad_new->io_surface_resource_id);
+ EXPECT_EQ(resource_id, quad_new->io_surface_resource_id());
EXPECT_EQ(1, IterateAndCount(quad_new));
- EXPECT_EQ(resource_id + 1, quad_new->io_surface_resource_id);
+ EXPECT_EQ(resource_id + 1, quad_new->io_surface_resource_id());
}
TEST_F(DrawQuadIteratorTest, RenderPassDrawQuad) {
gfx::Rect visible_rect(40, 50, 30, 20);
RenderPassId render_pass_id(22, 64);
- ResourceProvider::ResourceId mask_resource_id = 78;
+ ResourceId mask_resource_id = 78;
gfx::Vector2dF mask_uv_scale(33.f, 19.f);
gfx::Size mask_texture_size(128, 134);
FilterOperations filters;
@@ -807,12 +806,17 @@ TEST_F(DrawQuadIteratorTest, RenderPassDrawQuad) {
filters_scale,
background_filters,
copied_render_pass_id);
- EXPECT_EQ(mask_resource_id, quad_new->mask_resource_id);
+ EXPECT_EQ(mask_resource_id, quad_new->mask_resource_id());
EXPECT_EQ(1, IterateAndCount(quad_new));
- EXPECT_EQ(mask_resource_id + 1, quad_new->mask_resource_id);
- quad_new->mask_resource_id = 0;
+ EXPECT_EQ(mask_resource_id + 1, quad_new->mask_resource_id());
+
+ ResourceId new_mask_resource_id = 0;
+ gfx::Rect quad_rect(30, 40, 50, 60);
+ quad_new->SetNew(shared_state, quad_rect, visible_rect, render_pass_id,
+ new_mask_resource_id, mask_uv_scale, mask_texture_size,
+ filters, filters_scale, background_filters);
EXPECT_EQ(0, IterateAndCount(quad_new));
- EXPECT_EQ(0u, quad_new->mask_resource_id);
+ EXPECT_EQ(0u, quad_new->mask_resource_id());
}
TEST_F(DrawQuadIteratorTest, SolidColorDrawQuad) {
@@ -829,15 +833,19 @@ TEST_F(DrawQuadIteratorTest, SolidColorDrawQuad) {
TEST_F(DrawQuadIteratorTest, StreamVideoDrawQuad) {
gfx::Rect opaque_rect(33, 47, 10, 12);
gfx::Rect visible_rect(40, 50, 30, 20);
- ResourceProvider::ResourceId resource_id = 64;
+ ResourceId resource_id = 64;
+ gfx::Size resource_size_in_pixels = gfx::Size(40, 41);
+ bool allow_overlay = true;
gfx::Transform matrix = gfx::Transform(0.5, 0.25, 1, 0.75, 0, 1);
CREATE_SHARED_STATE();
- CREATE_QUAD_4_NEW(
- StreamVideoDrawQuad, opaque_rect, visible_rect, resource_id, matrix);
- EXPECT_EQ(resource_id, quad_new->resource_id);
+ CREATE_QUAD_6_NEW(StreamVideoDrawQuad, opaque_rect, visible_rect, resource_id,
+ resource_size_in_pixels, allow_overlay, matrix);
+ EXPECT_EQ(resource_id, quad_new->resource_id());
+ EXPECT_EQ(allow_overlay, quad_new->allow_overlay());
+ EXPECT_EQ(resource_size_in_pixels, quad_new->resource_size_in_pixels());
EXPECT_EQ(1, IterateAndCount(quad_new));
- EXPECT_EQ(resource_id + 1, quad_new->resource_id);
+ EXPECT_EQ(resource_id + 1, quad_new->resource_id());
}
TEST_F(DrawQuadIteratorTest, SurfaceDrawQuad) {
@@ -872,9 +880,9 @@ TEST_F(DrawQuadIteratorTest, TextureDrawQuad) {
vertex_opacity,
y_flipped,
nearest_neighbor);
- EXPECT_EQ(resource_id, quad_new->resource_id);
+ EXPECT_EQ(resource_id, quad_new->resource_id());
EXPECT_EQ(1, IterateAndCount(quad_new));
- EXPECT_EQ(resource_id + 1, quad_new->resource_id);
+ EXPECT_EQ(resource_id + 1, quad_new->resource_id());
}
TEST_F(DrawQuadIteratorTest, TileDrawQuad) {
@@ -895,9 +903,9 @@ TEST_F(DrawQuadIteratorTest, TileDrawQuad) {
texture_size,
swizzle_contents,
nearest_neighbor);
- EXPECT_EQ(resource_id, quad_new->resource_id);
+ EXPECT_EQ(resource_id, quad_new->resource_id());
EXPECT_EQ(1, IterateAndCount(quad_new));
- EXPECT_EQ(resource_id + 1, quad_new->resource_id);
+ EXPECT_EQ(resource_id + 1, quad_new->resource_id());
}
TEST_F(DrawQuadIteratorTest, YUVVideoDrawQuad) {
@@ -907,10 +915,10 @@ TEST_F(DrawQuadIteratorTest, YUVVideoDrawQuad) {
gfx::RectF uv_tex_coord_rect(0.0f, 0.0f, 0.375f, 0.25f);
gfx::Size ya_tex_size(32, 68);
gfx::Size uv_tex_size(41, 51);
- ResourceProvider::ResourceId y_plane_resource_id = 45;
- ResourceProvider::ResourceId u_plane_resource_id = 532;
- ResourceProvider::ResourceId v_plane_resource_id = 4;
- ResourceProvider::ResourceId a_plane_resource_id = 63;
+ ResourceId y_plane_resource_id = 45;
+ ResourceId u_plane_resource_id = 532;
+ ResourceId v_plane_resource_id = 4;
+ ResourceId a_plane_resource_id = 63;
YUVVideoDrawQuad::ColorSpace color_space = YUVVideoDrawQuad::JPEG;
CREATE_SHARED_STATE();
@@ -919,16 +927,16 @@ TEST_F(DrawQuadIteratorTest, YUVVideoDrawQuad) {
uv_tex_size, y_plane_resource_id, u_plane_resource_id,
v_plane_resource_id, a_plane_resource_id, color_space);
EXPECT_EQ(DrawQuad::YUV_VIDEO_CONTENT, copy_quad->material);
- EXPECT_EQ(y_plane_resource_id, quad_new->y_plane_resource_id);
- EXPECT_EQ(u_plane_resource_id, quad_new->u_plane_resource_id);
- EXPECT_EQ(v_plane_resource_id, quad_new->v_plane_resource_id);
- EXPECT_EQ(a_plane_resource_id, quad_new->a_plane_resource_id);
+ EXPECT_EQ(y_plane_resource_id, quad_new->y_plane_resource_id());
+ EXPECT_EQ(u_plane_resource_id, quad_new->u_plane_resource_id());
+ EXPECT_EQ(v_plane_resource_id, quad_new->v_plane_resource_id());
+ EXPECT_EQ(a_plane_resource_id, quad_new->a_plane_resource_id());
EXPECT_EQ(color_space, quad_new->color_space);
EXPECT_EQ(4, IterateAndCount(quad_new));
- EXPECT_EQ(y_plane_resource_id + 1, quad_new->y_plane_resource_id);
- EXPECT_EQ(u_plane_resource_id + 1, quad_new->u_plane_resource_id);
- EXPECT_EQ(v_plane_resource_id + 1, quad_new->v_plane_resource_id);
- EXPECT_EQ(a_plane_resource_id + 1, quad_new->a_plane_resource_id);
+ EXPECT_EQ(y_plane_resource_id + 1, quad_new->y_plane_resource_id());
+ EXPECT_EQ(u_plane_resource_id + 1, quad_new->u_plane_resource_id());
+ EXPECT_EQ(v_plane_resource_id + 1, quad_new->v_plane_resource_id());
+ EXPECT_EQ(a_plane_resource_id + 1, quad_new->a_plane_resource_id());
}
// Disabled until picture draw quad is supported for ubercomp: crbug.com/231715
diff --git a/chromium/cc/quads/io_surface_draw_quad.cc b/chromium/cc/quads/io_surface_draw_quad.cc
index 8a37b0a6f06..0ad70fcc6b8 100644
--- a/chromium/cc/quads/io_surface_draw_quad.cc
+++ b/chromium/cc/quads/io_surface_draw_quad.cc
@@ -11,9 +11,7 @@
namespace cc {
-IOSurfaceDrawQuad::IOSurfaceDrawQuad()
- : io_surface_resource_id(0),
- orientation(FLIPPED) {
+IOSurfaceDrawQuad::IOSurfaceDrawQuad() : orientation(FLIPPED) {
}
void IOSurfaceDrawQuad::SetNew(const SharedQuadState* shared_quad_state,
@@ -27,7 +25,8 @@ void IOSurfaceDrawQuad::SetNew(const SharedQuadState* shared_quad_state,
DrawQuad::SetAll(shared_quad_state, DrawQuad::IO_SURFACE_CONTENT, rect,
opaque_rect, visible_rect, needs_blending);
this->io_surface_size = io_surface_size;
- this->io_surface_resource_id = io_surface_resource_id;
+ resources.ids[kIOSurfaceResourceIdIndex] = io_surface_resource_id;
+ resources.count = 1;
this->orientation = orientation;
}
@@ -42,15 +41,11 @@ void IOSurfaceDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
DrawQuad::SetAll(shared_quad_state, DrawQuad::IO_SURFACE_CONTENT, rect,
opaque_rect, visible_rect, needs_blending);
this->io_surface_size = io_surface_size;
- this->io_surface_resource_id = io_surface_resource_id;
+ resources.ids[kIOSurfaceResourceIdIndex] = io_surface_resource_id;
+ resources.count = 1;
this->orientation = orientation;
}
-void IOSurfaceDrawQuad::IterateResources(
- const ResourceIteratorCallback& callback) {
- io_surface_resource_id = callback.Run(io_surface_resource_id);
-}
-
const IOSurfaceDrawQuad* IOSurfaceDrawQuad::MaterialCast(
const DrawQuad* quad) {
DCHECK(quad->material == DrawQuad::IO_SURFACE_CONTENT);
@@ -61,7 +56,8 @@ void IOSurfaceDrawQuad::ExtendValue(
base::trace_event::TracedValue* value) const {
MathUtil::AddToTracedValue("io_surface_size", io_surface_size, value);
- value->SetInteger("io_surface_resource_id", io_surface_resource_id);
+ value->SetInteger("io_surface_resource_id",
+ resources.ids[kIOSurfaceResourceIdIndex]);
const char* orientation_string = NULL;
switch (orientation) {
case FLIPPED:
diff --git a/chromium/cc/quads/io_surface_draw_quad.h b/chromium/cc/quads/io_surface_draw_quad.h
index 2c77905cd79..4a8a072c61c 100644
--- a/chromium/cc/quads/io_surface_draw_quad.h
+++ b/chromium/cc/quads/io_surface_draw_quad.h
@@ -40,14 +40,17 @@ class CC_EXPORT IOSurfaceDrawQuad : public DrawQuad {
Orientation orientation);
gfx::Size io_surface_size;
- unsigned io_surface_resource_id;
Orientation orientation;
- void IterateResources(const ResourceIteratorCallback& callback) override;
+ ResourceId io_surface_resource_id() const {
+ return resources.ids[kIOSurfaceResourceIdIndex];
+ }
static const IOSurfaceDrawQuad* MaterialCast(const DrawQuad*);
private:
+ static const size_t kIOSurfaceResourceIdIndex = 0;
+
void ExtendValue(base::trace_event::TracedValue* value) const override;
};
diff --git a/chromium/cc/quads/list_container.cc b/chromium/cc/quads/list_container.cc
deleted file mode 100644
index 4edcbdfab56..00000000000
--- a/chromium/cc/quads/list_container.cc
+++ /dev/null
@@ -1,720 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/quads/list_container.h"
-
-#include <algorithm>
-#include <vector>
-
-#include "cc/base/scoped_ptr_vector.h"
-#include "cc/playback/display_item.h"
-#include "cc/quads/draw_quad.h"
-#include "cc/quads/shared_quad_state.h"
-
-namespace {
-const size_t kDefaultNumElementTypesToReserve = 32;
-} // namespace
-
-namespace cc {
-
-// ListContainerCharAllocator
-////////////////////////////////////////////////////
-// This class deals only with char* and void*. It does allocation and passing
-// out raw pointers, as well as memory deallocation when being destroyed.
-template <typename BaseElementType>
-class ListContainer<BaseElementType>::ListContainerCharAllocator {
- public:
- // ListContainerCharAllocator::InnerList
- /////////////////////////////////////////////
- // This class holds the raw memory chunk, as well as information about its
- // size and availability.
- struct InnerList {
- scoped_ptr<char[]> data;
- // The number of elements in total the memory can hold. The difference
- // between capacity and size is the how many more elements this list can
- // hold.
- size_t capacity;
- // The number of elements have been put into this list.
- size_t size;
- // The size of each element is in bytes. This is used to move from between
- // elements' memory locations.
- size_t step;
-
- InnerList() : capacity(0), size(0), step(0) {}
-
- void Erase(char* position) {
- // Confident that destructor is called by caller of this function. Since
- // ListContainerCharAllocator does not handle construction after
- // allocation, it doesn't handle desctrution before deallocation.
- DCHECK_LE(position, LastElement());
- DCHECK_GE(position, Begin());
- char* start = position + step;
- std::copy(start, End(), position);
-
- --size;
- // Decrease capacity to avoid creating not full not last InnerList.
- --capacity;
- }
-
- bool IsFull() { return capacity == size; }
- size_t NumElementsAvailable() const { return capacity - size; }
-
- void* AddElement() {
- DCHECK_LT(size, capacity);
- ++size;
- return LastElement();
- }
-
- char* Begin() const { return data.get(); }
- char* End() const { return data.get() + size * step; }
- char* LastElement() const { return data.get() + (size - 1) * step; }
- char* ElementAt(size_t index) const { return data.get() + index * step; }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(InnerList);
- };
-
- explicit ListContainerCharAllocator(size_t element_size)
- : element_size_(element_size),
- size_(0),
- list_count_(0),
- last_list_(NULL) {
- AllocateNewList(kDefaultNumElementTypesToReserve);
- }
-
- ListContainerCharAllocator(size_t element_size, size_t element_count)
- : element_size_(element_size),
- size_(0),
- list_count_(0),
- last_list_(NULL) {
- AllocateNewList(element_count > 0 ? element_count
- : kDefaultNumElementTypesToReserve);
- }
-
- ~ListContainerCharAllocator() {}
-
- void* Allocate() {
- if (last_list_->IsFull())
- AllocateNewList(last_list_->capacity * 2);
-
- ++size_;
- return last_list_->AddElement();
- }
-
- size_t element_size() const { return element_size_; }
- size_t list_count() const { return list_count_; }
- size_t size() const { return size_; }
- bool IsEmpty() const { return size() == 0; }
-
- size_t Capacity() const {
- size_t capacity_sum = 0;
- for (typename ScopedPtrVector<InnerList>::const_iterator iter =
- storage_.begin();
- iter != storage_.end();
- ++iter) {
- capacity_sum += (*iter)->capacity;
- }
- return capacity_sum;
- }
-
- void Clear() {
- size_t initial_allocation_size = storage_.front()->capacity;
- storage_.clear();
- list_count_ = 0;
- last_list_ = NULL;
- size_ = 0;
- AllocateNewList(initial_allocation_size);
- }
-
- void Erase(PositionInListContainerCharAllocator position) {
- DCHECK_EQ(this, position.ptr_to_container);
- storage_[position.vector_index]->Erase(position.item_iterator);
- // TODO(weiliangc): Free the InnerList if it is empty.
- --size_;
- }
-
- InnerList* InnerListById(size_t id) const {
- DCHECK_LT(id, list_count_);
- return storage_[id];
- }
-
- size_t FirstInnerListId() const {
- // |size_| > 0 means that at least one vector in |storage_| will be
- // non-empty.
- DCHECK_GT(size_, 0u);
- size_t id = 0;
- while (storage_[id]->size == 0)
- ++id;
- return id;
- }
-
- size_t LastInnerListId() const {
- // |size_| > 0 means that at least one vector in |storage_| will be
- // non-empty.
- DCHECK_GT(size_, 0u);
- size_t id = list_count_ - 1;
- while (storage_[id]->size == 0)
- --id;
- return id;
- }
-
- void AllocateNewList(size_t list_size) {
- ++list_count_;
- scoped_ptr<InnerList> new_list(new InnerList);
- storage_.push_back(new_list.Pass());
- last_list_ = storage_.back();
- InnerList* list = last_list_;
- list->capacity = list_size;
- list->size = 0;
- list->step = element_size_;
- list->data.reset(new char[list->capacity * list->step]);
- }
-
- size_t NumAvailableElementsInLastList() const {
- return last_list_->NumElementsAvailable();
- }
-
- private:
- ScopedPtrVector<InnerList> storage_;
- const size_t element_size_;
- size_t size_;
- size_t list_count_;
- InnerList* last_list_;
-
- DISALLOW_COPY_AND_ASSIGN(ListContainerCharAllocator);
-};
-
-// PositionInListContainerCharAllocator
-//////////////////////////////////////////////////////
-template <typename BaseElementType>
-ListContainer<BaseElementType>::PositionInListContainerCharAllocator::
- PositionInListContainerCharAllocator(const typename ListContainer<
- BaseElementType>::PositionInListContainerCharAllocator& other)
- : ptr_to_container(other.ptr_to_container),
- vector_index(other.vector_index),
- item_iterator(other.item_iterator) {
-}
-
-template <typename BaseElementType>
-ListContainer<BaseElementType>::PositionInListContainerCharAllocator::
- PositionInListContainerCharAllocator(
- typename ListContainer<BaseElementType>::ListContainerCharAllocator*
- container,
- size_t vector_ind,
- char* item_iter)
- : ptr_to_container(container),
- vector_index(vector_ind),
- item_iterator(item_iter) {
-}
-
-template <typename BaseElementType>
-bool ListContainer<BaseElementType>::PositionInListContainerCharAllocator::
-operator==(const typename ListContainer<
- BaseElementType>::PositionInListContainerCharAllocator& other) const {
- DCHECK_EQ(ptr_to_container, other.ptr_to_container);
- return vector_index == other.vector_index &&
- item_iterator == other.item_iterator;
-}
-
-template <typename BaseElementType>
-bool ListContainer<BaseElementType>::PositionInListContainerCharAllocator::
-operator!=(const typename ListContainer<
- BaseElementType>::PositionInListContainerCharAllocator& other) const {
- return !(*this == other);
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::PositionInListContainerCharAllocator
-ListContainer<
- BaseElementType>::PositionInListContainerCharAllocator::Increment() {
- typename ListContainerCharAllocator::InnerList* list =
- ptr_to_container->InnerListById(vector_index);
- if (item_iterator == list->LastElement()) {
- ++vector_index;
- while (vector_index < ptr_to_container->list_count()) {
- if (ptr_to_container->InnerListById(vector_index)->size != 0)
- break;
- ++vector_index;
- }
- if (vector_index < ptr_to_container->list_count())
- item_iterator = ptr_to_container->InnerListById(vector_index)->Begin();
- else
- item_iterator = NULL;
- } else {
- item_iterator += list->step;
- }
- return *this;
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::PositionInListContainerCharAllocator
-ListContainer<
- BaseElementType>::PositionInListContainerCharAllocator::ReverseIncrement() {
- typename ListContainerCharAllocator::InnerList* list =
- ptr_to_container->InnerListById(vector_index);
- if (item_iterator == list->Begin()) {
- --vector_index;
- // Since |vector_index| is unsigned, we compare < list_count() instead of
- // comparing >= 0, as the variable will wrap around when it goes out of
- // range (below 0).
- while (vector_index < ptr_to_container->list_count()) {
- if (ptr_to_container->InnerListById(vector_index)->size != 0)
- break;
- --vector_index;
- }
- if (vector_index < ptr_to_container->list_count()) {
- item_iterator =
- ptr_to_container->InnerListById(vector_index)->LastElement();
- } else {
- item_iterator = NULL;
- }
- } else {
- item_iterator -= list->step;
- }
- return *this;
-}
-
-// ListContainer
-////////////////////////////////////////////
-template <typename BaseElementType>
-ListContainer<BaseElementType>::ListContainer(size_t max_size_for_derived_class)
- : data_(new ListContainerCharAllocator(max_size_for_derived_class)) {
-}
-
-template <typename BaseElementType>
-ListContainer<BaseElementType>::ListContainer(
- size_t max_size_for_derived_class,
- size_t num_of_elements_to_reserve_for)
- : data_(new ListContainerCharAllocator(max_size_for_derived_class,
- num_of_elements_to_reserve_for)) {
-}
-
-template <typename BaseElementType>
-ListContainer<BaseElementType>::ListContainer()
- : data_(new ListContainerCharAllocator(sizeof(BaseElementType))) {
-}
-
-template <typename BaseElementType>
-ListContainer<BaseElementType>::~ListContainer() {
- for (Iterator i = begin(); i != end(); ++i) {
- i->~BaseElementType();
- }
-}
-
-template <typename BaseElementType>
-void ListContainer<BaseElementType>::EraseAndInvalidateAllPointers(
- typename ListContainer<BaseElementType>::Iterator position) {
- BaseElementType* item = *position;
- item->~BaseElementType();
- data_->Erase(position);
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ConstReverseIterator
-ListContainer<BaseElementType>::crbegin() const {
- if (data_->IsEmpty())
- return crend();
-
- size_t id = data_->LastInnerListId();
- return ConstReverseIterator(data_.get(), id,
- data_->InnerListById(id)->LastElement(), 0);
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ConstReverseIterator
-ListContainer<BaseElementType>::crend() const {
- return ConstReverseIterator(data_.get(), static_cast<size_t>(-1), NULL,
- size());
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ConstReverseIterator
-ListContainer<BaseElementType>::rbegin() const {
- return crbegin();
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ConstReverseIterator
-ListContainer<BaseElementType>::rend() const {
- return crend();
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ReverseIterator
-ListContainer<BaseElementType>::rbegin() {
- if (data_->IsEmpty())
- return rend();
-
- size_t id = data_->LastInnerListId();
- return ReverseIterator(data_.get(), id,
- data_->InnerListById(id)->LastElement(), 0);
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ReverseIterator
-ListContainer<BaseElementType>::rend() {
- return ReverseIterator(data_.get(), static_cast<size_t>(-1), NULL, size());
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ConstIterator
-ListContainer<BaseElementType>::cbegin() const {
- if (data_->IsEmpty())
- return cend();
-
- size_t id = data_->FirstInnerListId();
- return ConstIterator(data_.get(), id, data_->InnerListById(id)->Begin(), 0);
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ConstIterator
-ListContainer<BaseElementType>::cend() const {
- if (data_->IsEmpty())
- return ConstIterator(data_.get(), 0, NULL, size());
-
- size_t id = data_->list_count();
- return ConstIterator(data_.get(), id, NULL, size());
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ConstIterator
-ListContainer<BaseElementType>::begin() const {
- return cbegin();
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ConstIterator
-ListContainer<BaseElementType>::end() const {
- return cend();
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::Iterator
-ListContainer<BaseElementType>::begin() {
- if (data_->IsEmpty())
- return end();
-
- size_t id = data_->FirstInnerListId();
- return Iterator(data_.get(), id, data_->InnerListById(id)->Begin(), 0);
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::Iterator
-ListContainer<BaseElementType>::end() {
- if (data_->IsEmpty())
- return Iterator(data_.get(), 0, NULL, size());
-
- size_t id = data_->list_count();
- return Iterator(data_.get(), id, NULL, size());
-}
-
-template <typename BaseElementType>
-BaseElementType* ListContainer<BaseElementType>::front() {
- Iterator iter = begin();
- return *iter;
-}
-
-template <typename BaseElementType>
-BaseElementType* ListContainer<BaseElementType>::back() {
- ReverseIterator iter = rbegin();
- return *iter;
-}
-
-template <typename BaseElementType>
-const BaseElementType* ListContainer<BaseElementType>::front() const {
- ConstIterator iter = begin();
- return *iter;
-}
-
-template <typename BaseElementType>
-const BaseElementType* ListContainer<BaseElementType>::back() const {
- ConstReverseIterator iter = rbegin();
- return *iter;
-}
-
-template <typename BaseElementType>
-const BaseElementType* ListContainer<BaseElementType>::ElementAt(
- size_t index) const {
- DCHECK_LT(index, size());
- size_t original_index = index;
- size_t list_index;
- for (list_index = 0; list_index < data_->list_count(); ++list_index) {
- size_t current_size = data_->InnerListById(list_index)->size;
- if (index < current_size)
- break;
- index -= current_size;
- }
- return *ConstIterator(data_.get(),
- list_index,
- data_->InnerListById(list_index)->ElementAt(index),
- original_index);
-}
-
-template <typename BaseElementType>
-BaseElementType* ListContainer<BaseElementType>::ElementAt(size_t index) {
- DCHECK_LT(index, size());
- size_t original_index = index;
- size_t list_index;
- for (list_index = 0; list_index < data_->list_count(); ++list_index) {
- size_t current_size = data_->InnerListById(list_index)->size;
- if (index < current_size)
- break;
- index -= current_size;
- }
- return *Iterator(data_.get(),
- list_index,
- data_->InnerListById(list_index)->ElementAt(index),
- original_index);
-}
-
-template <typename BaseElementType>
-void* ListContainer<BaseElementType>::Allocate(
- size_t size_of_actual_element_in_bytes) {
- DCHECK_LE(size_of_actual_element_in_bytes, data_->element_size());
- return data_->Allocate();
-}
-
-template <typename BaseElementType>
-size_t ListContainer<BaseElementType>::size() const {
- return data_->size();
-}
-
-template <typename BaseElementType>
-bool ListContainer<BaseElementType>::empty() const {
- return data_->IsEmpty();
-}
-
-template <typename BaseElementType>
-void ListContainer<BaseElementType>::clear() {
- for (Iterator i = begin(); i != end(); ++i) {
- i->~BaseElementType();
- }
- data_->Clear();
-}
-
-template <typename BaseElementType>
-size_t ListContainer<
- BaseElementType>::AvailableSizeWithoutAnotherAllocationForTesting() const {
- return data_->NumAvailableElementsInLastList();
-}
-
-// ListContainer::Iterator
-/////////////////////////////////////////////////
-template <typename BaseElementType>
-ListContainer<BaseElementType>::Iterator::Iterator(
- ListContainerCharAllocator* container,
- size_t vector_ind,
- char* item_iter,
- size_t index)
- : PositionInListContainerCharAllocator(container, vector_ind, item_iter),
- index_(index) {
-}
-
-template <typename BaseElementType>
-ListContainer<BaseElementType>::Iterator::~Iterator() {
-}
-
-template <typename BaseElementType>
-BaseElementType* ListContainer<BaseElementType>::Iterator::operator->() const {
- return reinterpret_cast<BaseElementType*>(this->item_iterator);
-}
-
-template <typename BaseElementType>
-BaseElementType* ListContainer<BaseElementType>::Iterator::operator*() const {
- return reinterpret_cast<BaseElementType*>(this->item_iterator);
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::Iterator
-ListContainer<BaseElementType>::Iterator::
-operator++(int unused_post_increment) {
- Iterator tmp = *this;
- operator++();
- return tmp;
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::Iterator&
- ListContainer<BaseElementType>::Iterator::
- operator++() {
- this->Increment();
- ++index_;
- return *this;
-}
-
-template <typename BaseElementType>
-size_t ListContainer<BaseElementType>::Iterator::index() const {
- return index_;
-}
-
-// ListContainer::ConstIterator
-/////////////////////////////////////////////////
-template <typename BaseElementType>
-ListContainer<BaseElementType>::ConstIterator::ConstIterator(
- const typename ListContainer<BaseElementType>::Iterator& other)
- : PositionInListContainerCharAllocator(other), index_(other.index()) {
-}
-
-template <typename BaseElementType>
-ListContainer<BaseElementType>::ConstIterator::ConstIterator(
- ListContainerCharAllocator* container,
- size_t vector_ind,
- char* item_iter,
- size_t index)
- : PositionInListContainerCharAllocator(container, vector_ind, item_iter),
- index_(index) {
-}
-
-template <typename BaseElementType>
-ListContainer<BaseElementType>::ConstIterator::~ConstIterator() {
-}
-
-template <typename BaseElementType>
-const BaseElementType* ListContainer<BaseElementType>::ConstIterator::
-operator->() const {
- return reinterpret_cast<const BaseElementType*>(this->item_iterator);
-}
-
-template <typename BaseElementType>
-const BaseElementType* ListContainer<BaseElementType>::ConstIterator::
-operator*() const {
- return reinterpret_cast<const BaseElementType*>(this->item_iterator);
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ConstIterator
-ListContainer<BaseElementType>::ConstIterator::
-operator++(int unused_post_increment) {
- ConstIterator tmp = *this;
- operator++();
- return tmp;
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ConstIterator&
- ListContainer<BaseElementType>::ConstIterator::
- operator++() {
- this->Increment();
- ++index_;
- return *this;
-}
-
-template <typename BaseElementType>
-size_t ListContainer<BaseElementType>::ConstIterator::index() const {
- return index_;
-}
-
-// ListContainer::ReverseIterator
-/////////////////////////////////////////////////
-template <typename BaseElementType>
-ListContainer<BaseElementType>::ReverseIterator::ReverseIterator(
- ListContainerCharAllocator* container,
- size_t vector_ind,
- char* item_iter,
- size_t index)
- : PositionInListContainerCharAllocator(container, vector_ind, item_iter),
- index_(index) {
-}
-
-template <typename BaseElementType>
-ListContainer<BaseElementType>::ReverseIterator::~ReverseIterator() {
-}
-
-template <typename BaseElementType>
-BaseElementType* ListContainer<BaseElementType>::ReverseIterator::operator->()
- const {
- return reinterpret_cast<BaseElementType*>(this->item_iterator);
-}
-
-template <typename BaseElementType>
-BaseElementType* ListContainer<BaseElementType>::ReverseIterator::operator*()
- const {
- return reinterpret_cast<BaseElementType*>(this->item_iterator);
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ReverseIterator
-ListContainer<BaseElementType>::ReverseIterator::
-operator++(int unused_post_increment) {
- ReverseIterator tmp = *this;
- operator++();
- return tmp;
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ReverseIterator&
- ListContainer<BaseElementType>::ReverseIterator::
- operator++() {
- this->ReverseIncrement();
- ++index_;
- return *this;
-}
-
-template <typename BaseElementType>
-size_t ListContainer<BaseElementType>::ReverseIterator::index() const {
- return index_;
-}
-
-// ListContainer::ConstReverseIterator
-/////////////////////////////////////////////////
-template <typename BaseElementType>
-ListContainer<BaseElementType>::ConstReverseIterator::ConstReverseIterator(
- const typename ListContainer<BaseElementType>::ReverseIterator& other)
- : PositionInListContainerCharAllocator(other), index_(other.index()) {
-}
-
-template <typename BaseElementType>
-ListContainer<BaseElementType>::ConstReverseIterator::ConstReverseIterator(
- ListContainerCharAllocator* container,
- size_t vector_ind,
- char* item_iter,
- size_t index)
- : PositionInListContainerCharAllocator(container, vector_ind, item_iter),
- index_(index) {
-}
-
-template <typename BaseElementType>
-ListContainer<BaseElementType>::ConstReverseIterator::~ConstReverseIterator() {
-}
-
-template <typename BaseElementType>
-const BaseElementType* ListContainer<BaseElementType>::ConstReverseIterator::
-operator->() const {
- return reinterpret_cast<const BaseElementType*>(this->item_iterator);
-}
-
-template <typename BaseElementType>
-const BaseElementType* ListContainer<BaseElementType>::ConstReverseIterator::
-operator*() const {
- return reinterpret_cast<const BaseElementType*>(this->item_iterator);
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ConstReverseIterator
-ListContainer<BaseElementType>::ConstReverseIterator::
-operator++(int unused_post_increment) {
- ConstReverseIterator tmp = *this;
- operator++();
- return tmp;
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ConstReverseIterator&
- ListContainer<BaseElementType>::ConstReverseIterator::
- operator++() {
- this->ReverseIncrement();
- ++index_;
- return *this;
-}
-
-template <typename BaseElementType>
-size_t ListContainer<BaseElementType>::ConstReverseIterator::index() const {
- return index_;
-}
-
-template class ListContainer<SharedQuadState>;
-template class ListContainer<DrawQuad>;
-template class ListContainer<DisplayItem>;
-
-} // namespace cc
diff --git a/chromium/cc/quads/list_container.h b/chromium/cc/quads/list_container.h
deleted file mode 100644
index 8abc33d62eb..00000000000
--- a/chromium/cc/quads/list_container.h
+++ /dev/null
@@ -1,242 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_QUADS_LIST_CONTAINER_H_
-#define CC_QUADS_LIST_CONTAINER_H_
-
-#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
-#include "cc/base/cc_export.h"
-
-namespace cc {
-class DisplayItem;
-class DrawQuad;
-class SharedQuadState;
-
-// This class is a container type that handles allocating contiguous memory for
-// new elements and traversing through elements with either iterator or reverse
-// iterator. Since this container hands out raw pointers of its elements, it is
-// very important that this container never reallocate its memory so those raw
-// pointer will continue to be valid. This class is used to contain
-// SharedQuadState or DrawQuad. Since the size of each DrawQuad varies, to hold
-// DrawQuads, the allocations size of each element in this class is
-// LargestDrawQuadSize while BaseElementType is DrawQuad.
-template <class BaseElementType>
-class CC_EXPORT ListContainer {
- public:
- // BaseElementType is the type of raw pointers this class hands out; however,
- // its derived classes might require different memory sizes.
- // max_size_for_derived_class the largest memory size required for all the
- // derived classes to use for allocation.
- explicit ListContainer(size_t max_size_for_derived_class);
- // This constructor omits input variable for max_size_for_derived_class. This
- // is used when there is no derived classes from BaseElementType we need to
- // worry about, and allocation size is just sizeof(BaseElementType).
- ListContainer();
- // This constructor reserves the requested memory up front so only single
- // allocation is needed. When num_of_elements_to_reserve_for is zero, use the
- // default size.
- ListContainer(size_t max_size_for_derived_class,
- size_t num_of_elements_to_reserve_for);
-
- ~ListContainer();
-
- // This class deals only with char* and void*. It does allocation and passing
- // out raw pointers, as well as memory deallocation when being destroyed.
- class CC_EXPORT ListContainerCharAllocator;
-
- // This class points to a certain position inside memory of
- // ListContainerCharAllocator. It is a base class for ListContainer iterators.
- struct CC_EXPORT PositionInListContainerCharAllocator {
- ListContainerCharAllocator* ptr_to_container;
- size_t vector_index;
- char* item_iterator;
-
- PositionInListContainerCharAllocator(
- const PositionInListContainerCharAllocator& other);
-
- PositionInListContainerCharAllocator(ListContainerCharAllocator* container,
- size_t vector_ind,
- char* item_iter);
-
- bool operator==(const PositionInListContainerCharAllocator& other) const;
- bool operator!=(const PositionInListContainerCharAllocator& other) const;
-
- PositionInListContainerCharAllocator Increment();
- PositionInListContainerCharAllocator ReverseIncrement();
- };
-
- // Iterator classes that can be used to access data.
- /////////////////////////////////////////////////////////////////
- class CC_EXPORT Iterator : public PositionInListContainerCharAllocator {
- // This class is only defined to forward iterate through
- // ListContainerCharAllocator.
- public:
- Iterator(ListContainerCharAllocator* container,
- size_t vector_ind,
- char* item_iter,
- size_t index);
- ~Iterator();
- BaseElementType* operator->() const;
- BaseElementType* operator*() const;
- Iterator operator++(int unused_post_increment);
- Iterator& operator++();
-
- size_t index() const;
-
- private:
- // This is used to track how many increment has happened since begin(). It
- // is used to avoid double increment at places an index reference is
- // needed. For iterator this means begin() corresponds to index 0 and end()
- // corresponds to index |size|.
- size_t index_;
- };
-
- class CC_EXPORT ConstIterator : public PositionInListContainerCharAllocator {
- // This class is only defined to forward iterate through
- // ListContainerCharAllocator.
- public:
- ConstIterator(ListContainerCharAllocator* container,
- size_t vector_ind,
- char* item_iter,
- size_t index);
- ConstIterator(const Iterator& other); // NOLINT
- ~ConstIterator();
- const BaseElementType* operator->() const;
- const BaseElementType* operator*() const;
- ConstIterator operator++(int unused_post_increment);
- ConstIterator& operator++();
-
- size_t index() const;
-
- private:
- // This is used to track how many increment has happened since begin(). It
- // is used to avoid double increment at places an index reference is
- // needed. For iterator this means begin() corresponds to index 0 and end()
- // corresponds to index |size|.
- size_t index_;
- };
-
- class CC_EXPORT ReverseIterator
- : public PositionInListContainerCharAllocator {
- // This class is only defined to reverse iterate through
- // ListContainerCharAllocator.
- public:
- ReverseIterator(ListContainerCharAllocator* container,
- size_t vector_ind,
- char* item_iter,
- size_t index);
- ~ReverseIterator();
- BaseElementType* operator->() const;
- BaseElementType* operator*() const;
- ReverseIterator operator++(int unused_post_increment);
- ReverseIterator& operator++();
-
- size_t index() const;
-
- private:
- // This is used to track how many increment has happened since rbegin(). It
- // is used to avoid double increment at places an index reference is
- // needed. For reverse iterator this means rbegin() corresponds to index 0
- // and rend() corresponds to index |size|.
- size_t index_;
- };
-
- class CC_EXPORT ConstReverseIterator
- : public PositionInListContainerCharAllocator {
- // This class is only defined to reverse iterate through
- // ListContainerCharAllocator.
- public:
- ConstReverseIterator(ListContainerCharAllocator* container,
- size_t vector_ind,
- char* item_iter,
- size_t index);
- ConstReverseIterator(const ReverseIterator& other); // NOLINT
- ~ConstReverseIterator();
- const BaseElementType* operator->() const;
- const BaseElementType* operator*() const;
- ConstReverseIterator operator++(int unused_post_increment);
- ConstReverseIterator& operator++();
-
- size_t index() const;
-
- private:
- // This is used to track how many increment has happened since rbegin(). It
- // is used to avoid double increment at places an index reference is
- // needed. For reverse iterator this means rbegin() corresponds to index 0
- // and rend() corresponds to index |size|.
- size_t index_;
- };
-
- // When called, all raw pointers that have been handed out are no longer
- // valid. Use with caution.
- // This function does not deallocate memory.
- void EraseAndInvalidateAllPointers(Iterator position);
-
- ConstReverseIterator crbegin() const;
- ConstReverseIterator crend() const;
- ConstReverseIterator rbegin() const;
- ConstReverseIterator rend() const;
- ReverseIterator rbegin();
- ReverseIterator rend();
- ConstIterator cbegin() const;
- ConstIterator cend() const;
- ConstIterator begin() const;
- ConstIterator end() const;
- Iterator begin();
- Iterator end();
-
- // TODO(weiliangc): front(), back() and ElementAt() function should return
- // reference, consistent with container-of-object.
- BaseElementType* front();
- BaseElementType* back();
- const BaseElementType* front() const;
- const BaseElementType* back() const;
-
- BaseElementType* ElementAt(size_t index);
- const BaseElementType* ElementAt(size_t index) const;
-
- // Take in derived element type and construct it at location generated by
- // Allocate().
- template <typename DerivedElementType>
- DerivedElementType* AllocateAndConstruct() {
- return new (Allocate(sizeof(DerivedElementType))) DerivedElementType;
- }
- // Take in derived element type and copy construct it at location generated by
- // Allocate().
- template <typename DerivedElementType>
- DerivedElementType* AllocateAndCopyFrom(const DerivedElementType* source) {
- return new (Allocate(sizeof(DerivedElementType)))
- DerivedElementType(*source);
- }
- // Construct a new element on top of an existing one.
- template <typename DerivedElementType>
- DerivedElementType* ReplaceExistingElement(Iterator at) {
- at->~BaseElementType();
- return new (*at) DerivedElementType();
- }
-
- size_t size() const;
- bool empty() const;
- void clear();
-
- size_t AvailableSizeWithoutAnotherAllocationForTesting() const;
-
- private:
- // Hands out memory location for an element at the end of data structure.
- void* Allocate(size_t size_of_actual_element_in_bytes);
-
- scoped_ptr<ListContainerCharAllocator> data_;
-
- DISALLOW_COPY_AND_ASSIGN(ListContainer);
-};
-
-#if !defined(COMPILER_MSVC)
-extern template class ListContainer<SharedQuadState>;
-extern template class ListContainer<DrawQuad>;
-extern template class ListContainer<DisplayItem>;
-#endif
-} // namespace cc
-
-#endif // CC_QUADS_LIST_CONTAINER_H_
diff --git a/chromium/cc/quads/list_container_unittest.cc b/chromium/cc/quads/list_container_unittest.cc
deleted file mode 100644
index 5de1ddd1941..00000000000
--- a/chromium/cc/quads/list_container_unittest.cc
+++ /dev/null
@@ -1,667 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/quads/list_container.h"
-
-#include <vector>
-#include "cc/quads/draw_quad.h"
-#include "cc/quads/largest_draw_quad.h"
-#include "cc/quads/render_pass_draw_quad.h"
-#include "cc/quads/shared_quad_state.h"
-#include "cc/quads/stream_video_draw_quad.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-namespace {
-
-int kMagicNumberToUseForDrawQuadOne = 42;
-int kMagicNumberToUseForDrawQuadTwo = 314;
-
-bool isConstSharedQuadStatePointer(const SharedQuadState* ptr) {
- return true;
-}
-
-bool isConstSharedQuadStatePointer(SharedQuadState* ptr) {
- return false;
-}
-
-class SimpleDrawQuad : public DrawQuad {
- public:
- ~SimpleDrawQuad() override {}
- void IterateResources(const ResourceIteratorCallback& callback) override {}
-
- void set_value(int val) { value = val; }
- int get_value() { return value; }
- void ExtendValue(base::trace_event::TracedValue* value) const override {}
-
- private:
- int value;
-};
-
-class SimpleDrawQuadConstructMagicNumberOne : public SimpleDrawQuad {
- public:
- SimpleDrawQuadConstructMagicNumberOne() : SimpleDrawQuad() {
- set_value(kMagicNumberToUseForDrawQuadOne);
- }
-};
-
-class SimpleDrawQuadConstructMagicNumberTwo : public SimpleDrawQuad {
- public:
- SimpleDrawQuadConstructMagicNumberTwo() : SimpleDrawQuad() {
- set_value(kMagicNumberToUseForDrawQuadTwo);
- }
-};
-
-class MockDrawQuad : public SimpleDrawQuadConstructMagicNumberOne {
- public:
- ~MockDrawQuad() override { Destruct(); }
- MOCK_METHOD0(Destruct, void());
-};
-
-class MockDrawQuadSubclass : public MockDrawQuad {
- public:
- MockDrawQuadSubclass() { set_value(kMagicNumberToUseForDrawQuadTwo); }
-};
-
-const size_t kLargestQuadSize =
- std::max(LargestDrawQuadSize(), sizeof(MockDrawQuadSubclass));
-
-TEST(ListContainerTest, ConstructorCalledInAllocateAndConstruct) {
- ListContainer<DrawQuad> list(kLargestQuadSize);
-
- size_t size = 2;
- SimpleDrawQuadConstructMagicNumberOne* dq_1 =
- list.AllocateAndConstruct<SimpleDrawQuadConstructMagicNumberOne>();
- SimpleDrawQuadConstructMagicNumberTwo* dq_2 =
- list.AllocateAndConstruct<SimpleDrawQuadConstructMagicNumberTwo>();
-
- EXPECT_EQ(size, list.size());
- EXPECT_EQ(dq_1, list.front());
- EXPECT_EQ(dq_2, list.back());
-
- EXPECT_EQ(kMagicNumberToUseForDrawQuadOne, dq_1->get_value());
- EXPECT_EQ(kMagicNumberToUseForDrawQuadTwo, dq_2->get_value());
-}
-
-TEST(ListContainerTest, DestructorCalled) {
- ListContainer<DrawQuad> list(kLargestQuadSize);
-
- size_t size = 1;
- MockDrawQuad* dq_1 = list.AllocateAndConstruct<MockDrawQuad>();
-
- EXPECT_CALL(*dq_1, Destruct());
- EXPECT_EQ(size, list.size());
- EXPECT_EQ(dq_1, list.front());
-}
-
-TEST(ListContainerTest, DestructorCalledOnceWhenClear) {
- ListContainer<DrawQuad> list(kLargestQuadSize);
- size_t size = 1;
- MockDrawQuad* dq_1 = list.AllocateAndConstruct<MockDrawQuad>();
-
- EXPECT_EQ(size, list.size());
- EXPECT_EQ(dq_1, list.front());
-
- // Make sure destructor is called once during clear, and won't be called
- // again.
- testing::MockFunction<void()> separator;
- {
- testing::InSequence s;
- EXPECT_CALL(*dq_1, Destruct());
- EXPECT_CALL(separator, Call());
- EXPECT_CALL(*dq_1, Destruct()).Times(0);
- }
-
- list.clear();
- separator.Call();
-}
-
-TEST(ListContainerTest, ReplaceExistingElement) {
- ListContainer<DrawQuad> list(kLargestQuadSize);
- size_t size = 1;
- MockDrawQuad* dq_1 = list.AllocateAndConstruct<MockDrawQuad>();
-
- EXPECT_EQ(size, list.size());
- EXPECT_EQ(dq_1, list.front());
-
- // Make sure destructor is called once during clear, and won't be called
- // again.
- testing::MockFunction<void()> separator;
- {
- testing::InSequence s;
- EXPECT_CALL(*dq_1, Destruct());
- EXPECT_CALL(separator, Call());
- EXPECT_CALL(*dq_1, Destruct()).Times(0);
- }
-
- list.ReplaceExistingElement<MockDrawQuadSubclass>(list.begin());
- EXPECT_EQ(kMagicNumberToUseForDrawQuadTwo, dq_1->get_value());
- separator.Call();
-
- EXPECT_CALL(*dq_1, Destruct());
- list.clear();
-}
-
-TEST(ListContainerTest, DestructorCalledOnceWhenErase) {
- ListContainer<DrawQuad> list(kLargestQuadSize);
- size_t size = 1;
- MockDrawQuad* dq_1 = list.AllocateAndConstruct<MockDrawQuad>();
-
- EXPECT_EQ(size, list.size());
- EXPECT_EQ(dq_1, list.front());
-
- // Make sure destructor is called once during clear, and won't be called
- // again.
- testing::MockFunction<void()> separator;
- {
- testing::InSequence s;
- EXPECT_CALL(*dq_1, Destruct());
- EXPECT_CALL(separator, Call());
- EXPECT_CALL(*dq_1, Destruct()).Times(0);
- }
-
- list.EraseAndInvalidateAllPointers(list.begin());
- separator.Call();
-}
-
-TEST(ListContainerTest, SimpleIndexAccessSharedQuadState) {
- ListContainer<SharedQuadState> list;
-
- size_t size = 3;
- SharedQuadState* sqs_1 = list.AllocateAndConstruct<SharedQuadState>();
- SharedQuadState* sqs_2 = list.AllocateAndConstruct<SharedQuadState>();
- SharedQuadState* sqs_3 = list.AllocateAndConstruct<SharedQuadState>();
-
- EXPECT_EQ(size, list.size());
- EXPECT_EQ(sqs_1, list.front());
- EXPECT_EQ(sqs_3, list.back());
- EXPECT_EQ(list.front(), list.ElementAt(0));
- EXPECT_EQ(sqs_2, list.ElementAt(1));
- EXPECT_EQ(list.back(), list.ElementAt(2));
-}
-
-TEST(ListContainerTest, SimpleInsertionSharedQuadState) {
- ListContainer<SharedQuadState> list;
-
- size_t size = 3;
- SharedQuadState* sqs_1 = list.AllocateAndConstruct<SharedQuadState>();
- list.AllocateAndConstruct<SharedQuadState>();
- SharedQuadState* sqs_3 = list.AllocateAndConstruct<SharedQuadState>();
-
- EXPECT_EQ(size, list.size());
- EXPECT_EQ(sqs_1, list.front());
- EXPECT_EQ(sqs_3, list.back());
-}
-
-TEST(ListContainerTest, SimpleInsertionAndClearSharedQuadState) {
- ListContainer<SharedQuadState> list;
- EXPECT_TRUE(list.empty());
- EXPECT_EQ(0u, list.size());
-
- size_t size = 3;
- SharedQuadState* sqs_1 = list.AllocateAndConstruct<SharedQuadState>();
- list.AllocateAndConstruct<SharedQuadState>();
- SharedQuadState* sqs_3 = list.AllocateAndConstruct<SharedQuadState>();
-
- EXPECT_EQ(size, list.size());
- EXPECT_EQ(sqs_1, list.front());
- EXPECT_EQ(sqs_3, list.back());
- EXPECT_FALSE(list.empty());
-
- list.clear();
- EXPECT_TRUE(list.empty());
- EXPECT_EQ(0u, list.size());
-}
-
-TEST(ListContainerTest, SimpleInsertionClearAndInsertAgainSharedQuadState) {
- ListContainer<SharedQuadState> list;
- EXPECT_TRUE(list.empty());
- EXPECT_EQ(0u, list.size());
-
- size_t size = 2;
- SharedQuadState* sqs_front = list.AllocateAndConstruct<SharedQuadState>();
- SharedQuadState* sqs_back = list.AllocateAndConstruct<SharedQuadState>();
-
- EXPECT_EQ(size, list.size());
- EXPECT_EQ(sqs_front, list.front());
- EXPECT_EQ(sqs_back, list.back());
- EXPECT_FALSE(list.empty());
-
- list.clear();
- EXPECT_TRUE(list.empty());
- EXPECT_EQ(0u, list.size());
-
- size = 3;
- sqs_front = list.AllocateAndConstruct<SharedQuadState>();
- list.AllocateAndConstruct<SharedQuadState>();
- sqs_back = list.AllocateAndConstruct<SharedQuadState>();
-
- EXPECT_EQ(size, list.size());
- EXPECT_EQ(sqs_front, list.front());
- EXPECT_EQ(sqs_back, list.back());
- EXPECT_FALSE(list.empty());
-}
-
-// This test is used to test when there is more than one allocation needed
-// for, ListContainer can still perform like normal vector.
-TEST(ListContainerTest,
- SimpleInsertionTriggerMoreThanOneAllocationSharedQuadState) {
- ListContainer<SharedQuadState> list(sizeof(SharedQuadState), 2);
- std::vector<SharedQuadState*> sqs_list;
- size_t size = 10;
- for (size_t i = 0; i < size; ++i) {
- sqs_list.push_back(list.AllocateAndConstruct<SharedQuadState>());
- }
- EXPECT_EQ(size, list.size());
-
- ListContainer<SharedQuadState>::Iterator iter = list.begin();
- for (std::vector<SharedQuadState*>::const_iterator sqs_iter =
- sqs_list.begin();
- sqs_iter != sqs_list.end();
- ++sqs_iter) {
- EXPECT_EQ(*sqs_iter, *iter);
- ++iter;
- }
-}
-
-TEST(ListContainerTest,
- CorrectAllocationSizeForMoreThanOneAllocationSharedQuadState) {
- // Constructor sets the allocation size to 2. Every time ListContainer needs
- // to allocate again, it doubles allocation size. In this test, 10 elements is
- // needed, thus ListContainerShould allocate spaces 2, 4 and 8 elements.
- ListContainer<SharedQuadState> list(sizeof(SharedQuadState), 2);
- std::vector<SharedQuadState*> sqs_list;
- size_t size = 10;
- for (size_t i = 0; i < size; ++i) {
- // Before asking for a new element, space available without another
- // allocation follows.
- switch (i) {
- case 2:
- case 6:
- EXPECT_EQ(0u, list.AvailableSizeWithoutAnotherAllocationForTesting());
- break;
- case 1:
- case 5:
- EXPECT_EQ(1u, list.AvailableSizeWithoutAnotherAllocationForTesting());
- break;
- case 0:
- case 4:
- EXPECT_EQ(2u, list.AvailableSizeWithoutAnotherAllocationForTesting());
- break;
- case 3:
- EXPECT_EQ(3u, list.AvailableSizeWithoutAnotherAllocationForTesting());
- break;
- case 9:
- EXPECT_EQ(5u, list.AvailableSizeWithoutAnotherAllocationForTesting());
- break;
- case 8:
- EXPECT_EQ(6u, list.AvailableSizeWithoutAnotherAllocationForTesting());
- break;
- case 7:
- EXPECT_EQ(7u, list.AvailableSizeWithoutAnotherAllocationForTesting());
- break;
- default:
- break;
- }
- sqs_list.push_back(list.AllocateAndConstruct<SharedQuadState>());
- // After asking for a new element, space available without another
- // allocation follows.
- switch (i) {
- case 1:
- case 5:
- EXPECT_EQ(0u, list.AvailableSizeWithoutAnotherAllocationForTesting());
- break;
- case 0:
- case 4:
- EXPECT_EQ(1u, list.AvailableSizeWithoutAnotherAllocationForTesting());
- break;
- case 3:
- EXPECT_EQ(2u, list.AvailableSizeWithoutAnotherAllocationForTesting());
- break;
- case 2:
- EXPECT_EQ(3u, list.AvailableSizeWithoutAnotherAllocationForTesting());
- break;
- case 9:
- EXPECT_EQ(4u, list.AvailableSizeWithoutAnotherAllocationForTesting());
- break;
- case 8:
- EXPECT_EQ(5u, list.AvailableSizeWithoutAnotherAllocationForTesting());
- break;
- case 7:
- EXPECT_EQ(6u, list.AvailableSizeWithoutAnotherAllocationForTesting());
- break;
- case 6:
- EXPECT_EQ(7u, list.AvailableSizeWithoutAnotherAllocationForTesting());
- break;
- default:
- break;
- }
- }
- EXPECT_EQ(size, list.size());
-
- ListContainer<SharedQuadState>::Iterator iter = list.begin();
- for (std::vector<SharedQuadState*>::const_iterator sqs_iter =
- sqs_list.begin();
- sqs_iter != sqs_list.end();
- ++sqs_iter) {
- EXPECT_EQ(*sqs_iter, *iter);
- ++iter;
- }
-}
-
-TEST(ListContainerTest, SimpleIterationSharedQuadState) {
- ListContainer<SharedQuadState> list;
- std::vector<SharedQuadState*> sqs_list;
- size_t size = 10;
- for (size_t i = 0; i < size; ++i) {
- sqs_list.push_back(list.AllocateAndConstruct<SharedQuadState>());
- }
- EXPECT_EQ(size, list.size());
-
- size_t num_iters_in_list = 0;
- {
- std::vector<SharedQuadState*>::const_iterator sqs_iter = sqs_list.begin();
- for (ListContainer<SharedQuadState>::Iterator iter = list.begin();
- iter != list.end();
- ++iter) {
- EXPECT_EQ(*sqs_iter, *iter);
- ++num_iters_in_list;
- ++sqs_iter;
- }
- }
-
- size_t num_iters_in_vector = 0;
- {
- ListContainer<SharedQuadState>::Iterator iter = list.begin();
- for (std::vector<SharedQuadState*>::const_iterator sqs_iter =
- sqs_list.begin();
- sqs_iter != sqs_list.end();
- ++sqs_iter) {
- EXPECT_EQ(*sqs_iter, *iter);
- ++num_iters_in_vector;
- ++iter;
- }
- }
-
- EXPECT_EQ(num_iters_in_vector, num_iters_in_list);
-}
-
-TEST(ListContainerTest, SimpleConstIteratorIterationSharedQuadState) {
- ListContainer<SharedQuadState> list;
- std::vector<const SharedQuadState*> sqs_list;
- size_t size = 10;
- for (size_t i = 0; i < size; ++i) {
- sqs_list.push_back(list.AllocateAndConstruct<SharedQuadState>());
- }
- EXPECT_EQ(size, list.size());
-
- {
- std::vector<const SharedQuadState*>::const_iterator sqs_iter =
- sqs_list.begin();
- for (ListContainer<SharedQuadState>::ConstIterator iter = list.begin();
- iter != list.end();
- ++iter) {
- EXPECT_TRUE(isConstSharedQuadStatePointer(*iter));
- EXPECT_EQ(*sqs_iter, *iter);
- ++sqs_iter;
- }
- }
-
- {
- std::vector<const SharedQuadState*>::const_iterator sqs_iter =
- sqs_list.begin();
- for (ListContainer<SharedQuadState>::Iterator iter = list.begin();
- iter != list.end();
- ++iter) {
- EXPECT_FALSE(isConstSharedQuadStatePointer(*iter));
- EXPECT_EQ(*sqs_iter, *iter);
- ++sqs_iter;
- }
- }
-
- {
- ListContainer<SharedQuadState>::ConstIterator iter = list.begin();
- for (std::vector<const SharedQuadState*>::const_iterator sqs_iter =
- sqs_list.begin();
- sqs_iter != sqs_list.end();
- ++sqs_iter) {
- EXPECT_EQ(*sqs_iter, *iter);
- ++iter;
- }
- }
-}
-
-TEST(ListContainerTest, SimpleReverseInsertionSharedQuadState) {
- ListContainer<SharedQuadState> list;
- std::vector<SharedQuadState*> sqs_list;
- size_t size = 10;
- for (size_t i = 0; i < size; ++i) {
- sqs_list.push_back(list.AllocateAndConstruct<SharedQuadState>());
- }
- EXPECT_EQ(size, list.size());
-
- {
- std::vector<SharedQuadState*>::const_reverse_iterator sqs_iter =
- sqs_list.rbegin();
- for (ListContainer<SharedQuadState>::ReverseIterator iter = list.rbegin();
- iter != list.rend();
- ++iter) {
- EXPECT_EQ(*sqs_iter, *iter);
- ++sqs_iter;
- }
- }
-
- {
- ListContainer<SharedQuadState>::ReverseIterator iter = list.rbegin();
- for (std::vector<SharedQuadState*>::reverse_iterator sqs_iter =
- sqs_list.rbegin();
- sqs_iter != sqs_list.rend();
- ++sqs_iter) {
- EXPECT_EQ(*sqs_iter, *iter);
- ++iter;
- }
- }
-}
-
-TEST(ListContainerTest, SimpleDeletion) {
- ListContainer<DrawQuad> list(kLargestQuadSize);
- std::vector<SimpleDrawQuad*> sdq_list;
- size_t size = 10;
- for (size_t i = 0; i < size; ++i) {
- sdq_list.push_back(list.AllocateAndConstruct<SimpleDrawQuad>());
- sdq_list.back()->set_value(i);
- }
- EXPECT_EQ(size, list.size());
-
- list.EraseAndInvalidateAllPointers(list.begin());
- --size;
- EXPECT_EQ(size, list.size());
- int i = 1;
- for (ListContainer<DrawQuad>::Iterator iter = list.begin();
- iter != list.end();
- ++iter) {
- EXPECT_EQ(i, static_cast<SimpleDrawQuad*>(*iter)->get_value());
- ++i;
- }
-}
-
-TEST(ListContainerTest, DeletionAllInAllocation) {
- const size_t kReserve = 10;
- ListContainer<DrawQuad> list(kLargestQuadSize, kReserve);
- std::vector<SimpleDrawQuad*> sdq_list;
- // Add enough quads to cause another allocation.
- for (size_t i = 0; i < kReserve + 1; ++i) {
- sdq_list.push_back(list.AllocateAndConstruct<SimpleDrawQuad>());
- sdq_list.back()->set_value(static_cast<int>(i));
- }
- EXPECT_EQ(kReserve + 1, list.size());
-
- // Remove everything in the first allocation.
- for (size_t i = 0; i < kReserve; ++i)
- list.EraseAndInvalidateAllPointers(list.begin());
- EXPECT_EQ(1u, list.size());
-
- // The last quad is left.
- SimpleDrawQuad* quad = static_cast<SimpleDrawQuad*>(*list.begin());
- EXPECT_EQ(static_cast<int>(kReserve), quad->get_value());
-
- // Remove the quad from the 2nd allocation.
- list.EraseAndInvalidateAllPointers(list.begin());
- EXPECT_EQ(0u, list.size());
-}
-
-TEST(ListContainerTest, DeletionAllInAllocationReversed) {
- const size_t kReserve = 10;
- ListContainer<DrawQuad> list(kLargestQuadSize, kReserve);
- std::vector<SimpleDrawQuad*> sdq_list;
- // Add enough quads to cause another allocation.
- for (size_t i = 0; i < kReserve + 1; ++i) {
- sdq_list.push_back(list.AllocateAndConstruct<SimpleDrawQuad>());
- sdq_list.back()->set_value(static_cast<int>(i));
- }
- EXPECT_EQ(kReserve + 1, list.size());
-
- // Remove everything in the 2nd allocation.
- auto it = list.begin();
- for (size_t i = 0; i < kReserve; ++i)
- ++it;
- list.EraseAndInvalidateAllPointers(it);
-
- // The 2nd-last quad is next, and the rest of the quads exist.
- size_t i = kReserve - 1;
- for (auto it = list.rbegin(); it != list.rend(); ++it) {
- SimpleDrawQuad* quad = static_cast<SimpleDrawQuad*>(*it);
- EXPECT_EQ(static_cast<int>(i), quad->get_value());
- --i;
- }
-
- // Can forward iterate too.
- i = 0;
- for (auto it = list.begin(); it != list.end(); ++it) {
- SimpleDrawQuad* quad = static_cast<SimpleDrawQuad*>(*it);
- EXPECT_EQ(static_cast<int>(i), quad->get_value());
- ++i;
- }
-
- // Remove the last thing from the 1st allocation.
- it = list.begin();
- for (size_t i = 0; i < kReserve - 1; ++i)
- ++it;
- list.EraseAndInvalidateAllPointers(it);
-
- // The 2nd-last quad is next, and the rest of the quads exist.
- i = kReserve - 2;
- for (auto it = list.rbegin(); it != list.rend(); ++it) {
- SimpleDrawQuad* quad = static_cast<SimpleDrawQuad*>(*it);
- EXPECT_EQ(static_cast<int>(i), quad->get_value());
- --i;
- }
-
- // Can forward iterate too.
- i = 0;
- for (auto it = list.begin(); it != list.end(); ++it) {
- SimpleDrawQuad* quad = static_cast<SimpleDrawQuad*>(*it);
- EXPECT_EQ(static_cast<int>(i), quad->get_value());
- ++i;
- }
-}
-
-TEST(ListContainerTest, SimpleIterationAndManipulation) {
- ListContainer<DrawQuad> list(kLargestQuadSize);
- std::vector<SimpleDrawQuad*> sdq_list;
- size_t size = 10;
- for (size_t i = 0; i < size; ++i) {
- SimpleDrawQuad* simple_dq = list.AllocateAndConstruct<SimpleDrawQuad>();
- sdq_list.push_back(simple_dq);
- }
- EXPECT_EQ(size, list.size());
-
- ListContainer<DrawQuad>::Iterator iter = list.begin();
- for (int i = 0; i < 10; ++i) {
- static_cast<SimpleDrawQuad*>(*iter)->set_value(i);
- ++iter;
- }
-
- int i = 0;
- for (std::vector<SimpleDrawQuad*>::const_iterator sdq_iter = sdq_list.begin();
- sdq_iter < sdq_list.end();
- ++sdq_iter) {
- EXPECT_EQ(i, (*sdq_iter)->get_value());
- ++i;
- }
-}
-
-TEST(ListContainerTest, SimpleManipulationWithIndexSimpleDrawQuad) {
- ListContainer<DrawQuad> list(kLargestQuadSize);
- std::vector<SimpleDrawQuad*> dq_list;
- size_t size = 10;
- for (size_t i = 0; i < size; ++i) {
- dq_list.push_back(list.AllocateAndConstruct<SimpleDrawQuad>());
- }
- EXPECT_EQ(size, list.size());
-
- for (size_t i = 0; i < size; ++i) {
- static_cast<SimpleDrawQuad*>(list.ElementAt(i))->set_value(i);
- }
-
- int i = 0;
- for (std::vector<SimpleDrawQuad*>::const_iterator dq_iter = dq_list.begin();
- dq_iter != dq_list.end();
- ++dq_iter, ++i) {
- EXPECT_EQ(i, (*dq_iter)->get_value());
- }
-}
-
-TEST(ListContainerTest,
- SimpleManipulationWithIndexMoreThanOneAllocationSimpleDrawQuad) {
- ListContainer<DrawQuad> list(LargestDrawQuadSize(), 2);
- std::vector<SimpleDrawQuad*> dq_list;
- size_t size = 10;
- for (size_t i = 0; i < size; ++i) {
- dq_list.push_back(list.AllocateAndConstruct<SimpleDrawQuad>());
- }
- EXPECT_EQ(size, list.size());
-
- for (size_t i = 0; i < size; ++i) {
- static_cast<SimpleDrawQuad*>(list.ElementAt(i))->set_value(i);
- }
-
- int i = 0;
- for (std::vector<SimpleDrawQuad*>::const_iterator dq_iter = dq_list.begin();
- dq_iter != dq_list.end();
- ++dq_iter, ++i) {
- EXPECT_EQ(i, (*dq_iter)->get_value());
- }
-}
-
-TEST(ListContainerTest,
- SimpleIterationAndReverseIterationWithIndexSharedQuadState) {
- ListContainer<SharedQuadState> list;
- std::vector<SharedQuadState*> sqs_list;
- size_t size = 10;
- for (size_t i = 0; i < size; ++i) {
- sqs_list.push_back(list.AllocateAndConstruct<SharedQuadState>());
- }
- EXPECT_EQ(size, list.size());
-
- size_t i = 0;
- for (ListContainer<SharedQuadState>::Iterator iter = list.begin();
- iter != list.end();
- ++iter) {
- EXPECT_EQ(i, iter.index());
- ++i;
- }
-
- i = 0;
- for (ListContainer<SharedQuadState>::ReverseIterator iter = list.rbegin();
- iter != list.rend();
- ++iter) {
- EXPECT_EQ(i, iter.index());
- ++i;
- }
-}
-
-} // namespace
-} // namespace cc
diff --git a/chromium/cc/quads/picture_draw_quad.cc b/chromium/cc/quads/picture_draw_quad.cc
index af6fba12db0..b98fa90b10e 100644
--- a/chromium/cc/quads/picture_draw_quad.cc
+++ b/chromium/cc/quads/picture_draw_quad.cc
@@ -73,12 +73,6 @@ void PictureDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
this->texture_format = texture_format;
}
-void PictureDrawQuad::IterateResources(
- const ResourceIteratorCallback& callback) {
- // TODO(danakj): Convert to TextureDrawQuad?
- NOTIMPLEMENTED();
-}
-
const PictureDrawQuad* PictureDrawQuad::MaterialCast(const DrawQuad* quad) {
DCHECK(quad->material == DrawQuad::PICTURE_CONTENT);
return static_cast<const PictureDrawQuad*>(quad);
diff --git a/chromium/cc/quads/picture_draw_quad.h b/chromium/cc/quads/picture_draw_quad.h
index 243a2f9d174..9a01a9be029 100644
--- a/chromium/cc/quads/picture_draw_quad.h
+++ b/chromium/cc/quads/picture_draw_quad.h
@@ -10,6 +10,7 @@
#include "cc/base/cc_export.h"
#include "cc/playback/raster_source.h"
#include "cc/quads/content_draw_quad_base.h"
+#include "cc/resources/resource_provider.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/size.h"
@@ -52,8 +53,6 @@ class CC_EXPORT PictureDrawQuad : public ContentDrawQuadBase {
scoped_refptr<RasterSource> raster_source;
ResourceFormat texture_format;
- void IterateResources(const ResourceIteratorCallback& callback) override;
-
static const PictureDrawQuad* MaterialCast(const DrawQuad* quad);
private:
diff --git a/chromium/cc/quads/render_pass.cc b/chromium/cc/quads/render_pass.cc
index 567145a82d6..5c4d98a33c9 100644
--- a/chromium/cc/quads/render_pass.cc
+++ b/chromium/cc/quads/render_pass.cc
@@ -6,6 +6,7 @@
#include <algorithm>
+#include "base/numerics/safe_conversions.h"
#include "base/trace_event/trace_event_argument.h"
#include "base/values.h"
#include "cc/base/math_util.h"
@@ -52,8 +53,7 @@ scoped_ptr<RenderPass> RenderPass::Create(size_t shared_quad_state_list_size,
}
RenderPass::RenderPass()
- : id(RenderPassId(-1, -1)),
- has_transparent_background(true),
+ : has_transparent_background(true),
quad_list(kDefaultNumQuadsToReserve),
shared_quad_state_list(sizeof(SharedQuadState),
kDefaultNumSharedQuadStatesToReserve) {
@@ -62,16 +62,14 @@ RenderPass::RenderPass()
// Each layer usually produces one shared quad state, so the number of layers
// is a good hint for what to reserve here.
RenderPass::RenderPass(size_t num_layers)
- : id(RenderPassId(-1, -1)),
- has_transparent_background(true),
+ : has_transparent_background(true),
quad_list(kDefaultNumQuadsToReserve),
shared_quad_state_list(sizeof(SharedQuadState), num_layers) {
}
RenderPass::RenderPass(size_t shared_quad_state_list_size,
size_t quad_list_size)
- : id(RenderPassId(-1, -1)),
- has_transparent_background(true),
+ : has_transparent_background(true),
quad_list(quad_list_size),
shared_quad_state_list(sizeof(SharedQuadState),
shared_quad_state_list_size) {
@@ -148,7 +146,6 @@ void RenderPass::SetNew(RenderPassId id,
const gfx::Rect& damage_rect,
const gfx::Transform& transform_to_root_target) {
DCHECK_GT(id.layer_id, 0);
- DCHECK_GE(id.index, 0);
DCHECK(damage_rect.IsEmpty() || output_rect.Contains(damage_rect))
<< "damage_rect: " << damage_rect.ToString()
<< " output_rect: " << output_rect.ToString();
@@ -168,7 +165,6 @@ void RenderPass::SetAll(RenderPassId id,
const gfx::Transform& transform_to_root_target,
bool has_transparent_background) {
DCHECK_GT(id.layer_id, 0);
- DCHECK_GE(id.index, 0);
this->id = id;
this->output_rect = output_rect;
@@ -185,7 +181,8 @@ void RenderPass::AsValueInto(base::trace_event::TracedValue* value) const {
MathUtil::AddToTracedValue("damage_rect", damage_rect, value);
value->SetBoolean("has_transparent_background", has_transparent_background);
- value->SetInteger("copy_requests", copy_requests.size());
+ value->SetInteger("copy_requests",
+ base::saturated_cast<int>(copy_requests.size()));
value->BeginArray("shared_quad_state_list");
for (const auto& shared_quad_state : shared_quad_state_list) {
diff --git a/chromium/cc/quads/render_pass.h b/chromium/cc/quads/render_pass.h
index 46a8084b387..14caeba7c7a 100644
--- a/chromium/cc/quads/render_pass.h
+++ b/chromium/cc/quads/render_pass.h
@@ -11,9 +11,10 @@
#include "base/callback.h"
#include "base/containers/hash_tables.h"
#include "cc/base/cc_export.h"
+#include "cc/base/list_container.h"
#include "cc/base/scoped_ptr_vector.h"
-#include "cc/quads/list_container.h"
#include "cc/quads/render_pass_id.h"
+#include "cc/surfaces/surface_id.h"
#include "skia/ext/refptr.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_f.h"
@@ -116,6 +117,10 @@ class CC_EXPORT RenderPass {
QuadList quad_list;
SharedQuadStateList shared_quad_state_list;
+ // This vector contains the complete set of SurfaceIds referenced by
+ // DrawQuads in quad_list.
+ std::vector<SurfaceId> referenced_surfaces;
+
protected:
explicit RenderPass(size_t num_layers);
RenderPass();
@@ -136,7 +141,7 @@ namespace BASE_HASH_NAMESPACE {
template <>
struct hash<cc::RenderPassId> {
size_t operator()(cc::RenderPassId key) const {
- return base::HashPair(key.layer_id, key.index);
+ return base::HashPair(key.layer_id, static_cast<int>(key.index));
}
};
} // namespace BASE_HASH_NAMESPACE
diff --git a/chromium/cc/quads/render_pass_draw_quad.cc b/chromium/cc/quads/render_pass_draw_quad.cc
index 963a1906ee7..47c976b96bc 100644
--- a/chromium/cc/quads/render_pass_draw_quad.cc
+++ b/chromium/cc/quads/render_pass_draw_quad.cc
@@ -12,9 +12,7 @@
namespace cc {
-RenderPassDrawQuad::RenderPassDrawQuad()
- : render_pass_id(RenderPassId(-1, -1)),
- mask_resource_id(static_cast<ResourceProvider::ResourceId>(-1)) {
+RenderPassDrawQuad::RenderPassDrawQuad() {
}
RenderPassDrawQuad::~RenderPassDrawQuad() {
@@ -24,14 +22,13 @@ void RenderPassDrawQuad::SetNew(const SharedQuadState* shared_quad_state,
const gfx::Rect& rect,
const gfx::Rect& visible_rect,
RenderPassId render_pass_id,
- ResourceProvider::ResourceId mask_resource_id,
+ ResourceId mask_resource_id,
const gfx::Vector2dF& mask_uv_scale,
const gfx::Size& mask_texture_size,
const FilterOperations& filters,
const gfx::Vector2dF& filters_scale,
const FilterOperations& background_filters) {
DCHECK_GT(render_pass_id.layer_id, 0);
- DCHECK_GE(render_pass_id.index, 0);
gfx::Rect opaque_rect;
bool needs_blending = false;
@@ -55,19 +52,19 @@ void RenderPassDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
const gfx::Rect& visible_rect,
bool needs_blending,
RenderPassId render_pass_id,
- ResourceProvider::ResourceId mask_resource_id,
+ ResourceId mask_resource_id,
const gfx::Vector2dF& mask_uv_scale,
const gfx::Size& mask_texture_size,
const FilterOperations& filters,
const gfx::Vector2dF& filters_scale,
const FilterOperations& background_filters) {
DCHECK_GT(render_pass_id.layer_id, 0);
- DCHECK_GE(render_pass_id.index, 0);
DrawQuad::SetAll(shared_quad_state, DrawQuad::RENDER_PASS, rect, opaque_rect,
visible_rect, needs_blending);
this->render_pass_id = render_pass_id;
- this->mask_resource_id = mask_resource_id;
+ resources.ids[kMaskResourceIdIndex] = mask_resource_id;
+ resources.count = mask_resource_id ? 1 : 0;
this->mask_uv_scale = mask_uv_scale;
this->mask_texture_size = mask_texture_size;
this->filters = filters;
@@ -75,12 +72,6 @@ void RenderPassDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
this->background_filters = background_filters;
}
-void RenderPassDrawQuad::IterateResources(
- const ResourceIteratorCallback& callback) {
- if (mask_resource_id)
- mask_resource_id = callback.Run(mask_resource_id);
-}
-
gfx::RectF RenderPassDrawQuad::MaskUVRect() const {
gfx::RectF mask_uv_rect((mask_uv_scale.x() * rect.x()) / rect.width(),
(mask_uv_scale.y() * rect.y()) / rect.height(),
@@ -98,13 +89,13 @@ const RenderPassDrawQuad* RenderPassDrawQuad::MaterialCast(
void RenderPassDrawQuad::ExtendValue(
base::trace_event::TracedValue* value) const {
TracedValue::SetIDRef(render_pass_id.AsTracingId(), value, "render_pass_id");
- value->SetInteger("mask_resource_id", mask_resource_id);
+ value->SetInteger("mask_resource_id", resources.ids[kMaskResourceIdIndex]);
MathUtil::AddToTracedValue("mask_texture_size", mask_texture_size, value);
MathUtil::AddToTracedValue("mask_uv_scale", mask_uv_scale, value);
- value->BeginDictionary("filters");
+ value->BeginArray("filters");
filters.AsValueInto(value);
- value->EndDictionary();
+ value->EndArray();
MathUtil::AddToTracedValue("filters_scale", filters_scale, value);
value->BeginDictionary("background_filters");
diff --git a/chromium/cc/quads/render_pass_draw_quad.h b/chromium/cc/quads/render_pass_draw_quad.h
index 758b8e85004..c0d6b52bf08 100644
--- a/chromium/cc/quads/render_pass_draw_quad.h
+++ b/chromium/cc/quads/render_pass_draw_quad.h
@@ -24,7 +24,7 @@ class CC_EXPORT RenderPassDrawQuad : public DrawQuad {
const gfx::Rect& rect,
const gfx::Rect& visible_rect,
RenderPassId render_pass_id,
- ResourceProvider::ResourceId mask_resource_id,
+ ResourceId mask_resource_id,
const gfx::Vector2dF& mask_uv_scale,
const gfx::Size& mask_texture_size,
const FilterOperations& filters,
@@ -37,7 +37,7 @@ class CC_EXPORT RenderPassDrawQuad : public DrawQuad {
const gfx::Rect& visible_rect,
bool needs_blending,
RenderPassId render_pass_id,
- ResourceProvider::ResourceId mask_resource_id,
+ ResourceId mask_resource_id,
const gfx::Vector2dF& mask_uv_scale,
const gfx::Size& mask_texture_size,
const FilterOperations& filters,
@@ -45,7 +45,6 @@ class CC_EXPORT RenderPassDrawQuad : public DrawQuad {
const FilterOperations& background_filters);
RenderPassId render_pass_id;
- ResourceProvider::ResourceId mask_resource_id;
gfx::Vector2dF mask_uv_scale;
gfx::Size mask_texture_size;
@@ -65,11 +64,15 @@ class CC_EXPORT RenderPassDrawQuad : public DrawQuad {
// Helper function to generate the normalized uv rect.
gfx::RectF MaskUVRect() const;
- void IterateResources(const ResourceIteratorCallback& callback) override;
+ ResourceId mask_resource_id() const {
+ return resources.ids[kMaskResourceIdIndex];
+ }
static const RenderPassDrawQuad* MaterialCast(const DrawQuad*);
private:
+ static const size_t kMaskResourceIdIndex = 0;
+
void ExtendValue(base::trace_event::TracedValue* value) const override;
};
diff --git a/chromium/cc/quads/render_pass_id.cc b/chromium/cc/quads/render_pass_id.cc
index a84582c5ce3..5fea6dc8cb2 100644
--- a/chromium/cc/quads/render_pass_id.cc
+++ b/chromium/cc/quads/render_pass_id.cc
@@ -9,7 +9,8 @@ namespace cc {
void* RenderPassId::AsTracingId() const {
static_assert(sizeof(size_t) <= sizeof(void*), // NOLINT
"size of size_t should not be greater than that of a pointer");
- return reinterpret_cast<void*>(base::HashPair(layer_id, index));
+ return reinterpret_cast<void*>(
+ base::HashPair(layer_id, static_cast<int>(index)));
}
} // namespace cc
diff --git a/chromium/cc/quads/render_pass_id.h b/chromium/cc/quads/render_pass_id.h
index 05541307a07..ebf6387e73c 100644
--- a/chromium/cc/quads/render_pass_id.h
+++ b/chromium/cc/quads/render_pass_id.h
@@ -14,9 +14,10 @@ namespace cc {
class CC_EXPORT RenderPassId {
public:
int layer_id;
- int index;
+ size_t index;
- RenderPassId(int layer_id, int index) : layer_id(layer_id), index(index) {}
+ RenderPassId() : layer_id(-1), index(0) {}
+ RenderPassId(int layer_id, size_t index) : layer_id(layer_id), index(index) {}
void* AsTracingId() const;
bool operator==(const RenderPassId& other) const {
diff --git a/chromium/cc/quads/render_pass_unittest.cc b/chromium/cc/quads/render_pass_unittest.cc
index e6f39bcab82..5ab8c3170c3 100644
--- a/chromium/cc/quads/render_pass_unittest.cc
+++ b/chromium/cc/quads/render_pass_unittest.cc
@@ -30,6 +30,7 @@ struct RenderPassSize {
gfx::Rect output_rect;
gfx::Rect damage_rect;
bool has_transparent_background;
+ std::vector<SurfaceId> referenced_surfaces;
ScopedPtrVector<CopyOutputRequest> copy_callbacks;
};
@@ -51,14 +52,15 @@ static void CompareRenderPassLists(const RenderPassList& expected_list,
EXPECT_EQ(expected->shared_quad_state_list.size(),
actual->shared_quad_state_list.size());
EXPECT_EQ(expected->quad_list.size(), actual->quad_list.size());
+ EXPECT_EQ(expected->referenced_surfaces, actual->referenced_surfaces);
for (auto exp_iter = expected->quad_list.cbegin(),
act_iter = actual->quad_list.cbegin();
exp_iter != expected->quad_list.cend();
++exp_iter, ++act_iter) {
EXPECT_EQ(exp_iter->rect.ToString(), act_iter->rect.ToString());
- EXPECT_EQ(exp_iter->shared_quad_state->content_bounds.ToString(),
- act_iter->shared_quad_state->content_bounds.ToString());
+ EXPECT_EQ(exp_iter->shared_quad_state->quad_layer_bounds.ToString(),
+ act_iter->shared_quad_state->quad_layer_bounds.ToString());
}
}
}
@@ -104,6 +106,7 @@ TEST(RenderPassTest, CopyShouldBeIdenticalExceptIdAndQuads) {
EXPECT_EQ(pass->damage_rect, copy->damage_rect);
EXPECT_EQ(pass->has_transparent_background, copy->has_transparent_background);
EXPECT_EQ(0u, copy->quad_list.size());
+ EXPECT_EQ(0u, copy->referenced_surfaces.size());
// The copy request should not be copied/duplicated.
EXPECT_EQ(1u, pass->copy_requests.size());
diff --git a/chromium/cc/quads/shared_quad_state.cc b/chromium/cc/quads/shared_quad_state.cc
index 5e46fcc24d7..e09cdaf9f3b 100644
--- a/chromium/cc/quads/shared_quad_state.cc
+++ b/chromium/cc/quads/shared_quad_state.cc
@@ -28,17 +28,17 @@ void SharedQuadState::CopyFrom(const SharedQuadState* other) {
*this = *other;
}
-void SharedQuadState::SetAll(const gfx::Transform& content_to_target_transform,
- const gfx::Size& content_bounds,
- const gfx::Rect& visible_content_rect,
+void SharedQuadState::SetAll(const gfx::Transform& quad_to_target_transform,
+ const gfx::Size& quad_layer_bounds,
+ const gfx::Rect& visible_quad_layer_rect,
const gfx::Rect& clip_rect,
bool is_clipped,
float opacity,
SkXfermode::Mode blend_mode,
int sorting_context_id) {
- this->content_to_target_transform = content_to_target_transform;
- this->content_bounds = content_bounds;
- this->visible_content_rect = visible_content_rect;
+ this->quad_to_target_transform = quad_to_target_transform;
+ this->quad_layer_bounds = quad_layer_bounds;
+ this->visible_quad_layer_rect = visible_quad_layer_rect;
this->clip_rect = clip_rect;
this->is_clipped = is_clipped;
this->opacity = opacity;
@@ -47,10 +47,10 @@ void SharedQuadState::SetAll(const gfx::Transform& content_to_target_transform,
}
void SharedQuadState::AsValueInto(base::trace_event::TracedValue* value) const {
- MathUtil::AddToTracedValue("transform", content_to_target_transform, value);
- MathUtil::AddToTracedValue("layer_content_bounds", content_bounds, value);
- MathUtil::AddToTracedValue("layer_visible_content_rect", visible_content_rect,
- value);
+ MathUtil::AddToTracedValue("transform", quad_to_target_transform, value);
+ MathUtil::AddToTracedValue("layer_content_bounds", quad_layer_bounds, value);
+ MathUtil::AddToTracedValue("layer_visible_content_rect",
+ visible_quad_layer_rect, value);
value->SetBoolean("is_clipped", is_clipped);
diff --git a/chromium/cc/quads/shared_quad_state.h b/chromium/cc/quads/shared_quad_state.h
index 6f0ef92908d..a66c7bcac2f 100644
--- a/chromium/cc/quads/shared_quad_state.h
+++ b/chromium/cc/quads/shared_quad_state.h
@@ -32,9 +32,9 @@ class CC_EXPORT SharedQuadState {
void CopyFrom(const SharedQuadState* other);
- void SetAll(const gfx::Transform& content_to_target_transform,
- const gfx::Size& content_bounds,
- const gfx::Rect& visible_content_rect,
+ void SetAll(const gfx::Transform& quad_to_target_transform,
+ const gfx::Size& layer_bounds,
+ const gfx::Rect& visible_layer_rect,
const gfx::Rect& clip_rect,
bool is_clipped,
float opacity,
@@ -42,12 +42,13 @@ class CC_EXPORT SharedQuadState {
int sorting_context_id);
void AsValueInto(base::trace_event::TracedValue* dict) const;
- // Transforms from quad's original content space to its target content space.
- gfx::Transform content_to_target_transform;
- // This size lives in the content space for the quad's originating layer.
- gfx::Size content_bounds;
- // This rect lives in the content space for the quad's originating layer.
- gfx::Rect visible_content_rect;
+ // Transforms quad rects into the target content space.
+ gfx::Transform quad_to_target_transform;
+ // The size of the quads' originating layer in the space of the quad rects.
+ gfx::Size quad_layer_bounds;
+ // The size of the visible area in the quads' originating layer, in the space
+ // of the quad rects.
+ gfx::Rect visible_quad_layer_rect;
// This rect lives in the target content space.
gfx::Rect clip_rect;
bool is_clipped;
diff --git a/chromium/cc/quads/solid_color_draw_quad.cc b/chromium/cc/quads/solid_color_draw_quad.cc
index 229e98b1426..f122e1c8b4b 100644
--- a/chromium/cc/quads/solid_color_draw_quad.cc
+++ b/chromium/cc/quads/solid_color_draw_quad.cc
@@ -39,9 +39,6 @@ void SolidColorDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
this->force_anti_aliasing_off = force_anti_aliasing_off;
}
-void SolidColorDrawQuad::IterateResources(
- const ResourceIteratorCallback& callback) {}
-
const SolidColorDrawQuad* SolidColorDrawQuad::MaterialCast(
const DrawQuad* quad) {
DCHECK(quad->material == DrawQuad::SOLID_COLOR);
diff --git a/chromium/cc/quads/solid_color_draw_quad.h b/chromium/cc/quads/solid_color_draw_quad.h
index f0f5f5a28b4..8b950411ded 100644
--- a/chromium/cc/quads/solid_color_draw_quad.h
+++ b/chromium/cc/quads/solid_color_draw_quad.h
@@ -33,8 +33,6 @@ class CC_EXPORT SolidColorDrawQuad : public DrawQuad {
SkColor color;
bool force_anti_aliasing_off;
- void IterateResources(const ResourceIteratorCallback& callback) override;
-
static const SolidColorDrawQuad* MaterialCast(const DrawQuad*);
private:
diff --git a/chromium/cc/quads/stream_video_draw_quad.cc b/chromium/cc/quads/stream_video_draw_quad.cc
index fb6f728ee2e..c25e5d5869c 100644
--- a/chromium/cc/quads/stream_video_draw_quad.cc
+++ b/chromium/cc/quads/stream_video_draw_quad.cc
@@ -11,18 +11,24 @@
namespace cc {
-StreamVideoDrawQuad::StreamVideoDrawQuad() : resource_id(0) {}
+StreamVideoDrawQuad::StreamVideoDrawQuad() {
+}
void StreamVideoDrawQuad::SetNew(const SharedQuadState* shared_quad_state,
const gfx::Rect& rect,
const gfx::Rect& opaque_rect,
const gfx::Rect& visible_rect,
unsigned resource_id,
+ gfx::Size resource_size_in_pixels,
+ bool allow_overlay,
const gfx::Transform& matrix) {
bool needs_blending = false;
DrawQuad::SetAll(shared_quad_state, DrawQuad::STREAM_VIDEO_CONTENT, rect,
opaque_rect, visible_rect, needs_blending);
- this->resource_id = resource_id;
+ resources.ids[kResourceIdIndex] = resource_id;
+ overlay_resources.size_in_pixels[kResourceIdIndex] = resource_size_in_pixels;
+ overlay_resources.allow_overlay[kResourceIdIndex] = allow_overlay;
+ resources.count = 1;
this->matrix = matrix;
}
@@ -32,18 +38,18 @@ void StreamVideoDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
const gfx::Rect& visible_rect,
bool needs_blending,
unsigned resource_id,
+ gfx::Size resource_size_in_pixels,
+ bool allow_overlay,
const gfx::Transform& matrix) {
DrawQuad::SetAll(shared_quad_state, DrawQuad::STREAM_VIDEO_CONTENT, rect,
opaque_rect, visible_rect, needs_blending);
- this->resource_id = resource_id;
+ resources.ids[kResourceIdIndex] = resource_id;
+ overlay_resources.size_in_pixels[kResourceIdIndex] = resource_size_in_pixels;
+ overlay_resources.allow_overlay[kResourceIdIndex] = allow_overlay;
+ resources.count = 1;
this->matrix = matrix;
}
-void StreamVideoDrawQuad::IterateResources(
- const ResourceIteratorCallback& callback) {
- resource_id = callback.Run(resource_id);
-}
-
const StreamVideoDrawQuad* StreamVideoDrawQuad::MaterialCast(
const DrawQuad* quad) {
DCHECK(quad->material == DrawQuad::STREAM_VIDEO_CONTENT);
@@ -52,8 +58,13 @@ const StreamVideoDrawQuad* StreamVideoDrawQuad::MaterialCast(
void StreamVideoDrawQuad::ExtendValue(
base::trace_event::TracedValue* value) const {
- value->SetInteger("resource_id", resource_id);
+ value->SetInteger("resource_id", resources.ids[kResourceIdIndex]);
MathUtil::AddToTracedValue("matrix", matrix, value);
}
+StreamVideoDrawQuad::OverlayResources::OverlayResources() {
+ for (size_t i = 0; i < Resources::kMaxResourceIdCount; ++i)
+ allow_overlay[i] = false;
+}
+
} // namespace cc
diff --git a/chromium/cc/quads/stream_video_draw_quad.h b/chromium/cc/quads/stream_video_draw_quad.h
index 45c28f2f957..519c35363ed 100644
--- a/chromium/cc/quads/stream_video_draw_quad.h
+++ b/chromium/cc/quads/stream_video_draw_quad.h
@@ -21,6 +21,8 @@ class CC_EXPORT StreamVideoDrawQuad : public DrawQuad {
const gfx::Rect& opaque_rect,
const gfx::Rect& visible_rect,
unsigned resource_id,
+ gfx::Size resource_size_in_pixels,
+ bool allow_overlay,
const gfx::Transform& matrix);
void SetAll(const SharedQuadState* shared_quad_state,
@@ -29,16 +31,33 @@ class CC_EXPORT StreamVideoDrawQuad : public DrawQuad {
const gfx::Rect& visible_rect,
bool needs_blending,
unsigned resource_id,
+ gfx::Size resource_size_in_pixels,
+ bool allow_overlay,
const gfx::Transform& matrix);
- unsigned resource_id;
gfx::Transform matrix;
- void IterateResources(const ResourceIteratorCallback& callback) override;
+ struct OverlayResources {
+ OverlayResources();
+
+ gfx::Size size_in_pixels[Resources::kMaxResourceIdCount];
+ bool allow_overlay[Resources::kMaxResourceIdCount];
+ };
+ OverlayResources overlay_resources;
static const StreamVideoDrawQuad* MaterialCast(const DrawQuad*);
+ ResourceId resource_id() const { return resources.ids[kResourceIdIndex]; }
+ const gfx::Size& resource_size_in_pixels() const {
+ return overlay_resources.size_in_pixels[kResourceIdIndex];
+ }
+ bool allow_overlay() const {
+ return overlay_resources.allow_overlay[kResourceIdIndex];
+ }
+
private:
+ static const size_t kResourceIdIndex = 0;
+
void ExtendValue(base::trace_event::TracedValue* value) const override;
};
diff --git a/chromium/cc/quads/surface_draw_quad.cc b/chromium/cc/quads/surface_draw_quad.cc
index 5823558ae68..655158152a6 100644
--- a/chromium/cc/quads/surface_draw_quad.cc
+++ b/chromium/cc/quads/surface_draw_quad.cc
@@ -35,9 +35,6 @@ void SurfaceDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
this->surface_id = surface_id;
}
-void SurfaceDrawQuad::IterateResources(
- const ResourceIteratorCallback& callback) {}
-
const SurfaceDrawQuad* SurfaceDrawQuad::MaterialCast(const DrawQuad* quad) {
DCHECK_EQ(quad->material, DrawQuad::SURFACE_CONTENT);
return static_cast<const SurfaceDrawQuad*>(quad);
diff --git a/chromium/cc/quads/surface_draw_quad.h b/chromium/cc/quads/surface_draw_quad.h
index 36dc8090895..86887cae8b3 100644
--- a/chromium/cc/quads/surface_draw_quad.h
+++ b/chromium/cc/quads/surface_draw_quad.h
@@ -30,8 +30,6 @@ class CC_EXPORT SurfaceDrawQuad : public DrawQuad {
SurfaceId surface_id;
- void IterateResources(const ResourceIteratorCallback& callback) override;
-
static const SurfaceDrawQuad* MaterialCast(const DrawQuad* quad);
private:
diff --git a/chromium/cc/quads/texture_draw_quad.cc b/chromium/cc/quads/texture_draw_quad.cc
index 4b8720a1ed7..c469c875138 100644
--- a/chromium/cc/quads/texture_draw_quad.cc
+++ b/chromium/cc/quads/texture_draw_quad.cc
@@ -13,8 +13,7 @@
namespace cc {
TextureDrawQuad::TextureDrawQuad()
- : resource_id(0),
- premultiplied_alpha(false),
+ : premultiplied_alpha(false),
background_color(SK_ColorTRANSPARENT),
y_flipped(false),
nearest_neighbor(false) {
@@ -40,7 +39,8 @@ void TextureDrawQuad::SetNew(const SharedQuadState* shared_quad_state,
|| vertex_opacity[2] != 1.0f || vertex_opacity[3] != 1.0f;
DrawQuad::SetAll(shared_quad_state, DrawQuad::TEXTURE_CONTENT, rect,
opaque_rect, visible_rect, needs_blending);
- this->resource_id = resource_id;
+ resources.ids[kResourceIdIndex] = resource_id;
+ resources.count = 1;
this->premultiplied_alpha = premultiplied_alpha;
this->uv_top_left = uv_top_left;
this->uv_bottom_right = uv_bottom_right;
@@ -59,6 +59,8 @@ void TextureDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
const gfx::Rect& visible_rect,
bool needs_blending,
unsigned resource_id,
+ gfx::Size resource_size_in_pixels,
+ bool allow_overlay,
bool premultiplied_alpha,
const gfx::PointF& uv_top_left,
const gfx::PointF& uv_bottom_right,
@@ -68,7 +70,10 @@ void TextureDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
bool nearest_neighbor) {
DrawQuad::SetAll(shared_quad_state, DrawQuad::TEXTURE_CONTENT, rect,
opaque_rect, visible_rect, needs_blending);
- this->resource_id = resource_id;
+ resources.ids[kResourceIdIndex] = resource_id;
+ overlay_resources.size_in_pixels[kResourceIdIndex] = resource_size_in_pixels;
+ overlay_resources.allow_overlay[kResourceIdIndex] = allow_overlay;
+ resources.count = 1;
this->premultiplied_alpha = premultiplied_alpha;
this->uv_top_left = uv_top_left;
this->uv_bottom_right = uv_bottom_right;
@@ -81,18 +86,13 @@ void TextureDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
this->nearest_neighbor = nearest_neighbor;
}
-void TextureDrawQuad::IterateResources(
- const ResourceIteratorCallback& callback) {
- resource_id = callback.Run(resource_id);
-}
-
const TextureDrawQuad* TextureDrawQuad::MaterialCast(const DrawQuad* quad) {
DCHECK(quad->material == DrawQuad::TEXTURE_CONTENT);
return static_cast<const TextureDrawQuad*>(quad);
}
void TextureDrawQuad::ExtendValue(base::trace_event::TracedValue* value) const {
- value->SetInteger("resource_id", resource_id);
+ value->SetInteger("resource_id", resources.ids[kResourceIdIndex]);
value->SetBoolean("premultiplied_alpha", premultiplied_alpha);
MathUtil::AddToTracedValue("uv_top_left", uv_top_left, value);
@@ -109,4 +109,9 @@ void TextureDrawQuad::ExtendValue(base::trace_event::TracedValue* value) const {
value->SetBoolean("nearest_neighbor", nearest_neighbor);
}
+TextureDrawQuad::OverlayResources::OverlayResources() {
+ for (size_t i = 0; i < Resources::kMaxResourceIdCount; ++i)
+ allow_overlay[i] = false;
+}
+
} // namespace cc
diff --git a/chromium/cc/quads/texture_draw_quad.h b/chromium/cc/quads/texture_draw_quad.h
index 70641492368..40c7623c5cd 100644
--- a/chromium/cc/quads/texture_draw_quad.h
+++ b/chromium/cc/quads/texture_draw_quad.h
@@ -35,6 +35,8 @@ class CC_EXPORT TextureDrawQuad : public DrawQuad {
const gfx::Rect& visible_rect,
bool needs_blending,
unsigned resource_id,
+ gfx::Size resource_size_in_pixels,
+ bool allow_overlay,
bool premultiplied_alpha,
const gfx::PointF& uv_top_left,
const gfx::PointF& uv_bottom_right,
@@ -43,7 +45,6 @@ class CC_EXPORT TextureDrawQuad : public DrawQuad {
bool y_flipped,
bool nearest_neighbor);
- unsigned resource_id;
bool premultiplied_alpha;
gfx::PointF uv_top_left;
gfx::PointF uv_bottom_right;
@@ -52,11 +53,33 @@ class CC_EXPORT TextureDrawQuad : public DrawQuad {
bool y_flipped;
bool nearest_neighbor;
- void IterateResources(const ResourceIteratorCallback& callback) override;
+ struct OverlayResources {
+ OverlayResources();
+
+ gfx::Size size_in_pixels[Resources::kMaxResourceIdCount];
+ bool allow_overlay[Resources::kMaxResourceIdCount];
+ };
+ OverlayResources overlay_resources;
+
+ ResourceId resource_id() const { return resources.ids[kResourceIdIndex]; }
+ const gfx::Size& resource_size_in_pixels() const {
+ return overlay_resources.size_in_pixels[kResourceIdIndex];
+ }
+ void set_resource_size_in_pixels(const gfx::Size& size_in_pixels) {
+ overlay_resources.size_in_pixels[kResourceIdIndex] = size_in_pixels;
+ }
+ bool allow_overlay() const {
+ return overlay_resources.allow_overlay[kResourceIdIndex];
+ }
+ void set_allow_overlay(bool allow_overlay) {
+ overlay_resources.allow_overlay[kResourceIdIndex] = allow_overlay;
+ }
static const TextureDrawQuad* MaterialCast(const DrawQuad*);
private:
+ static const size_t kResourceIdIndex = 0;
+
void ExtendValue(base::trace_event::TracedValue* value) const override;
};
diff --git a/chromium/cc/quads/tile_draw_quad.cc b/chromium/cc/quads/tile_draw_quad.cc
index aa8f748d8b8..02c4a1e25a5 100644
--- a/chromium/cc/quads/tile_draw_quad.cc
+++ b/chromium/cc/quads/tile_draw_quad.cc
@@ -10,8 +10,7 @@
namespace cc {
-TileDrawQuad::TileDrawQuad()
- : resource_id(0) {
+TileDrawQuad::TileDrawQuad() {
}
TileDrawQuad::~TileDrawQuad() {
@@ -35,7 +34,8 @@ void TileDrawQuad::SetNew(const SharedQuadState* shared_quad_state,
texture_size,
swizzle_contents,
nearest_neighbor);
- this->resource_id = resource_id;
+ resources.ids[kResourceIdIndex] = resource_id;
+ resources.count = 1;
}
void TileDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
@@ -52,12 +52,8 @@ void TileDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
opaque_rect, visible_rect, needs_blending,
tex_coord_rect, texture_size, swizzle_contents,
nearest_neighbor);
- this->resource_id = resource_id;
-}
-
-void TileDrawQuad::IterateResources(
- const ResourceIteratorCallback& callback) {
- resource_id = callback.Run(resource_id);
+ resources.ids[kResourceIdIndex] = resource_id;
+ resources.count = 1;
}
const TileDrawQuad* TileDrawQuad::MaterialCast(const DrawQuad* quad) {
@@ -67,7 +63,7 @@ const TileDrawQuad* TileDrawQuad::MaterialCast(const DrawQuad* quad) {
void TileDrawQuad::ExtendValue(base::trace_event::TracedValue* value) const {
ContentDrawQuadBase::ExtendValue(value);
- value->SetInteger("resource_id", resource_id);
+ value->SetInteger("resource_id", resources.ids[kResourceIdIndex]);
}
} // namespace cc
diff --git a/chromium/cc/quads/tile_draw_quad.h b/chromium/cc/quads/tile_draw_quad.h
index b858e148d23..feb9e87c7cc 100644
--- a/chromium/cc/quads/tile_draw_quad.h
+++ b/chromium/cc/quads/tile_draw_quad.h
@@ -41,13 +41,13 @@ class CC_EXPORT TileDrawQuad : public ContentDrawQuadBase {
bool swizzle_contents,
bool nearest_neighbor);
- unsigned resource_id;
-
- void IterateResources(const ResourceIteratorCallback& callback) override;
-
static const TileDrawQuad* MaterialCast(const DrawQuad*);
+ ResourceId resource_id() const { return resources.ids[kResourceIdIndex]; }
+
private:
+ static const size_t kResourceIdIndex = 0;
+
void ExtendValue(base::trace_event::TracedValue* value) const override;
};
diff --git a/chromium/cc/quads/yuv_video_draw_quad.cc b/chromium/cc/quads/yuv_video_draw_quad.cc
index 5706f288cd5..f9a878a93e9 100644
--- a/chromium/cc/quads/yuv_video_draw_quad.cc
+++ b/chromium/cc/quads/yuv_video_draw_quad.cc
@@ -11,11 +11,8 @@
namespace cc {
-YUVVideoDrawQuad::YUVVideoDrawQuad()
- : y_plane_resource_id(0),
- u_plane_resource_id(0),
- v_plane_resource_id(0),
- a_plane_resource_id(0) {}
+YUVVideoDrawQuad::YUVVideoDrawQuad() {
+}
YUVVideoDrawQuad::~YUVVideoDrawQuad() {}
void YUVVideoDrawQuad::SetNew(const SharedQuadState* shared_quad_state,
@@ -38,10 +35,11 @@ void YUVVideoDrawQuad::SetNew(const SharedQuadState* shared_quad_state,
this->uv_tex_coord_rect = uv_tex_coord_rect;
this->ya_tex_size = ya_tex_size;
this->uv_tex_size = uv_tex_size;
- this->y_plane_resource_id = y_plane_resource_id;
- this->u_plane_resource_id = u_plane_resource_id;
- this->v_plane_resource_id = v_plane_resource_id;
- this->a_plane_resource_id = a_plane_resource_id;
+ resources.ids[kYPlaneResourceIdIndex] = y_plane_resource_id;
+ resources.ids[kUPlaneResourceIdIndex] = u_plane_resource_id;
+ resources.ids[kVPlaneResourceIdIndex] = v_plane_resource_id;
+ resources.ids[kAPlaneResourceIdIndex] = a_plane_resource_id;
+ resources.count = a_plane_resource_id ? 4 : 3;
this->color_space = color_space;
}
@@ -65,22 +63,14 @@ void YUVVideoDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
this->uv_tex_coord_rect = uv_tex_coord_rect;
this->ya_tex_size = ya_tex_size;
this->uv_tex_size = uv_tex_size;
- this->y_plane_resource_id = y_plane_resource_id;
- this->u_plane_resource_id = u_plane_resource_id;
- this->v_plane_resource_id = v_plane_resource_id;
- this->a_plane_resource_id = a_plane_resource_id;
+ resources.ids[kYPlaneResourceIdIndex] = y_plane_resource_id;
+ resources.ids[kUPlaneResourceIdIndex] = u_plane_resource_id;
+ resources.ids[kVPlaneResourceIdIndex] = v_plane_resource_id;
+ resources.ids[kAPlaneResourceIdIndex] = a_plane_resource_id;
+ resources.count = resources.ids[kAPlaneResourceIdIndex] ? 4 : 3;
this->color_space = color_space;
}
-void YUVVideoDrawQuad::IterateResources(
- const ResourceIteratorCallback& callback) {
- y_plane_resource_id = callback.Run(y_plane_resource_id);
- u_plane_resource_id = callback.Run(u_plane_resource_id);
- v_plane_resource_id = callback.Run(v_plane_resource_id);
- if (a_plane_resource_id)
- a_plane_resource_id = callback.Run(a_plane_resource_id);
-}
-
const YUVVideoDrawQuad* YUVVideoDrawQuad::MaterialCast(
const DrawQuad* quad) {
DCHECK(quad->material == DrawQuad::YUV_VIDEO_CONTENT);
@@ -93,10 +83,14 @@ void YUVVideoDrawQuad::ExtendValue(
MathUtil::AddToTracedValue("uv_tex_coord_rect", uv_tex_coord_rect, value);
MathUtil::AddToTracedValue("ya_tex_size", ya_tex_size, value);
MathUtil::AddToTracedValue("uv_tex_size", uv_tex_size, value);
- value->SetInteger("y_plane_resource_id", y_plane_resource_id);
- value->SetInteger("u_plane_resource_id", u_plane_resource_id);
- value->SetInteger("v_plane_resource_id", v_plane_resource_id);
- value->SetInteger("a_plane_resource_id", a_plane_resource_id);
+ value->SetInteger("y_plane_resource_id",
+ resources.ids[kYPlaneResourceIdIndex]);
+ value->SetInteger("u_plane_resource_id",
+ resources.ids[kUPlaneResourceIdIndex]);
+ value->SetInteger("v_plane_resource_id",
+ resources.ids[kVPlaneResourceIdIndex]);
+ value->SetInteger("a_plane_resource_id",
+ resources.ids[kAPlaneResourceIdIndex]);
}
} // namespace cc
diff --git a/chromium/cc/quads/yuv_video_draw_quad.h b/chromium/cc/quads/yuv_video_draw_quad.h
index deeca2c1cbc..53ef5710d20 100644
--- a/chromium/cc/quads/yuv_video_draw_quad.h
+++ b/chromium/cc/quads/yuv_video_draw_quad.h
@@ -64,17 +64,29 @@ class CC_EXPORT YUVVideoDrawQuad : public DrawQuad {
gfx::RectF uv_tex_coord_rect;
gfx::Size ya_tex_size;
gfx::Size uv_tex_size;
- unsigned y_plane_resource_id;
- unsigned u_plane_resource_id;
- unsigned v_plane_resource_id;
- unsigned a_plane_resource_id;
ColorSpace color_space;
- void IterateResources(const ResourceIteratorCallback& callback) override;
-
static const YUVVideoDrawQuad* MaterialCast(const DrawQuad*);
+ ResourceId y_plane_resource_id() const {
+ return resources.ids[kYPlaneResourceIdIndex];
+ }
+ ResourceId u_plane_resource_id() const {
+ return resources.ids[kUPlaneResourceIdIndex];
+ }
+ ResourceId v_plane_resource_id() const {
+ return resources.ids[kVPlaneResourceIdIndex];
+ }
+ ResourceId a_plane_resource_id() const {
+ return resources.ids[kAPlaneResourceIdIndex];
+ }
+
private:
+ static const size_t kYPlaneResourceIdIndex = 0;
+ static const size_t kUPlaneResourceIdIndex = 1;
+ static const size_t kVPlaneResourceIdIndex = 2;
+ static const size_t kAPlaneResourceIdIndex = 3;
+
void ExtendValue(base::trace_event::TracedValue* value) const override;
};
diff --git a/chromium/cc/raster/bitmap_tile_task_worker_pool.cc b/chromium/cc/raster/bitmap_tile_task_worker_pool.cc
index 1792a2053da..bd6af35215c 100644
--- a/chromium/cc/raster/bitmap_tile_task_worker_pool.cc
+++ b/chromium/cc/raster/bitmap_tile_task_worker_pool.cc
@@ -12,6 +12,7 @@
#include "cc/debug/traced_value.h"
#include "cc/playback/raster_source.h"
#include "cc/raster/raster_buffer.h"
+#include "cc/resources/platform_color.h"
#include "cc/resources/resource.h"
namespace cc {
@@ -20,21 +21,38 @@ namespace {
class RasterBufferImpl : public RasterBuffer {
public:
RasterBufferImpl(ResourceProvider* resource_provider,
- const Resource* resource)
- : lock_(resource_provider, resource->id()), resource_(resource) {}
+ const Resource* resource,
+ uint64_t resource_content_id,
+ uint64_t previous_content_id)
+ : lock_(resource_provider, resource->id()),
+ resource_(resource),
+ resource_has_previous_content_(
+ resource_content_id && resource_content_id == previous_content_id) {
+ }
// Overridden from RasterBuffer:
void Playback(const RasterSource* raster_source,
- const gfx::Rect& rect,
+ const gfx::Rect& raster_full_rect,
+ const gfx::Rect& raster_dirty_rect,
+ uint64_t new_content_id,
float scale) override {
- TileTaskWorkerPool::PlaybackToMemory(lock_.sk_bitmap().getPixels(),
- resource_->format(), resource_->size(),
- 0, raster_source, rect, scale);
+ gfx::Rect playback_rect = raster_full_rect;
+ if (resource_has_previous_content_) {
+ playback_rect.Intersect(raster_dirty_rect);
+ }
+ DCHECK(!playback_rect.IsEmpty())
+ << "Why are we rastering a tile that's not dirty?";
+
+ size_t stride = 0u;
+ TileTaskWorkerPool::PlaybackToMemory(
+ lock_.sk_bitmap().getPixels(), resource_->format(), resource_->size(),
+ stride, raster_source, raster_full_rect, playback_rect, scale);
}
private:
ResourceProvider::ScopedWriteLockSoftware lock_;
const Resource* resource_;
+ bool resource_has_previous_content_;
DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl);
};
@@ -89,7 +107,7 @@ void BitmapTileTaskWorkerPool::ScheduleTasks(TileTaskQueue* queue) {
// Mark all task sets as pending.
tasks_pending_.set();
- unsigned priority = kTileTaskPriorityBase;
+ size_t priority = kTileTaskPriorityBase;
graph_.Reset();
@@ -161,14 +179,20 @@ void BitmapTileTaskWorkerPool::CheckForCompletedTasks() {
completed_tasks_.clear();
}
-ResourceFormat BitmapTileTaskWorkerPool::GetResourceFormat() {
+ResourceFormat BitmapTileTaskWorkerPool::GetResourceFormat() const {
return resource_provider_->best_texture_format();
}
+bool BitmapTileTaskWorkerPool::GetResourceRequiresSwizzle() const {
+ return !PlatformColor::SameComponentOrder(GetResourceFormat());
+}
+
scoped_ptr<RasterBuffer> BitmapTileTaskWorkerPool::AcquireBufferForRaster(
- const Resource* resource) {
- return make_scoped_ptr<RasterBuffer>(
- new RasterBufferImpl(resource_provider_, resource));
+ const Resource* resource,
+ uint64_t resource_content_id,
+ uint64_t previous_content_id) {
+ return scoped_ptr<RasterBuffer>(new RasterBufferImpl(
+ resource_provider_, resource, resource_content_id, previous_content_id));
}
void BitmapTileTaskWorkerPool::ReleaseBufferForRaster(
diff --git a/chromium/cc/raster/bitmap_tile_task_worker_pool.h b/chromium/cc/raster/bitmap_tile_task_worker_pool.h
index 4fcfd5a33f9..3df206a09bd 100644
--- a/chromium/cc/raster/bitmap_tile_task_worker_pool.h
+++ b/chromium/cc/raster/bitmap_tile_task_worker_pool.h
@@ -38,11 +38,14 @@ class CC_EXPORT BitmapTileTaskWorkerPool : public TileTaskWorkerPool,
void Shutdown() override;
void ScheduleTasks(TileTaskQueue* queue) override;
void CheckForCompletedTasks() override;
- ResourceFormat GetResourceFormat() override;
+ ResourceFormat GetResourceFormat() const override;
+ bool GetResourceRequiresSwizzle() const override;
// Overridden from TileTaskClient:
scoped_ptr<RasterBuffer> AcquireBufferForRaster(
- const Resource* resource) override;
+ const Resource* resource,
+ uint64_t resource_content_id,
+ uint64_t previous_content_id) override;
void ReleaseBufferForRaster(scoped_ptr<RasterBuffer> buffer) override;
protected:
diff --git a/chromium/cc/raster/gpu_rasterizer.cc b/chromium/cc/raster/gpu_rasterizer.cc
index 17a9322bebe..176889494e7 100644
--- a/chromium/cc/raster/gpu_rasterizer.cc
+++ b/chromium/cc/raster/gpu_rasterizer.cc
@@ -41,7 +41,8 @@ GpuRasterizer::~GpuRasterizer() {
void GpuRasterizer::RasterizeSource(
ResourceProvider::ScopedWriteLockGr* write_lock,
const RasterSource* raster_source,
- const gfx::Rect& rect,
+ const gfx::Rect& raster_full_rect,
+ const gfx::Rect& playback_rect,
float scale) {
// Play back raster_source into temp SkPicture.
SkPictureRecorder recorder;
@@ -50,7 +51,8 @@ void GpuRasterizer::RasterizeSource(
skia::RefPtr<SkCanvas> canvas = skia::SharePtr(
recorder.beginRecording(size.width(), size.height(), NULL, flags));
canvas->save();
- raster_source->PlaybackToCanvas(canvas.get(), rect, scale);
+ raster_source->PlaybackToCanvas(canvas.get(), raster_full_rect, playback_rect,
+ scale);
canvas->restore();
skia::RefPtr<SkPicture> picture =
skia::AdoptRef(recorder.endRecordingAsPicture());
diff --git a/chromium/cc/raster/gpu_rasterizer.h b/chromium/cc/raster/gpu_rasterizer.h
index 443e6efeb85..76e8639869c 100644
--- a/chromium/cc/raster/gpu_rasterizer.h
+++ b/chromium/cc/raster/gpu_rasterizer.h
@@ -24,7 +24,8 @@ class CC_EXPORT GpuRasterizer {
void RasterizeSource(ResourceProvider::ScopedWriteLockGr* write_lock,
const RasterSource* raster_source,
- const gfx::Rect& rect,
+ const gfx::Rect& raster_full_rect,
+ const gfx::Rect& playback_rect,
float scale);
ResourceProvider* resource_provider() { return resource_provider_; }
diff --git a/chromium/cc/raster/gpu_tile_task_worker_pool.cc b/chromium/cc/raster/gpu_tile_task_worker_pool.cc
index 24a4710530e..7c21177d527 100644
--- a/chromium/cc/raster/gpu_tile_task_worker_pool.cc
+++ b/chromium/cc/raster/gpu_tile_task_worker_pool.cc
@@ -23,14 +23,21 @@ namespace {
class RasterBufferImpl : public RasterBuffer {
public:
- RasterBufferImpl(GpuRasterizer* rasterizer, const Resource* resource)
+ RasterBufferImpl(GpuRasterizer* rasterizer,
+ const Resource* resource,
+ uint64_t resource_content_id,
+ uint64_t previous_content_id)
: rasterizer_(rasterizer),
lock_(rasterizer->resource_provider(), resource->id()),
- resource_(resource) {}
+ resource_has_previous_content_(
+ resource_content_id && resource_content_id == previous_content_id) {
+ }
// Overridden from RasterBuffer:
void Playback(const RasterSource* raster_source,
- const gfx::Rect& rect,
+ const gfx::Rect& raster_full_rect,
+ const gfx::Rect& raster_dirty_rect,
+ uint64_t new_content_id,
float scale) override {
TRACE_EVENT0("cc", "RasterBufferImpl::Playback");
ContextProvider* context_provider = rasterizer_->resource_provider()
@@ -44,8 +51,17 @@ class RasterBufferImpl : public RasterBuffer {
// Allow this worker thread to bind to context_provider.
context_provider->DetachFromThread();
+ gfx::Rect playback_rect = raster_full_rect;
+ if (resource_has_previous_content_) {
+ playback_rect.Intersect(raster_dirty_rect);
+ }
+ DCHECK(!playback_rect.IsEmpty())
+ << "Why are we rastering a tile that's not dirty?";
+
+ // TODO(danakj): Implement partial raster with raster_dirty_rect.
// Rasterize source into resource.
- rasterizer_->RasterizeSource(&lock_, raster_source, rect, scale);
+ rasterizer_->RasterizeSource(&lock_, raster_source, raster_full_rect,
+ playback_rect, scale);
// Barrier to sync worker context output to cc context.
context_provider->ContextGL()->OrderingBarrierCHROMIUM();
@@ -57,7 +73,7 @@ class RasterBufferImpl : public RasterBuffer {
private:
GpuRasterizer* rasterizer_;
ResourceProvider::ScopedWriteLockGr lock_;
- const Resource* resource_;
+ bool resource_has_previous_content_;
DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl);
};
@@ -121,7 +137,7 @@ void GpuTileTaskWorkerPool::ScheduleTasks(TileTaskQueue* queue) {
// Mark all task sets as pending.
tasks_pending_.set();
- unsigned priority = kTileTaskPriorityBase;
+ size_t priority = kTileTaskPriorityBase;
graph_.Reset();
@@ -189,8 +205,13 @@ void GpuTileTaskWorkerPool::CheckForCompletedTasks() {
completed_tasks_.clear();
}
-ResourceFormat GpuTileTaskWorkerPool::GetResourceFormat() {
- return rasterizer_->resource_provider()->best_texture_format();
+ResourceFormat GpuTileTaskWorkerPool::GetResourceFormat() const {
+ return rasterizer_->resource_provider()->best_render_buffer_format();
+}
+
+bool GpuTileTaskWorkerPool::GetResourceRequiresSwizzle() const {
+ // This doesn't require a swizzle because we rasterize to the correct format.
+ return false;
}
void GpuTileTaskWorkerPool::CompleteTasks(const Task::Vector& tasks) {
@@ -207,9 +228,11 @@ void GpuTileTaskWorkerPool::CompleteTasks(const Task::Vector& tasks) {
}
scoped_ptr<RasterBuffer> GpuTileTaskWorkerPool::AcquireBufferForRaster(
- const Resource* resource) {
- return make_scoped_ptr<RasterBuffer>(
- new RasterBufferImpl(rasterizer_.get(), resource));
+ const Resource* resource,
+ uint64_t resource_content_id,
+ uint64_t previous_content_id) {
+ return scoped_ptr<RasterBuffer>(new RasterBufferImpl(
+ rasterizer_.get(), resource, resource_content_id, previous_content_id));
}
void GpuTileTaskWorkerPool::ReleaseBufferForRaster(
diff --git a/chromium/cc/raster/gpu_tile_task_worker_pool.h b/chromium/cc/raster/gpu_tile_task_worker_pool.h
index 4e35eaa380a..32a9d232550 100644
--- a/chromium/cc/raster/gpu_tile_task_worker_pool.h
+++ b/chromium/cc/raster/gpu_tile_task_worker_pool.h
@@ -36,11 +36,14 @@ class CC_EXPORT GpuTileTaskWorkerPool : public TileTaskWorkerPool,
void Shutdown() override;
void ScheduleTasks(TileTaskQueue* queue) override;
void CheckForCompletedTasks() override;
- ResourceFormat GetResourceFormat() override;
+ ResourceFormat GetResourceFormat() const override;
+ bool GetResourceRequiresSwizzle() const override;
// Overridden from TileTaskClient:
scoped_ptr<RasterBuffer> AcquireBufferForRaster(
- const Resource* resource) override;
+ const Resource* resource,
+ uint64_t resource_content_id,
+ uint64_t previous_content_id) override;
void ReleaseBufferForRaster(scoped_ptr<RasterBuffer> buffer) override;
private:
diff --git a/chromium/cc/raster/one_copy_tile_task_worker_pool.cc b/chromium/cc/raster/one_copy_tile_task_worker_pool.cc
index d504be8fbf6..78e6b106ce9 100644
--- a/chromium/cc/raster/one_copy_tile_task_worker_pool.cc
+++ b/chromium/cc/raster/one_copy_tile_task_worker_pool.cc
@@ -10,8 +10,10 @@
#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"
+#include "cc/base/math_util.h"
#include "cc/debug/traced_value.h"
#include "cc/raster/raster_buffer.h"
+#include "cc/resources/platform_color.h"
#include "cc/resources/resource_pool.h"
#include "cc/resources/scoped_resource.h"
#include "gpu/command_buffer/client/gles2_interface.h"
@@ -26,17 +28,32 @@ class RasterBufferImpl : public RasterBuffer {
ResourceProvider* resource_provider,
ResourcePool* resource_pool,
ResourceFormat resource_format,
- const Resource* resource)
+ const Resource* output_resource,
+ uint64_t previous_content_id)
: worker_pool_(worker_pool),
resource_provider_(resource_provider),
resource_pool_(resource_pool),
- resource_(resource),
- raster_resource_(
- resource_pool->AcquireResource(resource->size(), resource_format)),
- lock_(new ResourceProvider::ScopedWriteLockGpuMemoryBuffer(
- resource_provider_,
- raster_resource_->id())),
- sequence_(0) {}
+ output_resource_(output_resource),
+ raster_content_id_(0),
+ sequence_(0) {
+ if (worker_pool->have_persistent_gpu_memory_buffers() &&
+ previous_content_id) {
+ raster_resource_ =
+ resource_pool->TryAcquireResourceWithContentId(previous_content_id);
+ }
+ if (raster_resource_) {
+ raster_content_id_ = previous_content_id;
+ DCHECK_EQ(resource_format, raster_resource_->format());
+ DCHECK_EQ(output_resource->size().ToString(),
+ raster_resource_->size().ToString());
+ } else {
+ raster_resource_ = resource_pool->AcquireResource(output_resource->size(),
+ resource_format);
+ }
+
+ lock_.reset(new ResourceProvider::ScopedWriteLockGpuMemoryBuffer(
+ resource_provider_, raster_resource_->id()));
+ }
~RasterBufferImpl() override {
// Release write lock in case a copy was never scheduled.
@@ -47,26 +64,35 @@ class RasterBufferImpl : public RasterBuffer {
if (sequence_)
worker_pool_->AdvanceLastIssuedCopyTo(sequence_);
- // Return raster resource to pool so it can be used by another RasterBuffer
+ // Return resources to pool so they can be used by another RasterBuffer
// instance.
- if (raster_resource_)
- resource_pool_->ReleaseResource(raster_resource_.Pass());
+ resource_pool_->ReleaseResource(raster_resource_.Pass(),
+ raster_content_id_);
}
// Overridden from RasterBuffer:
void Playback(const RasterSource* raster_source,
- const gfx::Rect& rect,
+ const gfx::Rect& raster_full_rect,
+ const gfx::Rect& raster_dirty_rect,
+ uint64_t new_content_id,
float scale) override {
+ // If there's a raster_content_id_, we are reusing a resource with that
+ // content id.
+ bool reusing_raster_resource = raster_content_id_ != 0;
sequence_ = worker_pool_->PlaybackAndScheduleCopyOnWorkerThread(
- lock_.Pass(), raster_resource_.Pass(), resource_, raster_source, rect,
+ reusing_raster_resource, lock_.Pass(), raster_resource_.get(),
+ output_resource_, raster_source, raster_full_rect, raster_dirty_rect,
scale);
+ // Store the content id of the resource to return to the pool.
+ raster_content_id_ = new_content_id;
}
private:
OneCopyTileTaskWorkerPool* worker_pool_;
ResourceProvider* resource_provider_;
ResourcePool* resource_pool_;
- const Resource* resource_;
+ const Resource* output_resource_;
+ uint64_t raster_content_id_;
scoped_ptr<ScopedResource> raster_resource_;
scoped_ptr<ResourceProvider::ScopedWriteLockGpuMemoryBuffer> lock_;
CopySequenceNumber sequence_;
@@ -74,9 +100,6 @@ class RasterBufferImpl : public RasterBuffer {
DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl);
};
-// Flush interval when performing copy operations.
-const int kCopyFlushPeriod = 4;
-
// Number of in-flight copy operations to allow.
const int kMaxCopyOperations = 32;
@@ -87,13 +110,18 @@ const int kCheckForCompletedCopyOperationsTickRateMs = 1;
// wait for copy operations to complete if needed.
const int kFailedAttemptsBeforeWaitIfNeeded = 256;
+// 4MiB is the size of 4 512x512 tiles, which has proven to be a good
+// default batch size for copy operations.
+const int kMaxBytesPerCopyOperation = 1024 * 1024 * 4;
+
} // namespace
OneCopyTileTaskWorkerPool::CopyOperation::CopyOperation(
- scoped_ptr<ResourceProvider::ScopedWriteLockGpuMemoryBuffer> write_lock,
- scoped_ptr<ScopedResource> src,
- const Resource* dst)
- : write_lock(write_lock.Pass()), src(src.Pass()), dst(dst) {
+ scoped_ptr<ResourceProvider::ScopedWriteLockGpuMemoryBuffer> src_write_lock,
+ const Resource* src,
+ const Resource* dst,
+ const gfx::Rect& rect)
+ : src_write_lock(src_write_lock.Pass()), src(src), dst(dst), rect(rect) {
}
OneCopyTileTaskWorkerPool::CopyOperation::~CopyOperation() {
@@ -105,10 +133,13 @@ scoped_ptr<TileTaskWorkerPool> OneCopyTileTaskWorkerPool::Create(
TaskGraphRunner* task_graph_runner,
ContextProvider* context_provider,
ResourceProvider* resource_provider,
- ResourcePool* resource_pool) {
+ ResourcePool* resource_pool,
+ int max_copy_texture_chromium_size,
+ bool have_persistent_gpu_memory_buffers) {
return make_scoped_ptr<TileTaskWorkerPool>(new OneCopyTileTaskWorkerPool(
task_runner, task_graph_runner, context_provider, resource_provider,
- resource_pool));
+ resource_pool, max_copy_texture_chromium_size,
+ have_persistent_gpu_memory_buffers));
}
OneCopyTileTaskWorkerPool::OneCopyTileTaskWorkerPool(
@@ -116,18 +147,26 @@ OneCopyTileTaskWorkerPool::OneCopyTileTaskWorkerPool(
TaskGraphRunner* task_graph_runner,
ContextProvider* context_provider,
ResourceProvider* resource_provider,
- ResourcePool* resource_pool)
+ ResourcePool* resource_pool,
+ int max_copy_texture_chromium_size,
+ bool have_persistent_gpu_memory_buffers)
: task_runner_(task_runner),
task_graph_runner_(task_graph_runner),
namespace_token_(task_graph_runner->GetNamespaceToken()),
context_provider_(context_provider),
resource_provider_(resource_provider),
resource_pool_(resource_pool),
+ max_bytes_per_copy_operation_(
+ max_copy_texture_chromium_size
+ ? std::min(kMaxBytesPerCopyOperation,
+ max_copy_texture_chromium_size)
+ : kMaxBytesPerCopyOperation),
+ have_persistent_gpu_memory_buffers_(have_persistent_gpu_memory_buffers),
last_issued_copy_operation_(0),
last_flushed_copy_operation_(0),
lock_(),
copy_operation_count_cv_(&lock_),
- scheduled_copy_operation_count_(0),
+ bytes_scheduled_since_last_flush_(0),
issued_copy_operation_count_(0),
next_copy_operation_sequence_(1),
check_for_completed_copy_operations_pending_(false),
@@ -138,7 +177,7 @@ OneCopyTileTaskWorkerPool::OneCopyTileTaskWorkerPool(
}
OneCopyTileTaskWorkerPool::~OneCopyTileTaskWorkerPool() {
- DCHECK_EQ(scheduled_copy_operation_count_, 0u);
+ DCHECK_EQ(pending_copy_operations_.size(), 0u);
}
TileTaskRunner* OneCopyTileTaskWorkerPool::AsTileTaskRunner() {
@@ -180,7 +219,7 @@ void OneCopyTileTaskWorkerPool::ScheduleTasks(TileTaskQueue* queue) {
// Mark all task sets as pending.
tasks_pending_.set();
- unsigned priority = kTileTaskPriorityBase;
+ size_t priority = kTileTaskPriorityBase;
graph_.Reset();
@@ -257,17 +296,25 @@ void OneCopyTileTaskWorkerPool::CheckForCompletedTasks() {
completed_tasks_.clear();
}
-ResourceFormat OneCopyTileTaskWorkerPool::GetResourceFormat() {
+ResourceFormat OneCopyTileTaskWorkerPool::GetResourceFormat() const {
return resource_provider_->best_texture_format();
}
+bool OneCopyTileTaskWorkerPool::GetResourceRequiresSwizzle() const {
+ return !PlatformColor::SameComponentOrder(GetResourceFormat());
+}
+
scoped_ptr<RasterBuffer> OneCopyTileTaskWorkerPool::AcquireBufferForRaster(
- const Resource* resource) {
+ const Resource* resource,
+ uint64_t resource_content_id,
+ uint64_t previous_content_id) {
+ // TODO(danakj): If resource_content_id != 0, we only need to copy/upload
+ // the dirty rect.
DCHECK_EQ(resource->format(), resource_provider_->best_texture_format());
return make_scoped_ptr<RasterBuffer>(
new RasterBufferImpl(this, resource_provider_, resource_pool_,
- resource_provider_->best_texture_format(),
- resource));
+ resource_provider_->best_texture_format(), resource,
+ previous_content_id));
}
void OneCopyTileTaskWorkerPool::ReleaseBufferForRaster(
@@ -277,74 +324,108 @@ void OneCopyTileTaskWorkerPool::ReleaseBufferForRaster(
CopySequenceNumber
OneCopyTileTaskWorkerPool::PlaybackAndScheduleCopyOnWorkerThread(
- scoped_ptr<ResourceProvider::ScopedWriteLockGpuMemoryBuffer> write_lock,
- scoped_ptr<ScopedResource> src,
- const Resource* dst,
+ bool reusing_raster_resource,
+ scoped_ptr<ResourceProvider::ScopedWriteLockGpuMemoryBuffer>
+ raster_resource_write_lock,
+ const Resource* raster_resource,
+ const Resource* output_resource,
const RasterSource* raster_source,
- const gfx::Rect& rect,
+ const gfx::Rect& raster_full_rect,
+ const gfx::Rect& raster_dirty_rect,
float scale) {
- base::AutoLock lock(lock_);
-
- int failed_attempts = 0;
- while ((scheduled_copy_operation_count_ + issued_copy_operation_count_) >=
- kMaxCopyOperations) {
- // Ignore limit when shutdown is set.
- if (shutdown_)
- break;
-
- ++failed_attempts;
-
- // Schedule a check that will also wait for operations to complete
- // after too many failed attempts.
- bool wait_if_needed = failed_attempts > kFailedAttemptsBeforeWaitIfNeeded;
-
- // Schedule a check for completed copy operations if too many operations
- // are currently in-flight.
- ScheduleCheckForCompletedCopyOperationsWithLockAcquired(wait_if_needed);
-
- {
- TRACE_EVENT0("cc", "WaitingForCopyOperationsToComplete");
-
- // Wait for in-flight copy operations to drop below limit.
- copy_operation_count_cv_.Wait();
+ gfx::GpuMemoryBuffer* gpu_memory_buffer =
+ raster_resource_write_lock->GetGpuMemoryBuffer();
+ if (gpu_memory_buffer) {
+ void* data = NULL;
+ bool rv = gpu_memory_buffer->Map(&data);
+ DCHECK(rv);
+ int stride;
+ gpu_memory_buffer->GetStride(&stride);
+ // TileTaskWorkerPool::PlaybackToMemory only supports unsigned strides.
+ DCHECK_GE(stride, 0);
+
+ gfx::Rect playback_rect = raster_full_rect;
+ if (reusing_raster_resource) {
+ playback_rect.Intersect(raster_dirty_rect);
}
+ DCHECK(!playback_rect.IsEmpty())
+ << "Why are we rastering a tile that's not dirty?";
+ TileTaskWorkerPool::PlaybackToMemory(
+ data, raster_resource->format(), raster_resource->size(),
+ static_cast<size_t>(stride), raster_source, raster_full_rect,
+ playback_rect, scale);
+ gpu_memory_buffer->Unmap();
}
- // Increment |scheduled_copy_operation_count_| before releasing |lock_|.
- ++scheduled_copy_operation_count_;
-
- // There may be more work available, so wake up another worker thread.
- copy_operation_count_cv_.Signal();
+ base::AutoLock lock(lock_);
- {
- base::AutoUnlock unlock(lock_);
-
- gfx::GpuMemoryBuffer* gpu_memory_buffer = write_lock->GetGpuMemoryBuffer();
- if (gpu_memory_buffer) {
- void* data = NULL;
- bool rv = gpu_memory_buffer->Map(&data);
- DCHECK(rv);
- int stride;
- gpu_memory_buffer->GetStride(&stride);
- TileTaskWorkerPool::PlaybackToMemory(data, src->format(), src->size(),
- stride, raster_source, rect, scale);
- gpu_memory_buffer->Unmap();
+ CopySequenceNumber sequence = 0;
+ int bytes_per_row = (BitsPerPixel(raster_resource->format()) *
+ raster_resource->size().width()) /
+ 8;
+ int chunk_size_in_rows =
+ std::max(1, max_bytes_per_copy_operation_ / bytes_per_row);
+ // Align chunk size to 4. Required to support compressed texture formats.
+ chunk_size_in_rows = MathUtil::RoundUp(chunk_size_in_rows, 4);
+ int y = 0;
+ int height = raster_resource->size().height();
+ while (y < height) {
+ int failed_attempts = 0;
+ while ((pending_copy_operations_.size() + issued_copy_operation_count_) >=
+ kMaxCopyOperations) {
+ // Ignore limit when shutdown is set.
+ if (shutdown_)
+ break;
+
+ ++failed_attempts;
+
+ // Schedule a check that will also wait for operations to complete
+ // after too many failed attempts.
+ bool wait_if_needed = failed_attempts > kFailedAttemptsBeforeWaitIfNeeded;
+
+ // Schedule a check for completed copy operations if too many operations
+ // are currently in-flight.
+ ScheduleCheckForCompletedCopyOperationsWithLockAcquired(wait_if_needed);
+
+ {
+ TRACE_EVENT0("cc", "WaitingForCopyOperationsToComplete");
+
+ // Wait for in-flight copy operations to drop below limit.
+ copy_operation_count_cv_.Wait();
+ }
}
- }
-
- pending_copy_operations_.push_back(
- make_scoped_ptr(new CopyOperation(write_lock.Pass(), src.Pass(), dst)));
- // Acquire a sequence number for this copy operation.
- CopySequenceNumber sequence = next_copy_operation_sequence_++;
+ // There may be more work available, so wake up another worker thread.
+ copy_operation_count_cv_.Signal();
- // Post task that will advance last flushed copy operation to |sequence|
- // if we have reached the flush period.
- if ((sequence % kCopyFlushPeriod) == 0) {
- task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&OneCopyTileTaskWorkerPool::AdvanceLastFlushedCopyTo,
- weak_ptr_factory_.GetWeakPtr(), sequence));
+ // Copy at most |chunk_size_in_rows|.
+ int rows_to_copy = std::min(chunk_size_in_rows, height - y);
+ DCHECK_GT(rows_to_copy, 0);
+
+ // |raster_resource_write_lock| is passed to the first copy operation as it
+ // needs to be released before we can issue a copy.
+ pending_copy_operations_.push_back(make_scoped_ptr(new CopyOperation(
+ raster_resource_write_lock.Pass(), raster_resource, output_resource,
+ gfx::Rect(0, y, raster_resource->size().width(), rows_to_copy))));
+ y += rows_to_copy;
+
+ // Acquire a sequence number for this copy operation.
+ sequence = next_copy_operation_sequence_++;
+
+ // Increment |bytes_scheduled_since_last_flush_| by the amount of memory
+ // used for this copy operation.
+ bytes_scheduled_since_last_flush_ += rows_to_copy * bytes_per_row;
+
+ // Post task that will advance last flushed copy operation to |sequence|
+ // when |bytes_scheduled_since_last_flush_| has reached
+ // |max_bytes_per_copy_operation_|.
+ if (bytes_scheduled_since_last_flush_ >= max_bytes_per_copy_operation_) {
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&OneCopyTileTaskWorkerPool::AdvanceLastFlushedCopyTo,
+ weak_ptr_factory_.GetWeakPtr(), sequence));
+ bytes_scheduled_since_last_flush_ = 0;
+ }
}
return sequence;
@@ -400,11 +481,8 @@ void OneCopyTileTaskWorkerPool::IssueCopyOperations(int64 count) {
copy_operations.push_back(pending_copy_operations_.take_front());
}
- // Decrement |scheduled_copy_operation_count_| and increment
- // |issued_copy_operation_count_| to reflect the transition of copy
- // operations from "pending" to "issued" state.
- DCHECK_GE(scheduled_copy_operation_count_, copy_operations.size());
- scheduled_copy_operation_count_ -= copy_operations.size();
+ // Increment |issued_copy_operation_count_| to reflect the transition of
+ // copy operations from "pending" to "issued" state.
issued_copy_operation_count_ += copy_operations.size();
}
@@ -412,15 +490,12 @@ void OneCopyTileTaskWorkerPool::IssueCopyOperations(int64 count) {
scoped_ptr<CopyOperation> copy_operation = copy_operations.take_front();
// Remove the write lock.
- copy_operation->write_lock.reset();
+ copy_operation->src_write_lock.reset();
// Copy contents of source resource to destination resource.
resource_provider_->CopyResource(copy_operation->src->id(),
- copy_operation->dst->id());
-
- // Return source resource to pool where it can be reused once copy
- // operation has completed and resource is no longer busy.
- resource_pool_->ReleaseResource(copy_operation->src.Pass());
+ copy_operation->dst->id(),
+ copy_operation->rect);
}
}
@@ -496,16 +571,20 @@ OneCopyTileTaskWorkerPool::StateAsValue() const {
void OneCopyTileTaskWorkerPool::StagingStateAsValueInto(
base::trace_event::TracedValue* staging_state) const {
- staging_state->SetInteger("staging_resource_count",
- resource_pool_->total_resource_count());
- staging_state->SetInteger("bytes_used_for_staging_resources",
- resource_pool_->total_memory_usage_bytes());
- staging_state->SetInteger("pending_copy_count",
- resource_pool_->total_resource_count() -
- resource_pool_->acquired_resource_count());
- staging_state->SetInteger("bytes_pending_copy",
- resource_pool_->total_memory_usage_bytes() -
- resource_pool_->acquired_memory_usage_bytes());
+ staging_state->SetInteger(
+ "staging_resource_count",
+ static_cast<int>(resource_pool_->total_resource_count()));
+ staging_state->SetInteger(
+ "bytes_used_for_staging_resources",
+ static_cast<int>(resource_pool_->total_memory_usage_bytes()));
+ staging_state->SetInteger(
+ "pending_copy_count",
+ static_cast<int>(resource_pool_->total_resource_count() -
+ resource_pool_->acquired_resource_count()));
+ staging_state->SetInteger(
+ "bytes_pending_copy",
+ static_cast<int>(resource_pool_->total_memory_usage_bytes() -
+ resource_pool_->acquired_memory_usage_bytes()));
}
} // namespace cc
diff --git a/chromium/cc/raster/one_copy_tile_task_worker_pool.h b/chromium/cc/raster/one_copy_tile_task_worker_pool.h
index 35b8873033a..518aaa2d490 100644
--- a/chromium/cc/raster/one_copy_tile_task_worker_pool.h
+++ b/chromium/cc/raster/one_copy_tile_task_worker_pool.h
@@ -38,7 +38,9 @@ class CC_EXPORT OneCopyTileTaskWorkerPool : public TileTaskWorkerPool,
TaskGraphRunner* task_graph_runner,
ContextProvider* context_provider,
ResourceProvider* resource_provider,
- ResourcePool* resource_pool);
+ ResourcePool* resource_pool,
+ int max_copy_texture_chromium_size,
+ bool have_persistent_gpu_memory_buffers);
// Overridden from TileTaskWorkerPool:
TileTaskRunner* AsTileTaskRunner() override;
@@ -48,47 +50,62 @@ class CC_EXPORT OneCopyTileTaskWorkerPool : public TileTaskWorkerPool,
void Shutdown() override;
void ScheduleTasks(TileTaskQueue* queue) override;
void CheckForCompletedTasks() override;
- ResourceFormat GetResourceFormat() override;
+ ResourceFormat GetResourceFormat() const override;
+ bool GetResourceRequiresSwizzle() const override;
// Overridden from TileTaskClient:
scoped_ptr<RasterBuffer> AcquireBufferForRaster(
- const Resource* resource) override;
+ const Resource* resource,
+ uint64_t resource_content_id,
+ uint64_t previous_content_id) override;
void ReleaseBufferForRaster(scoped_ptr<RasterBuffer> buffer) override;
- // Playback raster source and schedule copy of |src| resource to |dst|
- // resource. Returns a non-zero sequence number for this copy operation.
+ // Playback raster source and schedule copy of |raster_resource| resource to
+ // |output_resource|. Returns a non-zero sequence number for this copy
+ // operation.
CopySequenceNumber PlaybackAndScheduleCopyOnWorkerThread(
- scoped_ptr<ResourceProvider::ScopedWriteLockGpuMemoryBuffer> write_lock,
- scoped_ptr<ScopedResource> src,
- const Resource* dst,
+ bool reusing_raster_resource,
+ scoped_ptr<ResourceProvider::ScopedWriteLockGpuMemoryBuffer>
+ raster_resource_write_lock,
+ const Resource* raster_resource,
+ const Resource* output_resource,
const RasterSource* raster_source,
- const gfx::Rect& rect,
+ const gfx::Rect& raster_full_rect,
+ const gfx::Rect& raster_dirty_rect,
float scale);
// Issues copy operations until |sequence| has been processed. This will
// return immediately if |sequence| has already been processed.
void AdvanceLastIssuedCopyTo(CopySequenceNumber sequence);
+ bool have_persistent_gpu_memory_buffers() const {
+ return have_persistent_gpu_memory_buffers_;
+ }
+
protected:
OneCopyTileTaskWorkerPool(base::SequencedTaskRunner* task_runner,
TaskGraphRunner* task_graph_runner,
ContextProvider* context_provider,
ResourceProvider* resource_provider,
- ResourcePool* resource_pool);
+ ResourcePool* resource_pool,
+ int max_copy_texture_chromium_size,
+ bool have_persistent_gpu_memory_buffers);
private:
struct CopyOperation {
typedef ScopedPtrDeque<CopyOperation> Deque;
- CopyOperation(
- scoped_ptr<ResourceProvider::ScopedWriteLockGpuMemoryBuffer> write_lock,
- scoped_ptr<ScopedResource> src,
- const Resource* dst);
+ CopyOperation(scoped_ptr<ResourceProvider::ScopedWriteLockGpuMemoryBuffer>
+ src_write_lock,
+ const Resource* src,
+ const Resource* dst,
+ const gfx::Rect& rect);
~CopyOperation();
- scoped_ptr<ResourceProvider::ScopedWriteLockGpuMemoryBuffer> write_lock;
- scoped_ptr<ScopedResource> src;
+ scoped_ptr<ResourceProvider::ScopedWriteLockGpuMemoryBuffer> src_write_lock;
+ const Resource* src;
const Resource* dst;
+ const gfx::Rect rect;
};
void OnTaskSetFinished(TaskSet task_set);
@@ -109,6 +126,8 @@ class CC_EXPORT OneCopyTileTaskWorkerPool : public TileTaskWorkerPool,
ContextProvider* context_provider_;
ResourceProvider* resource_provider_;
ResourcePool* resource_pool_;
+ const int max_bytes_per_copy_operation_;
+ const bool have_persistent_gpu_memory_buffers_;
TaskSetCollection tasks_pending_;
scoped_refptr<TileTask> task_set_finished_tasks_[kNumberOfTaskSets];
CopySequenceNumber last_issued_copy_operation_;
@@ -122,7 +141,7 @@ class CC_EXPORT OneCopyTileTaskWorkerPool : public TileTaskWorkerPool,
base::Lock lock_;
// |lock_| must be acquired when accessing the following members.
base::ConditionVariable copy_operation_count_cv_;
- size_t scheduled_copy_operation_count_;
+ int bytes_scheduled_since_last_flush_;
size_t issued_copy_operation_count_;
CopyOperation::Deque pending_copy_operations_;
CopySequenceNumber next_copy_operation_sequence_;
diff --git a/chromium/cc/raster/pixel_buffer_tile_task_worker_pool.cc b/chromium/cc/raster/pixel_buffer_tile_task_worker_pool.cc
index 674e145c534..df79519485d 100644
--- a/chromium/cc/raster/pixel_buffer_tile_task_worker_pool.cc
+++ b/chromium/cc/raster/pixel_buffer_tile_task_worker_pool.cc
@@ -12,6 +12,7 @@
#include "base/trace_event/trace_event_argument.h"
#include "cc/debug/traced_value.h"
#include "cc/raster/raster_buffer.h"
+#include "cc/resources/platform_color.h"
#include "cc/resources/resource.h"
#include "gpu/command_buffer/client/gles2_interface.h"
@@ -36,14 +37,19 @@ class RasterBufferImpl : public RasterBuffer {
// Overridden from RasterBuffer:
void Playback(const RasterSource* raster_source,
- const gfx::Rect& rect,
+ const gfx::Rect& raster_full_rect,
+ const gfx::Rect& raster_dirty_rect,
+ uint64_t new_content_id,
float scale) override {
if (!memory_)
return;
- TileTaskWorkerPool::PlaybackToMemory(memory_, resource_->format(),
- resource_->size(), stride_,
- raster_source, rect, scale);
+ // TileTaskWorkerPool::PlaybackToMemory only supports unsigned strides.
+ DCHECK_GE(stride_, 0);
+ TileTaskWorkerPool::PlaybackToMemory(
+ memory_, resource_->format(), resource_->size(),
+ static_cast<size_t>(stride_), raster_source, raster_full_rect,
+ raster_full_rect, scale);
}
private:
@@ -307,12 +313,18 @@ void PixelBufferTileTaskWorkerPool::CheckForCompletedTasks() {
completed_raster_tasks_.clear();
}
-ResourceFormat PixelBufferTileTaskWorkerPool::GetResourceFormat() {
+ResourceFormat PixelBufferTileTaskWorkerPool::GetResourceFormat() const {
return resource_provider_->memory_efficient_texture_format();
}
+bool PixelBufferTileTaskWorkerPool::GetResourceRequiresSwizzle() const {
+ return !PlatformColor::SameComponentOrder(GetResourceFormat());
+}
+
scoped_ptr<RasterBuffer> PixelBufferTileTaskWorkerPool::AcquireBufferForRaster(
- const Resource* resource) {
+ const Resource* resource,
+ uint64_t resource_content_id,
+ uint64_t previous_content_id) {
return make_scoped_ptr<RasterBuffer>(
new RasterBufferImpl(resource_provider_, resource));
}
@@ -424,7 +436,10 @@ void PixelBufferTileTaskWorkerPool::CheckForCompletedUploads() {
DCHECK(state_it != raster_task_states_.end());
RasterTaskState& state = *state_it;
- bytes_pending_upload_ -= task->resource()->bytes();
+ // We can use UncheckedMemorySizeBytes here, since these tasks come from
+ // tiles, the size of which is controlled by the compositor.
+ bytes_pending_upload_ -= Resource::UncheckedMemorySizeBytes(
+ task->resource()->size(), task->resource()->format());
task->WillComplete();
task->CompleteOnOriginThread(this);
@@ -493,7 +508,7 @@ void PixelBufferTileTaskWorkerPool::ScheduleMoreTasks() {
RasterTaskVector tasks[kNumberOfTaskSets];
- unsigned priority = kTileTaskPriorityBase;
+ size_t priority = kTileTaskPriorityBase;
graph_.Reset();
@@ -530,7 +545,10 @@ void PixelBufferTileTaskWorkerPool::ScheduleMoreTasks() {
// but if it's the only task allow it to complete no matter what its size,
// to prevent starvation of the task queue.
size_t new_bytes_pending_upload = bytes_pending_upload;
- new_bytes_pending_upload += task->resource()->bytes();
+ // We can use UncheckedMemorySizeBytes here, since these tasks come from
+ // tiles, the size of which is controlled by the compositor.
+ new_bytes_pending_upload += Resource::UncheckedMemorySizeBytes(
+ task->resource()->size(), task->resource()->format());
if (new_bytes_pending_upload > max_bytes_pending_upload_ &&
bytes_pending_upload) {
did_throttle_raster_tasks |= item.task_sets;
@@ -611,8 +629,8 @@ void PixelBufferTileTaskWorkerPool::ScheduleMoreTasks() {
task_set_finished_tasks_);
}
-unsigned PixelBufferTileTaskWorkerPool::PendingRasterTaskCount() const {
- unsigned num_completed_raster_tasks =
+size_t PixelBufferTileTaskWorkerPool::PendingRasterTaskCount() const {
+ size_t num_completed_raster_tasks =
raster_tasks_with_pending_upload_.size() + completed_raster_tasks_.size();
DCHECK_GE(raster_task_states_.size(), num_completed_raster_tasks);
return raster_task_states_.size() - num_completed_raster_tasks;
@@ -694,7 +712,10 @@ void PixelBufferTileTaskWorkerPool::CheckForCompletedRasterizerTasks() {
resource_provider_->BeginSetPixels(raster_task->resource()->id());
has_performed_uploads_since_last_flush_ = true;
- bytes_pending_upload_ += raster_task->resource()->bytes();
+ // We can use UncheckedMemorySizeBytes here, since these tasks come from
+ // tiles, the size of which is controlled by the compositor.
+ bytes_pending_upload_ += Resource::UncheckedMemorySizeBytes(
+ raster_task->resource()->size(), raster_task->resource()->format());
raster_tasks_with_pending_upload_.push_back(raster_task);
state.type = RasterTaskState::UPLOADING;
}
@@ -705,13 +726,14 @@ scoped_refptr<base::trace_event::ConvertableToTraceFormat>
PixelBufferTileTaskWorkerPool::StateAsValue() const {
scoped_refptr<base::trace_event::TracedValue> state =
new base::trace_event::TracedValue();
- state->SetInteger("completed_count", completed_raster_tasks_.size());
+ state->SetInteger("completed_count",
+ static_cast<int>(completed_raster_tasks_.size()));
state->BeginArray("pending_count");
for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set)
- state->AppendInteger(task_counts_[task_set]);
+ state->AppendInteger(static_cast<int>(task_counts_[task_set]));
state->EndArray();
state->SetInteger("pending_upload_count",
- raster_tasks_with_pending_upload_.size());
+ static_cast<int>(raster_tasks_with_pending_upload_.size()));
state->BeginDictionary("throttle_state");
ThrottleStateAsValueInto(state.get());
state->EndDictionary();
@@ -720,11 +742,13 @@ PixelBufferTileTaskWorkerPool::StateAsValue() const {
void PixelBufferTileTaskWorkerPool::ThrottleStateAsValueInto(
base::trace_event::TracedValue* throttle_state) const {
- throttle_state->SetInteger("bytes_available_for_upload",
- max_bytes_pending_upload_ - bytes_pending_upload_);
- throttle_state->SetInteger("bytes_pending_upload", bytes_pending_upload_);
+ throttle_state->SetInteger(
+ "bytes_available_for_upload",
+ static_cast<int>(max_bytes_pending_upload_ - bytes_pending_upload_));
+ throttle_state->SetInteger("bytes_pending_upload",
+ static_cast<int>(bytes_pending_upload_));
throttle_state->SetInteger("scheduled_raster_task_count",
- scheduled_raster_task_count_);
+ static_cast<int>(scheduled_raster_task_count_));
}
} // namespace cc
diff --git a/chromium/cc/raster/pixel_buffer_tile_task_worker_pool.h b/chromium/cc/raster/pixel_buffer_tile_task_worker_pool.h
index e6ddd39312d..2c6aeb98228 100644
--- a/chromium/cc/raster/pixel_buffer_tile_task_worker_pool.h
+++ b/chromium/cc/raster/pixel_buffer_tile_task_worker_pool.h
@@ -46,11 +46,14 @@ class CC_EXPORT PixelBufferTileTaskWorkerPool : public TileTaskWorkerPool,
void Shutdown() override;
void ScheduleTasks(TileTaskQueue* queue) override;
void CheckForCompletedTasks() override;
- ResourceFormat GetResourceFormat() override;
+ ResourceFormat GetResourceFormat() const override;
+ bool GetResourceRequiresSwizzle() const override;
// Overridden from TileTaskClient:
scoped_ptr<RasterBuffer> AcquireBufferForRaster(
- const Resource* resource) override;
+ const Resource* resource,
+ uint64_t resource_content_id,
+ uint64_t previous_content_id) override;
void ReleaseBufferForRaster(scoped_ptr<RasterBuffer> buffer) override;
private:
@@ -89,7 +92,7 @@ class CC_EXPORT PixelBufferTileTaskWorkerPool : public TileTaskWorkerPool,
void CheckForCompletedUploads();
void CheckForCompletedRasterTasks();
void ScheduleMoreTasks();
- unsigned PendingRasterTaskCount() const;
+ size_t PendingRasterTaskCount() const;
TaskSetCollection PendingTasks() const;
void CheckForCompletedRasterizerTasks();
diff --git a/chromium/cc/raster/raster_buffer.h b/chromium/cc/raster/raster_buffer.h
index 8f3a56200f6..5af4deca25b 100644
--- a/chromium/cc/raster/raster_buffer.h
+++ b/chromium/cc/raster/raster_buffer.h
@@ -17,7 +17,9 @@ class CC_EXPORT RasterBuffer {
virtual ~RasterBuffer();
virtual void Playback(const RasterSource* raster_source,
- const gfx::Rect& rect,
+ const gfx::Rect& raster_full_rect,
+ const gfx::Rect& raster_dirty_rect,
+ uint64_t new_content_id,
float scale) = 0;
};
diff --git a/chromium/cc/raster/task_graph_runner.h b/chromium/cc/raster/task_graph_runner.h
index a54984353b0..bb55afc19ae 100644
--- a/chromium/cc/raster/task_graph_runner.h
+++ b/chromium/cc/raster/task_graph_runner.h
@@ -53,11 +53,11 @@ struct CC_EXPORT TaskGraph {
typedef std::vector<Node> Vector;
- Node(Task* task, unsigned priority, size_t dependencies)
+ Node(Task* task, size_t priority, size_t dependencies)
: task(task), priority(priority), dependencies(dependencies) {}
Task* task;
- unsigned priority;
+ size_t priority;
size_t dependencies;
};
@@ -141,11 +141,11 @@ class CC_EXPORT TaskGraphRunner {
struct PrioritizedTask {
typedef std::vector<PrioritizedTask> Vector;
- PrioritizedTask(Task* task, unsigned priority)
+ PrioritizedTask(Task* task, size_t priority)
: task(task), priority(priority) {}
Task* task;
- unsigned priority;
+ size_t priority;
};
typedef std::vector<const Task*> TaskVector;
diff --git a/chromium/cc/raster/texture_compressor_etc1_unittest.cc b/chromium/cc/raster/texture_compressor_etc1_unittest.cc
index 98ccd77560f..d0c63f46f63 100644
--- a/chromium/cc/raster/texture_compressor_etc1_unittest.cc
+++ b/chromium/cc/raster/texture_compressor_etc1_unittest.cc
@@ -4,7 +4,6 @@
#include "cc/raster/texture_compressor.h"
-#include "cc/base/util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cc {
diff --git a/chromium/cc/raster/tile_task_runner.h b/chromium/cc/raster/tile_task_runner.h
index 234ca6f04ab..9dffee48c74 100644
--- a/chromium/cc/raster/tile_task_runner.h
+++ b/chromium/cc/raster/tile_task_runner.h
@@ -21,7 +21,9 @@ class RasterBuffer;
class CC_EXPORT TileTaskClient {
public:
virtual scoped_ptr<RasterBuffer> AcquireBufferForRaster(
- const Resource* resource) = 0;
+ const Resource* resource,
+ uint64_t resource_content_id,
+ uint64_t previous_content_id) = 0;
virtual void ReleaseBufferForRaster(scoped_ptr<RasterBuffer> buffer) = 0;
protected:
@@ -161,7 +163,10 @@ class CC_EXPORT TileTaskRunner {
virtual void CheckForCompletedTasks() = 0;
// Returns the format to use for the tiles.
- virtual ResourceFormat GetResourceFormat() = 0;
+ virtual ResourceFormat GetResourceFormat() const = 0;
+
+ // Determine if the resource requires swizzling.
+ virtual bool GetResourceRequiresSwizzle() const = 0;
protected:
virtual ~TileTaskRunner() {}
diff --git a/chromium/cc/raster/tile_task_worker_pool.cc b/chromium/cc/raster/tile_task_worker_pool.cc
index 477acc31263..d349514c4e8 100644
--- a/chromium/cc/raster/tile_task_worker_pool.cc
+++ b/chromium/cc/raster/tile_task_worker_pool.cc
@@ -52,14 +52,14 @@ class TaskSetFinishedTaskImpl : public TileTask {
// This allows a micro benchmark system to run tasks with highest priority,
// since it should finish as quickly as possible.
-unsigned TileTaskWorkerPool::kBenchmarkTaskPriority = 0u;
+size_t TileTaskWorkerPool::kBenchmarkTaskPriority = 0u;
// Task priorities that make sure task set finished tasks run before any
// other remaining tasks. This is combined with the task set type to ensure
// proper prioritization ordering between task set types.
-unsigned TileTaskWorkerPool::kTaskSetFinishedTaskPriorityBase = 1u;
+size_t TileTaskWorkerPool::kTaskSetFinishedTaskPriorityBase = 1u;
// For correctness, |kTileTaskPriorityBase| must be greater than
// |kTaskSetFinishedTaskPriorityBase + kNumberOfTaskSets|.
-unsigned TileTaskWorkerPool::kTileTaskPriorityBase = 10u;
+size_t TileTaskWorkerPool::kTileTaskPriorityBase = 10u;
TileTaskWorkerPool::TileTaskWorkerPool() {
}
@@ -96,7 +96,7 @@ void TileTaskWorkerPool::ScheduleTasksOnOriginThread(TileTaskClient* client,
// static
void TileTaskWorkerPool::InsertNodeForTask(TaskGraph* graph,
TileTask* task,
- unsigned priority,
+ size_t priority,
size_t dependencies) {
DCHECK(std::find_if(graph->nodes.begin(), graph->nodes.end(),
TaskGraph::Node::TaskComparator(task)) ==
@@ -109,7 +109,7 @@ void TileTaskWorkerPool::InsertNodesForRasterTask(
TaskGraph* graph,
RasterTask* raster_task,
const ImageDecodeTask::Vector& decode_tasks,
- unsigned priority) {
+ size_t priority) {
size_t dependencies = 0u;
// Insert image decode tasks.
@@ -157,9 +157,10 @@ static bool IsSupportedPlaybackToMemoryFormat(ResourceFormat format) {
void TileTaskWorkerPool::PlaybackToMemory(void* memory,
ResourceFormat format,
const gfx::Size& size,
- int stride,
+ size_t stride,
const RasterSource* raster_source,
- const gfx::Rect& rect,
+ const gfx::Rect& canvas_bitmap_rect,
+ const gfx::Rect& canvas_playback_rect,
float scale) {
DCHECK(IsSupportedPlaybackToMemoryFormat(format)) << format;
@@ -178,23 +179,26 @@ void TileTaskWorkerPool::PlaybackToMemory(void* memory,
if (!stride)
stride = info.minRowBytes();
- DCHECK_GT(stride, 0);
+ DCHECK_GT(stride, 0u);
if (!needs_copy) {
skia::RefPtr<SkSurface> surface = skia::AdoptRef(
SkSurface::NewRasterDirect(info, memory, stride, &surface_props));
skia::RefPtr<SkCanvas> canvas = skia::SharePtr(surface->getCanvas());
- raster_source->PlaybackToCanvas(canvas.get(), rect, scale);
+ raster_source->PlaybackToCanvas(canvas.get(), canvas_bitmap_rect,
+ canvas_playback_rect, scale);
return;
}
skia::RefPtr<SkSurface> surface =
skia::AdoptRef(SkSurface::NewRaster(info, &surface_props));
skia::RefPtr<SkCanvas> canvas = skia::SharePtr(surface->getCanvas());
- raster_source->PlaybackToCanvas(canvas.get(), rect, scale);
+ raster_source->PlaybackToCanvas(canvas.get(), canvas_bitmap_rect,
+ canvas_playback_rect, scale);
- SkImageInfo dst_info = info;
- dst_info.fColorType = buffer_color_type;
+ SkImageInfo dst_info =
+ SkImageInfo::Make(info.width(), info.height(), buffer_color_type,
+ info.alphaType(), info.profileType());
// TODO(kaanb): The GL pipeline assumes a 4-byte alignment for the
// bitmap data. There will be no need to call SkAlign4 once crbug.com/293728
// is fixed.
diff --git a/chromium/cc/raster/tile_task_worker_pool.h b/chromium/cc/raster/tile_task_worker_pool.h
index 75916f5dd6f..ff001890507 100644
--- a/chromium/cc/raster/tile_task_worker_pool.h
+++ b/chromium/cc/raster/tile_task_worker_pool.h
@@ -19,9 +19,9 @@ class RenderingStatsInstrumentation;
class CC_EXPORT TileTaskWorkerPool {
public:
- static unsigned kBenchmarkTaskPriority;
- static unsigned kTaskSetFinishedTaskPriorityBase;
- static unsigned kTileTaskPriorityBase;
+ static size_t kBenchmarkTaskPriority;
+ static size_t kTaskSetFinishedTaskPriorityBase;
+ static size_t kTileTaskPriorityBase;
TileTaskWorkerPool();
virtual ~TileTaskWorkerPool();
@@ -42,7 +42,7 @@ class CC_EXPORT TileTaskWorkerPool {
// |priority| values.
static void InsertNodeForTask(TaskGraph* graph,
TileTask* task,
- unsigned priority,
+ size_t priority,
size_t dependencies);
// Utility function that can be used to build a task graph. Inserts nodes that
@@ -51,16 +51,21 @@ class CC_EXPORT TileTaskWorkerPool {
TaskGraph* graph,
RasterTask* task,
const ImageDecodeTask::Vector& decode_tasks,
- unsigned priority);
+ size_t priority);
// Utility function that will create a temporary bitmap and copy pixels to
- // |memory| when necessary.
+ // |memory| when necessary. The |canvas_bitmap_rect| is the rect of the bitmap
+ // being played back in the pixel space of the source, ie a rect in the source
+ // that will cover the resulting |memory|. The |canvas_playback_rect| can be a
+ // smaller contained rect inside the |canvas_bitmap_rect| if the |memory| is
+ // already partially complete, and only the subrect needs to be played back.
static void PlaybackToMemory(void* memory,
ResourceFormat format,
const gfx::Size& size,
- int stride,
+ size_t stride,
const RasterSource* raster_source,
- const gfx::Rect& rect,
+ const gfx::Rect& canvas_bitmap_rect,
+ const gfx::Rect& canvas_playback_rect,
float scale);
// Type-checking downcast routine.
diff --git a/chromium/cc/raster/tile_task_worker_pool_perftest.cc b/chromium/cc/raster/tile_task_worker_pool_perftest.cc
index 508f966eeb7..b49c498ac05 100644
--- a/chromium/cc/raster/tile_task_worker_pool_perftest.cc
+++ b/chromium/cc/raster/tile_task_worker_pool_perftest.cc
@@ -21,6 +21,7 @@
#include "cc/resources/scoped_resource.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_output_surface_client.h"
+#include "cc/test/fake_resource_provider.h"
#include "cc/test/test_context_support.h"
#include "cc/test/test_gpu_memory_buffer_manager.h"
#include "cc/test/test_shared_bitmap_manager.h"
@@ -96,7 +97,6 @@ class PerfContextProvider : public ContextProvider {
}
void SetupLock() override {}
base::Lock* GetLock() override { return &context_lock_; }
- bool IsContextLost() override { return false; }
void VerifyContexts() override {}
void DeleteCachedResources() override {}
bool DestroyedOnMainThread() override { return false; }
@@ -160,7 +160,8 @@ class PerfRasterTaskImpl : public RasterTask {
// Overridden from TileTask:
void ScheduleOnOriginThread(TileTaskClient* client) override {
- raster_buffer_ = client->AcquireBufferForRaster(resource());
+ // No tile ids are given to support partial updates.
+ raster_buffer_ = client->AcquireBufferForRaster(resource(), 0, 0);
}
void CompleteOnOriginThread(TileTaskClient* client) override {
client->ReleaseBufferForRaster(raster_buffer_.Pass());
@@ -269,7 +270,8 @@ class TileTaskWorkerPoolPerfTest
tile_task_worker_pool_ = OneCopyTileTaskWorkerPool::Create(
task_runner_.get(), task_graph_runner_.get(),
context_provider_.get(), resource_provider_.get(),
- staging_resource_pool_.get());
+ staging_resource_pool_.get(), std::numeric_limits<int>::max(),
+ false);
break;
case TILE_TASK_WORKER_POOL_TYPE_GPU:
Create3dOutputSurfaceAndResourceProvider();
@@ -400,18 +402,16 @@ class TileTaskWorkerPoolPerfTest
void Create3dOutputSurfaceAndResourceProvider() {
output_surface_ = FakeOutputSurface::Create3d(context_provider_).Pass();
CHECK(output_surface_->BindToClient(&output_surface_client_));
- resource_provider_ = ResourceProvider::Create(output_surface_.get(), NULL,
- &gpu_memory_buffer_manager_,
- NULL, 0, false, 1).Pass();
+ resource_provider_ = FakeResourceProvider::Create(
+ output_surface_.get(), nullptr, &gpu_memory_buffer_manager_);
}
void CreateSoftwareOutputSurfaceAndResourceProvider() {
output_surface_ = FakeOutputSurface::CreateSoftware(
make_scoped_ptr(new SoftwareOutputDevice));
CHECK(output_surface_->BindToClient(&output_surface_client_));
- resource_provider_ =
- ResourceProvider::Create(output_surface_.get(), &shared_bitmap_manager_,
- NULL, NULL, 0, false, 1).Pass();
+ resource_provider_ = FakeResourceProvider::Create(
+ output_surface_.get(), &shared_bitmap_manager_, nullptr);
}
std::string TestModifierString() const {
@@ -481,8 +481,7 @@ class TileTaskWorkerPoolCommonPerfTest : public TileTaskWorkerPoolPerfTestBase,
output_surface_ = FakeOutputSurface::Create3d(context_provider_).Pass();
CHECK(output_surface_->BindToClient(&output_surface_client_));
resource_provider_ =
- ResourceProvider::Create(output_surface_.get(), NULL, NULL, NULL, 0,
- false, 1).Pass();
+ FakeResourceProvider::Create(output_surface_.get(), nullptr);
}
void RunBuildTileTaskQueueTest(const std::string& test_name,
diff --git a/chromium/cc/raster/tile_task_worker_pool_unittest.cc b/chromium/cc/raster/tile_task_worker_pool_unittest.cc
index 7394af59a90..76e5fe4d56f 100644
--- a/chromium/cc/raster/tile_task_worker_pool_unittest.cc
+++ b/chromium/cc/raster/tile_task_worker_pool_unittest.cc
@@ -28,6 +28,7 @@
#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_output_surface_client.h"
#include "cc/test/fake_picture_pile_impl.h"
+#include "cc/test/fake_resource_provider.h"
#include "cc/test/test_gpu_memory_buffer_manager.h"
#include "cc/test/test_shared_bitmap_manager.h"
#include "cc/test/test_task_graph_runner.h"
@@ -39,6 +40,8 @@ namespace cc {
namespace {
const size_t kMaxTransferBufferUsageBytes = 10000U;
+const size_t kMaxBytesPerCopyOperation = 1000U;
+
// A resource of this dimension^2 * 4 must be greater than the above transfer
// buffer constant.
const size_t kLargeResourceDimension = 1000U;
@@ -66,12 +69,16 @@ class TestRasterTaskImpl : public RasterTask {
// Overridden from Task:
void RunOnWorkerThread() override {
- raster_buffer_->Playback(picture_pile_.get(), gfx::Rect(0, 0, 1, 1), 1.0);
+ uint64_t new_content_id = 0;
+ raster_buffer_->Playback(picture_pile_.get(), gfx::Rect(1, 1),
+ gfx::Rect(1, 1), new_content_id, 1.f);
}
// Overridden from TileTask:
void ScheduleOnOriginThread(TileTaskClient* client) override {
- raster_buffer_ = client->AcquireBufferForRaster(resource());
+ // The raster buffer has no tile ids associated with it for partial update,
+ // so doesn't need to provide a valid dirty rect.
+ raster_buffer_ = client->AcquireBufferForRaster(resource(), 0, 0);
}
void CompleteOnOriginThread(TileTaskClient* client) override {
client->ReleaseBufferForRaster(raster_buffer_.Pass());
@@ -163,7 +170,7 @@ class TileTaskWorkerPoolTest
tile_task_worker_pool_ = OneCopyTileTaskWorkerPool::Create(
base::ThreadTaskRunnerHandle::Get().get(), &task_graph_runner_,
context_provider_.get(), resource_provider_.get(),
- staging_resource_pool_.get());
+ staging_resource_pool_.get(), kMaxBytesPerCopyOperation, false);
break;
case TILE_TASK_WORKER_POOL_TYPE_GPU:
Create3dOutputSurfaceAndResourceProvider();
@@ -287,23 +294,21 @@ class TileTaskWorkerPoolTest
private:
void Create3dOutputSurfaceAndResourceProvider() {
- output_surface_ = FakeOutputSurface::Create3d(
- context_provider_, worker_context_provider_).Pass();
+ output_surface_ = FakeOutputSurface::Create3d(context_provider_,
+ worker_context_provider_);
CHECK(output_surface_->BindToClient(&output_surface_client_));
TestWebGraphicsContext3D* context3d = context_provider_->TestContext3d();
context3d->set_support_sync_query(true);
- resource_provider_ = ResourceProvider::Create(output_surface_.get(), NULL,
- &gpu_memory_buffer_manager_,
- NULL, 0, false, 1).Pass();
+ resource_provider_ = FakeResourceProvider::Create(
+ output_surface_.get(), nullptr, &gpu_memory_buffer_manager_);
}
void CreateSoftwareOutputSurfaceAndResourceProvider() {
output_surface_ = FakeOutputSurface::CreateSoftware(
make_scoped_ptr(new SoftwareOutputDevice));
CHECK(output_surface_->BindToClient(&output_surface_client_));
- resource_provider_ =
- ResourceProvider::Create(output_surface_.get(), &shared_bitmap_manager_,
- NULL, NULL, 0, false, 1).Pass();
+ resource_provider_ = FakeResourceProvider::Create(
+ output_surface_.get(), &shared_bitmap_manager_, nullptr);
}
void OnTaskCompleted(scoped_ptr<ScopedResource> resource,
@@ -401,7 +406,9 @@ TEST_P(TileTaskWorkerPoolTest, LargeResources) {
ScopedResource::Create(resource_provider_.get()));
resource->Allocate(size, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
RGBA_8888);
- EXPECT_GE(resource->bytes(), kMaxTransferBufferUsageBytes);
+ EXPECT_GE(Resource::UncheckedMemorySizeBytes(resource->size(),
+ resource->format()),
+ kMaxTransferBufferUsageBytes);
}
AppendTask(0u, size);
@@ -429,6 +436,21 @@ TEST_P(TileTaskWorkerPoolTest, LostContext) {
EXPECT_FALSE(completed_tasks()[1].canceled);
}
+TEST_P(TileTaskWorkerPoolTest, ScheduleEmptyStillTriggersCallback) {
+ // Don't append any tasks, just call ScheduleTasks.
+ ScheduleTasks();
+
+ EXPECT_FALSE(completed_task_sets_[REQUIRED_FOR_ACTIVATION]);
+ EXPECT_FALSE(completed_task_sets_[REQUIRED_FOR_DRAW]);
+ EXPECT_FALSE(completed_task_sets_[ALL]);
+
+ RunMessageLoopUntilAllTasksHaveCompleted();
+
+ EXPECT_TRUE(completed_task_sets_[REQUIRED_FOR_ACTIVATION]);
+ EXPECT_TRUE(completed_task_sets_[REQUIRED_FOR_DRAW]);
+ EXPECT_TRUE(completed_task_sets_[ALL]);
+}
+
INSTANTIATE_TEST_CASE_P(
TileTaskWorkerPoolTests,
TileTaskWorkerPoolTest,
diff --git a/chromium/cc/raster/zero_copy_tile_task_worker_pool.cc b/chromium/cc/raster/zero_copy_tile_task_worker_pool.cc
index 5a1dc23058b..64fc5f453b3 100644
--- a/chromium/cc/raster/zero_copy_tile_task_worker_pool.cc
+++ b/chromium/cc/raster/zero_copy_tile_task_worker_pool.cc
@@ -11,6 +11,7 @@
#include "base/trace_event/trace_event_argument.h"
#include "cc/debug/traced_value.h"
#include "cc/raster/raster_buffer.h"
+#include "cc/resources/platform_color.h"
#include "cc/resources/resource.h"
#include "ui/gfx/gpu_memory_buffer.h"
@@ -25,20 +26,25 @@ class RasterBufferImpl : public RasterBuffer {
// Overridden from RasterBuffer:
void Playback(const RasterSource* raster_source,
- const gfx::Rect& rect,
+ const gfx::Rect& raster_full_rect,
+ const gfx::Rect& raster_dirty_rect,
+ uint64_t new_content_id,
float scale) override {
gfx::GpuMemoryBuffer* gpu_memory_buffer = lock_.GetGpuMemoryBuffer();
if (!gpu_memory_buffer)
return;
-
void* data = NULL;
bool rv = gpu_memory_buffer->Map(&data);
DCHECK(rv);
int stride;
gpu_memory_buffer->GetStride(&stride);
- TileTaskWorkerPool::PlaybackToMemory(data, resource_->format(),
- resource_->size(), stride,
- raster_source, rect, scale);
+ // TileTaskWorkerPool::PlaybackToMemory only supports unsigned strides.
+ DCHECK_GE(stride, 0);
+ // TODO(danakj): Implement partial raster with raster_dirty_rect.
+ TileTaskWorkerPool::PlaybackToMemory(
+ data, resource_->format(), resource_->size(),
+ static_cast<size_t>(stride), raster_source, raster_full_rect,
+ raster_full_rect, scale);
gpu_memory_buffer->Unmap();
}
@@ -99,7 +105,7 @@ void ZeroCopyTileTaskWorkerPool::ScheduleTasks(TileTaskQueue* queue) {
// Mark all task sets as pending.
tasks_pending_.set();
- unsigned priority = kTileTaskPriorityBase;
+ size_t priority = kTileTaskPriorityBase;
graph_.Reset();
@@ -171,12 +177,18 @@ void ZeroCopyTileTaskWorkerPool::CheckForCompletedTasks() {
completed_tasks_.clear();
}
-ResourceFormat ZeroCopyTileTaskWorkerPool::GetResourceFormat() {
+ResourceFormat ZeroCopyTileTaskWorkerPool::GetResourceFormat() const {
return resource_provider_->best_texture_format();
}
+bool ZeroCopyTileTaskWorkerPool::GetResourceRequiresSwizzle() const {
+ return !PlatformColor::SameComponentOrder(GetResourceFormat());
+}
+
scoped_ptr<RasterBuffer> ZeroCopyTileTaskWorkerPool::AcquireBufferForRaster(
- const Resource* resource) {
+ const Resource* resource,
+ uint64_t resource_content_id,
+ uint64_t previous_content_id) {
return make_scoped_ptr<RasterBuffer>(
new RasterBufferImpl(resource_provider_, resource));
}
diff --git a/chromium/cc/raster/zero_copy_tile_task_worker_pool.h b/chromium/cc/raster/zero_copy_tile_task_worker_pool.h
index 193eeda373d..7dcdff0a686 100644
--- a/chromium/cc/raster/zero_copy_tile_task_worker_pool.h
+++ b/chromium/cc/raster/zero_copy_tile_task_worker_pool.h
@@ -38,11 +38,14 @@ class CC_EXPORT ZeroCopyTileTaskWorkerPool : public TileTaskWorkerPool,
void Shutdown() override;
void ScheduleTasks(TileTaskQueue* queue) override;
void CheckForCompletedTasks() override;
- ResourceFormat GetResourceFormat() override;
+ ResourceFormat GetResourceFormat() const override;
+ bool GetResourceRequiresSwizzle() const override;
// Overridden from TileTaskClient:
scoped_ptr<RasterBuffer> AcquireBufferForRaster(
- const Resource* resource) override;
+ const Resource* resource,
+ uint64_t resource_content_id,
+ uint64_t previous_content_id) override;
void ReleaseBufferForRaster(scoped_ptr<RasterBuffer> buffer) override;
protected:
diff --git a/chromium/cc/resources/bitmap_content_layer_updater.cc b/chromium/cc/resources/bitmap_content_layer_updater.cc
deleted file mode 100644
index 31a62c3d7a9..00000000000
--- a/chromium/cc/resources/bitmap_content_layer_updater.cc
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/resources/bitmap_content_layer_updater.h"
-
-#include "cc/debug/devtools_instrumentation.h"
-#include "cc/debug/rendering_stats_instrumentation.h"
-#include "cc/resources/layer_painter.h"
-#include "cc/resources/prioritized_resource.h"
-#include "cc/resources/resource_update.h"
-#include "cc/resources/resource_update_queue.h"
-#include "skia/ext/platform_canvas.h"
-
-namespace cc {
-
-BitmapContentLayerUpdater::Resource::Resource(
- BitmapContentLayerUpdater* updater,
- scoped_ptr<PrioritizedResource> texture)
- : LayerUpdater::Resource(texture.Pass()), updater_(updater) {}
-
-BitmapContentLayerUpdater::Resource::~Resource() {}
-
-void BitmapContentLayerUpdater::Resource::Update(
- ResourceUpdateQueue* queue,
- const gfx::Rect& source_rect,
- const gfx::Vector2d& dest_offset,
- bool partial_update) {
- updater_->UpdateTexture(
- queue, texture(), source_rect, dest_offset, partial_update);
-}
-
-scoped_refptr<BitmapContentLayerUpdater> BitmapContentLayerUpdater::Create(
- scoped_ptr<LayerPainter> painter,
- int layer_id) {
- return make_scoped_refptr(
- new BitmapContentLayerUpdater(painter.Pass(),
- layer_id));
-}
-
-BitmapContentLayerUpdater::BitmapContentLayerUpdater(
- scoped_ptr<LayerPainter> painter,
- int layer_id)
- : ContentLayerUpdater(painter.Pass(), layer_id) {
-}
-
-BitmapContentLayerUpdater::~BitmapContentLayerUpdater() {}
-
-scoped_ptr<LayerUpdater::Resource> BitmapContentLayerUpdater::CreateResource(
- PrioritizedResourceManager* manager) {
- return make_scoped_ptr(
- new Resource(this, PrioritizedResource::Create(manager)));
-}
-
-void BitmapContentLayerUpdater::PrepareToUpdate(const gfx::Size& content_size,
- const gfx::Rect& paint_rect,
- const gfx::Size& tile_size,
- float contents_width_scale,
- float contents_height_scale) {
- if (canvas_size_ != paint_rect.size()) {
- devtools_instrumentation::ScopedLayerTask paint_setup(
- devtools_instrumentation::kPaintSetup, layer_id_);
- canvas_size_ = paint_rect.size();
- bitmap_backing_.allocN32Pixels(
- canvas_size_.width(), canvas_size_.height(), layer_is_opaque_);
- // TODO(danak): Remove when skia does the check for us: crbug.com/360384
- canvas_ = skia::AdoptRef(new SkCanvas(bitmap_backing_));
- DCHECK_EQ(paint_rect.width(), canvas_->getBaseLayerSize().width());
- DCHECK_EQ(paint_rect.height(), canvas_->getBaseLayerSize().height());
- }
-
- PaintContents(canvas_.get(),
- content_size,
- paint_rect,
- contents_width_scale,
- contents_height_scale);
-}
-
-void BitmapContentLayerUpdater::UpdateTexture(ResourceUpdateQueue* queue,
- PrioritizedResource* texture,
- const gfx::Rect& source_rect,
- const gfx::Vector2d& dest_offset,
- bool partial_update) {
- CHECK(canvas_);
- ResourceUpdate upload = ResourceUpdate::Create(
- texture, &bitmap_backing_, paint_rect(), source_rect, dest_offset);
- if (partial_update)
- queue->AppendPartialUpload(upload);
- else
- queue->AppendFullUpload(upload);
-}
-
-void BitmapContentLayerUpdater::ReduceMemoryUsage() {
- canvas_.clear();
- canvas_size_ = gfx::Size();
-}
-
-void BitmapContentLayerUpdater::SetOpaque(bool opaque) {
- if (opaque != layer_is_opaque_) {
- canvas_.clear();
- canvas_size_ = gfx::Size();
- }
-
- ContentLayerUpdater::SetOpaque(opaque);
-}
-
-} // namespace cc
diff --git a/chromium/cc/resources/bitmap_content_layer_updater.h b/chromium/cc/resources/bitmap_content_layer_updater.h
deleted file mode 100644
index 34776002000..00000000000
--- a/chromium/cc/resources/bitmap_content_layer_updater.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_RESOURCES_BITMAP_CONTENT_LAYER_UPDATER_H_
-#define CC_RESOURCES_BITMAP_CONTENT_LAYER_UPDATER_H_
-
-#include "cc/base/cc_export.h"
-#include "cc/resources/content_layer_updater.h"
-#include "skia/ext/refptr.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-
-class SkCanvas;
-
-namespace cc {
-
-class LayerPainter;
-class RenderingStatsInstrumenation;
-
-// This class rasterizes the content_rect into a skia bitmap canvas. It then
-// creates a ResourceUpdate with this bitmap canvas and inserts the
-// ResourceBundle to the provided ResourceUpdateQueue. Actual texture uploading
-// is done by ResourceUpdateController.
-class CC_EXPORT BitmapContentLayerUpdater : public ContentLayerUpdater {
- public:
- class Resource : public LayerUpdater::Resource {
- public:
- Resource(BitmapContentLayerUpdater* updater,
- scoped_ptr<PrioritizedResource> resource);
- ~Resource() override;
-
- void Update(ResourceUpdateQueue* queue,
- const gfx::Rect& source_rect,
- const gfx::Vector2d& dest_offset,
- bool partial_update) override;
-
- private:
- BitmapContentLayerUpdater* updater_;
-
- DISALLOW_COPY_AND_ASSIGN(Resource);
- };
-
- static scoped_refptr<BitmapContentLayerUpdater> Create(
- scoped_ptr<LayerPainter> painter,
- int layer_id);
-
- scoped_ptr<LayerUpdater::Resource> CreateResource(
- PrioritizedResourceManager* manager) override;
- void PrepareToUpdate(const gfx::Size& content_size,
- const gfx::Rect& paint_rect,
- const gfx::Size& tile_size,
- float contents_width_scale,
- float contents_height_scale) override;
- void UpdateTexture(ResourceUpdateQueue* queue,
- PrioritizedResource* resource,
- const gfx::Rect& source_rect,
- const gfx::Vector2d& dest_offset,
- bool partial_update);
- void SetOpaque(bool opaque) override;
- void ReduceMemoryUsage() override;
-
- protected:
- BitmapContentLayerUpdater(
- scoped_ptr<LayerPainter> painter,
- int layer_id);
- ~BitmapContentLayerUpdater() override;
-
- SkBitmap bitmap_backing_;
- skia::RefPtr<SkCanvas> canvas_;
- gfx::Size canvas_size_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(BitmapContentLayerUpdater);
-};
-
-} // namespace cc
-
-#endif // CC_RESOURCES_BITMAP_CONTENT_LAYER_UPDATER_H_
diff --git a/chromium/cc/resources/bitmap_skpicture_content_layer_updater.cc b/chromium/cc/resources/bitmap_skpicture_content_layer_updater.cc
deleted file mode 100644
index a78a9df4ded..00000000000
--- a/chromium/cc/resources/bitmap_skpicture_content_layer_updater.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/resources/bitmap_skpicture_content_layer_updater.h"
-
-#include "base/time/time.h"
-#include "cc/debug/rendering_stats_instrumentation.h"
-#include "cc/resources/layer_painter.h"
-#include "cc/resources/prioritized_resource.h"
-#include "cc/resources/resource_update_queue.h"
-#include "third_party/skia/include/core/SkCanvas.h"
-
-namespace cc {
-
-BitmapSkPictureContentLayerUpdater::Resource::Resource(
- BitmapSkPictureContentLayerUpdater* updater,
- scoped_ptr<PrioritizedResource> texture)
- : ContentLayerUpdater::Resource(texture.Pass()), updater_(updater) {}
-
-void BitmapSkPictureContentLayerUpdater::Resource::Update(
- ResourceUpdateQueue* queue,
- const gfx::Rect& source_rect,
- const gfx::Vector2d& dest_offset,
- bool partial_update) {
- SkAlphaType at =
- updater_->layer_is_opaque() ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
- bitmap_.allocPixels(SkImageInfo::Make(
- source_rect.width(), source_rect.height(), kN32_SkColorType, at));
- SkCanvas canvas(bitmap_);
- updater_->PaintContentsRect(&canvas, source_rect);
-
- ResourceUpdate upload = ResourceUpdate::Create(
- texture(), &bitmap_, source_rect, source_rect, dest_offset);
- if (partial_update)
- queue->AppendPartialUpload(upload);
- else
- queue->AppendFullUpload(upload);
-}
-
-scoped_refptr<BitmapSkPictureContentLayerUpdater>
-BitmapSkPictureContentLayerUpdater::Create(
- scoped_ptr<LayerPainter> painter,
- RenderingStatsInstrumentation* stats_instrumentation,
- int layer_id) {
- return make_scoped_refptr(
- new BitmapSkPictureContentLayerUpdater(painter.Pass(),
- stats_instrumentation,
- layer_id));
-}
-
-BitmapSkPictureContentLayerUpdater::BitmapSkPictureContentLayerUpdater(
- scoped_ptr<LayerPainter> painter,
- RenderingStatsInstrumentation* stats_instrumentation,
- int layer_id)
- : SkPictureContentLayerUpdater(painter.Pass(), layer_id) {
-}
-
-BitmapSkPictureContentLayerUpdater::~BitmapSkPictureContentLayerUpdater() {}
-
-scoped_ptr<LayerUpdater::Resource>
-BitmapSkPictureContentLayerUpdater::CreateResource(
- PrioritizedResourceManager* manager) {
- return make_scoped_ptr(
- new Resource(this, PrioritizedResource::Create(manager)));
-}
-
-void BitmapSkPictureContentLayerUpdater::PaintContentsRect(
- SkCanvas* canvas,
- const gfx::Rect& source_rect) {
- if (!canvas)
- return;
- // Translate the origin of content_rect to that of source_rect.
- canvas->translate(paint_rect().x() - source_rect.x(),
- paint_rect().y() - source_rect.y());
- DrawPicture(canvas);
-}
-
-} // namespace cc
diff --git a/chromium/cc/resources/bitmap_skpicture_content_layer_updater.h b/chromium/cc/resources/bitmap_skpicture_content_layer_updater.h
deleted file mode 100644
index ba22b2e5908..00000000000
--- a/chromium/cc/resources/bitmap_skpicture_content_layer_updater.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_RESOURCES_BITMAP_SKPICTURE_CONTENT_LAYER_UPDATER_H_
-#define CC_RESOURCES_BITMAP_SKPICTURE_CONTENT_LAYER_UPDATER_H_
-
-#include "cc/resources/skpicture_content_layer_updater.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-
-namespace cc {
-
-// This class records the content_rect into an SkPicture, then software
-// rasterizes the SkPicture into bitmaps for each tile. This implements
-// LayerTreeSettingSettings::per_tile_painting_enabled.
-class BitmapSkPictureContentLayerUpdater : public SkPictureContentLayerUpdater {
- public:
- class Resource : public ContentLayerUpdater::Resource {
- public:
- Resource(BitmapSkPictureContentLayerUpdater* updater,
- scoped_ptr<PrioritizedResource> texture);
-
- void Update(ResourceUpdateQueue* queue,
- const gfx::Rect& source_rect,
- const gfx::Vector2d& dest_offset,
- bool partial_update) override;
-
- private:
- SkBitmap bitmap_;
- BitmapSkPictureContentLayerUpdater* updater_;
-
- DISALLOW_COPY_AND_ASSIGN(Resource);
- };
-
- static scoped_refptr<BitmapSkPictureContentLayerUpdater> Create(
- scoped_ptr<LayerPainter> painter,
- RenderingStatsInstrumentation* stats_instrumentation,
- int layer_id);
-
- scoped_ptr<LayerUpdater::Resource> CreateResource(
- PrioritizedResourceManager* manager) override;
- void PaintContentsRect(SkCanvas* canvas,
- const gfx::Rect& source_rect);
-
- private:
- BitmapSkPictureContentLayerUpdater(
- scoped_ptr<LayerPainter> painter,
- RenderingStatsInstrumentation* stats_instrumentation,
- int layer_id);
- ~BitmapSkPictureContentLayerUpdater() override;
-
- DISALLOW_COPY_AND_ASSIGN(BitmapSkPictureContentLayerUpdater);
-};
-
-} // namespace cc
-
-#endif // CC_RESOURCES_BITMAP_SKPICTURE_CONTENT_LAYER_UPDATER_H_
diff --git a/chromium/cc/resources/content_layer_updater.cc b/chromium/cc/resources/content_layer_updater.cc
deleted file mode 100644
index 7101dd13d84..00000000000
--- a/chromium/cc/resources/content_layer_updater.cc
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/resources/content_layer_updater.h"
-
-#include "base/trace_event/trace_event.h"
-#include "cc/resources/layer_painter.h"
-#include "third_party/skia/include/core/SkCanvas.h"
-#include "third_party/skia/include/core/SkRect.h"
-#include "third_party/skia/include/core/SkScalar.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-#include "ui/gfx/geometry/rect_f.h"
-#include "ui/gfx/skia_util.h"
-
-namespace cc {
-
-ContentLayerUpdater::ContentLayerUpdater(scoped_ptr<LayerPainter> painter,
- int layer_id)
- : layer_id_(layer_id),
- layer_is_opaque_(false),
- layer_fills_bounds_completely_(false),
- painter_(painter.Pass()),
- background_color_(SK_ColorTRANSPARENT) {
-}
-
-ContentLayerUpdater::~ContentLayerUpdater() {}
-
-void ContentLayerUpdater::PaintContents(SkCanvas* canvas,
- const gfx::Size& layer_content_size,
- const gfx::Rect& paint_rect,
- float contents_width_scale,
- float contents_height_scale) {
- TRACE_EVENT0("cc", "ContentLayerUpdater::PaintContents");
- if (!canvas)
- return;
- canvas->save();
- canvas->translate(SkIntToScalar(-paint_rect.x()),
- SkIntToScalar(-paint_rect.y()));
-
- // The |canvas| backing should be sized to hold the |paint_rect|.
- DCHECK_EQ(paint_rect.width(), canvas->getBaseLayerSize().width());
- DCHECK_EQ(paint_rect.height(), canvas->getBaseLayerSize().height());
-
- const bool is_scaled =
- contents_width_scale != 1.f || contents_height_scale != 1.f;
-
- if (is_scaled && (layer_is_opaque_ || layer_fills_bounds_completely_)) {
- // Even if completely covered, for rasterizations that touch the edge of the
- // layer, we also need to raster the background color underneath the last
- // texel (since the paint won't cover it).
- //
- // The final texel of content may only be partially covered by a
- // rasterization; this rect represents the content rect that is fully
- // covered by content.
- const gfx::Rect layer_content_rect = gfx::Rect(layer_content_size);
- gfx::Rect deflated_layer_content_rect = layer_content_rect;
- deflated_layer_content_rect.Inset(0, 0, 1, 1);
-
- if (!layer_content_rect.Contains(deflated_layer_content_rect)) {
- // Drawing at most 1 x 1 x (canvas width + canvas height) texels is 2-3X
- // faster than clearing, so special case this.
- DCHECK_LE(paint_rect.right(), layer_content_rect.right());
- DCHECK_LE(paint_rect.bottom(), layer_content_rect.bottom());
- canvas->save();
- canvas->clipRect(gfx::RectToSkRect(layer_content_rect),
- SkRegion::kReplace_Op);
- canvas->clipRect(gfx::RectToSkRect(deflated_layer_content_rect),
- SkRegion::kDifference_Op);
- canvas->drawColor(background_color_, SkXfermode::kSrc_Mode);
- canvas->restore();
- }
- }
-
- gfx::Rect layer_rect;
- if (is_scaled) {
- canvas->scale(SkFloatToScalar(contents_width_scale),
- SkFloatToScalar(contents_height_scale));
-
- // NOTE: this may go beyond the bounds of the layer, but that shouldn't
- // cause problems (anything beyond the layer is clipped out).
- layer_rect = gfx::ScaleToEnclosingRect(
- paint_rect, 1.f / contents_width_scale, 1.f / contents_height_scale);
- } else {
- layer_rect = paint_rect;
- }
-
- SkRect layer_sk_rect = SkRect::MakeXYWH(
- layer_rect.x(), layer_rect.y(), layer_rect.width(), layer_rect.height());
-
- canvas->clipRect(layer_sk_rect);
-
- // If the layer has opaque contents or will fill the bounds completely there
- // is no need to clear the canvas before painting.
- if (!layer_is_opaque_ && !layer_fills_bounds_completely_) {
- TRACE_EVENT0("cc", "Clear");
- canvas->drawColor(SK_ColorTRANSPARENT, SkXfermode::kSrc_Mode);
- }
-
- painter_->Paint(canvas, layer_rect);
- canvas->restore();
-
- paint_rect_ = paint_rect;
-}
-
-void ContentLayerUpdater::SetOpaque(bool opaque) {
- layer_is_opaque_ = opaque;
-}
-
-void ContentLayerUpdater::SetFillsBoundsCompletely(bool fills_bounds) {
- layer_fills_bounds_completely_ = fills_bounds;
-}
-
-void ContentLayerUpdater::SetBackgroundColor(SkColor background_color) {
- background_color_ = background_color;
-}
-
-} // namespace cc
diff --git a/chromium/cc/resources/content_layer_updater.h b/chromium/cc/resources/content_layer_updater.h
deleted file mode 100644
index 0f26b820ff4..00000000000
--- a/chromium/cc/resources/content_layer_updater.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_RESOURCES_CONTENT_LAYER_UPDATER_H_
-#define CC_RESOURCES_CONTENT_LAYER_UPDATER_H_
-
-#include "cc/base/cc_export.h"
-#include "cc/resources/layer_updater.h"
-#include "ui/gfx/geometry/rect.h"
-
-class SkCanvas;
-
-namespace cc {
-
-class LayerPainter;
-class RenderingStatsInstrumentation;
-
-// Base class for BitmapContentLayerUpdater and
-// SkPictureContentLayerUpdater that reduces code duplication between
-// their respective PaintContents implementations.
-class CC_EXPORT ContentLayerUpdater : public LayerUpdater {
- public:
- void SetOpaque(bool opaque) override;
- void SetFillsBoundsCompletely(bool fills_bounds) override;
- void SetBackgroundColor(SkColor background_color) override;
-
- protected:
- ContentLayerUpdater(scoped_ptr<LayerPainter> painter, int layer_id);
- ~ContentLayerUpdater() override;
-
- // Paints the contents. |content_size| size of the underlying layer in
- // layer's content space. |paint_rect| bounds to paint in content space of the
- // layer. Both |content_size| and |paint_rect| are in pixels.
- void PaintContents(SkCanvas* canvas,
- const gfx::Size& layer_content_size,
- const gfx::Rect& paint_rect,
- float contents_width_scale,
- float contents_height_scale);
- gfx::Rect paint_rect() const { return paint_rect_; }
-
- bool layer_is_opaque() const { return layer_is_opaque_; }
- bool layer_fills_bounds_completely() const {
- return layer_fills_bounds_completely_;
- }
-
- SkColor background_color() const { return background_color_; }
-
- int layer_id_;
-
- // True when it is known that all output pixels will be opaque.
- bool layer_is_opaque_;
- // True when it is known that all output pixels will be filled.
- bool layer_fills_bounds_completely_;
-
- private:
- gfx::Rect paint_rect_;
- scoped_ptr<LayerPainter> painter_;
- SkColor background_color_;
-
- DISALLOW_COPY_AND_ASSIGN(ContentLayerUpdater);
-};
-
-} // namespace cc
-
-#endif // CC_RESOURCES_CONTENT_LAYER_UPDATER_H_
diff --git a/chromium/cc/resources/image_layer_updater.cc b/chromium/cc/resources/image_layer_updater.cc
deleted file mode 100644
index 0538d96ea36..00000000000
--- a/chromium/cc/resources/image_layer_updater.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/resources/image_layer_updater.h"
-#include "cc/resources/prioritized_resource.h"
-#include "cc/resources/resource_update_queue.h"
-
-namespace cc {
-
-ImageLayerUpdater::Resource::Resource(ImageLayerUpdater* updater,
- scoped_ptr<PrioritizedResource> texture)
- : LayerUpdater::Resource(texture.Pass()), updater_(updater) {}
-
-ImageLayerUpdater::Resource::~Resource() {}
-
-void ImageLayerUpdater::Resource::Update(ResourceUpdateQueue* queue,
- const gfx::Rect& source_rect,
- const gfx::Vector2d& dest_offset,
- bool partial_update) {
- updater_->UpdateTexture(
- queue, texture(), source_rect, dest_offset, partial_update);
-}
-
-// static
-scoped_refptr<ImageLayerUpdater> ImageLayerUpdater::Create() {
- return make_scoped_refptr(new ImageLayerUpdater());
-}
-
-scoped_ptr<LayerUpdater::Resource> ImageLayerUpdater::CreateResource(
- PrioritizedResourceManager* manager) {
- return make_scoped_ptr(
- new Resource(this, PrioritizedResource::Create(manager)));
-}
-
-void ImageLayerUpdater::UpdateTexture(ResourceUpdateQueue* queue,
- PrioritizedResource* texture,
- const gfx::Rect& source_rect,
- const gfx::Vector2d& dest_offset,
- bool partial_update) {
- // Source rect should never go outside the image pixels, even if this
- // is requested because the texture extends outside the image.
- gfx::Rect clipped_source_rect = source_rect;
- gfx::Rect image_rect = gfx::Rect(0, 0, bitmap_.width(), bitmap_.height());
- clipped_source_rect.Intersect(image_rect);
-
- gfx::Vector2d clipped_dest_offset =
- dest_offset +
- gfx::Vector2d(clipped_source_rect.origin() - source_rect.origin());
-
- ResourceUpdate upload = ResourceUpdate::Create(
- texture, &bitmap_, image_rect, clipped_source_rect, clipped_dest_offset);
- if (partial_update)
- queue->AppendPartialUpload(upload);
- else
- queue->AppendFullUpload(upload);
-}
-
-void ImageLayerUpdater::SetBitmap(const SkBitmap& bitmap) {
- DCHECK(bitmap.pixelRef());
- bitmap_ = bitmap;
-}
-
-bool ImageLayerUpdater::UsingBitmap(const SkBitmap& bitmap) const {
- return bitmap.pixelRef() == bitmap_.pixelRef();
-}
-
-} // namespace cc
diff --git a/chromium/cc/resources/image_layer_updater.h b/chromium/cc/resources/image_layer_updater.h
deleted file mode 100644
index 81225ba7b5e..00000000000
--- a/chromium/cc/resources/image_layer_updater.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_RESOURCES_IMAGE_LAYER_UPDATER_H_
-#define CC_RESOURCES_IMAGE_LAYER_UPDATER_H_
-
-#include "cc/base/cc_export.h"
-#include "cc/resources/layer_updater.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-
-namespace cc {
-
-class ResourceUpdateQueue;
-
-class CC_EXPORT ImageLayerUpdater : public LayerUpdater {
- public:
- class Resource : public LayerUpdater::Resource {
- public:
- Resource(ImageLayerUpdater* updater,
- scoped_ptr<PrioritizedResource> texture);
- ~Resource() override;
-
- void Update(ResourceUpdateQueue* queue,
- const gfx::Rect& source_rect,
- const gfx::Vector2d& dest_offset,
- bool partial_update) override;
-
- private:
- ImageLayerUpdater* updater_;
-
- DISALLOW_COPY_AND_ASSIGN(Resource);
- };
-
- static scoped_refptr<ImageLayerUpdater> Create();
-
- scoped_ptr<LayerUpdater::Resource> CreateResource(
- PrioritizedResourceManager*) override;
-
- void UpdateTexture(ResourceUpdateQueue* queue,
- PrioritizedResource* texture,
- const gfx::Rect& source_rect,
- const gfx::Vector2d& dest_offset,
- bool partial_update);
-
- void SetBitmap(const SkBitmap& bitmap);
- bool UsingBitmap(const SkBitmap& bitmap) const;
-
- private:
- ImageLayerUpdater() {}
- ~ImageLayerUpdater() override {}
-
- SkBitmap bitmap_;
-
- DISALLOW_COPY_AND_ASSIGN(ImageLayerUpdater);
-};
-
-} // namespace cc
-
-#endif // CC_RESOURCES_IMAGE_LAYER_UPDATER_H_
diff --git a/chromium/cc/resources/layer_painter.h b/chromium/cc/resources/layer_painter.h
deleted file mode 100644
index 54dc434671d..00000000000
--- a/chromium/cc/resources/layer_painter.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_RESOURCES_LAYER_PAINTER_H_
-#define CC_RESOURCES_LAYER_PAINTER_H_
-
-#include "cc/base/cc_export.h"
-
-class SkCanvas;
-
-namespace gfx {
-class Rect;
-class RectF;
-}
-
-namespace cc {
-
-class CC_EXPORT LayerPainter {
- public:
- virtual ~LayerPainter() {}
- virtual void Paint(SkCanvas* canvas, const gfx::Rect& content_rect) = 0;
-};
-
-} // namespace cc
-
-#endif // CC_RESOURCES_LAYER_PAINTER_H_
diff --git a/chromium/cc/resources/layer_updater.cc b/chromium/cc/resources/layer_updater.cc
deleted file mode 100644
index aa7d1a4622e..00000000000
--- a/chromium/cc/resources/layer_updater.cc
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/resources/layer_updater.h"
-
-#include "cc/resources/prioritized_resource.h"
-
-namespace cc {
-
-LayerUpdater::Resource::Resource(scoped_ptr<PrioritizedResource> texture)
- : texture_(texture.Pass()) {}
-
-LayerUpdater::Resource::~Resource() {}
-
-} // namespace cc
diff --git a/chromium/cc/resources/layer_updater.h b/chromium/cc/resources/layer_updater.h
deleted file mode 100644
index a5eb0a11da7..00000000000
--- a/chromium/cc/resources/layer_updater.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_RESOURCES_LAYER_UPDATER_H_
-#define CC_RESOURCES_LAYER_UPDATER_H_
-
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "cc/base/cc_export.h"
-#include "third_party/skia/include/core/SkColor.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/vector2d.h"
-
-namespace cc {
-
-class PrioritizedResource;
-class PrioritizedResourceManager;
-class ResourceUpdateQueue;
-class TextureManager;
-
-class CC_EXPORT LayerUpdater : public base::RefCounted<LayerUpdater> {
- public:
- // Allows updaters to store per-resource update properties.
- class CC_EXPORT Resource {
- public:
- virtual ~Resource();
-
- PrioritizedResource* texture() { return texture_.get(); }
- // TODO(reveman): partial_update should be a property of this class
- // instead of an argument passed to Update().
- virtual void Update(ResourceUpdateQueue* queue,
- const gfx::Rect& source_rect,
- const gfx::Vector2d& dest_offset,
- bool partial_update) = 0;
-
- protected:
- explicit Resource(scoped_ptr<PrioritizedResource> texture);
-
- private:
- scoped_ptr<PrioritizedResource> texture_;
-
- DISALLOW_COPY_AND_ASSIGN(Resource);
- };
-
- LayerUpdater() {}
-
- virtual scoped_ptr<Resource> CreateResource(
- PrioritizedResourceManager* manager) = 0;
- virtual void PrepareToUpdate(const gfx::Size& content_size,
- const gfx::Rect& paint_rect,
- const gfx::Size& tile_size,
- float contents_width_scale,
- float contents_height_scale) {}
- virtual void ReduceMemoryUsage() {}
-
- // Set true by the layer when it is known that the entire output is going to
- // be opaque.
- virtual void SetOpaque(bool opaque) {}
- // Set true by the layer when it is known that the entire output bounds will
- // be rasterized.
- virtual void SetFillsBoundsCompletely(bool fills_bounds) {}
- virtual void SetBackgroundColor(SkColor background_color) {}
-
- protected:
- virtual ~LayerUpdater() {}
-
- private:
- friend class base::RefCounted<LayerUpdater>;
-
- DISALLOW_COPY_AND_ASSIGN(LayerUpdater);
-};
-
-} // namespace cc
-
-#endif // CC_RESOURCES_LAYER_UPDATER_H_
diff --git a/chromium/cc/resources/memory_history.cc b/chromium/cc/resources/memory_history.cc
index 4dc49c881a6..29bad2a30b3 100644
--- a/chromium/cc/resources/memory_history.cc
+++ b/chromium/cc/resources/memory_history.cc
@@ -19,21 +19,4 @@ void MemoryHistory::SaveEntry(const MemoryHistory::Entry& entry) {
ring_buffer_.SaveToBuffer(entry);
}
-void MemoryHistory::GetMinAndMax(size_t* min, size_t* max) const {
- *min = std::numeric_limits<size_t>::max();
- *max = 0;
-
- for (RingBufferType::Iterator it = ring_buffer_.Begin(); it; ++it) {
- size_t bytes_total = it->total_bytes_used;
-
- if (bytes_total < *min)
- *min = bytes_total;
- if (bytes_total > *max)
- *max = bytes_total;
- }
-
- if (*min > *max)
- *min = *max;
-}
-
} // namespace cc
diff --git a/chromium/cc/resources/memory_history.h b/chromium/cc/resources/memory_history.h
index 570a3d0ca43..15ddc75aa24 100644
--- a/chromium/cc/resources/memory_history.h
+++ b/chromium/cc/resources/memory_history.h
@@ -26,12 +26,11 @@ class MemoryHistory {
had_enough_memory(false) {}
size_t total_budget_in_bytes;
- size_t total_bytes_used;
+ int64 total_bytes_used;
bool had_enough_memory;
};
void SaveEntry(const Entry& entry);
- void GetMinAndMax(size_t* min, size_t* max) const;
typedef RingBuffer<Entry, 80> RingBufferType;
RingBufferType::Iterator Begin() const { return ring_buffer_.Begin(); }
diff --git a/chromium/cc/resources/prioritized_resource.cc b/chromium/cc/resources/prioritized_resource.cc
deleted file mode 100644
index 968083cb968..00000000000
--- a/chromium/cc/resources/prioritized_resource.cc
+++ /dev/null
@@ -1,203 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/resources/prioritized_resource.h"
-
-#include <algorithm>
-
-#include "cc/resources/platform_color.h"
-#include "cc/resources/prioritized_resource_manager.h"
-#include "cc/resources/priority_calculator.h"
-#include "cc/trees/proxy.h"
-
-namespace cc {
-
-PrioritizedResource::PrioritizedResource(PrioritizedResourceManager* manager,
- const gfx::Size& size,
- ResourceFormat format)
- : size_(size),
- format_(format),
- bytes_(0),
- contents_swizzled_(false),
- priority_(PriorityCalculator::LowestPriority()),
- is_above_priority_cutoff_(false),
- is_self_managed_(false),
- backing_(NULL),
- manager_(NULL) {
- bytes_ = Resource::MemorySizeBytes(size, format);
- if (manager)
- manager->RegisterTexture(this);
-}
-
-PrioritizedResource::~PrioritizedResource() {
- if (manager_)
- manager_->UnregisterTexture(this);
-}
-
-void PrioritizedResource::SetTextureManager(
- PrioritizedResourceManager* manager) {
- if (manager_ == manager)
- return;
- if (manager_)
- manager_->UnregisterTexture(this);
- if (manager)
- manager->RegisterTexture(this);
-}
-
-void PrioritizedResource::SetDimensions(const gfx::Size& size,
- ResourceFormat format) {
- if (format_ != format || size_ != size) {
- is_above_priority_cutoff_ = false;
- format_ = format;
- size_ = size;
- bytes_ = Resource::MemorySizeBytes(size, format);
- DCHECK(manager_ || !backing_);
- if (manager_)
- manager_->ReturnBackingTexture(this);
- }
-}
-
-bool PrioritizedResource::RequestLate() {
- if (!manager_)
- return false;
- return manager_->RequestLate(this);
-}
-
-bool PrioritizedResource::BackingResourceWasEvicted() const {
- return backing_ ? backing_->ResourceHasBeenDeleted() : false;
-}
-
-void PrioritizedResource::AcquireBackingTexture(
- ResourceProvider* resource_provider) {
- DCHECK(is_above_priority_cutoff_);
- if (is_above_priority_cutoff_)
- manager_->AcquireBackingTextureIfNeeded(this, resource_provider);
-}
-
-void PrioritizedResource::SetPixels(ResourceProvider* resource_provider,
- const uint8_t* image,
- const gfx::Rect& image_rect,
- const gfx::Rect& source_rect,
- const gfx::Vector2d& dest_offset) {
- DCHECK(is_above_priority_cutoff_);
- if (is_above_priority_cutoff_)
- AcquireBackingTexture(resource_provider);
- DCHECK(backing_);
- resource_provider->SetPixels(
- resource_id(), image, image_rect, source_rect, dest_offset);
-
- // The component order may be bgra if we uploaded bgra pixels to rgba
- // texture. Mark contents as swizzled if image component order is
- // different than texture format.
- contents_swizzled_ = !PlatformColor::SameComponentOrder(format_);
-}
-
-void PrioritizedResource::Link(Backing* backing) {
- DCHECK(backing);
- DCHECK(!backing->owner_);
- DCHECK(!backing_);
-
- backing_ = backing;
- backing_->owner_ = this;
-}
-
-void PrioritizedResource::Unlink() {
- DCHECK(backing_);
- DCHECK(backing_->owner_ == this);
-
- backing_->owner_ = NULL;
- backing_ = NULL;
-}
-
-void PrioritizedResource::SetToSelfManagedMemoryPlaceholder(size_t bytes) {
- SetDimensions(gfx::Size(), RGBA_8888);
- set_is_self_managed(true);
- bytes_ = bytes;
-}
-
-PrioritizedResource::Backing::Backing(unsigned id,
- ResourceProvider* resource_provider,
- const gfx::Size& size,
- ResourceFormat format)
- : Resource(id, size, format),
- owner_(NULL),
- priority_at_last_priority_update_(PriorityCalculator::LowestPriority()),
- was_above_priority_cutoff_at_last_priority_update_(false),
- in_drawing_impl_tree_(false),
- in_parent_compositor_(false),
-#if !DCHECK_IS_ON()
- resource_has_been_deleted_(false) {
-#else
- resource_has_been_deleted_(false),
- resource_provider_(resource_provider) {
-#endif
-}
-
-PrioritizedResource::Backing::~Backing() {
- DCHECK(!owner_);
- DCHECK(resource_has_been_deleted_);
-}
-
-void PrioritizedResource::Backing::DeleteResource(
- ResourceProvider* resource_provider) {
- DCHECK(!proxy() || proxy()->IsImplThread());
- DCHECK(!resource_has_been_deleted_);
-#if DCHECK_IS_ON()
- DCHECK(resource_provider == resource_provider_);
-#endif
-
- resource_provider->DeleteResource(id());
- set_id(0);
- resource_has_been_deleted_ = true;
-}
-
-bool PrioritizedResource::Backing::ResourceHasBeenDeleted() const {
- DCHECK(!proxy() || proxy()->IsImplThread());
- return resource_has_been_deleted_;
-}
-
-bool PrioritizedResource::Backing::CanBeRecycledIfNotInExternalUse() const {
- DCHECK(!proxy() || proxy()->IsImplThread());
- return !was_above_priority_cutoff_at_last_priority_update_ &&
- !in_drawing_impl_tree_;
-}
-
-void PrioritizedResource::Backing::UpdatePriority() {
- DCHECK(!proxy() ||
- (proxy()->IsImplThread() && proxy()->IsMainThreadBlocked()));
- if (owner_) {
- priority_at_last_priority_update_ = owner_->request_priority();
- was_above_priority_cutoff_at_last_priority_update_ =
- owner_->is_above_priority_cutoff();
- } else {
- priority_at_last_priority_update_ = PriorityCalculator::LowestPriority();
- was_above_priority_cutoff_at_last_priority_update_ = false;
- }
-}
-
-void PrioritizedResource::Backing::UpdateState(
- ResourceProvider* resource_provider) {
- DCHECK(!proxy() ||
- (proxy()->IsImplThread() && proxy()->IsMainThreadBlocked()));
- in_drawing_impl_tree_ = !!owner();
- in_parent_compositor_ = resource_provider->InUseByConsumer(id());
- if (!in_drawing_impl_tree_) {
- DCHECK_EQ(priority_at_last_priority_update_,
- PriorityCalculator::LowestPriority());
- }
-}
-
-void PrioritizedResource::ReturnBackingTexture() {
- DCHECK(manager_ || !backing_);
- if (manager_)
- manager_->ReturnBackingTexture(this);
-}
-
-const Proxy* PrioritizedResource::Backing::proxy() const {
- if (!owner_ || !owner_->resource_manager())
- return NULL;
- return owner_->resource_manager()->ProxyForDebug();
-}
-
-} // namespace cc
diff --git a/chromium/cc/resources/prioritized_resource.h b/chromium/cc/resources/prioritized_resource.h
deleted file mode 100644
index 3b6ecc028e8..00000000000
--- a/chromium/cc/resources/prioritized_resource.h
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_RESOURCES_PRIORITIZED_RESOURCE_H_
-#define CC_RESOURCES_PRIORITIZED_RESOURCE_H_
-
-#include "base/basictypes.h"
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "cc/base/cc_export.h"
-#include "cc/resources/resource.h"
-#include "cc/resources/resource_provider.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/geometry/vector2d.h"
-
-namespace cc {
-
-class PrioritizedResourceManager;
-class Proxy;
-
-class CC_EXPORT PrioritizedResource {
- public:
- static scoped_ptr<PrioritizedResource> Create(
- PrioritizedResourceManager* manager,
- const gfx::Size& size,
- ResourceFormat format) {
- return make_scoped_ptr(new PrioritizedResource(manager, size, format));
- }
- static scoped_ptr<PrioritizedResource> Create(
- PrioritizedResourceManager* manager) {
- return make_scoped_ptr(
- new PrioritizedResource(manager, gfx::Size(), RGBA_8888));
- }
- ~PrioritizedResource();
-
- // Texture properties. Changing these causes the backing texture to be lost.
- // Setting these to the same value is a no-op.
- void SetTextureManager(PrioritizedResourceManager* manager);
- PrioritizedResourceManager* resource_manager() { return manager_; }
- void SetDimensions(const gfx::Size& size, ResourceFormat format);
- ResourceFormat format() const { return format_; }
- gfx::Size size() const { return size_; }
- size_t bytes() const { return bytes_; }
- bool contents_swizzled() const { return contents_swizzled_; }
-
- // Set priority for the requested texture.
- void set_request_priority(int priority) { priority_ = priority; }
- int request_priority() const { return priority_; }
-
- // After PrioritizedResource::PrioritizeTextures() is called, this returns
- // if the the request succeeded and this texture can be acquired for use.
- bool can_acquire_backing_texture() const { return is_above_priority_cutoff_; }
-
- // This returns whether we still have a backing texture. This can continue
- // to be true even after CanAcquireBackingTexture() becomes false. In this
- // case the texture can be used but shouldn't be updated since it will get
- // taken away "soon".
- bool have_backing_texture() const { return !!backing(); }
-
- bool BackingResourceWasEvicted() const;
-
- // If CanAcquireBackingTexture() is true AcquireBackingTexture() will acquire
- // a backing texture for use. Call this whenever the texture is actually
- // needed.
- void AcquireBackingTexture(ResourceProvider* resource_provider);
-
- // TODO(epenner): Request late is really a hack for when we are totally out of
- // memory (all textures are visible) but we can still squeeze into the limit
- // by not painting occluded textures. In this case the manager refuses all
- // visible textures and RequestLate() will enable CanAcquireBackingTexture()
- // on a call-order basis. We might want to just remove this in the future
- // (carefully) and just make sure we don't regress OOMs situations.
- bool RequestLate();
-
- // Update pixels of backing resource from image. This functions will aquire
- // the backing if needed.
- void SetPixels(ResourceProvider* resource_provider,
- const uint8_t* image,
- const gfx::Rect& image_rect,
- const gfx::Rect& source_rect,
- const gfx::Vector2d& dest_offset);
-
- ResourceProvider::ResourceId resource_id() const {
- return backing_ ? backing_->id() : 0;
- }
-
- // Self-managed textures are accounted for when prioritizing other textures,
- // but they are not allocated/recycled/deleted, so this needs to be done
- // externally. CanAcquireBackingTexture() indicates if the texture would have
- // been allowed given its priority.
- void set_is_self_managed(bool is_self_managed) {
- is_self_managed_ = is_self_managed;
- }
- bool is_self_managed() { return is_self_managed_; }
- void SetToSelfManagedMemoryPlaceholder(size_t bytes);
-
- void ReturnBackingTexture();
-
- private:
- friend class PrioritizedResourceManager;
- friend class PrioritizedResourceTest;
-
- class Backing : public Resource {
- public:
- Backing(unsigned id,
- ResourceProvider* resource_provider,
- const gfx::Size& size,
- ResourceFormat format);
- ~Backing();
- void UpdatePriority();
- void UpdateState(ResourceProvider* resource_provider);
-
- PrioritizedResource* owner() { return owner_; }
- bool CanBeRecycledIfNotInExternalUse() const;
- int request_priority_at_last_priority_update() const {
- return priority_at_last_priority_update_;
- }
- bool was_above_priority_cutoff_at_last_priority_update() const {
- return was_above_priority_cutoff_at_last_priority_update_;
- }
- bool in_drawing_impl_tree() const { return in_drawing_impl_tree_; }
- bool in_parent_compositor() const { return in_parent_compositor_; }
-
- void DeleteResource(ResourceProvider* resource_provider);
- bool ResourceHasBeenDeleted() const;
-
- private:
- const Proxy* proxy() const;
-
- friend class PrioritizedResource;
- friend class PrioritizedResourceManager;
- PrioritizedResource* owner_;
- int priority_at_last_priority_update_;
- bool was_above_priority_cutoff_at_last_priority_update_;
-
- // Set if this is currently-drawing impl tree.
- bool in_drawing_impl_tree_;
- // Set if this is in the parent compositor.
- bool in_parent_compositor_;
-
- bool resource_has_been_deleted_;
-
-#if DCHECK_IS_ON()
- ResourceProvider* resource_provider_;
-#endif
- DISALLOW_COPY_AND_ASSIGN(Backing);
- };
-
- PrioritizedResource(PrioritizedResourceManager* resource_manager,
- const gfx::Size& size,
- ResourceFormat format);
-
- bool is_above_priority_cutoff() { return is_above_priority_cutoff_; }
- void set_above_priority_cutoff(bool is_above_priority_cutoff) {
- is_above_priority_cutoff_ = is_above_priority_cutoff;
- }
- void set_manager_internal(PrioritizedResourceManager* manager) {
- manager_ = manager;
- }
-
- Backing* backing() const { return backing_; }
- void Link(Backing* backing);
- void Unlink();
-
- gfx::Size size_;
- ResourceFormat format_;
- size_t bytes_;
- bool contents_swizzled_;
-
- int priority_;
- bool is_above_priority_cutoff_;
- bool is_self_managed_;
-
- Backing* backing_;
- PrioritizedResourceManager* manager_;
-
- DISALLOW_COPY_AND_ASSIGN(PrioritizedResource);
-};
-
-} // namespace cc
-
-#endif // CC_RESOURCES_PRIORITIZED_RESOURCE_H_
diff --git a/chromium/cc/resources/prioritized_resource_manager.cc b/chromium/cc/resources/prioritized_resource_manager.cc
deleted file mode 100644
index 236377b8511..00000000000
--- a/chromium/cc/resources/prioritized_resource_manager.cc
+++ /dev/null
@@ -1,547 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/resources/prioritized_resource_manager.h"
-
-#include <algorithm>
-
-#include "base/trace_event/trace_event.h"
-#include "cc/resources/prioritized_resource.h"
-#include "cc/resources/priority_calculator.h"
-#include "cc/trees/proxy.h"
-
-namespace cc {
-
-PrioritizedResourceManager::PrioritizedResourceManager(const Proxy* proxy)
- : max_memory_limit_bytes_(DefaultMemoryAllocationLimit()),
- external_priority_cutoff_(PriorityCalculator::AllowEverythingCutoff()),
- memory_use_bytes_(0),
- memory_above_cutoff_bytes_(0),
- max_memory_needed_bytes_(0),
- memory_available_bytes_(0),
- proxy_(proxy),
- backings_tail_not_sorted_(false),
- memory_visible_bytes_(0),
- memory_visible_and_nearby_bytes_(0),
- memory_visible_last_pushed_bytes_(0),
- memory_visible_and_nearby_last_pushed_bytes_(0) {}
-
-PrioritizedResourceManager::~PrioritizedResourceManager() {
- while (textures_.size() > 0)
- UnregisterTexture(*textures_.begin());
-
- UnlinkAndClearEvictedBackings();
- DCHECK(evicted_backings_.empty());
-
- // Each remaining backing is a leaked opengl texture. There should be none.
- DCHECK(backings_.empty());
-}
-
-size_t PrioritizedResourceManager::MemoryVisibleBytes() const {
- DCHECK(proxy_->IsImplThread());
- return memory_visible_last_pushed_bytes_;
-}
-
-size_t PrioritizedResourceManager::MemoryVisibleAndNearbyBytes() const {
- DCHECK(proxy_->IsImplThread());
- return memory_visible_and_nearby_last_pushed_bytes_;
-}
-
-void PrioritizedResourceManager::PrioritizeTextures() {
- TRACE_EVENT0("cc", "PrioritizedResourceManager::PrioritizeTextures");
- DCHECK(proxy_->IsMainThread());
-
- // Sorting textures in this function could be replaced by a slightly
- // modified O(n) quick-select to partition textures rather than
- // sort them (if performance of the sort becomes an issue).
-
- TextureVector& sorted_textures = temp_texture_vector_;
- sorted_textures.clear();
-
- // Copy all textures into a vector, sort them, and collect memory requirements
- // statistics.
- memory_visible_bytes_ = 0;
- memory_visible_and_nearby_bytes_ = 0;
- for (TextureSet::iterator it = textures_.begin(); it != textures_.end();
- ++it) {
- PrioritizedResource* texture = (*it);
- sorted_textures.push_back(texture);
- if (PriorityCalculator::priority_is_higher(
- texture->request_priority(),
- PriorityCalculator::AllowVisibleOnlyCutoff()))
- memory_visible_bytes_ += texture->bytes();
- if (PriorityCalculator::priority_is_higher(
- texture->request_priority(),
- PriorityCalculator::AllowVisibleAndNearbyCutoff()))
- memory_visible_and_nearby_bytes_ += texture->bytes();
- }
- std::sort(sorted_textures.begin(), sorted_textures.end(), CompareTextures);
-
- // Compute a priority cutoff based on memory pressure
- memory_available_bytes_ = max_memory_limit_bytes_;
- priority_cutoff_ = external_priority_cutoff_;
- size_t memory_bytes = 0;
- for (TextureVector::iterator it = sorted_textures.begin();
- it != sorted_textures.end();
- ++it) {
- if ((*it)->is_self_managed()) {
- // Account for self-managed memory immediately by reducing the memory
- // available (since it never gets acquired).
- size_t new_memory_bytes = memory_bytes + (*it)->bytes();
- if (new_memory_bytes > memory_available_bytes_) {
- priority_cutoff_ = (*it)->request_priority();
- memory_available_bytes_ = memory_bytes;
- break;
- }
- memory_available_bytes_ -= (*it)->bytes();
- } else {
- size_t new_memory_bytes = memory_bytes + (*it)->bytes();
- if (new_memory_bytes > memory_available_bytes_) {
- priority_cutoff_ = (*it)->request_priority();
- break;
- }
- memory_bytes = new_memory_bytes;
- }
- }
-
- // Disallow any textures with priority below the external cutoff to have
- // backings.
- for (TextureVector::iterator it = sorted_textures.begin();
- it != sorted_textures.end();
- ++it) {
- PrioritizedResource* texture = (*it);
- if (!PriorityCalculator::priority_is_higher(texture->request_priority(),
- external_priority_cutoff_) &&
- texture->have_backing_texture())
- texture->Unlink();
- }
-
- // Only allow textures if they are higher than the cutoff. All textures
- // of the same priority are accepted or rejected together, rather than
- // being partially allowed randomly.
- max_memory_needed_bytes_ = 0;
- memory_above_cutoff_bytes_ = 0;
- for (TextureVector::iterator it = sorted_textures.begin();
- it != sorted_textures.end();
- ++it) {
- PrioritizedResource* resource = *it;
- bool is_above_priority_cutoff = PriorityCalculator::priority_is_higher(
- resource->request_priority(), priority_cutoff_);
- resource->set_above_priority_cutoff(is_above_priority_cutoff);
- if (!resource->is_self_managed()) {
- max_memory_needed_bytes_ += resource->bytes();
- if (is_above_priority_cutoff)
- memory_above_cutoff_bytes_ += resource->bytes();
- }
- }
- sorted_textures.clear();
-
- DCHECK_LE(memory_above_cutoff_bytes_, memory_available_bytes_);
- DCHECK_LE(MemoryAboveCutoffBytes(), MaxMemoryLimitBytes());
-}
-
-void PrioritizedResourceManager::PushTexturePrioritiesToBackings() {
- TRACE_EVENT0("cc",
- "PrioritizedResourceManager::PushTexturePrioritiesToBackings");
- DCHECK(proxy_->IsImplThread() && proxy_->IsMainThreadBlocked());
-
- AssertInvariants();
- for (BackingList::iterator it = backings_.begin(); it != backings_.end();
- ++it)
- (*it)->UpdatePriority();
- SortBackings();
- AssertInvariants();
-
- // Push memory requirements to the impl thread structure.
- memory_visible_last_pushed_bytes_ = memory_visible_bytes_;
- memory_visible_and_nearby_last_pushed_bytes_ =
- memory_visible_and_nearby_bytes_;
-}
-
-void PrioritizedResourceManager::UpdateBackingsState(
- ResourceProvider* resource_provider) {
- TRACE_EVENT0("cc",
- "PrioritizedResourceManager::UpdateBackingsInDrawingImplTree");
- DCHECK(proxy_->IsImplThread() && proxy_->IsMainThreadBlocked());
-
- AssertInvariants();
- for (BackingList::iterator it = backings_.begin(); it != backings_.end();
- ++it) {
- PrioritizedResource::Backing* backing = (*it);
- backing->UpdateState(resource_provider);
- }
- SortBackings();
- AssertInvariants();
-}
-
-void PrioritizedResourceManager::SortBackings() {
- TRACE_EVENT0("cc", "PrioritizedResourceManager::SortBackings");
- DCHECK(proxy_->IsImplThread());
-
- // Put backings in eviction/recycling order.
- backings_.sort(CompareBackings);
- backings_tail_not_sorted_ = false;
-}
-
-void PrioritizedResourceManager::ClearPriorities() {
- DCHECK(proxy_->IsMainThread());
- for (TextureSet::iterator it = textures_.begin(); it != textures_.end();
- ++it) {
- // TODO(reveman): We should remove this and just set all priorities to
- // PriorityCalculator::lowestPriority() once we have priorities for all
- // textures (we can't currently calculate distances for off-screen
- // textures).
- (*it)->set_request_priority(
- PriorityCalculator::LingeringPriority((*it)->request_priority()));
- }
-}
-
-bool PrioritizedResourceManager::RequestLate(PrioritizedResource* texture) {
- DCHECK(proxy_->IsMainThread());
-
- // This is already above cutoff, so don't double count it's memory below.
- if (texture->is_above_priority_cutoff())
- return true;
-
- // Allow textures that have priority equal to the cutoff, but not strictly
- // lower.
- if (PriorityCalculator::priority_is_lower(texture->request_priority(),
- priority_cutoff_))
- return false;
-
- // Disallow textures that do not have a priority strictly higher than the
- // external cutoff.
- if (!PriorityCalculator::priority_is_higher(texture->request_priority(),
- external_priority_cutoff_))
- return false;
-
- size_t new_memory_bytes = memory_above_cutoff_bytes_ + texture->bytes();
- if (new_memory_bytes > memory_available_bytes_)
- return false;
-
- memory_above_cutoff_bytes_ = new_memory_bytes;
- texture->set_above_priority_cutoff(true);
- return true;
-}
-
-void PrioritizedResourceManager::AcquireBackingTextureIfNeeded(
- PrioritizedResource* texture,
- ResourceProvider* resource_provider) {
- DCHECK(proxy_->IsImplThread() && proxy_->IsMainThreadBlocked());
- DCHECK(!texture->is_self_managed());
- DCHECK(texture->is_above_priority_cutoff());
- if (texture->backing() || !texture->is_above_priority_cutoff())
- return;
-
- // Find a backing below, by either recycling or allocating.
- PrioritizedResource::Backing* backing = NULL;
-
- // First try to recycle
- for (BackingList::iterator it = backings_.begin(); it != backings_.end();
- ++it) {
- if (!(*it)->CanBeRecycledIfNotInExternalUse())
- break;
- if (resource_provider->InUseByConsumer((*it)->id()))
- continue;
- if ((*it)->size() == texture->size() &&
- (*it)->format() == texture->format()) {
- backing = (*it);
- backings_.erase(it);
- break;
- }
- }
-
- // Otherwise reduce memory and just allocate a new backing texures.
- if (!backing) {
- EvictBackingsToReduceMemory(memory_available_bytes_ - texture->bytes(),
- PriorityCalculator::AllowEverythingCutoff(),
- EVICT_ONLY_RECYCLABLE,
- DO_NOT_UNLINK_BACKINGS,
- resource_provider);
- backing =
- CreateBacking(texture->size(), texture->format(), resource_provider);
- }
-
- // Move the used backing to the end of the eviction list, and note that
- // the tail is not sorted.
- if (backing->owner())
- backing->owner()->Unlink();
- texture->Link(backing);
- backings_.push_back(backing);
- backings_tail_not_sorted_ = true;
-
- // Update the backing's priority from its new owner.
- backing->UpdatePriority();
-}
-
-bool PrioritizedResourceManager::EvictBackingsToReduceMemory(
- size_t limit_bytes,
- int priority_cutoff,
- EvictionPolicy eviction_policy,
- UnlinkPolicy unlink_policy,
- ResourceProvider* resource_provider) {
- DCHECK(proxy_->IsImplThread());
- if (unlink_policy == UNLINK_BACKINGS)
- DCHECK(proxy_->IsMainThreadBlocked());
- if (MemoryUseBytes() <= limit_bytes &&
- PriorityCalculator::AllowEverythingCutoff() == priority_cutoff)
- return false;
-
- // Destroy backings until we are below the limit,
- // or until all backings remaining are above the cutoff.
- bool evicted_anything = false;
- while (backings_.size() > 0) {
- PrioritizedResource::Backing* backing = backings_.front();
- if (MemoryUseBytes() <= limit_bytes &&
- PriorityCalculator::priority_is_higher(
- backing->request_priority_at_last_priority_update(),
- priority_cutoff))
- break;
- if (eviction_policy == EVICT_ONLY_RECYCLABLE &&
- !backing->CanBeRecycledIfNotInExternalUse())
- break;
- if (unlink_policy == UNLINK_BACKINGS && backing->owner())
- backing->owner()->Unlink();
- EvictFirstBackingResource(resource_provider);
- evicted_anything = true;
- }
- return evicted_anything;
-}
-
-void PrioritizedResourceManager::ReduceWastedMemory(
- ResourceProvider* resource_provider) {
- // We currently collect backings from deleted textures for later recycling.
- // However, if we do that forever we will always use the max limit even if
- // we really need very little memory. This should probably be solved by
- // reducing the limit externally, but until then this just does some "clean
- // up" of unused backing textures (any more than 10%).
- size_t wasted_memory = 0;
- for (BackingList::iterator it = backings_.begin(); it != backings_.end();
- ++it) {
- if ((*it)->owner())
- break;
- if ((*it)->in_parent_compositor())
- continue;
- wasted_memory += (*it)->bytes();
- }
- size_t wasted_memory_to_allow = memory_available_bytes_ / 10;
- // If the external priority cutoff indicates that unused memory should be
- // freed, then do not allow any memory for texture recycling.
- if (external_priority_cutoff_ != PriorityCalculator::AllowEverythingCutoff())
- wasted_memory_to_allow = 0;
- if (wasted_memory > wasted_memory_to_allow)
- EvictBackingsToReduceMemory(MemoryUseBytes() -
- (wasted_memory - wasted_memory_to_allow),
- PriorityCalculator::AllowEverythingCutoff(),
- EVICT_ONLY_RECYCLABLE,
- DO_NOT_UNLINK_BACKINGS,
- resource_provider);
-}
-
-void PrioritizedResourceManager::ReduceMemory(
- ResourceProvider* resource_provider) {
- DCHECK(proxy_->IsImplThread() && proxy_->IsMainThreadBlocked());
- EvictBackingsToReduceMemory(memory_available_bytes_,
- PriorityCalculator::AllowEverythingCutoff(),
- EVICT_ANYTHING,
- UNLINK_BACKINGS,
- resource_provider);
- DCHECK_LE(MemoryUseBytes(), memory_available_bytes_);
-
- ReduceWastedMemory(resource_provider);
-}
-
-void PrioritizedResourceManager::ClearAllMemory(
- ResourceProvider* resource_provider) {
- DCHECK(proxy_->IsImplThread() && proxy_->IsMainThreadBlocked());
- if (!resource_provider) {
- DCHECK(backings_.empty());
- return;
- }
- EvictBackingsToReduceMemory(0,
- PriorityCalculator::AllowEverythingCutoff(),
- EVICT_ANYTHING,
- DO_NOT_UNLINK_BACKINGS,
- resource_provider);
-}
-
-bool PrioritizedResourceManager::ReduceMemoryOnImplThread(
- size_t limit_bytes,
- int priority_cutoff,
- ResourceProvider* resource_provider) {
- DCHECK(proxy_->IsImplThread());
- DCHECK(resource_provider);
-
- // If we are in the process of uploading a new frame then the backings at the
- // very end of the list are not sorted by priority. Sort them before doing the
- // eviction.
- if (backings_tail_not_sorted_)
- SortBackings();
- return EvictBackingsToReduceMemory(limit_bytes,
- priority_cutoff,
- EVICT_ANYTHING,
- DO_NOT_UNLINK_BACKINGS,
- resource_provider);
-}
-
-void PrioritizedResourceManager::UnlinkAndClearEvictedBackings() {
- DCHECK(proxy_->IsMainThread());
- base::AutoLock scoped_lock(evicted_backings_lock_);
- for (BackingList::const_iterator it = evicted_backings_.begin();
- it != evicted_backings_.end();
- ++it) {
- PrioritizedResource::Backing* backing = (*it);
- if (backing->owner())
- backing->owner()->Unlink();
- delete backing;
- }
- evicted_backings_.clear();
-}
-
-bool PrioritizedResourceManager::LinkedEvictedBackingsExist() const {
- DCHECK(proxy_->IsImplThread() && proxy_->IsMainThreadBlocked());
- base::AutoLock scoped_lock(evicted_backings_lock_);
- for (BackingList::const_iterator it = evicted_backings_.begin();
- it != evicted_backings_.end();
- ++it) {
- if ((*it)->owner())
- return true;
- }
- return false;
-}
-
-void PrioritizedResourceManager::RegisterTexture(PrioritizedResource* texture) {
- DCHECK(proxy_->IsMainThread());
- DCHECK(texture);
- DCHECK(!texture->resource_manager());
- DCHECK(!texture->backing());
- DCHECK(!ContainsKey(textures_, texture));
-
- texture->set_manager_internal(this);
- textures_.insert(texture);
-}
-
-void PrioritizedResourceManager::UnregisterTexture(
- PrioritizedResource* texture) {
- DCHECK(proxy_->IsMainThread() ||
- (proxy_->IsImplThread() && proxy_->IsMainThreadBlocked()));
- DCHECK(texture);
- DCHECK(ContainsKey(textures_, texture));
-
- ReturnBackingTexture(texture);
- texture->set_manager_internal(NULL);
- textures_.erase(texture);
- texture->set_above_priority_cutoff(false);
-}
-
-void PrioritizedResourceManager::ReturnBackingTexture(
- PrioritizedResource* texture) {
- DCHECK(proxy_->IsMainThread() ||
- (proxy_->IsImplThread() && proxy_->IsMainThreadBlocked()));
- if (texture->backing())
- texture->Unlink();
-}
-
-PrioritizedResource::Backing* PrioritizedResourceManager::CreateBacking(
- const gfx::Size& size,
- ResourceFormat format,
- ResourceProvider* resource_provider) {
- DCHECK(proxy_->IsImplThread() && proxy_->IsMainThreadBlocked());
- DCHECK(resource_provider);
- ResourceProvider::ResourceId resource_id =
- resource_provider->CreateManagedResource(
- size, GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
- ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
- PrioritizedResource::Backing* backing = new PrioritizedResource::Backing(
- resource_id, resource_provider, size, format);
- memory_use_bytes_ += backing->bytes();
- return backing;
-}
-
-void PrioritizedResourceManager::EvictFirstBackingResource(
- ResourceProvider* resource_provider) {
- DCHECK(proxy_->IsImplThread());
- DCHECK(resource_provider);
- DCHECK(!backings_.empty());
- PrioritizedResource::Backing* backing = backings_.front();
-
- // Note that we create a backing and its resource at the same time, but we
- // delete the backing structure and its resource in two steps. This is because
- // we can delete the resource while the main thread is running, but we cannot
- // unlink backings while the main thread is running.
- backing->DeleteResource(resource_provider);
- memory_use_bytes_ -= backing->bytes();
- backings_.pop_front();
- base::AutoLock scoped_lock(evicted_backings_lock_);
- evicted_backings_.push_back(backing);
-}
-
-void PrioritizedResourceManager::AssertInvariants() {
-#if DCHECK_IS_ON()
- DCHECK(proxy_->IsImplThread() && proxy_->IsMainThreadBlocked());
-
- // If we hit any of these asserts, there is a bug in this class. To see
- // where the bug is, call this function at the beginning and end of
- // every public function.
-
- // Backings/textures must be doubly-linked and only to other backings/textures
- // in this manager.
- for (BackingList::iterator it = backings_.begin(); it != backings_.end();
- ++it) {
- if ((*it)->owner()) {
- DCHECK(ContainsKey(textures_, (*it)->owner()));
- DCHECK((*it)->owner()->backing() == (*it));
- }
- }
- for (TextureSet::iterator it = textures_.begin(); it != textures_.end();
- ++it) {
- PrioritizedResource* texture = (*it);
- PrioritizedResource::Backing* backing = texture->backing();
- base::AutoLock scoped_lock(evicted_backings_lock_);
- if (backing) {
- if (backing->ResourceHasBeenDeleted()) {
- DCHECK(std::find(backings_.begin(), backings_.end(), backing) ==
- backings_.end());
- DCHECK(std::find(evicted_backings_.begin(),
- evicted_backings_.end(),
- backing) != evicted_backings_.end());
- } else {
- DCHECK(std::find(backings_.begin(), backings_.end(), backing) !=
- backings_.end());
- DCHECK(std::find(evicted_backings_.begin(),
- evicted_backings_.end(),
- backing) == evicted_backings_.end());
- }
- DCHECK(backing->owner() == texture);
- }
- }
-
- // At all times, backings that can be evicted must always come before
- // backings that can't be evicted in the backing texture list (otherwise
- // ReduceMemory will not find all textures available for eviction/recycling).
- bool reached_unrecyclable = false;
- PrioritizedResource::Backing* previous_backing = NULL;
- for (BackingList::iterator it = backings_.begin(); it != backings_.end();
- ++it) {
- PrioritizedResource::Backing* backing = *it;
- if (previous_backing &&
- (!backings_tail_not_sorted_ ||
- !backing->was_above_priority_cutoff_at_last_priority_update()))
- DCHECK(CompareBackings(previous_backing, backing));
- if (!backing->CanBeRecycledIfNotInExternalUse())
- reached_unrecyclable = true;
- if (reached_unrecyclable)
- DCHECK(!backing->CanBeRecycledIfNotInExternalUse());
- else
- DCHECK(backing->CanBeRecycledIfNotInExternalUse());
- previous_backing = backing;
- }
-#endif // DCHECK_IS_ON()
-}
-
-const Proxy* PrioritizedResourceManager::ProxyForDebug() const {
- return proxy_;
-}
-
-} // namespace cc
diff --git a/chromium/cc/resources/prioritized_resource_manager.h b/chromium/cc/resources/prioritized_resource_manager.h
deleted file mode 100644
index b7583f4315f..00000000000
--- a/chromium/cc/resources/prioritized_resource_manager.h
+++ /dev/null
@@ -1,235 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_RESOURCES_PRIORITIZED_RESOURCE_MANAGER_H_
-#define CC_RESOURCES_PRIORITIZED_RESOURCE_MANAGER_H_
-
-#include <list>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/containers/hash_tables.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/synchronization/lock.h"
-#include "cc/base/cc_export.h"
-#include "cc/resources/prioritized_resource.h"
-#include "cc/resources/priority_calculator.h"
-#include "cc/resources/resource.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace cc {
-
-class Proxy;
-
-class CC_EXPORT PrioritizedResourceManager {
- public:
- static scoped_ptr<PrioritizedResourceManager> Create(const Proxy* proxy) {
- return make_scoped_ptr(new PrioritizedResourceManager(proxy));
- }
- scoped_ptr<PrioritizedResource> CreateTexture(
- const gfx::Size& size, ResourceFormat format) {
- return make_scoped_ptr(new PrioritizedResource(this, size, format));
- }
- ~PrioritizedResourceManager();
-
- typedef std::list<PrioritizedResource::Backing*> BackingList;
-
- // TODO(epenner): (http://crbug.com/137094) This 64MB default is a straggler
- // from the old texture manager and is just to give us a default memory
- // allocation before we get a callback from the GPU memory manager. We
- // should probaby either:
- // - wait for the callback before rendering anything instead
- // - push this into the GPU memory manager somehow.
- static size_t DefaultMemoryAllocationLimit() { return 64 * 1024 * 1024; }
-
- // MemoryUseBytes() describes the number of bytes used by existing allocated
- // textures.
- size_t MemoryUseBytes() const { return memory_use_bytes_; }
- // MemoryAboveCutoffBytes() describes the number of bytes that
- // would be used if all textures that are above the cutoff were allocated.
- // MemoryUseBytes() <= MemoryAboveCutoffBytes() should always be true.
- size_t MemoryAboveCutoffBytes() const { return memory_above_cutoff_bytes_; }
- // MaxMemoryNeededBytes() describes the number of bytes that would be used
- // by textures if there were no limit on memory usage.
- size_t MaxMemoryNeededBytes() const { return max_memory_needed_bytes_; }
- size_t MemoryForSelfManagedTextures() const {
- return max_memory_limit_bytes_ - memory_available_bytes_;
- }
-
- void SetMaxMemoryLimitBytes(size_t bytes) { max_memory_limit_bytes_ = bytes; }
- size_t MaxMemoryLimitBytes() const { return max_memory_limit_bytes_; }
-
- // Sepecify a external priority cutoff. Only textures that have a strictly
- // higher priority than this cutoff will be allowed.
- void SetExternalPriorityCutoff(int priority_cutoff) {
- external_priority_cutoff_ = priority_cutoff;
- }
- int ExternalPriorityCutoff() const {
- return external_priority_cutoff_;
- }
-
- // Return the amount of texture memory required at particular cutoffs.
- size_t MemoryVisibleBytes() const;
- size_t MemoryVisibleAndNearbyBytes() const;
-
- void PrioritizeTextures();
- void ClearPriorities();
-
- // Delete contents textures' backing resources until they use only
- // limit_bytes bytes. This may be called on the impl thread while the main
- // thread is running. Returns true if resources are indeed evicted as a
- // result of this call.
- bool ReduceMemoryOnImplThread(size_t limit_bytes,
- int priority_cutoff,
- ResourceProvider* resource_provider);
-
- // Returns true if there exist any textures that are linked to backings that
- // have had their resources evicted. Only when we commit a tree that has no
- // textures linked to evicted backings may we allow drawing. After an
- // eviction, this will not become true until unlinkAndClearEvictedBackings
- // is called.
- bool LinkedEvictedBackingsExist() const;
-
- // Unlink the list of contents textures' backings from their owning textures
- // and delete the evicted backings' structures. This is called just before
- // updating layers, and is only ever called on the main thread.
- void UnlinkAndClearEvictedBackings();
-
- bool RequestLate(PrioritizedResource* texture);
-
- void ReduceWastedMemory(ResourceProvider* resource_provider);
- void ReduceMemory(ResourceProvider* resource_provider);
- void ClearAllMemory(ResourceProvider* resource_provider);
-
- void AcquireBackingTextureIfNeeded(PrioritizedResource* texture,
- ResourceProvider* resource_provider);
-
- void RegisterTexture(PrioritizedResource* texture);
- void UnregisterTexture(PrioritizedResource* texture);
- void ReturnBackingTexture(PrioritizedResource* texture);
-
- // Update all backings' priorities from their owning texture.
- void PushTexturePrioritiesToBackings();
-
- // Mark all textures' backings as being in the drawing impl tree.
- void UpdateBackingsState(ResourceProvider* resource_provider);
-
- const Proxy* ProxyForDebug() const;
-
- private:
- friend class PrioritizedResourceTest;
-
- enum EvictionPolicy {
- EVICT_ONLY_RECYCLABLE,
- EVICT_ANYTHING,
- };
- enum UnlinkPolicy {
- DO_NOT_UNLINK_BACKINGS,
- UNLINK_BACKINGS,
- };
-
- // Compare textures. Highest priority first.
- static inline bool CompareTextures(PrioritizedResource* a,
- PrioritizedResource* b) {
- if (a->request_priority() == b->request_priority())
- return a < b;
- return PriorityCalculator::priority_is_higher(a->request_priority(),
- b->request_priority());
- }
- // Compare backings. Lowest priority first.
- static inline bool CompareBackings(PrioritizedResource::Backing* a,
- PrioritizedResource::Backing* b) {
- // Make textures that can be recycled appear first.
- if (a->CanBeRecycledIfNotInExternalUse() !=
- b->CanBeRecycledIfNotInExternalUse())
- return (a->CanBeRecycledIfNotInExternalUse() >
- b->CanBeRecycledIfNotInExternalUse());
- // Then sort by being above or below the priority cutoff.
- if (a->was_above_priority_cutoff_at_last_priority_update() !=
- b->was_above_priority_cutoff_at_last_priority_update())
- return (a->was_above_priority_cutoff_at_last_priority_update() <
- b->was_above_priority_cutoff_at_last_priority_update());
- // Then sort by priority (note that backings that no longer have owners will
- // always have the lowest priority).
- if (a->request_priority_at_last_priority_update() !=
- b->request_priority_at_last_priority_update())
- return PriorityCalculator::priority_is_lower(
- a->request_priority_at_last_priority_update(),
- b->request_priority_at_last_priority_update());
- // Then sort by being in the impl tree versus being completely
- // unreferenced.
- if (a->in_drawing_impl_tree() != b->in_drawing_impl_tree())
- return (a->in_drawing_impl_tree() < b->in_drawing_impl_tree());
- // Finally, prefer to evict textures in the parent compositor because
- // they will otherwise take another roundtrip to the parent compositor
- // before they are evicted.
- if (a->in_parent_compositor() != b->in_parent_compositor())
- return (a->in_parent_compositor() > b->in_parent_compositor());
- return a < b;
- }
-
- explicit PrioritizedResourceManager(const Proxy* proxy);
-
- bool EvictBackingsToReduceMemory(size_t limit_bytes,
- int priority_cutoff,
- EvictionPolicy eviction_policy,
- UnlinkPolicy unlink_policy,
- ResourceProvider* resource_provider);
- PrioritizedResource::Backing* CreateBacking(
- const gfx::Size& size,
- ResourceFormat format,
- ResourceProvider* resource_provider);
- void EvictFirstBackingResource(ResourceProvider* resource_provider);
- void SortBackings();
-
- void AssertInvariants();
-
- size_t max_memory_limit_bytes_;
- // The priority cutoff based on memory pressure. This is not a strict
- // cutoff -- RequestLate allows textures with priority equal to this
- // cutoff to be allowed.
- int priority_cutoff_;
- // The priority cutoff based on external memory policy. This is a strict
- // cutoff -- no textures with priority equal to this cutoff will be allowed.
- int external_priority_cutoff_;
- size_t memory_use_bytes_;
- size_t memory_above_cutoff_bytes_;
- size_t max_memory_needed_bytes_;
- size_t memory_available_bytes_;
-
- typedef base::hash_set<PrioritizedResource*> TextureSet;
- typedef std::vector<PrioritizedResource*> TextureVector;
-
- const Proxy* proxy_;
-
- TextureSet textures_;
- // This list is always sorted in eviction order, with the exception the
- // newly-allocated or recycled textures at the very end of the tail that
- // are not sorted by priority.
- BackingList backings_;
- bool backings_tail_not_sorted_;
-
- // The list of backings that have been evicted, but may still be linked
- // to textures. This can be accessed concurrently by the main and impl
- // threads, and may only be accessed while holding evicted_backings_lock_.
- mutable base::Lock evicted_backings_lock_;
- BackingList evicted_backings_;
-
- TextureVector temp_texture_vector_;
-
- // Statistics about memory usage at priority cutoffs, computed at
- // PrioritizeTextures.
- size_t memory_visible_bytes_;
- size_t memory_visible_and_nearby_bytes_;
-
- // Statistics copied at the time of PushTexturePrioritiesToBackings.
- size_t memory_visible_last_pushed_bytes_;
- size_t memory_visible_and_nearby_last_pushed_bytes_;
-
- DISALLOW_COPY_AND_ASSIGN(PrioritizedResourceManager);
-};
-
-} // namespace cc
-
-#endif // CC_RESOURCES_PRIORITIZED_RESOURCE_MANAGER_H_
diff --git a/chromium/cc/resources/prioritized_resource_unittest.cc b/chromium/cc/resources/prioritized_resource_unittest.cc
deleted file mode 100644
index f08af8b752e..00000000000
--- a/chromium/cc/resources/prioritized_resource_unittest.cc
+++ /dev/null
@@ -1,1117 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/resources/prioritized_resource.h"
-
-#include <vector>
-
-#include "cc/resources/prioritized_resource_manager.h"
-#include "cc/resources/resource.h"
-#include "cc/resources/resource_provider.h"
-#include "cc/test/fake_output_surface.h"
-#include "cc/test/fake_output_surface_client.h"
-#include "cc/test/fake_proxy.h"
-#include "cc/test/test_shared_bitmap_manager.h"
-#include "cc/test/tiled_layer_test_common.h"
-#include "cc/trees/single_thread_proxy.h" // For DebugScopedSetImplThread
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-
-class PrioritizedResourceTest : public testing::Test {
- public:
- PrioritizedResourceTest()
- : texture_size_(256, 256),
- texture_format_(RGBA_8888),
- output_surface_(FakeOutputSurface::Create3d()) {
- DebugScopedSetImplThread impl_thread(&proxy_);
- CHECK(output_surface_->BindToClient(&output_surface_client_));
- shared_bitmap_manager_.reset(new TestSharedBitmapManager());
- resource_provider_ = ResourceProvider::Create(output_surface_.get(),
- shared_bitmap_manager_.get(),
- NULL,
- NULL,
- 0,
- false,
- 1);
- }
-
- ~PrioritizedResourceTest() override {
- DebugScopedSetImplThread impl_thread(&proxy_);
- resource_provider_ = nullptr;
- }
-
- size_t TexturesMemorySize(size_t texture_count) {
- return Resource::MemorySizeBytes(texture_size_, texture_format_) *
- texture_count;
- }
-
- scoped_ptr<PrioritizedResourceManager> CreateManager(size_t max_textures) {
- scoped_ptr<PrioritizedResourceManager> manager =
- PrioritizedResourceManager::Create(&proxy_);
- manager->SetMaxMemoryLimitBytes(TexturesMemorySize(max_textures));
- return manager.Pass();
- }
-
- bool ValidateTexture(PrioritizedResource* texture,
- bool request_late) {
- ResourceManagerAssertInvariants(texture->resource_manager());
- if (request_late)
- texture->RequestLate();
- ResourceManagerAssertInvariants(texture->resource_manager());
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- bool success = texture->can_acquire_backing_texture();
- if (success)
- texture->AcquireBackingTexture(resource_provider());
- return success;
- }
-
- void PrioritizeTexturesAndBackings(
- PrioritizedResourceManager* resource_manager) {
- resource_manager->PrioritizeTextures();
- ResourceManagerUpdateBackingsPriorities(resource_manager);
- }
-
- void ResourceManagerUpdateBackingsPriorities(
- PrioritizedResourceManager* resource_manager) {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->PushTexturePrioritiesToBackings();
- }
-
- ResourceProvider* resource_provider() { return resource_provider_.get(); }
-
- void ResourceManagerAssertInvariants(
- PrioritizedResourceManager* resource_manager) {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->AssertInvariants();
- }
-
- bool TextureBackingIsAbovePriorityCutoff(PrioritizedResource* texture) {
- return texture->backing()->
- was_above_priority_cutoff_at_last_priority_update();
- }
-
- size_t EvictedBackingCount(PrioritizedResourceManager* resource_manager) {
- return resource_manager->evicted_backings_.size();
- }
-
- std::vector<unsigned> BackingResources(
- PrioritizedResourceManager* resource_manager) {
- std::vector<unsigned> resources;
- for (PrioritizedResourceManager::BackingList::iterator it =
- resource_manager->backings_.begin();
- it != resource_manager->backings_.end();
- ++it)
- resources.push_back((*it)->id());
- return resources;
- }
-
- protected:
- FakeProxy proxy_;
- const gfx::Size texture_size_;
- const ResourceFormat texture_format_;
- FakeOutputSurfaceClient output_surface_client_;
- scoped_ptr<OutputSurface> output_surface_;
- scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
- scoped_ptr<ResourceProvider> resource_provider_;
-};
-
-namespace {
-
-TEST_F(PrioritizedResourceTest, RequestTextureExceedingMaxLimit) {
- const size_t kMaxTextures = 8;
- scoped_ptr<PrioritizedResourceManager> resource_manager =
- CreateManager(kMaxTextures);
-
- // Create textures for double our memory limit.
- scoped_ptr<PrioritizedResource> textures[kMaxTextures * 2];
-
- for (size_t i = 0; i < kMaxTextures * 2; ++i)
- textures[i] =
- resource_manager->CreateTexture(texture_size_, texture_format_);
-
- // Set decreasing priorities
- for (size_t i = 0; i < kMaxTextures * 2; ++i)
- textures[i]->set_request_priority(100 + i);
-
- // Only lower half should be available.
- PrioritizeTexturesAndBackings(resource_manager.get());
- EXPECT_TRUE(ValidateTexture(textures[0].get(), false));
- EXPECT_TRUE(ValidateTexture(textures[7].get(), false));
- EXPECT_FALSE(ValidateTexture(textures[8].get(), false));
- EXPECT_FALSE(ValidateTexture(textures[15].get(), false));
-
- // Set increasing priorities
- for (size_t i = 0; i < kMaxTextures * 2; ++i)
- textures[i]->set_request_priority(100 - i);
-
- // Only upper half should be available.
- PrioritizeTexturesAndBackings(resource_manager.get());
- EXPECT_FALSE(ValidateTexture(textures[0].get(), false));
- EXPECT_FALSE(ValidateTexture(textures[7].get(), false));
- EXPECT_TRUE(ValidateTexture(textures[8].get(), false));
- EXPECT_TRUE(ValidateTexture(textures[15].get(), false));
-
- EXPECT_EQ(TexturesMemorySize(kMaxTextures),
- resource_manager->MemoryAboveCutoffBytes());
- EXPECT_LE(resource_manager->MemoryUseBytes(),
- resource_manager->MemoryAboveCutoffBytes());
- EXPECT_EQ(TexturesMemorySize(2*kMaxTextures),
- resource_manager->MaxMemoryNeededBytes());
-
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->ClearAllMemory(resource_provider());
-}
-
-TEST_F(PrioritizedResourceTest, ChangeMemoryLimits) {
- const size_t kMaxTextures = 8;
- scoped_ptr<PrioritizedResourceManager> resource_manager =
- CreateManager(kMaxTextures);
- scoped_ptr<PrioritizedResource> textures[kMaxTextures];
-
- for (size_t i = 0; i < kMaxTextures; ++i) {
- textures[i] =
- resource_manager->CreateTexture(texture_size_, texture_format_);
- }
- for (size_t i = 0; i < kMaxTextures; ++i)
- textures[i]->set_request_priority(100 + i);
-
- // Set max limit to 8 textures
- resource_manager->SetMaxMemoryLimitBytes(TexturesMemorySize(8));
- PrioritizeTexturesAndBackings(resource_manager.get());
- for (size_t i = 0; i < kMaxTextures; ++i)
- ValidateTexture(textures[i].get(), false);
- {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->ReduceMemory(resource_provider());
- }
-
- EXPECT_EQ(TexturesMemorySize(8), resource_manager->MemoryAboveCutoffBytes());
- EXPECT_LE(resource_manager->MemoryUseBytes(),
- resource_manager->MemoryAboveCutoffBytes());
-
- // Set max limit to 5 textures
- resource_manager->SetMaxMemoryLimitBytes(TexturesMemorySize(5));
- PrioritizeTexturesAndBackings(resource_manager.get());
- for (size_t i = 0; i < kMaxTextures; ++i)
- EXPECT_EQ(ValidateTexture(textures[i].get(), false), i < 5);
- {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->ReduceMemory(resource_provider());
- }
-
- EXPECT_EQ(TexturesMemorySize(5), resource_manager->MemoryAboveCutoffBytes());
- EXPECT_LE(resource_manager->MemoryUseBytes(),
- resource_manager->MemoryAboveCutoffBytes());
- EXPECT_EQ(TexturesMemorySize(kMaxTextures),
- resource_manager->MaxMemoryNeededBytes());
-
- // Set max limit to 4 textures
- resource_manager->SetMaxMemoryLimitBytes(TexturesMemorySize(4));
- PrioritizeTexturesAndBackings(resource_manager.get());
- for (size_t i = 0; i < kMaxTextures; ++i)
- EXPECT_EQ(ValidateTexture(textures[i].get(), false), i < 4);
- {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->ReduceMemory(resource_provider());
- }
-
- EXPECT_EQ(TexturesMemorySize(4), resource_manager->MemoryAboveCutoffBytes());
- EXPECT_LE(resource_manager->MemoryUseBytes(),
- resource_manager->MemoryAboveCutoffBytes());
- EXPECT_EQ(TexturesMemorySize(kMaxTextures),
- resource_manager->MaxMemoryNeededBytes());
-
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->ClearAllMemory(resource_provider());
-}
-
-TEST_F(PrioritizedResourceTest, ReduceWastedMemory) {
- const size_t kMaxTextures = 20;
- scoped_ptr<PrioritizedResourceManager> resource_manager =
- CreateManager(kMaxTextures);
- scoped_ptr<PrioritizedResource> textures[kMaxTextures];
-
- for (size_t i = 0; i < kMaxTextures; ++i) {
- textures[i] =
- resource_manager->CreateTexture(texture_size_, texture_format_);
- }
- for (size_t i = 0; i < kMaxTextures; ++i)
- textures[i]->set_request_priority(100 + i);
-
- // Set the memory limit to the max number of textures.
- resource_manager->SetMaxMemoryLimitBytes(TexturesMemorySize(kMaxTextures));
- PrioritizeTexturesAndBackings(resource_manager.get());
-
- // Create backings and textures for all of the textures.
- for (size_t i = 0; i < kMaxTextures; ++i) {
- ValidateTexture(textures[i].get(), false);
-
- {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- uint8_t image[4] = {0};
- textures[i]->SetPixels(resource_provider_.get(),
- image,
- gfx::Rect(1, 1),
- gfx::Rect(1, 1),
- gfx::Vector2d());
- }
- }
- {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->ReduceMemory(resource_provider());
- }
-
- // 20 textures have backings allocated.
- EXPECT_EQ(TexturesMemorySize(20), resource_manager->MemoryUseBytes());
-
- // Destroy one texture, not enough is wasted to cause cleanup.
- textures[0] = nullptr;
- PrioritizeTexturesAndBackings(resource_manager.get());
- {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->UpdateBackingsState(resource_provider());
- resource_manager->ReduceWastedMemory(resource_provider());
- }
- EXPECT_EQ(TexturesMemorySize(20), resource_manager->MemoryUseBytes());
-
- // Destroy half the textures, leaving behind the backings. Now a cleanup
- // should happen.
- for (size_t i = 0; i < kMaxTextures / 2; ++i)
- textures[i] = nullptr;
- PrioritizeTexturesAndBackings(resource_manager.get());
- {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->UpdateBackingsState(resource_provider());
- resource_manager->ReduceWastedMemory(resource_provider());
- }
- EXPECT_GT(TexturesMemorySize(20), resource_manager->MemoryUseBytes());
-
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->ClearAllMemory(resource_provider());
-}
-
-TEST_F(PrioritizedResourceTest, InUseNotWastedMemory) {
- const size_t kMaxTextures = 20;
- scoped_ptr<PrioritizedResourceManager> resource_manager =
- CreateManager(kMaxTextures);
- scoped_ptr<PrioritizedResource> textures[kMaxTextures];
-
- for (size_t i = 0; i < kMaxTextures; ++i) {
- textures[i] =
- resource_manager->CreateTexture(texture_size_, texture_format_);
- }
- for (size_t i = 0; i < kMaxTextures; ++i)
- textures[i]->set_request_priority(100 + i);
-
- // Set the memory limit to the max number of textures.
- resource_manager->SetMaxMemoryLimitBytes(TexturesMemorySize(kMaxTextures));
- PrioritizeTexturesAndBackings(resource_manager.get());
-
- // Create backings and textures for all of the textures.
- for (size_t i = 0; i < kMaxTextures; ++i) {
- ValidateTexture(textures[i].get(), false);
-
- {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- uint8_t image[4] = {0};
- textures[i]->SetPixels(resource_provider_.get(),
- image,
- gfx::Rect(1, 1),
- gfx::Rect(1, 1),
- gfx::Vector2d());
- }
- }
- {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->ReduceMemory(resource_provider());
- }
-
- // 20 textures have backings allocated.
- EXPECT_EQ(TexturesMemorySize(20), resource_manager->MemoryUseBytes());
-
- // Send half the textures to a parent compositor.
- ResourceProvider::ResourceIdArray to_send;
- TransferableResourceArray transferable;
- for (size_t i = 0; i < kMaxTextures / 2; ++i)
- to_send.push_back(textures[i]->resource_id());
- resource_provider_->PrepareSendToParent(to_send, &transferable);
-
- // Destroy half the textures, leaving behind the backings. The backings are
- // sent to a parent compositor though, so they should not be considered wasted
- // and a cleanup should not happen.
- for (size_t i = 0; i < kMaxTextures / 2; ++i)
- textures[i] = nullptr;
- PrioritizeTexturesAndBackings(resource_manager.get());
- {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->UpdateBackingsState(resource_provider());
- resource_manager->ReduceWastedMemory(resource_provider());
- }
- EXPECT_EQ(TexturesMemorySize(20), resource_manager->MemoryUseBytes());
-
- // Receive the textures back from the parent compositor. Now a cleanup should
- // happen.
- ReturnedResourceArray returns;
- TransferableResource::ReturnResources(transferable, &returns);
- resource_provider_->ReceiveReturnsFromParent(returns);
- {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->UpdateBackingsState(resource_provider());
- resource_manager->ReduceWastedMemory(resource_provider());
- }
- EXPECT_GT(TexturesMemorySize(20), resource_manager->MemoryUseBytes());
-
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->ClearAllMemory(resource_provider());
-}
-
-TEST_F(PrioritizedResourceTest, ChangePriorityCutoff) {
- const size_t kMaxTextures = 8;
- scoped_ptr<PrioritizedResourceManager> resource_manager =
- CreateManager(kMaxTextures);
- scoped_ptr<PrioritizedResource> textures[kMaxTextures];
-
- for (size_t i = 0; i < kMaxTextures; ++i) {
- textures[i] =
- resource_manager->CreateTexture(texture_size_, texture_format_);
- }
- for (size_t i = 0; i < kMaxTextures; ++i)
- textures[i]->set_request_priority(100 + i);
-
- // Set the cutoff to drop two textures. Try to request_late on all textures,
- // and make sure that request_late doesn't work on a texture with equal
- // priority to the cutoff.
- resource_manager->SetMaxMemoryLimitBytes(TexturesMemorySize(8));
- resource_manager->SetExternalPriorityCutoff(106);
- PrioritizeTexturesAndBackings(resource_manager.get());
- for (size_t i = 0; i < kMaxTextures; ++i)
- EXPECT_EQ(ValidateTexture(textures[i].get(), true), i < 6);
- {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->ReduceMemory(resource_provider());
- }
- EXPECT_EQ(TexturesMemorySize(6), resource_manager->MemoryAboveCutoffBytes());
- EXPECT_LE(resource_manager->MemoryUseBytes(),
- resource_manager->MemoryAboveCutoffBytes());
-
- // Set the cutoff to drop two more textures.
- resource_manager->SetExternalPriorityCutoff(104);
- PrioritizeTexturesAndBackings(resource_manager.get());
- for (size_t i = 0; i < kMaxTextures; ++i)
- EXPECT_EQ(ValidateTexture(textures[i].get(), false), i < 4);
- {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->ReduceMemory(resource_provider());
- }
- EXPECT_EQ(TexturesMemorySize(4), resource_manager->MemoryAboveCutoffBytes());
-
- // Do a one-time eviction for one more texture based on priority cutoff
- resource_manager->UnlinkAndClearEvictedBackings();
- {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->ReduceMemoryOnImplThread(
- TexturesMemorySize(8), 104, resource_provider());
- EXPECT_EQ(0u, EvictedBackingCount(resource_manager.get()));
- resource_manager->ReduceMemoryOnImplThread(
- TexturesMemorySize(8), 103, resource_provider());
- EXPECT_EQ(1u, EvictedBackingCount(resource_manager.get()));
- }
- resource_manager->UnlinkAndClearEvictedBackings();
- EXPECT_EQ(TexturesMemorySize(3), resource_manager->MemoryUseBytes());
-
- // Re-allocate the the texture after the one-time drop.
- PrioritizeTexturesAndBackings(resource_manager.get());
- for (size_t i = 0; i < kMaxTextures; ++i)
- EXPECT_EQ(ValidateTexture(textures[i].get(), false), i < 4);
- {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->ReduceMemory(resource_provider());
- }
- EXPECT_EQ(TexturesMemorySize(4), resource_manager->MemoryAboveCutoffBytes());
-
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->ClearAllMemory(resource_provider());
-}
-
-TEST_F(PrioritizedResourceTest, EvictingTexturesInParent) {
- const size_t kMaxTextures = 8;
- scoped_ptr<PrioritizedResourceManager> resource_manager =
- CreateManager(kMaxTextures);
- scoped_ptr<PrioritizedResource> textures[kMaxTextures];
- unsigned texture_resource_ids[kMaxTextures];
-
- for (size_t i = 0; i < kMaxTextures; ++i) {
- textures[i] =
- resource_manager->CreateTexture(texture_size_, texture_format_);
- textures[i]->set_request_priority(100 + i);
- }
-
- PrioritizeTexturesAndBackings(resource_manager.get());
- for (size_t i = 0; i < kMaxTextures; ++i) {
- EXPECT_TRUE(ValidateTexture(textures[i].get(), true));
-
- {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- uint8_t image[4] = {0};
- textures[i]->SetPixels(resource_provider_.get(),
- image,
- gfx::Rect(1, 1),
- gfx::Rect(1, 1),
- gfx::Vector2d());
- }
- }
- {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->ReduceMemory(resource_provider());
- }
- EXPECT_EQ(TexturesMemorySize(8), resource_manager->MemoryAboveCutoffBytes());
-
- for (size_t i = 0; i < 8; ++i)
- texture_resource_ids[i] = textures[i]->resource_id();
-
- // Evict four textures. It will be the last four.
- {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->ReduceMemoryOnImplThread(
- TexturesMemorySize(4), 200, resource_provider());
-
- EXPECT_EQ(4u, EvictedBackingCount(resource_manager.get()));
-
- // The last four backings are evicted.
- std::vector<unsigned> remaining = BackingResources(resource_manager.get());
- EXPECT_TRUE(std::find(remaining.begin(),
- remaining.end(),
- texture_resource_ids[0]) != remaining.end());
- EXPECT_TRUE(std::find(remaining.begin(),
- remaining.end(),
- texture_resource_ids[1]) != remaining.end());
- EXPECT_TRUE(std::find(remaining.begin(),
- remaining.end(),
- texture_resource_ids[2]) != remaining.end());
- EXPECT_TRUE(std::find(remaining.begin(),
- remaining.end(),
- texture_resource_ids[3]) != remaining.end());
- }
- resource_manager->UnlinkAndClearEvictedBackings();
- EXPECT_EQ(TexturesMemorySize(4), resource_manager->MemoryUseBytes());
-
- // Re-allocate the the texture after the eviction.
- PrioritizeTexturesAndBackings(resource_manager.get());
- for (size_t i = 0; i < kMaxTextures; ++i) {
- EXPECT_TRUE(ValidateTexture(textures[i].get(), true));
-
- {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- uint8_t image[4] = {0};
- textures[i]->SetPixels(resource_provider_.get(),
- image,
- gfx::Rect(1, 1),
- gfx::Rect(1, 1),
- gfx::Vector2d());
- }
- }
- {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->ReduceMemory(resource_provider());
- }
- EXPECT_EQ(TexturesMemorySize(8), resource_manager->MemoryAboveCutoffBytes());
-
- // Send the last two of the textures to a parent compositor.
- ResourceProvider::ResourceIdArray to_send;
- TransferableResourceArray transferable;
- for (size_t i = 6; i < 8; ++i)
- to_send.push_back(textures[i]->resource_id());
- resource_provider_->PrepareSendToParent(to_send, &transferable);
-
- // Set the last two textures to be tied for prioity with the two
- // before them. Being sent to the parent will break the tie.
- textures[4]->set_request_priority(100 + 4);
- textures[5]->set_request_priority(100 + 5);
- textures[6]->set_request_priority(100 + 4);
- textures[7]->set_request_priority(100 + 5);
-
- for (size_t i = 0; i < 8; ++i)
- texture_resource_ids[i] = textures[i]->resource_id();
-
- // Drop all the textures. Now we have backings that can be recycled.
- for (size_t i = 0; i < 8; ++i)
- textures[0] = nullptr;
- PrioritizeTexturesAndBackings(resource_manager.get());
-
- // The next commit finishes.
- {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->UpdateBackingsState(resource_provider());
- }
-
- // Evict four textures. It would be the last four again, except that 2 of them
- // are sent to the parent, so they are evicted last.
- {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->ReduceMemoryOnImplThread(
- TexturesMemorySize(4), 200, resource_provider());
-
- EXPECT_EQ(4u, EvictedBackingCount(resource_manager.get()));
- // The last 2 backings remain this time.
- std::vector<unsigned> remaining = BackingResources(resource_manager.get());
- EXPECT_TRUE(std::find(remaining.begin(),
- remaining.end(),
- texture_resource_ids[6]) == remaining.end());
- EXPECT_TRUE(std::find(remaining.begin(),
- remaining.end(),
- texture_resource_ids[7]) == remaining.end());
- }
- resource_manager->UnlinkAndClearEvictedBackings();
- EXPECT_EQ(TexturesMemorySize(4), resource_manager->MemoryUseBytes());
-
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->ClearAllMemory(resource_provider());
-}
-
-TEST_F(PrioritizedResourceTest, ResourceManagerPartialUpdateTextures) {
- const size_t kMaxTextures = 4;
- const size_t kNumTextures = 4;
- scoped_ptr<PrioritizedResourceManager> resource_manager =
- CreateManager(kMaxTextures);
- scoped_ptr<PrioritizedResource> textures[kNumTextures];
- scoped_ptr<PrioritizedResource> more_textures[kNumTextures];
-
- for (size_t i = 0; i < kNumTextures; ++i) {
- textures[i] =
- resource_manager->CreateTexture(texture_size_, texture_format_);
- more_textures[i] =
- resource_manager->CreateTexture(texture_size_, texture_format_);
- }
-
- for (size_t i = 0; i < kNumTextures; ++i)
- textures[i]->set_request_priority(200 + i);
- PrioritizeTexturesAndBackings(resource_manager.get());
-
- // Allocate textures which are currently high priority.
- EXPECT_TRUE(ValidateTexture(textures[0].get(), false));
- EXPECT_TRUE(ValidateTexture(textures[1].get(), false));
- EXPECT_TRUE(ValidateTexture(textures[2].get(), false));
- EXPECT_TRUE(ValidateTexture(textures[3].get(), false));
-
- EXPECT_TRUE(textures[0]->have_backing_texture());
- EXPECT_TRUE(textures[1]->have_backing_texture());
- EXPECT_TRUE(textures[2]->have_backing_texture());
- EXPECT_TRUE(textures[3]->have_backing_texture());
-
- for (size_t i = 0; i < kNumTextures; ++i)
- more_textures[i]->set_request_priority(100 + i);
- PrioritizeTexturesAndBackings(resource_manager.get());
-
- // Textures are now below cutoff.
- EXPECT_FALSE(ValidateTexture(textures[0].get(), false));
- EXPECT_FALSE(ValidateTexture(textures[1].get(), false));
- EXPECT_FALSE(ValidateTexture(textures[2].get(), false));
- EXPECT_FALSE(ValidateTexture(textures[3].get(), false));
-
- // But they are still valid to use.
- EXPECT_TRUE(textures[0]->have_backing_texture());
- EXPECT_TRUE(textures[1]->have_backing_texture());
- EXPECT_TRUE(textures[2]->have_backing_texture());
- EXPECT_TRUE(textures[3]->have_backing_texture());
-
- // Higher priority textures are finally needed.
- EXPECT_TRUE(ValidateTexture(more_textures[0].get(), false));
- EXPECT_TRUE(ValidateTexture(more_textures[1].get(), false));
- EXPECT_TRUE(ValidateTexture(more_textures[2].get(), false));
- EXPECT_TRUE(ValidateTexture(more_textures[3].get(), false));
-
- // Lower priority have been fully evicted.
- EXPECT_FALSE(textures[0]->have_backing_texture());
- EXPECT_FALSE(textures[1]->have_backing_texture());
- EXPECT_FALSE(textures[2]->have_backing_texture());
- EXPECT_FALSE(textures[3]->have_backing_texture());
-
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->ClearAllMemory(resource_provider());
-}
-
-TEST_F(PrioritizedResourceTest, ResourceManagerPrioritiesAreEqual) {
- const size_t kMaxTextures = 16;
- scoped_ptr<PrioritizedResourceManager> resource_manager =
- CreateManager(kMaxTextures);
- scoped_ptr<PrioritizedResource> textures[kMaxTextures];
-
- for (size_t i = 0; i < kMaxTextures; ++i) {
- textures[i] =
- resource_manager->CreateTexture(texture_size_, texture_format_);
- }
-
- // All 16 textures have the same priority except 2 higher priority.
- for (size_t i = 0; i < kMaxTextures; ++i)
- textures[i]->set_request_priority(100);
- textures[0]->set_request_priority(99);
- textures[1]->set_request_priority(99);
-
- // Set max limit to 8 textures
- resource_manager->SetMaxMemoryLimitBytes(TexturesMemorySize(8));
- PrioritizeTexturesAndBackings(resource_manager.get());
-
- // The two high priority textures should be available, others should not.
- for (size_t i = 0; i < 2; ++i)
- EXPECT_TRUE(ValidateTexture(textures[i].get(), false));
- for (size_t i = 2; i < kMaxTextures; ++i)
- EXPECT_FALSE(ValidateTexture(textures[i].get(), false));
- EXPECT_EQ(TexturesMemorySize(2), resource_manager->MemoryAboveCutoffBytes());
- EXPECT_LE(resource_manager->MemoryUseBytes(),
- resource_manager->MemoryAboveCutoffBytes());
-
- // Manually reserving textures should only succeed on the higher priority
- // textures, and on remaining textures up to the memory limit.
- for (size_t i = 0; i < 8; i++)
- EXPECT_TRUE(ValidateTexture(textures[i].get(), true));
- for (size_t i = 9; i < kMaxTextures; i++)
- EXPECT_FALSE(ValidateTexture(textures[i].get(), true));
- EXPECT_EQ(TexturesMemorySize(8), resource_manager->MemoryAboveCutoffBytes());
- EXPECT_LE(resource_manager->MemoryUseBytes(),
- resource_manager->MemoryAboveCutoffBytes());
-
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->ClearAllMemory(resource_provider());
-}
-
-TEST_F(PrioritizedResourceTest, ResourceManagerDestroyedFirst) {
- scoped_ptr<PrioritizedResourceManager> resource_manager = CreateManager(1);
- scoped_ptr<PrioritizedResource> texture =
- resource_manager->CreateTexture(texture_size_, texture_format_);
-
- // Texture is initially invalid, but it will become available.
- EXPECT_FALSE(texture->have_backing_texture());
-
- texture->set_request_priority(100);
- PrioritizeTexturesAndBackings(resource_manager.get());
-
- EXPECT_TRUE(ValidateTexture(texture.get(), false));
- EXPECT_TRUE(texture->can_acquire_backing_texture());
- EXPECT_TRUE(texture->have_backing_texture());
- {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->ClearAllMemory(resource_provider());
- }
- resource_manager = nullptr;
-
- EXPECT_FALSE(texture->can_acquire_backing_texture());
- EXPECT_FALSE(texture->have_backing_texture());
-}
-
-TEST_F(PrioritizedResourceTest, TextureMovedToNewManager) {
- scoped_ptr<PrioritizedResourceManager> resource_manager_one =
- CreateManager(1);
- scoped_ptr<PrioritizedResourceManager> resource_manager_two =
- CreateManager(1);
- scoped_ptr<PrioritizedResource> texture =
- resource_manager_one->CreateTexture(texture_size_, texture_format_);
-
- // Texture is initially invalid, but it will become available.
- EXPECT_FALSE(texture->have_backing_texture());
-
- texture->set_request_priority(100);
- PrioritizeTexturesAndBackings(resource_manager_one.get());
-
- EXPECT_TRUE(ValidateTexture(texture.get(), false));
- EXPECT_TRUE(texture->can_acquire_backing_texture());
- EXPECT_TRUE(texture->have_backing_texture());
-
- texture->SetTextureManager(NULL);
- {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager_one->ClearAllMemory(resource_provider());
- }
- resource_manager_one = nullptr;
-
- EXPECT_FALSE(texture->can_acquire_backing_texture());
- EXPECT_FALSE(texture->have_backing_texture());
-
- texture->SetTextureManager(resource_manager_two.get());
-
- PrioritizeTexturesAndBackings(resource_manager_two.get());
-
- EXPECT_TRUE(ValidateTexture(texture.get(), false));
- EXPECT_TRUE(texture->can_acquire_backing_texture());
- EXPECT_TRUE(texture->have_backing_texture());
-
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager_two->ClearAllMemory(resource_provider());
-}
-
-TEST_F(PrioritizedResourceTest,
- RenderSurfacesReduceMemoryAvailableOutsideRootSurface) {
- const size_t kMaxTextures = 8;
- scoped_ptr<PrioritizedResourceManager> resource_manager =
- CreateManager(kMaxTextures);
-
- // Half of the memory is taken by surfaces (with high priority place-holder)
- scoped_ptr<PrioritizedResource> render_surface_place_holder =
- resource_manager->CreateTexture(texture_size_, texture_format_);
- render_surface_place_holder->SetToSelfManagedMemoryPlaceholder(
- TexturesMemorySize(4));
- render_surface_place_holder->set_request_priority(
- PriorityCalculator::RenderSurfacePriority());
-
- // Create textures to fill our memory limit.
- scoped_ptr<PrioritizedResource> textures[kMaxTextures];
-
- for (size_t i = 0; i < kMaxTextures; ++i) {
- textures[i] =
- resource_manager->CreateTexture(texture_size_, texture_format_);
- }
-
- // Set decreasing non-visible priorities outside root surface.
- for (size_t i = 0; i < kMaxTextures; ++i)
- textures[i]->set_request_priority(100 + i);
-
- // Only lower half should be available.
- PrioritizeTexturesAndBackings(resource_manager.get());
- EXPECT_TRUE(ValidateTexture(textures[0].get(), false));
- EXPECT_TRUE(ValidateTexture(textures[3].get(), false));
- EXPECT_FALSE(ValidateTexture(textures[4].get(), false));
- EXPECT_FALSE(ValidateTexture(textures[7].get(), false));
-
- // Set increasing non-visible priorities outside root surface.
- for (size_t i = 0; i < kMaxTextures; ++i)
- textures[i]->set_request_priority(100 - i);
-
- // Only upper half should be available.
- PrioritizeTexturesAndBackings(resource_manager.get());
- EXPECT_FALSE(ValidateTexture(textures[0].get(), false));
- EXPECT_FALSE(ValidateTexture(textures[3].get(), false));
- EXPECT_TRUE(ValidateTexture(textures[4].get(), false));
- EXPECT_TRUE(ValidateTexture(textures[7].get(), false));
-
- EXPECT_EQ(TexturesMemorySize(4), resource_manager->MemoryAboveCutoffBytes());
- EXPECT_EQ(TexturesMemorySize(4),
- resource_manager->MemoryForSelfManagedTextures());
- EXPECT_LE(resource_manager->MemoryUseBytes(),
- resource_manager->MemoryAboveCutoffBytes());
- EXPECT_EQ(TexturesMemorySize(8),
- resource_manager->MaxMemoryNeededBytes());
-
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->ClearAllMemory(resource_provider());
-}
-
-TEST_F(PrioritizedResourceTest,
- RenderSurfacesReduceMemoryAvailableForRequestLate) {
- const size_t kMaxTextures = 8;
- scoped_ptr<PrioritizedResourceManager> resource_manager =
- CreateManager(kMaxTextures);
-
- // Half of the memory is taken by surfaces (with high priority place-holder)
- scoped_ptr<PrioritizedResource> render_surface_place_holder =
- resource_manager->CreateTexture(texture_size_, texture_format_);
- render_surface_place_holder->SetToSelfManagedMemoryPlaceholder(
- TexturesMemorySize(4));
- render_surface_place_holder->set_request_priority(
- PriorityCalculator::RenderSurfacePriority());
-
- // Create textures to fill our memory limit.
- scoped_ptr<PrioritizedResource> textures[kMaxTextures];
-
- for (size_t i = 0; i < kMaxTextures; ++i) {
- textures[i] =
- resource_manager->CreateTexture(texture_size_, texture_format_);
- }
-
- // Set equal priorities.
- for (size_t i = 0; i < kMaxTextures; ++i)
- textures[i]->set_request_priority(100);
-
- // The first four to be requested late will be available.
- PrioritizeTexturesAndBackings(resource_manager.get());
- for (unsigned i = 0; i < kMaxTextures; ++i)
- EXPECT_FALSE(ValidateTexture(textures[i].get(), false));
- for (unsigned i = 0; i < kMaxTextures; i += 2)
- EXPECT_TRUE(ValidateTexture(textures[i].get(), true));
- for (unsigned i = 1; i < kMaxTextures; i += 2)
- EXPECT_FALSE(ValidateTexture(textures[i].get(), true));
-
- EXPECT_EQ(TexturesMemorySize(4), resource_manager->MemoryAboveCutoffBytes());
- EXPECT_EQ(TexturesMemorySize(4),
- resource_manager->MemoryForSelfManagedTextures());
- EXPECT_LE(resource_manager->MemoryUseBytes(),
- resource_manager->MemoryAboveCutoffBytes());
- EXPECT_EQ(TexturesMemorySize(8),
- resource_manager->MaxMemoryNeededBytes());
-
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->ClearAllMemory(resource_provider());
-}
-
-TEST_F(PrioritizedResourceTest,
- WhenRenderSurfaceNotAvailableTexturesAlsoNotAvailable) {
- const size_t kMaxTextures = 8;
- scoped_ptr<PrioritizedResourceManager> resource_manager =
- CreateManager(kMaxTextures);
-
- // Half of the memory is taken by surfaces (with high priority place-holder)
- scoped_ptr<PrioritizedResource> render_surface_place_holder =
- resource_manager->CreateTexture(texture_size_, texture_format_);
- render_surface_place_holder->SetToSelfManagedMemoryPlaceholder(
- TexturesMemorySize(4));
- render_surface_place_holder->set_request_priority(
- PriorityCalculator::RenderSurfacePriority());
-
- // Create textures to fill our memory limit.
- scoped_ptr<PrioritizedResource> textures[kMaxTextures];
-
- for (size_t i = 0; i < kMaxTextures; ++i)
- textures[i] =
- resource_manager->CreateTexture(texture_size_, texture_format_);
-
- // Set 6 visible textures in the root surface, and 2 in a child surface.
- for (size_t i = 0; i < 6; ++i) {
- textures[i]->
- set_request_priority(PriorityCalculator::VisiblePriority(true));
- }
- for (size_t i = 6; i < 8; ++i) {
- textures[i]->
- set_request_priority(PriorityCalculator::VisiblePriority(false));
- }
-
- PrioritizeTexturesAndBackings(resource_manager.get());
-
- // Unable to request_late textures in the child surface.
- EXPECT_FALSE(ValidateTexture(textures[6].get(), true));
- EXPECT_FALSE(ValidateTexture(textures[7].get(), true));
-
- // Root surface textures are valid.
- for (size_t i = 0; i < 6; ++i)
- EXPECT_TRUE(ValidateTexture(textures[i].get(), false));
-
- EXPECT_EQ(TexturesMemorySize(6), resource_manager->MemoryAboveCutoffBytes());
- EXPECT_EQ(TexturesMemorySize(2),
- resource_manager->MemoryForSelfManagedTextures());
- EXPECT_LE(resource_manager->MemoryUseBytes(),
- resource_manager->MemoryAboveCutoffBytes());
-
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->ClearAllMemory(resource_provider());
-}
-
-TEST_F(PrioritizedResourceTest, RequestLateBackingsSorting) {
- const size_t kMaxTextures = 8;
- scoped_ptr<PrioritizedResourceManager> resource_manager =
- CreateManager(kMaxTextures);
- resource_manager->SetMaxMemoryLimitBytes(TexturesMemorySize(kMaxTextures));
-
- // Create textures to fill our memory limit.
- scoped_ptr<PrioritizedResource> textures[kMaxTextures];
- for (size_t i = 0; i < kMaxTextures; ++i)
- textures[i] =
- resource_manager->CreateTexture(texture_size_, texture_format_);
-
- // Set equal priorities, and allocate backings for all textures.
- for (size_t i = 0; i < kMaxTextures; ++i)
- textures[i]->set_request_priority(100);
- PrioritizeTexturesAndBackings(resource_manager.get());
- for (unsigned i = 0; i < kMaxTextures; ++i)
- EXPECT_TRUE(ValidateTexture(textures[i].get(), false));
-
- // Drop the memory limit and prioritize (none will be above the threshold,
- // but they still have backings because ReduceMemory hasn't been called).
- resource_manager->SetMaxMemoryLimitBytes(
- TexturesMemorySize(kMaxTextures / 2));
- PrioritizeTexturesAndBackings(resource_manager.get());
-
- // Push half of them back over the limit.
- for (size_t i = 0; i < kMaxTextures; i += 2)
- EXPECT_TRUE(textures[i]->RequestLate());
-
- // Push the priorities to the backings array and sort the backings array
- ResourceManagerUpdateBackingsPriorities(resource_manager.get());
-
- // Assert that the backings list be sorted with the below-limit backings
- // before the above-limit backings.
- ResourceManagerAssertInvariants(resource_manager.get());
-
- // Make sure that we have backings for all of the textures.
- for (size_t i = 0; i < kMaxTextures; ++i)
- EXPECT_TRUE(textures[i]->have_backing_texture());
-
- // Make sure that only the request_late textures are above the priority
- // cutoff
- for (size_t i = 0; i < kMaxTextures; i += 2)
- EXPECT_TRUE(TextureBackingIsAbovePriorityCutoff(textures[i].get()));
- for (size_t i = 1; i < kMaxTextures; i += 2)
- EXPECT_FALSE(TextureBackingIsAbovePriorityCutoff(textures[i].get()));
-
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->ClearAllMemory(resource_provider());
-}
-
-TEST_F(PrioritizedResourceTest, ClearUploadsToEvictedResources) {
- const size_t kMaxTextures = 4;
- scoped_ptr<PrioritizedResourceManager> resource_manager =
- CreateManager(kMaxTextures);
- resource_manager->SetMaxMemoryLimitBytes(TexturesMemorySize(kMaxTextures));
-
- // Create textures to fill our memory limit.
- scoped_ptr<PrioritizedResource> textures[kMaxTextures];
-
- for (size_t i = 0; i < kMaxTextures; ++i)
- textures[i] =
- resource_manager->CreateTexture(texture_size_, texture_format_);
-
- // Set equal priorities, and allocate backings for all textures.
- for (size_t i = 0; i < kMaxTextures; ++i)
- textures[i]->set_request_priority(100);
- PrioritizeTexturesAndBackings(resource_manager.get());
- for (unsigned i = 0; i < kMaxTextures; ++i)
- EXPECT_TRUE(ValidateTexture(textures[i].get(), false));
-
- ResourceUpdateQueue queue;
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- for (size_t i = 0; i < kMaxTextures; ++i) {
- const ResourceUpdate upload = ResourceUpdate::Create(
- textures[i].get(), NULL, gfx::Rect(), gfx::Rect(), gfx::Vector2d());
- queue.AppendFullUpload(upload);
- }
-
- // Make sure that we have backings for all of the textures.
- for (size_t i = 0; i < kMaxTextures; ++i)
- EXPECT_TRUE(textures[i]->have_backing_texture());
-
- queue.ClearUploadsToEvictedResources();
- EXPECT_EQ(4u, queue.FullUploadSize());
-
- resource_manager->ReduceMemoryOnImplThread(
- TexturesMemorySize(1),
- PriorityCalculator::AllowEverythingCutoff(),
- resource_provider());
- queue.ClearUploadsToEvictedResources();
- EXPECT_EQ(1u, queue.FullUploadSize());
-
- resource_manager->ReduceMemoryOnImplThread(
- 0, PriorityCalculator::AllowEverythingCutoff(), resource_provider());
- queue.ClearUploadsToEvictedResources();
- EXPECT_EQ(0u, queue.FullUploadSize());
-}
-
-TEST_F(PrioritizedResourceTest, UsageStatistics) {
- const size_t kMaxTextures = 5;
- scoped_ptr<PrioritizedResourceManager> resource_manager =
- CreateManager(kMaxTextures);
- scoped_ptr<PrioritizedResource> textures[kMaxTextures];
-
- for (size_t i = 0; i < kMaxTextures; ++i) {
- textures[i] =
- resource_manager->CreateTexture(texture_size_, texture_format_);
- }
-
- textures[0]->
- set_request_priority(PriorityCalculator::AllowVisibleOnlyCutoff() - 1);
- textures[1]->
- set_request_priority(PriorityCalculator::AllowVisibleOnlyCutoff());
- textures[2]->set_request_priority(
- PriorityCalculator::AllowVisibleAndNearbyCutoff() - 1);
- textures[3]->
- set_request_priority(PriorityCalculator::AllowVisibleAndNearbyCutoff());
- textures[4]->set_request_priority(
- PriorityCalculator::AllowVisibleAndNearbyCutoff() + 1);
-
- // Set max limit to 2 textures.
- resource_manager->SetMaxMemoryLimitBytes(TexturesMemorySize(2));
- PrioritizeTexturesAndBackings(resource_manager.get());
-
- // The first two textures should be available, others should not.
- for (size_t i = 0; i < 2; ++i)
- EXPECT_TRUE(ValidateTexture(textures[i].get(), false));
- for (size_t i = 2; i < kMaxTextures; ++i)
- EXPECT_FALSE(ValidateTexture(textures[i].get(), false));
-
- // Validate the statistics.
- {
- DebugScopedSetImplThread impl_thread(&proxy_);
- EXPECT_EQ(TexturesMemorySize(2), resource_manager->MemoryUseBytes());
- EXPECT_EQ(TexturesMemorySize(1), resource_manager->MemoryVisibleBytes());
- EXPECT_EQ(TexturesMemorySize(3),
- resource_manager->MemoryVisibleAndNearbyBytes());
- }
-
- // Re-prioritize the textures, but do not push the values to backings.
- textures[0]->
- set_request_priority(PriorityCalculator::AllowVisibleOnlyCutoff() - 1);
- textures[1]->
- set_request_priority(PriorityCalculator::AllowVisibleOnlyCutoff() - 1);
- textures[2]->
- set_request_priority(PriorityCalculator::AllowVisibleOnlyCutoff() - 1);
- textures[3]->set_request_priority(
- PriorityCalculator::AllowVisibleAndNearbyCutoff() - 1);
- textures[4]->
- set_request_priority(PriorityCalculator::AllowVisibleAndNearbyCutoff());
- resource_manager->PrioritizeTextures();
-
- // Verify that we still see the old values.
- {
- DebugScopedSetImplThread impl_thread(&proxy_);
- EXPECT_EQ(TexturesMemorySize(2), resource_manager->MemoryUseBytes());
- EXPECT_EQ(TexturesMemorySize(1), resource_manager->MemoryVisibleBytes());
- EXPECT_EQ(TexturesMemorySize(3),
- resource_manager->MemoryVisibleAndNearbyBytes());
- }
-
- // Push priorities to backings, and verify we see the new values.
- {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->PushTexturePrioritiesToBackings();
- EXPECT_EQ(TexturesMemorySize(2), resource_manager->MemoryUseBytes());
- EXPECT_EQ(TexturesMemorySize(3), resource_manager->MemoryVisibleBytes());
- EXPECT_EQ(TexturesMemorySize(4),
- resource_manager->MemoryVisibleAndNearbyBytes());
- }
-
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager->ClearAllMemory(resource_provider());
-}
-
-} // namespace
-} // namespace cc
diff --git a/chromium/cc/resources/priority_calculator.cc b/chromium/cc/resources/priority_calculator.cc
deleted file mode 100644
index 5f5916fda9c..00000000000
--- a/chromium/cc/resources/priority_calculator.cc
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/resources/priority_calculator.h"
-
-#include <algorithm>
-
-#include "ui/gfx/geometry/rect.h"
-
-namespace cc {
-
-static const int kNothingPriorityCutoff = -3;
-
-static const int kMostHighPriority = -2;
-
-static const int kUIDrawsToRootSurfacePriority = -1;
-static const int kVisibleDrawsToRootSurfacePriority = 0;
-static const int kRenderSurfacesPriority = 1;
-static const int kUIDoesNotDrawToRootSurfacePriority = 2;
-static const int kVisibleDoesNotDrawToRootSurfacePriority = 3;
-
-static const int kVisibleOnlyPriorityCutoff = 4;
-
-// The lower digits are how far from being visible the texture is,
-// in pixels.
-static const int kNotVisibleBasePriority = 1000000;
-static const int kNotVisibleLimitPriority = 1900000;
-
-// Arbitrarily define "nearby" to be 2000 pixels. A better estimate
-// would be percent-of-viewport or percent-of-screen.
-static const int kVisibleAndNearbyPriorityCutoff =
- kNotVisibleBasePriority + 2000;
-
-// Small animated layers are treated as though they are 512 pixels
-// from being visible.
-static const int kSmallAnimatedLayerPriority = kNotVisibleBasePriority + 512;
-
-static const int kLingeringBasePriority = 2000000;
-static const int kLingeringLimitPriority = 2900000;
-
-static const int kMostLowPriority = 3000000;
-
-static const int kEverythingPriorityCutoff = 3000001;
-
-// static
-int PriorityCalculator::UIPriority(bool draws_to_root_surface) {
- return draws_to_root_surface ? kUIDrawsToRootSurfacePriority
- : kUIDoesNotDrawToRootSurfacePriority;
-}
-
-// static
-int PriorityCalculator::VisiblePriority(bool draws_to_root_surface) {
- return draws_to_root_surface ? kVisibleDrawsToRootSurfacePriority
- : kVisibleDoesNotDrawToRootSurfacePriority;
-}
-
-// static
-int PriorityCalculator::RenderSurfacePriority() {
- return kRenderSurfacesPriority;
-}
-
-// static
-int PriorityCalculator::LingeringPriority(int previous_priority) {
- // TODO(reveman): We should remove this once we have priorities for all
- // textures (we can't currently calculate distances for off-screen textures).
- return std::min(kLingeringLimitPriority,
- std::max(kLingeringBasePriority, previous_priority + 1));
-}
-
-// static
-int PriorityCalculator::PriorityFromDistance(const gfx::Rect& visible_rect,
- const gfx::Rect& texture_rect,
- bool draws_to_root_surface) {
- int distance = visible_rect.ManhattanInternalDistance(texture_rect);
- if (!distance)
- return VisiblePriority(draws_to_root_surface);
- return std::min(kNotVisibleLimitPriority, kNotVisibleBasePriority + distance);
-}
-
-// static
-int PriorityCalculator::SmallAnimatedLayerMinPriority() {
- return kSmallAnimatedLayerPriority;
-}
-
-// static
-int PriorityCalculator::HighestPriority() {
- return kMostHighPriority;
-}
-
-// static
-int PriorityCalculator::LowestPriority() {
- return kMostLowPriority;
-}
-
-// static
-int PriorityCalculator::AllowNothingCutoff() {
- return kNothingPriorityCutoff;
-}
-
-// static
-int PriorityCalculator::AllowVisibleOnlyCutoff() {
- return kVisibleOnlyPriorityCutoff;
-}
-
-// static
-int PriorityCalculator::AllowVisibleAndNearbyCutoff() {
- return kVisibleAndNearbyPriorityCutoff;
-}
-
-// static
-int PriorityCalculator::AllowEverythingCutoff() {
- return kEverythingPriorityCutoff;
-}
-
-} // namespace cc
diff --git a/chromium/cc/resources/priority_calculator.h b/chromium/cc/resources/priority_calculator.h
deleted file mode 100644
index 502bd2734f8..00000000000
--- a/chromium/cc/resources/priority_calculator.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_RESOURCES_PRIORITY_CALCULATOR_H_
-#define CC_RESOURCES_PRIORITY_CALCULATOR_H_
-
-#include "base/basictypes.h"
-#include "cc/base/cc_export.h"
-
-namespace gfx { class Rect; }
-
-namespace cc {
-
-class CC_EXPORT PriorityCalculator {
- public:
- PriorityCalculator() {}
-
- static int UIPriority(bool draws_to_root_surface);
- static int VisiblePriority(bool draws_to_root_surface);
- static int RenderSurfacePriority();
- static int LingeringPriority(int previous_priority);
- static int PriorityFromDistance(const gfx::Rect& visible_rect,
- const gfx::Rect& texture_rect,
- bool draws_to_root_surface);
- static int SmallAnimatedLayerMinPriority();
-
- static int HighestPriority();
- static int LowestPriority();
- static inline bool priority_is_lower(int a, int b) { return a > b; }
- static inline bool priority_is_higher(int a, int b) { return a < b; }
- static inline int max_priority(int a, int b) {
- return priority_is_higher(a, b) ? a : b;
- }
-
- static int AllowNothingCutoff();
- static int AllowVisibleOnlyCutoff();
- static int AllowVisibleAndNearbyCutoff();
- static int AllowEverythingCutoff();
-
- private:
- DISALLOW_COPY_AND_ASSIGN(PriorityCalculator);
-};
-
-} // namespace cc
-
-#endif // CC_RESOURCES_PRIORITY_CALCULATOR_H_
diff --git a/chromium/cc/resources/resource.cc b/chromium/cc/resources/resource.cc
deleted file mode 100644
index 9bbcd4f498b..00000000000
--- a/chromium/cc/resources/resource.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/resources/resource.h"
-
-namespace cc {
-
-size_t Resource::bytes() const {
- if (size_.IsEmpty())
- return 0;
-
- return MemorySizeBytes(size_, format_);
-}
-
-
-} // namespace cc
diff --git a/chromium/cc/resources/resource.h b/chromium/cc/resources/resource.h
index edafaefcfa3..f9138fbb876 100644
--- a/chromium/cc/resources/resource.h
+++ b/chromium/cc/resources/resource.h
@@ -5,6 +5,7 @@
#ifndef CC_RESOURCES_RESOURCE_H_
#define CC_RESOURCES_RESOURCE_H_
+#include "base/numerics/safe_math.h"
#include "cc/base/cc_export.h"
#include "cc/resources/resource_provider.h"
#include "ui/gfx/geometry/size.h"
@@ -13,32 +14,56 @@ namespace cc {
class CC_EXPORT Resource {
public:
- Resource() : id_(0) {}
+ Resource() : id_(0), format_(RGBA_8888) {}
Resource(unsigned id, const gfx::Size& size, ResourceFormat format)
: id_(id),
size_(size),
format_(format) {}
- ResourceProvider::ResourceId id() const { return id_; }
+ ResourceId id() const { return id_; }
gfx::Size size() const { return size_; }
ResourceFormat format() const { return format_; }
- size_t bytes() const;
- inline static size_t MemorySizeBytes(const gfx::Size& size,
+ // Return true if the call to UncheckedMemorySizeBytes would return a value
+ // that fits in a size_t.
+ static bool VerifySizeInBytes(const gfx::Size& size, ResourceFormat format) {
+ base::CheckedNumeric<size_t> checked_value = BitsPerPixel(format);
+ checked_value *= size.width();
+ checked_value *= size.height();
+ if (!checked_value.IsValid())
+ return false;
+ size_t value = checked_value.ValueOrDie();
+ if ((value % 8) != 0)
+ return false;
+ return true;
+ }
+
+ static size_t CheckedMemorySizeBytes(const gfx::Size& size,
ResourceFormat format) {
- DCHECK_EQ(0u, (BitsPerPixel(format) * size.width() * size.height()) % 8);
- return (BitsPerPixel(format) * size.width() * size.height()) / 8;
+ DCHECK(VerifySizeInBytes(size, format));
+ base::CheckedNumeric<size_t> checked_value = BitsPerPixel(format);
+ checked_value *= size.width();
+ checked_value *= size.height();
+ checked_value /= 8;
+ return checked_value.ValueOrDie();
+ }
+
+ inline static size_t UncheckedMemorySizeBytes(const gfx::Size& size,
+ ResourceFormat format) {
+ DCHECK(VerifySizeInBytes(size, format));
+ return static_cast<size_t>(BitsPerPixel(format)) * size.width() *
+ size.height() / 8;
}
protected:
- void set_id(ResourceProvider::ResourceId id) { id_ = id; }
+ void set_id(ResourceId id) { id_ = id; }
void set_dimensions(const gfx::Size& size, ResourceFormat format) {
size_ = size;
format_ = format;
}
private:
- ResourceProvider::ResourceId id_;
+ ResourceId id_;
gfx::Size size_;
ResourceFormat format_;
diff --git a/chromium/cc/resources/resource_pool.cc b/chromium/cc/resources/resource_pool.cc
index 22847809ba3..7b65d344ab3 100644
--- a/chromium/cc/resources/resource_pool.cc
+++ b/chromium/cc/resources/resource_pool.cc
@@ -21,7 +21,8 @@ ResourcePool::ResourcePool(ResourceProvider* resource_provider, GLenum target)
ResourcePool::~ResourcePool() {
while (!busy_resources_.empty()) {
- DidFinishUsingResource(busy_resources_.front());
+ auto const& front = busy_resources_.front();
+ DidFinishUsingResource(front.resource, front.content_id);
busy_resources_.pop_front();
}
@@ -37,7 +38,7 @@ scoped_ptr<ScopedResource> ResourcePool::AcquireResource(
for (ResourceList::iterator it = unused_resources_.begin();
it != unused_resources_.end();
++it) {
- ScopedResource* resource = *it;
+ ScopedResource* resource = it->resource;
DCHECK(resource_provider_->CanLockForWrite(resource->id()));
if (resource->format() != format)
@@ -46,7 +47,8 @@ scoped_ptr<ScopedResource> ResourcePool::AcquireResource(
continue;
unused_resources_.erase(it);
- unused_memory_usage_bytes_ -= resource->bytes();
+ unused_memory_usage_bytes_ -=
+ Resource::UncheckedMemorySizeBytes(size, format);
return make_scoped_ptr(resource);
}
@@ -54,13 +56,36 @@ scoped_ptr<ScopedResource> ResourcePool::AcquireResource(
ScopedResource::Create(resource_provider_);
resource->AllocateManaged(size, target_, format);
- memory_usage_bytes_ += resource->bytes();
+ DCHECK(Resource::VerifySizeInBytes(resource->size(), resource->format()));
+ memory_usage_bytes_ +=
+ Resource::UncheckedMemorySizeBytes(resource->size(), resource->format());
++resource_count_;
return resource.Pass();
}
-void ResourcePool::ReleaseResource(scoped_ptr<ScopedResource> resource) {
- busy_resources_.push_back(resource.release());
+scoped_ptr<ScopedResource> ResourcePool::TryAcquireResourceWithContentId(
+ uint64_t content_id) {
+ DCHECK(content_id);
+
+ auto it = std::find_if(unused_resources_.begin(), unused_resources_.end(),
+ [content_id](const PoolResource& pool_resource) {
+ return pool_resource.content_id == content_id;
+ });
+ if (it == unused_resources_.end())
+ return nullptr;
+
+ ScopedResource* resource = it->resource;
+ DCHECK(resource_provider_->CanLockForWrite(resource->id()));
+
+ unused_resources_.erase(it);
+ unused_memory_usage_bytes_ -=
+ Resource::UncheckedMemorySizeBytes(resource->size(), resource->format());
+ return make_scoped_ptr(resource);
+}
+
+void ResourcePool::ReleaseResource(scoped_ptr<ScopedResource> resource,
+ uint64_t content_id) {
+ busy_resources_.push_back(PoolResource(resource.release(), content_id));
}
void ResourcePool::SetResourceUsageLimits(size_t max_memory_usage_bytes,
@@ -85,12 +110,11 @@ void ResourcePool::ReduceResourceUsage() {
// can't be locked for write might also not be truly free-able.
// We can free the resource here but it doesn't mean that the
// memory is necessarily returned to the OS.
- ScopedResource* resource = unused_resources_.front();
+ ScopedResource* resource = unused_resources_.front().resource;
unused_resources_.pop_front();
- memory_usage_bytes_ -= resource->bytes();
- unused_memory_usage_bytes_ -= resource->bytes();
- --resource_count_;
- delete resource;
+ unused_memory_usage_bytes_ -= Resource::UncheckedMemorySizeBytes(
+ resource->size(), resource->format());
+ DeleteResource(resource);
}
}
@@ -104,17 +128,29 @@ bool ResourcePool::ResourceUsageTooHigh() {
return false;
}
+void ResourcePool::DeleteResource(ScopedResource* resource) {
+ size_t resource_bytes =
+ Resource::UncheckedMemorySizeBytes(resource->size(), resource->format());
+ memory_usage_bytes_ -= resource_bytes;
+ --resource_count_;
+ delete resource;
+}
+
void ResourcePool::CheckBusyResources(bool wait_if_needed) {
ResourceList::iterator it = busy_resources_.begin();
while (it != busy_resources_.end()) {
- ScopedResource* resource = *it;
+ ScopedResource* resource = it->resource;
if (wait_if_needed)
resource_provider_->WaitReadLockIfNeeded(resource->id());
if (resource_provider_->CanLockForWrite(resource->id())) {
- DidFinishUsingResource(resource);
+ DidFinishUsingResource(resource, it->content_id);
+ it = busy_resources_.erase(it);
+ } else if (resource_provider_->IsLost(resource->id())) {
+ // Remove lost resources from pool.
+ DeleteResource(resource);
it = busy_resources_.erase(it);
} else {
++it;
@@ -122,9 +158,11 @@ void ResourcePool::CheckBusyResources(bool wait_if_needed) {
}
}
-void ResourcePool::DidFinishUsingResource(ScopedResource* resource) {
- unused_memory_usage_bytes_ += resource->bytes();
- unused_resources_.push_back(resource);
+void ResourcePool::DidFinishUsingResource(ScopedResource* resource,
+ uint64_t content_id) {
+ unused_memory_usage_bytes_ +=
+ Resource::UncheckedMemorySizeBytes(resource->size(), resource->format());
+ unused_resources_.push_back(PoolResource(resource, content_id));
}
} // namespace cc
diff --git a/chromium/cc/resources/resource_pool.h b/chromium/cc/resources/resource_pool.h
index f79455905dd..88816aa73d4 100644
--- a/chromium/cc/resources/resource_pool.h
+++ b/chromium/cc/resources/resource_pool.h
@@ -5,7 +5,7 @@
#ifndef CC_RESOURCES_RESOURCE_POOL_H_
#define CC_RESOURCES_RESOURCE_POOL_H_
-#include <list>
+#include <deque>
#include "base/memory/scoped_ptr.h"
#include "cc/base/cc_export.h"
@@ -27,7 +27,9 @@ class CC_EXPORT ResourcePool {
scoped_ptr<ScopedResource> AcquireResource(const gfx::Size& size,
ResourceFormat format);
- void ReleaseResource(scoped_ptr<ScopedResource>);
+ scoped_ptr<ScopedResource> TryAcquireResourceWithContentId(uint64 content_id);
+ void ReleaseResource(scoped_ptr<ScopedResource> resource,
+ uint64_t content_id);
void SetResourceUsageLimits(size_t max_memory_usage_bytes,
size_t max_unused_memory_usage_bytes,
@@ -55,7 +57,8 @@ class CC_EXPORT ResourcePool {
bool ResourceUsageTooHigh();
private:
- void DidFinishUsingResource(ScopedResource* resource);
+ void DidFinishUsingResource(ScopedResource* resource, uint64_t content_id);
+ void DeleteResource(ScopedResource* resource);
ResourceProvider* resource_provider_;
const GLenum target_;
@@ -66,7 +69,13 @@ class CC_EXPORT ResourcePool {
size_t unused_memory_usage_bytes_;
size_t resource_count_;
- typedef std::list<ScopedResource*> ResourceList;
+ struct PoolResource {
+ PoolResource(ScopedResource* resource, uint64_t content_id)
+ : resource(resource), content_id(content_id) {}
+ ScopedResource* resource;
+ uint64_t content_id;
+ };
+ typedef std::deque<PoolResource> ResourceList;
ResourceList unused_resources_;
ResourceList busy_resources_;
diff --git a/chromium/cc/resources/resource_pool_unittest.cc b/chromium/cc/resources/resource_pool_unittest.cc
new file mode 100644
index 00000000000..96e7591ab8c
--- /dev/null
+++ b/chromium/cc/resources/resource_pool_unittest.cc
@@ -0,0 +1,141 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/resources/resource_pool.h"
+
+#include "cc/resources/scoped_resource.h"
+#include "cc/test/fake_output_surface.h"
+#include "cc/test/fake_output_surface_client.h"
+#include "cc/test/fake_resource_provider.h"
+#include "cc/test/test_shared_bitmap_manager.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+namespace {
+
+class ResourcePoolTest : public testing::Test {
+ public:
+ void SetUp() override {
+ output_surface_ = FakeOutputSurface::Create3d();
+ ASSERT_TRUE(output_surface_->BindToClient(&output_surface_client_));
+ shared_bitmap_manager_.reset(new TestSharedBitmapManager());
+ resource_provider_ = FakeResourceProvider::Create(
+ output_surface_.get(), shared_bitmap_manager_.get());
+ resource_pool_ =
+ ResourcePool::Create(resource_provider_.get(), GL_TEXTURE_2D);
+ }
+
+ protected:
+ FakeOutputSurfaceClient output_surface_client_;
+ scoped_ptr<FakeOutputSurface> output_surface_;
+ scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
+ scoped_ptr<ResourceProvider> resource_provider_;
+ scoped_ptr<ResourcePool> resource_pool_;
+};
+
+TEST_F(ResourcePoolTest, AcquireRelease) {
+ gfx::Size size(100, 100);
+ ResourceFormat format = RGBA_8888;
+ scoped_ptr<ScopedResource> resource =
+ resource_pool_->AcquireResource(size, format);
+ EXPECT_EQ(size, resource->size());
+ EXPECT_EQ(format, resource->format());
+ EXPECT_TRUE(resource_provider_->CanLockForWrite(resource->id()));
+
+ resource_pool_->ReleaseResource(resource.Pass(), 0u);
+}
+
+TEST_F(ResourcePoolTest, AccountingSingleResource) {
+ // Limits high enough to not be hit by this test.
+ size_t bytes_limit = 10 * 1024 * 1024;
+ size_t count_limit = 100;
+ resource_pool_->SetResourceUsageLimits(bytes_limit, bytes_limit, count_limit);
+
+ gfx::Size size(100, 100);
+ ResourceFormat format = RGBA_8888;
+ size_t resource_bytes = Resource::UncheckedMemorySizeBytes(size, format);
+ scoped_ptr<ScopedResource> resource =
+ resource_pool_->AcquireResource(size, format);
+
+ EXPECT_EQ(resource_bytes, resource_pool_->total_memory_usage_bytes());
+ EXPECT_EQ(resource_bytes, resource_pool_->acquired_memory_usage_bytes());
+ EXPECT_EQ(1u, resource_pool_->total_resource_count());
+ EXPECT_EQ(1u, resource_pool_->acquired_resource_count());
+ EXPECT_EQ(0u, resource_pool_->busy_resource_count());
+
+ resource_pool_->ReleaseResource(resource.Pass(), 0u);
+ EXPECT_EQ(resource_bytes, resource_pool_->total_memory_usage_bytes());
+ EXPECT_EQ(1u, resource_pool_->total_resource_count());
+ EXPECT_EQ(1u, resource_pool_->busy_resource_count());
+
+ bool wait_if_needed = false;
+ resource_pool_->CheckBusyResources(wait_if_needed);
+ EXPECT_EQ(resource_bytes, resource_pool_->total_memory_usage_bytes());
+ EXPECT_EQ(0u, resource_pool_->acquired_memory_usage_bytes());
+ EXPECT_EQ(1u, resource_pool_->total_resource_count());
+ EXPECT_EQ(0u, resource_pool_->acquired_resource_count());
+ EXPECT_EQ(0u, resource_pool_->busy_resource_count());
+
+ resource_pool_->SetResourceUsageLimits(0u, 0u, 0u);
+ resource_pool_->ReduceResourceUsage();
+ EXPECT_EQ(0u, resource_pool_->total_memory_usage_bytes());
+ EXPECT_EQ(0u, resource_pool_->acquired_memory_usage_bytes());
+ EXPECT_EQ(0u, resource_pool_->total_resource_count());
+ EXPECT_EQ(0u, resource_pool_->acquired_resource_count());
+ EXPECT_EQ(0u, resource_pool_->busy_resource_count());
+}
+
+TEST_F(ResourcePoolTest, SimpleResourceReuse) {
+ // Limits high enough to not be hit by this test.
+ size_t bytes_limit = 10 * 1024 * 1024;
+ size_t count_limit = 100;
+ resource_pool_->SetResourceUsageLimits(bytes_limit, bytes_limit, count_limit);
+
+ gfx::Size size(100, 100);
+ ResourceFormat format = RGBA_8888;
+ bool wait_if_needed = false;
+
+ scoped_ptr<ScopedResource> resource =
+ resource_pool_->AcquireResource(size, format);
+ resource_pool_->ReleaseResource(resource.Pass(), 0u);
+ resource_pool_->CheckBusyResources(wait_if_needed);
+ EXPECT_EQ(1u, resource_provider_->num_resources());
+
+ // Same size/format should re-use resource.
+ resource = resource_pool_->AcquireResource(size, format);
+ EXPECT_EQ(1u, resource_provider_->num_resources());
+ resource_pool_->ReleaseResource(resource.Pass(), 0u);
+ resource_pool_->CheckBusyResources(wait_if_needed);
+ EXPECT_EQ(1u, resource_provider_->num_resources());
+
+ // Different size/format should alloate new resource.
+ resource = resource_pool_->AcquireResource(gfx::Size(50, 50), LUMINANCE_8);
+ EXPECT_EQ(2u, resource_provider_->num_resources());
+ resource_pool_->ReleaseResource(resource.Pass(), 0u);
+ resource_pool_->CheckBusyResources(wait_if_needed);
+ EXPECT_EQ(2u, resource_provider_->num_resources());
+}
+
+TEST_F(ResourcePoolTest, LostResource) {
+ // Limits high enough to not be hit by this test.
+ size_t bytes_limit = 10 * 1024 * 1024;
+ size_t count_limit = 100;
+ resource_pool_->SetResourceUsageLimits(bytes_limit, bytes_limit, count_limit);
+
+ gfx::Size size(100, 100);
+ ResourceFormat format = RGBA_8888;
+ bool wait_if_needed = false;
+
+ scoped_ptr<ScopedResource> resource =
+ resource_pool_->AcquireResource(size, format);
+ EXPECT_EQ(1u, resource_provider_->num_resources());
+
+ resource_provider_->LoseResourceForTesting(resource->id());
+ resource_pool_->ReleaseResource(resource.Pass(), 0u);
+ resource_pool_->CheckBusyResources(wait_if_needed);
+ EXPECT_EQ(0u, resource_provider_->num_resources());
+}
+
+} // namespace
+} // namespace cc
diff --git a/chromium/cc/resources/resource_provider.cc b/chromium/cc/resources/resource_provider.cc
index eb774fe10b3..9f680669c08 100644
--- a/chromium/cc/resources/resource_provider.cc
+++ b/chromium/cc/resources/resource_provider.cc
@@ -9,15 +9,15 @@
#include "base/containers/hash_tables.h"
#include "base/metrics/histogram.h"
+#include "base/numerics/safe_math.h"
#include "base/stl_util.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/trace_event/trace_event.h"
-#include "cc/base/util.h"
+#include "cc/base/math_util.h"
#include "cc/resources/platform_color.h"
#include "cc/resources/returned_resource.h"
#include "cc/resources/shared_bitmap_manager.h"
-#include "cc/resources/texture_uploader.h"
#include "cc/resources/transferable_resource.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/gles2_interface.h"
@@ -27,7 +27,6 @@
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/gpu/GrContext.h"
#include "third_party/skia/include/gpu/GrTextureProvider.h"
-#include "ui/gfx/frame_time.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/vector2d.h"
#include "ui/gfx/gpu_memory_buffer.h"
@@ -49,6 +48,8 @@ class IdAllocator {
ids_(new GLuint[id_allocation_chunk_size]),
next_id_index_(id_allocation_chunk_size) {
DCHECK(id_allocation_chunk_size_);
+ DCHECK_LE(id_allocation_chunk_size_,
+ static_cast<size_t>(std::numeric_limits<int>::max()));
}
GLES2Interface* gl_;
@@ -59,10 +60,6 @@ class IdAllocator {
namespace {
-// Measured in seconds.
-const double kSoftwareUploadTickRate = 0.000250;
-const double kTextureUploadTickRate = 0.004;
-
GLenum TextureToStorageFormat(ResourceFormat format) {
GLenum storage_format = GL_RGBA8_OES;
switch (format) {
@@ -119,10 +116,11 @@ GrPixelConfig ToGrPixelConfig(ResourceFormat format) {
gfx::GpuMemoryBuffer::Format ToGpuMemoryBufferFormat(ResourceFormat format) {
switch (format) {
case RGBA_8888:
- return gfx::GpuMemoryBuffer::Format::RGBA_8888;
+ return gfx::GpuMemoryBuffer::RGBA_8888;
case BGRA_8888:
- return gfx::GpuMemoryBuffer::Format::BGRA_8888;
+ return gfx::GpuMemoryBuffer::BGRA_8888;
case RGBA_4444:
+ return gfx::GpuMemoryBuffer::RGBA_4444;
case ALPHA_8:
case LUMINANCE_8:
case RGB_565:
@@ -131,7 +129,7 @@ gfx::GpuMemoryBuffer::Format ToGpuMemoryBufferFormat(ResourceFormat format) {
break;
}
NOTREACHED();
- return gfx::GpuMemoryBuffer::Format::RGBA_8888;
+ return gfx::GpuMemoryBuffer::RGBA_8888;
}
class ScopedSetActiveTexture {
@@ -161,14 +159,15 @@ class TextureIdAllocator : public IdAllocator {
size_t texture_id_allocation_chunk_size)
: IdAllocator(gl, texture_id_allocation_chunk_size) {}
~TextureIdAllocator() override {
- gl_->DeleteTextures(id_allocation_chunk_size_ - next_id_index_,
- ids_.get() + next_id_index_);
+ gl_->DeleteTextures(
+ static_cast<int>(id_allocation_chunk_size_ - next_id_index_),
+ ids_.get() + next_id_index_);
}
// Overridden from IdAllocator:
GLuint NextId() override {
if (next_id_index_ == id_allocation_chunk_size_) {
- gl_->GenTextures(id_allocation_chunk_size_, ids_.get());
+ gl_->GenTextures(static_cast<int>(id_allocation_chunk_size_), ids_.get());
next_id_index_ = 0;
}
@@ -184,14 +183,15 @@ class BufferIdAllocator : public IdAllocator {
BufferIdAllocator(GLES2Interface* gl, size_t buffer_id_allocation_chunk_size)
: IdAllocator(gl, buffer_id_allocation_chunk_size) {}
~BufferIdAllocator() override {
- gl_->DeleteBuffers(id_allocation_chunk_size_ - next_id_index_,
- ids_.get() + next_id_index_);
+ gl_->DeleteBuffers(
+ static_cast<int>(id_allocation_chunk_size_ - next_id_index_),
+ ids_.get() + next_id_index_);
}
// Overridden from IdAllocator:
GLuint NextId() override {
if (next_id_index_ == id_allocation_chunk_size_) {
- gl_->GenBuffers(id_allocation_chunk_size_, ids_.get());
+ gl_->GenBuffers(static_cast<int>(id_allocation_chunk_size_), ids_.get());
next_id_index_ = 0;
}
@@ -273,7 +273,6 @@ ResourceProvider::Resource::Resource(GLuint texture_id,
allocated(false),
read_lock_fences_enabled(false),
has_shared_bitmap_id(false),
- allow_overlay(false),
read_lock_fence(NULL),
size(size),
origin(origin),
@@ -317,7 +316,6 @@ ResourceProvider::Resource::Resource(uint8_t* pixels,
allocated(false),
read_lock_fences_enabled(false),
has_shared_bitmap_id(!!bitmap),
- allow_overlay(false),
read_lock_fence(NULL),
size(size),
origin(origin),
@@ -362,7 +360,6 @@ ResourceProvider::Resource::Resource(const SharedBitmapId& bitmap_id,
allocated(false),
read_lock_fences_enabled(false),
has_shared_bitmap_id(true),
- allow_overlay(false),
read_lock_fence(NULL),
size(size),
origin(origin),
@@ -395,25 +392,15 @@ scoped_ptr<ResourceProvider> ResourceProvider::Create(
BlockingTaskRunner* blocking_main_thread_task_runner,
int highp_threshold_min,
bool use_rgba_4444_texture_format,
- size_t id_allocation_chunk_size) {
- ContextProvider* context_provider = output_surface->context_provider();
- GLES2Interface* gl =
- context_provider ? context_provider->ContextGL() : nullptr;
- ResourceType default_resource_type =
- gl ? RESOURCE_TYPE_GL_TEXTURE : RESOURCE_TYPE_BITMAP;
-
+ size_t id_allocation_chunk_size,
+ bool use_persistent_map_for_gpu_memory_buffers) {
scoped_ptr<ResourceProvider> resource_provider(new ResourceProvider(
output_surface, shared_bitmap_manager, gpu_memory_buffer_manager,
blocking_main_thread_task_runner, highp_threshold_min,
- default_resource_type, use_rgba_4444_texture_format,
- id_allocation_chunk_size));
-
- if (gl)
- resource_provider->InitializeGL();
- else
- resource_provider->InitializeSoftware();
-
- return resource_provider.Pass();
+ use_rgba_4444_texture_format, id_allocation_chunk_size,
+ use_persistent_map_for_gpu_memory_buffers));
+ resource_provider->Initialize();
+ return resource_provider;
}
ResourceProvider::~ResourceProvider() {
@@ -426,7 +413,6 @@ ResourceProvider::~ResourceProvider() {
if (default_resource_type_ != RESOURCE_TYPE_GL_TEXTURE) {
// We are not in GL mode, but double check before returning.
DCHECK(!gl);
- DCHECK(!texture_uploader_);
return;
}
@@ -439,7 +425,6 @@ ResourceProvider::~ResourceProvider() {
}
#endif // DCHECK_IS_ON()
- texture_uploader_ = nullptr;
texture_id_allocator_ = nullptr;
buffer_id_allocator_ = nullptr;
gl->Finish();
@@ -456,16 +441,16 @@ bool ResourceProvider::IsLost(ResourceId id) {
return resource->lost;
}
-bool ResourceProvider::AllowOverlay(ResourceId id) {
+void ResourceProvider::LoseResourceForTesting(ResourceId id) {
Resource* resource = GetResource(id);
- return resource->allow_overlay;
+ DCHECK(resource);
+ resource->lost = true;
}
-ResourceProvider::ResourceId ResourceProvider::CreateResource(
- const gfx::Size& size,
- GLint wrap_mode,
- TextureHint hint,
- ResourceFormat format) {
+ResourceId ResourceProvider::CreateResource(const gfx::Size& size,
+ GLint wrap_mode,
+ TextureHint hint,
+ ResourceFormat format) {
DCHECK(!size.IsEmpty());
switch (default_resource_type_) {
case RESOURCE_TYPE_GL_TEXTURE:
@@ -484,12 +469,11 @@ ResourceProvider::ResourceId ResourceProvider::CreateResource(
return 0;
}
-ResourceProvider::ResourceId ResourceProvider::CreateManagedResource(
- const gfx::Size& size,
- GLenum target,
- GLint wrap_mode,
- TextureHint hint,
- ResourceFormat format) {
+ResourceId ResourceProvider::CreateManagedResource(const gfx::Size& size,
+ GLenum target,
+ GLint wrap_mode,
+ TextureHint hint,
+ ResourceFormat format) {
DCHECK(!size.IsEmpty());
switch (default_resource_type_) {
case RESOURCE_TYPE_GL_TEXTURE:
@@ -508,13 +492,12 @@ ResourceProvider::ResourceId ResourceProvider::CreateManagedResource(
return 0;
}
-ResourceProvider::ResourceId ResourceProvider::CreateGLTexture(
- const gfx::Size& size,
- GLenum target,
- GLenum texture_pool,
- GLint wrap_mode,
- TextureHint hint,
- ResourceFormat format) {
+ResourceId ResourceProvider::CreateGLTexture(const gfx::Size& size,
+ GLenum target,
+ GLenum texture_pool,
+ GLint wrap_mode,
+ TextureHint hint,
+ ResourceFormat format) {
DCHECK_LE(size.width(), max_texture_size_);
DCHECK_LE(size.height(), max_texture_size_);
DCHECK(thread_checker_.CalledOnValidThread());
@@ -527,8 +510,8 @@ ResourceProvider::ResourceId ResourceProvider::CreateGLTexture(
return id;
}
-ResourceProvider::ResourceId ResourceProvider::CreateBitmap(
- const gfx::Size& size, GLint wrap_mode) {
+ResourceId ResourceProvider::CreateBitmap(const gfx::Size& size,
+ GLint wrap_mode) {
DCHECK(thread_checker_.CalledOnValidThread());
scoped_ptr<SharedBitmap> bitmap =
@@ -544,7 +527,7 @@ ResourceProvider::ResourceId ResourceProvider::CreateBitmap(
return id;
}
-ResourceProvider::ResourceId ResourceProvider::CreateResourceFromIOSurface(
+ResourceId ResourceProvider::CreateResourceFromIOSurface(
const gfx::Size& size,
unsigned io_surface_id) {
DCHECK(thread_checker_.CalledOnValidThread());
@@ -564,9 +547,10 @@ ResourceProvider::ResourceId ResourceProvider::CreateResourceFromIOSurface(
return id;
}
-ResourceProvider::ResourceId ResourceProvider::CreateResourceFromTextureMailbox(
+ResourceId ResourceProvider::CreateResourceFromTextureMailbox(
const TextureMailbox& mailbox,
- scoped_ptr<SingleReleaseCallbackImpl> release_callback_impl) {
+ scoped_ptr<SingleReleaseCallbackImpl> release_callback_impl,
+ bool read_lock_fences_enabled) {
DCHECK(thread_checker_.CalledOnValidThread());
// Just store the information. Mailbox will be consumed in LockForRead().
ResourceId id = next_id_++;
@@ -583,7 +567,7 @@ ResourceProvider::ResourceId ResourceProvider::CreateResourceFromTextureMailbox(
uint8_t* pixels = shared_bitmap->pixels();
DCHECK(pixels);
resource = InsertResource(
- id, Resource(pixels, shared_bitmap, mailbox.shared_memory_size(),
+ id, Resource(pixels, shared_bitmap, mailbox.size_in_pixels(),
Resource::EXTERNAL, GL_LINEAR, GL_CLAMP_TO_EDGE));
}
resource->allocated = true;
@@ -591,10 +575,17 @@ ResourceProvider::ResourceId ResourceProvider::CreateResourceFromTextureMailbox(
resource->release_callback_impl =
base::Bind(&SingleReleaseCallbackImpl::Run,
base::Owned(release_callback_impl.release()));
- resource->allow_overlay = mailbox.allow_overlay();
+ resource->read_lock_fences_enabled = read_lock_fences_enabled;
return id;
}
+ResourceId ResourceProvider::CreateResourceFromTextureMailbox(
+ const TextureMailbox& mailbox,
+ scoped_ptr<SingleReleaseCallbackImpl> release_callback_impl) {
+ return CreateResourceFromTextureMailbox(mailbox, release_callback_impl.Pass(),
+ false);
+}
+
void ResourceProvider::DeleteResource(ResourceId id) {
DCHECK(thread_checker_.CalledOnValidThread());
ResourceMap::iterator it = resources_.find(id);
@@ -604,7 +595,8 @@ void ResourceProvider::DeleteResource(ResourceId id) {
DCHECK_EQ(resource->imported_count, 0);
DCHECK(resource->pending_set_pixels || !resource->locked_for_write);
- if (resource->exported_count > 0 || resource->lock_for_read_count > 0) {
+ if (resource->exported_count > 0 || resource->lock_for_read_count > 0 ||
+ !ReadLockFenceHasPassed(resource)) {
resource->marked_for_deletion = true;
return;
} else {
@@ -698,54 +690,6 @@ ResourceProvider::ResourceType ResourceProvider::GetResourceType(
return GetResource(id)->type;
}
-void ResourceProvider::SetPixels(ResourceId id,
- const uint8_t* image,
- const gfx::Rect& image_rect,
- const gfx::Rect& source_rect,
- const gfx::Vector2d& dest_offset) {
- Resource* resource = GetResource(id);
- DCHECK(!resource->locked_for_write);
- DCHECK(!resource->lock_for_read_count);
- DCHECK(resource->origin == Resource::INTERNAL);
- DCHECK_EQ(resource->exported_count, 0);
- DCHECK(ReadLockFenceHasPassed(resource));
- LazyAllocate(resource);
-
- if (resource->type == RESOURCE_TYPE_GL_TEXTURE) {
- DCHECK(resource->gl_id);
- DCHECK(!resource->pending_set_pixels);
- DCHECK_EQ(resource->target, static_cast<GLenum>(GL_TEXTURE_2D));
- GLES2Interface* gl = ContextGL();
- DCHECK(gl);
- DCHECK(texture_uploader_.get());
- gl->BindTexture(GL_TEXTURE_2D, resource->gl_id);
- texture_uploader_->Upload(image,
- image_rect,
- source_rect,
- dest_offset,
- resource->format,
- resource->size);
- } else {
- DCHECK_EQ(RESOURCE_TYPE_BITMAP, resource->type);
- DCHECK(resource->allocated);
- DCHECK_EQ(RGBA_8888, resource->format);
- DCHECK(source_rect.x() >= image_rect.x());
- DCHECK(source_rect.y() >= image_rect.y());
- DCHECK(source_rect.right() <= image_rect.right());
- DCHECK(source_rect.bottom() <= image_rect.bottom());
- SkImageInfo source_info =
- SkImageInfo::MakeN32Premul(source_rect.width(), source_rect.height());
- size_t image_row_bytes = image_rect.width() * 4;
- gfx::Vector2d source_offset = source_rect.origin() - image_rect.origin();
- image += source_offset.y() * image_row_bytes + source_offset.x() * 4;
-
- ScopedWriteLockSoftware lock(this, id);
- SkCanvas dest(lock.sk_bitmap());
- dest.writePixels(source_info, image, image_row_bytes, dest_offset.x(),
- dest_offset.y());
- }
-}
-
void ResourceProvider::CopyToResource(ResourceId id,
const uint8_t* image,
const gfx::Size& image_size) {
@@ -777,15 +721,16 @@ void ResourceProvider::CopyToResource(ResourceId id,
DCHECK_EQ(resource->target, static_cast<GLenum>(GL_TEXTURE_2D));
GLES2Interface* gl = ContextGL();
DCHECK(gl);
- DCHECK(texture_uploader_.get());
gl->BindTexture(GL_TEXTURE_2D, resource->gl_id);
if (resource->format == ETC1) {
- size_t num_bytes = static_cast<size_t>(image_size.width()) *
- image_size.height() * BitsPerPixel(ETC1) / 8;
+ base::CheckedNumeric<int> num_bytes = BitsPerPixel(ETC1);
+ num_bytes *= image_size.width();
+ num_bytes *= image_size.height();
+ num_bytes /= 8;
gl->CompressedTexImage2D(GL_TEXTURE_2D, 0, GLInternalFormat(ETC1),
image_size.width(), image_size.height(), 0,
- num_bytes, image);
+ num_bytes.ValueOrDie(), image);
} else {
gl->TexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image_size.width(),
image_size.height(), GLDataFormat(resource->format),
@@ -794,65 +739,6 @@ void ResourceProvider::CopyToResource(ResourceId id,
}
}
-size_t ResourceProvider::NumBlockingUploads() {
- if (!texture_uploader_)
- return 0;
-
- return texture_uploader_->NumBlockingUploads();
-}
-
-void ResourceProvider::MarkPendingUploadsAsNonBlocking() {
- if (!texture_uploader_)
- return;
-
- texture_uploader_->MarkPendingUploadsAsNonBlocking();
-}
-
-size_t ResourceProvider::EstimatedUploadsPerTick() {
- if (!texture_uploader_)
- return 1u;
-
- double textures_per_second = texture_uploader_->EstimatedTexturesPerSecond();
- size_t textures_per_tick = floor(
- kTextureUploadTickRate * textures_per_second);
- return textures_per_tick ? textures_per_tick : 1u;
-}
-
-void ResourceProvider::FlushUploads() {
- if (!texture_uploader_)
- return;
-
- texture_uploader_->Flush();
-}
-
-void ResourceProvider::ReleaseCachedData() {
- if (!texture_uploader_)
- return;
-
- texture_uploader_->ReleaseCachedQueries();
-}
-
-base::TimeTicks ResourceProvider::EstimatedUploadCompletionTime(
- size_t uploads_per_tick) {
- if (lost_output_surface_)
- return base::TimeTicks();
-
- // Software resource uploads happen on impl thread, so don't bother batching
- // them up and trying to wait for them to complete.
- if (!texture_uploader_) {
- return gfx::FrameTime::Now() + base::TimeDelta::FromMicroseconds(
- base::Time::kMicrosecondsPerSecond * kSoftwareUploadTickRate);
- }
-
- base::TimeDelta upload_one_texture_time =
- base::TimeDelta::FromMicroseconds(
- base::Time::kMicrosecondsPerSecond * kTextureUploadTickRate) /
- uploads_per_tick;
-
- size_t total_uploads = NumBlockingUploads() + uploads_per_tick;
- return gfx::FrameTime::Now() + upload_one_texture_time * total_uploads;
-}
-
ResourceProvider::Resource* ResourceProvider::InsertResource(
ResourceId id,
const Resource& resource) {
@@ -961,9 +847,15 @@ void ResourceProvider::UnlockForWrite(ResourceProvider::Resource* resource) {
resource->locked_for_write = false;
}
+void ResourceProvider::EnableReadLockFencesForTesting(ResourceId id) {
+ Resource* resource = GetResource(id);
+ DCHECK(resource);
+ resource->read_lock_fences_enabled = true;
+}
+
ResourceProvider::ScopedReadLockGL::ScopedReadLockGL(
ResourceProvider* resource_provider,
- ResourceProvider::ResourceId resource_id)
+ ResourceId resource_id)
: resource_provider_(resource_provider),
resource_id_(resource_id),
resource_(resource_provider->LockForRead(resource_id)) {
@@ -976,7 +868,7 @@ ResourceProvider::ScopedReadLockGL::~ScopedReadLockGL() {
ResourceProvider::ScopedSamplerGL::ScopedSamplerGL(
ResourceProvider* resource_provider,
- ResourceProvider::ResourceId resource_id,
+ ResourceId resource_id,
GLenum filter)
: ScopedReadLockGL(resource_provider, resource_id),
unit_(GL_TEXTURE0),
@@ -985,7 +877,7 @@ ResourceProvider::ScopedSamplerGL::ScopedSamplerGL(
ResourceProvider::ScopedSamplerGL::ScopedSamplerGL(
ResourceProvider* resource_provider,
- ResourceProvider::ResourceId resource_id,
+ ResourceId resource_id,
GLenum unit,
GLenum filter)
: ScopedReadLockGL(resource_provider, resource_id),
@@ -998,7 +890,7 @@ ResourceProvider::ScopedSamplerGL::~ScopedSamplerGL() {
ResourceProvider::ScopedWriteLockGL::ScopedWriteLockGL(
ResourceProvider* resource_provider,
- ResourceProvider::ResourceId resource_id)
+ ResourceId resource_id)
: resource_provider_(resource_provider),
resource_(resource_provider->LockForWrite(resource_id)) {
resource_provider_->LazyAllocate(resource_);
@@ -1020,9 +912,8 @@ void ResourceProvider::PopulateSkBitmapWithResource(
ResourceProvider::ScopedReadLockSoftware::ScopedReadLockSoftware(
ResourceProvider* resource_provider,
- ResourceProvider::ResourceId resource_id)
- : resource_provider_(resource_provider),
- resource_id_(resource_id) {
+ ResourceId resource_id)
+ : resource_provider_(resource_provider), resource_id_(resource_id) {
const Resource* resource = resource_provider->LockForRead(resource_id);
wrap_mode_ = resource->wrap_mode;
ResourceProvider::PopulateSkBitmapWithResource(&sk_bitmap_, resource);
@@ -1034,7 +925,7 @@ ResourceProvider::ScopedReadLockSoftware::~ScopedReadLockSoftware() {
ResourceProvider::ScopedWriteLockSoftware::ScopedWriteLockSoftware(
ResourceProvider* resource_provider,
- ResourceProvider::ResourceId resource_id)
+ ResourceId resource_id)
: resource_provider_(resource_provider),
resource_(resource_provider->LockForWrite(resource_id)) {
ResourceProvider::PopulateSkBitmapWithResource(&sk_bitmap_, resource_);
@@ -1048,7 +939,7 @@ ResourceProvider::ScopedWriteLockSoftware::~ScopedWriteLockSoftware() {
ResourceProvider::ScopedWriteLockGpuMemoryBuffer::
ScopedWriteLockGpuMemoryBuffer(ResourceProvider* resource_provider,
- ResourceProvider::ResourceId resource_id)
+ ResourceId resource_id)
: resource_provider_(resource_provider),
resource_(resource_provider->LockForWrite(resource_id)),
gpu_memory_buffer_manager_(resource_provider->gpu_memory_buffer_manager_),
@@ -1066,6 +957,8 @@ ResourceProvider::ScopedWriteLockGpuMemoryBuffer::
if (!gpu_memory_buffer_)
return;
+ resource_provider_->LazyCreate(resource_);
+
if (!resource_->image_id) {
GLES2Interface* gl = resource_provider_->ContextGL();
DCHECK(gl);
@@ -1094,19 +987,22 @@ ResourceProvider::ScopedWriteLockGpuMemoryBuffer::
gfx::GpuMemoryBuffer*
ResourceProvider::ScopedWriteLockGpuMemoryBuffer::GetGpuMemoryBuffer() {
- if (!gpu_memory_buffer_) {
- scoped_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer =
- gpu_memory_buffer_manager_->AllocateGpuMemoryBuffer(
- size_, ToGpuMemoryBufferFormat(format_), gfx::GpuMemoryBuffer::MAP);
- gpu_memory_buffer_ = gpu_memory_buffer.release();
- }
-
+ if (gpu_memory_buffer_)
+ return gpu_memory_buffer_;
+ gfx::GpuMemoryBuffer::Usage usage =
+ resource_provider_->use_persistent_map_for_gpu_memory_buffers()
+ ? gfx::GpuMemoryBuffer::PERSISTENT_MAP
+ : gfx::GpuMemoryBuffer::MAP;
+ scoped_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer =
+ gpu_memory_buffer_manager_->AllocateGpuMemoryBuffer(
+ size_, ToGpuMemoryBufferFormat(format_), usage);
+ gpu_memory_buffer_ = gpu_memory_buffer.release();
return gpu_memory_buffer_;
}
ResourceProvider::ScopedWriteLockGr::ScopedWriteLockGr(
ResourceProvider* resource_provider,
- ResourceProvider::ResourceId resource_id)
+ ResourceId resource_id)
: resource_provider_(resource_provider),
resource_(resource_provider->LockForWrite(resource_id)) {
DCHECK(thread_checker_.CalledOnValidThread());
@@ -1137,24 +1033,17 @@ void ResourceProvider::ScopedWriteLockGr::InitSkSurface(
bool use_worker_context = true;
class GrContext* gr_context =
resource_provider_->GrContext(use_worker_context);
- skia::RefPtr<GrTexture> gr_texture =
- skia::AdoptRef(gr_context->textureProvider()->wrapBackendTexture(desc));
- if (gr_texture) {
- uint32_t flags = use_distance_field_text
- ? SkSurfaceProps::kUseDistanceFieldFonts_Flag
- : 0;
- // Use unknown pixel geometry to disable LCD text.
- SkSurfaceProps surface_props(flags, kUnknown_SkPixelGeometry);
- if (can_use_lcd_text) {
- // LegacyFontHost will get LCD text and skia figures out what type to use.
- surface_props =
- SkSurfaceProps(flags, SkSurfaceProps::kLegacyFontHost_InitType);
- }
- sk_surface_ = skia::AdoptRef(SkSurface::NewRenderTargetDirect(
- gr_texture->asRenderTarget(), &surface_props));
- return;
+ uint32_t flags =
+ use_distance_field_text ? SkSurfaceProps::kUseDistanceFieldFonts_Flag : 0;
+ // Use unknown pixel geometry to disable LCD text.
+ SkSurfaceProps surface_props(flags, kUnknown_SkPixelGeometry);
+ if (can_use_lcd_text) {
+ // LegacyFontHost will get LCD text and skia figures out what type to use.
+ surface_props =
+ SkSurfaceProps(flags, SkSurfaceProps::kLegacyFontHost_InitType);
}
- sk_surface_.clear();
+ sk_surface_ = skia::AdoptRef(
+ SkSurface::NewWrappedRenderTarget(gr_context, desc, &surface_props));
}
void ResourceProvider::ScopedWriteLockGr::ReleaseSkSurface() {
@@ -1196,9 +1085,9 @@ ResourceProvider::ResourceProvider(
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
BlockingTaskRunner* blocking_main_thread_task_runner,
int highp_threshold_min,
- ResourceType default_resource_type,
bool use_rgba_4444_texture_format,
- size_t id_allocation_chunk_size)
+ size_t id_allocation_chunk_size,
+ bool use_persistent_map_for_gpu_memory_buffers)
: output_surface_(output_surface),
shared_bitmap_manager_(shared_bitmap_manager),
gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
@@ -1207,7 +1096,7 @@ ResourceProvider::ResourceProvider(
highp_threshold_min_(highp_threshold_min),
next_id_(1),
next_child_(1),
- default_resource_type_(default_resource_type),
+ default_resource_type_(RESOURCE_TYPE_BITMAP),
use_texture_storage_ext_(false),
use_texture_format_bgra_(false),
use_texture_usage_hint_(false),
@@ -1215,32 +1104,35 @@ ResourceProvider::ResourceProvider(
yuv_resource_format_(LUMINANCE_8),
max_texture_size_(0),
best_texture_format_(RGBA_8888),
+ best_render_buffer_format_(RGBA_8888),
use_rgba_4444_texture_format_(use_rgba_4444_texture_format),
id_allocation_chunk_size_(id_allocation_chunk_size),
- use_sync_query_(false) {
+ use_sync_query_(false),
+ use_persistent_map_for_gpu_memory_buffers_(
+ use_persistent_map_for_gpu_memory_buffers) {
DCHECK(output_surface_->HasClient());
DCHECK(id_allocation_chunk_size_);
}
-void ResourceProvider::InitializeSoftware() {
+void ResourceProvider::Initialize() {
DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK_EQ(default_resource_type_, RESOURCE_TYPE_BITMAP);
- // Pick an arbitrary limit here similar to what hardware might.
- max_texture_size_ = 16 * 1024;
- best_texture_format_ = RGBA_8888;
-}
-void ResourceProvider::InitializeGL() {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK_EQ(default_resource_type_, RESOURCE_TYPE_GL_TEXTURE);
- DCHECK(!texture_uploader_);
+ GLES2Interface* gl = ContextGL();
+ if (!gl) {
+ default_resource_type_ = RESOURCE_TYPE_BITMAP;
+ // Pick an arbitrary limit here similar to what hardware might.
+ max_texture_size_ = 16 * 1024;
+ best_texture_format_ = RGBA_8888;
+ return;
+ }
+
DCHECK(!texture_id_allocator_);
DCHECK(!buffer_id_allocator_);
const ContextProvider::Capabilities& caps =
output_surface_->context_provider()->ContextCapabilities();
- bool use_bgra = caps.gpu.texture_format_bgra8888;
+ default_resource_type_ = RESOURCE_TYPE_GL_TEXTURE;
use_texture_storage_ext_ = caps.gpu.texture_storage;
use_texture_format_bgra_ = caps.gpu.texture_format_bgra8888;
use_texture_usage_hint_ = caps.gpu.texture_usage;
@@ -1248,13 +1140,13 @@ void ResourceProvider::InitializeGL() {
yuv_resource_format_ = caps.gpu.texture_rg ? RED_8 : LUMINANCE_8;
use_sync_query_ = caps.gpu.sync_query;
- GLES2Interface* gl = ContextGL();
- DCHECK(gl);
-
- texture_uploader_ = TextureUploader::Create(gl);
max_texture_size_ = 0; // Context expects cleared value.
gl->GetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size_);
- best_texture_format_ = PlatformColor::BestTextureFormat(use_bgra);
+ best_texture_format_ =
+ PlatformColor::BestTextureFormat(use_texture_format_bgra_);
+
+ best_render_buffer_format_ =
+ PlatformColor::BestTextureFormat(caps.gpu.render_buffer_format_bgra8888);
texture_id_allocator_.reset(
new TextureIdAllocator(gl, id_allocation_chunk_size_));
@@ -1386,12 +1278,12 @@ void ResourceProvider::ReceiveFromChild(
resource->mailbox = TextureMailbox(it->mailbox_holder.mailbox,
it->mailbox_holder.texture_target,
it->mailbox_holder.sync_point);
+ resource->read_lock_fences_enabled = it->read_lock_fences_enabled;
}
resource->child_id = child;
// Don't allocate a texture for a child.
resource->allocated = true;
resource->imported_count = 1;
- resource->allow_overlay = it->allow_overlay;
child_info.parent_to_child_map[local_id] = it->id;
child_info.child_to_parent_map[it->id] = local_id;
}
@@ -1442,14 +1334,6 @@ void ResourceProvider::ReceiveReturnsFromParent(
if (resource->exported_count)
continue;
- // Need to wait for the current read lock fence to pass before we can
- // recycle this resource.
- if (resource->read_lock_fences_enabled) {
- if (current_read_lock_fence_.get())
- current_read_lock_fence_->Set();
- resource->read_lock_fence = current_read_lock_fence_;
- }
-
if (returned.sync_point) {
DCHECK(!resource->has_shared_bitmap_id);
if (resource->origin == Resource::INTERNAL) {
@@ -1494,8 +1378,8 @@ void ResourceProvider::TransferResource(GLES2Interface* gl,
resource->mailbox_holder.texture_target = source->target;
resource->filter = source->filter;
resource->size = source->size;
+ resource->read_lock_fences_enabled = source->read_lock_fences_enabled;
resource->is_repeated = (source->wrap_mode == GL_REPEAT);
- resource->allow_overlay = source->allow_overlay;
if (source->type == RESOURCE_TYPE_BITMAP) {
resource->mailbox_holder.mailbox = source->shared_bitmap_id;
@@ -1506,6 +1390,7 @@ void ResourceProvider::TransferResource(GLES2Interface* gl,
DCHECK(source->origin == Resource::INTERNAL);
if (source->image_id) {
DCHECK(source->dirty_image);
+ gl->BindTexture(resource->mailbox_holder.texture_target, source->gl_id);
BindImageForSampling(source);
}
// This is a resource allocated by the compositor, we need to produce it.
@@ -1566,13 +1451,21 @@ void ResourceProvider::DeleteAndReturnUnusedResourcesToChild(
(resource.type == RESOURCE_TYPE_GL_TEXTURE && lost_output_surface_);
if (resource.exported_count > 0 || resource.lock_for_read_count > 0) {
if (style != FOR_SHUTDOWN) {
- // Defer this until we receive the resource back from the parent or
- // the read lock is released.
+ // Defer this resource deletion.
resource.marked_for_deletion = true;
continue;
}
-
- // We still have an exported_count, so we'll have to lose it.
+ // We can't postpone the deletion, so we'll have to lose it.
+ is_lost = true;
+ } else if (!ReadLockFenceHasPassed(&resource)) {
+ // TODO(dcastagna): see if it's possible to use this logic for
+ // the branch above too, where the resource is locked or still exported.
+ if (style != FOR_SHUTDOWN && !child_info->marked_for_deletion) {
+ // Defer this resource deletion.
+ resource.marked_for_deletion = true;
+ continue;
+ }
+ // We can't postpone the deletion, so we'll have to lose it.
is_lost = true;
}
@@ -1639,11 +1532,11 @@ void ResourceProvider::AcquirePixelBuffer(ResourceId id) {
gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
resource->gl_pixel_buffer_id);
unsigned bytes_per_pixel = BitsPerPixel(resource->format) / 8;
- gl->BufferData(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
- resource->size.height() *
- RoundUp(bytes_per_pixel * resource->size.width(), 4u),
- NULL,
- GL_DYNAMIC_DRAW);
+ gl->BufferData(
+ GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
+ resource->size.height() *
+ MathUtil::RoundUp(bytes_per_pixel * resource->size.width(), 4u),
+ NULL, GL_DYNAMIC_DRAW);
gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
}
@@ -1913,21 +1806,20 @@ void ResourceProvider::LazyAllocate(Resource* resource) {
resource->allocated = true;
GLES2Interface* gl = ContextGL();
gfx::Size& size = resource->size;
- DCHECK_EQ(resource->target, static_cast<GLenum>(GL_TEXTURE_2D));
ResourceFormat format = resource->format;
- gl->BindTexture(GL_TEXTURE_2D, resource->gl_id);
+ gl->BindTexture(resource->target, resource->gl_id);
if (use_texture_storage_ext_ &&
IsFormatSupportedForStorage(format, use_texture_format_bgra_) &&
(resource->hint & TEXTURE_HINT_IMMUTABLE)) {
GLenum storage_format = TextureToStorageFormat(format);
- gl->TexStorage2DEXT(GL_TEXTURE_2D, 1, storage_format, size.width(),
+ gl->TexStorage2DEXT(resource->target, 1, storage_format, size.width(),
size.height());
} else {
// ETC1 does not support preallocation.
if (format != ETC1) {
- gl->TexImage2D(GL_TEXTURE_2D, 0, GLInternalFormat(format), size.width(),
- size.height(), 0, GLDataFormat(format), GLDataType(format),
- NULL);
+ gl->TexImage2D(resource->target, 0, GLInternalFormat(format),
+ size.width(), size.height(), 0, GLDataFormat(format),
+ GLDataType(format), NULL);
}
}
}
@@ -1945,7 +1837,9 @@ void ResourceProvider::BindImageForSampling(Resource* resource) {
resource->dirty_image = false;
}
-void ResourceProvider::CopyResource(ResourceId source_id, ResourceId dest_id) {
+void ResourceProvider::CopyResource(ResourceId source_id,
+ ResourceId dest_id,
+ const gfx::Rect& rect) {
TRACE_EVENT0("cc", "ResourceProvider::CopyResource");
Resource* source_resource = GetResource(source_id);
@@ -1953,8 +1847,7 @@ void ResourceProvider::CopyResource(ResourceId source_id, ResourceId dest_id) {
DCHECK(source_resource->origin == Resource::INTERNAL);
DCHECK_EQ(source_resource->exported_count, 0);
DCHECK_EQ(RESOURCE_TYPE_GL_TEXTURE, source_resource->type);
- DCHECK(source_resource->allocated);
- LazyCreate(source_resource);
+ LazyAllocate(source_resource);
Resource* dest_resource = GetResource(dest_id);
DCHECK(!dest_resource->locked_for_write);
@@ -1967,6 +1860,7 @@ void ResourceProvider::CopyResource(ResourceId source_id, ResourceId dest_id) {
DCHECK_EQ(source_resource->type, dest_resource->type);
DCHECK_EQ(source_resource->format, dest_resource->format);
DCHECK(source_resource->size == dest_resource->size);
+ DCHECK(gfx::Rect(dest_resource->size).Contains(rect));
GLES2Interface* gl = ContextGL();
DCHECK(gl);
@@ -1991,7 +1885,9 @@ void ResourceProvider::CopyResource(ResourceId source_id, ResourceId dest_id) {
DCHECK(!dest_resource->image_id);
dest_resource->allocated = true;
gl->CopySubTextureCHROMIUM(dest_resource->target, source_resource->gl_id,
- dest_resource->gl_id, 0, 0);
+ dest_resource->gl_id, rect.x(), rect.y(), rect.x(),
+ rect.y(), rect.width(), rect.height(),
+ false, false, false);
if (source_resource->gl_read_lock_query_id) {
// End query and create a read lock fence that will prevent access to
// source resource until CopySubTextureCHROMIUM command has completed.
diff --git a/chromium/cc/resources/resource_provider.h b/chromium/cc/resources/resource_provider.h
index f7baac1e3bb..fbed140aa00 100644
--- a/chromium/cc/resources/resource_provider.h
+++ b/chromium/cc/resources/resource_provider.h
@@ -18,6 +18,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/threading/thread_checker.h"
#include "cc/base/cc_export.h"
+#include "cc/base/resource_id.h"
#include "cc/output/context_provider.h"
#include "cc/output/output_surface.h"
#include "cc/resources/release_callback_impl.h"
@@ -53,7 +54,6 @@ class BlockingTaskRunner;
class IdAllocator;
class SharedBitmap;
class SharedBitmapManager;
-class TextureUploader;
// This class is not thread-safe and can only be called from the thread it was
// created on (in practice, the impl thread).
@@ -62,7 +62,6 @@ class CC_EXPORT ResourceProvider {
struct Resource;
public:
- typedef unsigned ResourceId;
typedef std::vector<ResourceId> ResourceIdArray;
typedef base::hash_set<ResourceId> ResourceIdSet;
typedef base::hash_map<ResourceId, ResourceId> ResourceIdMap;
@@ -85,7 +84,8 @@ class CC_EXPORT ResourceProvider {
BlockingTaskRunner* blocking_main_thread_task_runner,
int highp_threshold_min,
bool use_rgba_4444_texture_format,
- size_t id_allocation_chunk_size);
+ size_t id_allocation_chunk_size,
+ bool use_persistent_map_for_gpu_memory_buffers);
virtual ~ResourceProvider();
void DidLoseOutputSurface() { lost_output_surface_ = true; }
@@ -95,15 +95,23 @@ class CC_EXPORT ResourceProvider {
return use_rgba_4444_texture_format_ ? RGBA_4444 : best_texture_format_;
}
ResourceFormat best_texture_format() const { return best_texture_format_; }
+ ResourceFormat best_render_buffer_format() const {
+ return best_render_buffer_format_;
+ }
ResourceFormat yuv_resource_format() const { return yuv_resource_format_; }
bool use_sync_query() const { return use_sync_query_; }
+ bool use_persistent_map_for_gpu_memory_buffers() const {
+ return use_persistent_map_for_gpu_memory_buffers_;
+ }
size_t num_resources() const { return resources_.size(); }
// Checks whether a resource is in use by a consumer.
bool InUseByConsumer(ResourceId id);
bool IsLost(ResourceId id);
- bool AllowOverlay(ResourceId id);
+
+ void LoseResourceForTesting(ResourceId id);
+ void EnableReadLockFencesForTesting(ResourceId id);
// Producer interface.
@@ -142,28 +150,19 @@ class CC_EXPORT ResourceProvider {
const TextureMailbox& mailbox,
scoped_ptr<SingleReleaseCallbackImpl> release_callback_impl);
+ ResourceId CreateResourceFromTextureMailbox(
+ const TextureMailbox& mailbox,
+ scoped_ptr<SingleReleaseCallbackImpl> release_callback_impl,
+ bool read_lock_fences_enabled);
+
void DeleteResource(ResourceId id);
// Update pixels from image, copying source_rect (in image) to dest_offset (in
// the resource).
- // NOTE: DEPRECATED. Use CopyToResource() instead.
- void SetPixels(ResourceId id,
- const uint8_t* image,
- const gfx::Rect& image_rect,
- const gfx::Rect& source_rect,
- const gfx::Vector2d& dest_offset);
void CopyToResource(ResourceId id,
const uint8_t* image,
const gfx::Size& image_size);
- // Check upload status.
- size_t NumBlockingUploads();
- void MarkPendingUploadsAsNonBlocking();
- size_t EstimatedUploadsPerTick();
- void FlushUploads();
- void ReleaseCachedData();
- base::TimeTicks EstimatedUploadCompletionTime(size_t uploads_per_tick);
-
// Only flush the command buffer if supported.
// Returns true if the shallow flush occurred, false otherwise.
bool ShallowFlushIfSupported();
@@ -220,7 +219,7 @@ class CC_EXPORT ResourceProvider {
class CC_EXPORT ScopedReadLockGL {
public:
ScopedReadLockGL(ResourceProvider* resource_provider,
- ResourceProvider::ResourceId resource_id);
+ ResourceId resource_id);
virtual ~ScopedReadLockGL();
unsigned texture_id() const { return resource_->gl_id; }
@@ -228,7 +227,7 @@ class CC_EXPORT ResourceProvider {
protected:
ResourceProvider* resource_provider_;
- ResourceProvider::ResourceId resource_id_;
+ ResourceId resource_id_;
private:
const ResourceProvider::Resource* resource_;
@@ -239,10 +238,10 @@ class CC_EXPORT ResourceProvider {
class CC_EXPORT ScopedSamplerGL : public ScopedReadLockGL {
public:
ScopedSamplerGL(ResourceProvider* resource_provider,
- ResourceProvider::ResourceId resource_id,
+ ResourceId resource_id,
GLenum filter);
ScopedSamplerGL(ResourceProvider* resource_provider,
- ResourceProvider::ResourceId resource_id,
+ ResourceId resource_id,
GLenum unit,
GLenum filter);
~ScopedSamplerGL() override;
@@ -259,7 +258,7 @@ class CC_EXPORT ResourceProvider {
class CC_EXPORT ScopedWriteLockGL {
public:
ScopedWriteLockGL(ResourceProvider* resource_provider,
- ResourceProvider::ResourceId resource_id);
+ ResourceId resource_id);
~ScopedWriteLockGL();
unsigned texture_id() const { return texture_id_; }
@@ -275,7 +274,7 @@ class CC_EXPORT ResourceProvider {
class CC_EXPORT ScopedReadLockSoftware {
public:
ScopedReadLockSoftware(ResourceProvider* resource_provider,
- ResourceProvider::ResourceId resource_id);
+ ResourceId resource_id);
~ScopedReadLockSoftware();
const SkBitmap* sk_bitmap() const {
@@ -288,7 +287,7 @@ class CC_EXPORT ResourceProvider {
private:
ResourceProvider* resource_provider_;
- ResourceProvider::ResourceId resource_id_;
+ ResourceId resource_id_;
SkBitmap sk_bitmap_;
GLint wrap_mode_;
@@ -298,7 +297,7 @@ class CC_EXPORT ResourceProvider {
class CC_EXPORT ScopedWriteLockSoftware {
public:
ScopedWriteLockSoftware(ResourceProvider* resource_provider,
- ResourceProvider::ResourceId resource_id);
+ ResourceId resource_id);
~ScopedWriteLockSoftware();
SkBitmap& sk_bitmap() { return sk_bitmap_; }
@@ -316,7 +315,7 @@ class CC_EXPORT ResourceProvider {
class CC_EXPORT ScopedWriteLockGpuMemoryBuffer {
public:
ScopedWriteLockGpuMemoryBuffer(ResourceProvider* resource_provider,
- ResourceProvider::ResourceId resource_id);
+ ResourceId resource_id);
~ScopedWriteLockGpuMemoryBuffer();
gfx::GpuMemoryBuffer* GetGpuMemoryBuffer();
@@ -336,7 +335,7 @@ class CC_EXPORT ResourceProvider {
class CC_EXPORT ScopedWriteLockGr {
public:
ScopedWriteLockGr(ResourceProvider* resource_provider,
- ResourceProvider::ResourceId resource_id);
+ ResourceId resource_id);
~ScopedWriteLockGr();
void InitSkSurface(bool use_distance_field_text,
@@ -424,8 +423,10 @@ class CC_EXPORT ResourceProvider {
// Indicates if we can currently lock this resource for write.
bool CanLockForWrite(ResourceId id);
- // Copy pixels from source to destination.
- void CopyResource(ResourceId source_id, ResourceId dest_id);
+ // Copy |rect| pixels from source to destination.
+ void CopyResource(ResourceId source_id,
+ ResourceId dest_id,
+ const gfx::Rect& rect);
void WaitSyncPointIfNeeded(ResourceId id);
@@ -437,6 +438,17 @@ class CC_EXPORT ResourceProvider {
void ValidateResource(ResourceId id) const;
+ protected:
+ ResourceProvider(OutputSurface* output_surface,
+ SharedBitmapManager* shared_bitmap_manager,
+ gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
+ BlockingTaskRunner* blocking_main_thread_task_runner,
+ int highp_threshold_min,
+ bool use_rgba_4444_texture_format,
+ size_t id_allocation_chunk_size,
+ bool use_persistent_map_for_gpu_memory_buffers);
+ void Initialize();
+
private:
struct Resource {
enum Origin { INTERNAL, EXTERNAL, DELEGATED };
@@ -486,7 +498,6 @@ class CC_EXPORT ResourceProvider {
bool allocated : 1;
bool read_lock_fences_enabled : 1;
bool has_shared_bitmap_id : 1;
- bool allow_overlay : 1;
scoped_refptr<Fence> read_lock_fence;
gfx::Size size;
Origin origin;
@@ -524,18 +535,6 @@ class CC_EXPORT ResourceProvider {
resource->read_lock_fence->HasPassed();
}
- ResourceProvider(OutputSurface* output_surface,
- SharedBitmapManager* shared_bitmap_manager,
- gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
- BlockingTaskRunner* blocking_main_thread_task_runner,
- int highp_threshold_min,
- ResourceType default_resource_type,
- bool use_rgba_4444_texture_format,
- size_t id_allocation_chunk_size);
-
- void InitializeSoftware();
- void InitializeGL();
-
Resource* InsertResource(ResourceId id, const Resource& resource);
Resource* GetResource(ResourceId id);
const Resource* LockForRead(ResourceId id);
@@ -582,15 +581,15 @@ class CC_EXPORT ResourceProvider {
int next_child_;
ChildMap children_;
- const ResourceType default_resource_type_;
+ ResourceType default_resource_type_;
bool use_texture_storage_ext_;
bool use_texture_format_bgra_;
bool use_texture_usage_hint_;
bool use_compressed_texture_etc1_;
ResourceFormat yuv_resource_format_;
- scoped_ptr<TextureUploader> texture_uploader_;
int max_texture_size_;
ResourceFormat best_texture_format_;
+ ResourceFormat best_render_buffer_format_;
base::ThreadChecker thread_checker_;
@@ -602,6 +601,7 @@ class CC_EXPORT ResourceProvider {
scoped_ptr<IdAllocator> buffer_id_allocator_;
bool use_sync_query_;
+ bool use_persistent_map_for_gpu_memory_buffers_;
// Fence used for CopyResource if CHROMIUM_sync_query is not supported.
scoped_refptr<SynchronousFence> synchronous_fence_;
@@ -610,7 +610,7 @@ class CC_EXPORT ResourceProvider {
// TODO(epenner): Move these format conversions to resource_format.h
// once that builds on mac (npapi.h currently #includes OpenGL.h).
-inline unsigned BitsPerPixel(ResourceFormat format) {
+inline int BitsPerPixel(ResourceFormat format) {
switch (format) {
case BGRA_8888:
case RGBA_8888:
diff --git a/chromium/cc/resources/resource_provider_unittest.cc b/chromium/cc/resources/resource_provider_unittest.cc
index 3ca1ab41dd7..136855847db 100644
--- a/chromium/cc/resources/resource_provider_unittest.cc
+++ b/chromium/cc/resources/resource_provider_unittest.cc
@@ -350,7 +350,7 @@ class ResourceProviderContext : public TestWebGraphicsContext3D {
void GetResourcePixels(ResourceProvider* resource_provider,
ResourceProviderContext* context,
- ResourceProvider::ResourceId id,
+ ResourceId id,
const gfx::Size& size,
ResourceFormat format,
uint8_t* pixels) {
@@ -418,22 +418,14 @@ class ResourceProviderTest
shared_bitmap_manager_.reset(new TestSharedBitmapManager);
gpu_memory_buffer_manager_.reset(new TestGpuMemoryBufferManager);
- resource_provider_ =
- ResourceProvider::Create(output_surface_.get(),
- shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(),
- main_thread_task_runner_.get(),
- 0,
- false,
- 1);
- child_resource_provider_ =
- ResourceProvider::Create(child_output_surface_.get(),
- shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(),
- main_thread_task_runner_.get(),
- 0,
- false,
- 1);
+ resource_provider_ = ResourceProvider::Create(
+ output_surface_.get(), shared_bitmap_manager_.get(),
+ gpu_memory_buffer_manager_.get(), main_thread_task_runner_.get(), 0,
+ false, 1, false);
+ child_resource_provider_ = ResourceProvider::Create(
+ child_output_surface_.get(), shared_bitmap_manager_.get(),
+ gpu_memory_buffer_manager_.get(), main_thread_task_runner_.get(), 0,
+ false, 1, false);
}
ResourceProviderTest() : ResourceProviderTest(true) {}
@@ -449,7 +441,7 @@ class ResourceProviderTest
}
static void SetResourceFilter(ResourceProvider* resource_provider,
- ResourceProvider::ResourceId id,
+ ResourceId id,
GLenum filter) {
ResourceProvider::ScopedSamplerGL sampler(
resource_provider, id, GL_TEXTURE_2D, filter);
@@ -457,10 +449,10 @@ class ResourceProviderTest
ResourceProviderContext* context() { return context3d_; }
- ResourceProvider::ResourceId CreateChildMailbox(uint32* release_sync_point,
- bool* lost_resource,
- bool* release_called,
- uint32* sync_point) {
+ ResourceId CreateChildMailbox(uint32* release_sync_point,
+ bool* lost_resource,
+ bool* release_called,
+ uint32* sync_point) {
if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) {
unsigned texture = child_context_->createTexture();
gpu::Mailbox gpu_mailbox;
@@ -518,7 +510,7 @@ void CheckCreateResource(ResourceProvider::ResourceType expected_default_type,
size_t pixel_size = TextureSizeBytes(size, format);
ASSERT_EQ(4U, pixel_size);
- ResourceProvider::ResourceId id = resource_provider->CreateResource(
+ ResourceId id = resource_provider->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
EXPECT_EQ(1, static_cast<int>(resource_provider->num_resources()));
if (expected_default_type == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
@@ -543,80 +535,13 @@ TEST_P(ResourceProviderTest, Basic) {
CheckCreateResource(GetParam(), resource_provider_.get(), context());
}
-TEST_P(ResourceProviderTest, Upload) {
- gfx::Size size(2, 2);
- ResourceFormat format = RGBA_8888;
- size_t pixel_size = TextureSizeBytes(size, format);
- ASSERT_EQ(16U, pixel_size);
-
- ResourceProvider::ResourceId id = resource_provider_->CreateResource(
- size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-
- uint8_t image[16] = { 0 };
- gfx::Rect image_rect(size);
- resource_provider_->SetPixels(
- id, image, image_rect, image_rect, gfx::Vector2d());
-
- for (uint8_t i = 0; i < pixel_size; ++i)
- image[i] = i;
-
- uint8_t result[16] = { 0 };
- {
- gfx::Rect source_rect(0, 0, 1, 1);
- gfx::Vector2d dest_offset(0, 0);
- resource_provider_->SetPixels(
- id, image, image_rect, source_rect, dest_offset);
-
- uint8_t expected[16] = { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- GetResourcePixels(
- resource_provider_.get(), context(), id, size, format, result);
- EXPECT_EQ(0, memcmp(expected, result, pixel_size));
- }
- {
- gfx::Rect source_rect(0, 0, 1, 1);
- gfx::Vector2d dest_offset(1, 1);
- resource_provider_->SetPixels(
- id, image, image_rect, source_rect, dest_offset);
-
- uint8_t expected[16] = { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3 };
- GetResourcePixels(
- resource_provider_.get(), context(), id, size, format, result);
- EXPECT_EQ(0, memcmp(expected, result, pixel_size));
- }
- {
- gfx::Rect source_rect(1, 0, 1, 1);
- gfx::Vector2d dest_offset(0, 1);
- resource_provider_->SetPixels(
- id, image, image_rect, source_rect, dest_offset);
-
- uint8_t expected[16] = { 0, 1, 2, 3, 0, 0, 0, 0, 4, 5, 6, 7, 0, 1, 2, 3 };
- GetResourcePixels(
- resource_provider_.get(), context(), id, size, format, result);
- EXPECT_EQ(0, memcmp(expected, result, pixel_size));
- }
- {
- gfx::Rect offset_image_rect(gfx::Point(100, 100), size);
- gfx::Rect source_rect(100, 100, 1, 1);
- gfx::Vector2d dest_offset(1, 0);
- resource_provider_->SetPixels(
- id, image, offset_image_rect, source_rect, dest_offset);
-
- uint8_t expected[16] = { 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3 };
- GetResourcePixels(
- resource_provider_.get(), context(), id, size, format, result);
- EXPECT_EQ(0, memcmp(expected, result, pixel_size));
- }
-
- resource_provider_->DeleteResource(id);
-}
-
TEST_P(ResourceProviderTest, SimpleUpload) {
gfx::Size size(2, 2);
ResourceFormat format = RGBA_8888;
size_t pixel_size = TextureSizeBytes(size, format);
ASSERT_EQ(16U, pixel_size);
- ResourceProvider::ResourceId id = resource_provider_->CreateResource(
+ ResourceId id = resource_provider_->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
uint8_t image[16] = {0};
@@ -650,17 +575,17 @@ TEST_P(ResourceProviderTest, TransferGLResources) {
size_t pixel_size = TextureSizeBytes(size, format);
ASSERT_EQ(4U, pixel_size);
- ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
+ ResourceId id1 = child_resource_provider_->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
uint8_t data1[4] = { 1, 2, 3, 4 };
child_resource_provider_->CopyToResource(id1, data1, size);
- ResourceProvider::ResourceId id2 = child_resource_provider_->CreateResource(
+ ResourceId id2 = child_resource_provider_->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
uint8_t data2[4] = { 5, 5, 5, 5 };
child_resource_provider_->CopyToResource(id2, data2, size);
- ResourceProvider::ResourceId id3 = child_resource_provider_->CreateResource(
+ ResourceId id3 = child_resource_provider_->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
{
ResourceProvider::ScopedWriteLockGpuMemoryBuffer lock(
@@ -675,11 +600,10 @@ TEST_P(ResourceProviderTest, TransferGLResources) {
child_context_->produceTextureDirectCHROMIUM(
external_texture_id, GL_TEXTURE_EXTERNAL_OES, external_mailbox.name);
const GLuint external_sync_point = child_context_->insertSyncPoint();
- ResourceProvider::ResourceId id4 =
- child_resource_provider_->CreateResourceFromTextureMailbox(
- TextureMailbox(
- external_mailbox, GL_TEXTURE_EXTERNAL_OES, external_sync_point),
- SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback)));
+ ResourceId id4 = child_resource_provider_->CreateResourceFromTextureMailbox(
+ TextureMailbox(external_mailbox, GL_TEXTURE_EXTERNAL_OES,
+ external_sync_point),
+ SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback)));
ReturnedResourceArray returned_to_child;
int child_id =
@@ -737,10 +661,10 @@ TEST_P(ResourceProviderTest, TransferGLResources) {
EXPECT_EQ(4u, resource_provider_->num_resources());
ResourceProvider::ResourceIdMap resource_map =
resource_provider_->GetChildToParentMap(child_id);
- ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
- ResourceProvider::ResourceId mapped_id2 = resource_map[id2];
- ResourceProvider::ResourceId mapped_id3 = resource_map[id3];
- ResourceProvider::ResourceId mapped_id4 = resource_map[id4];
+ ResourceId mapped_id1 = resource_map[id1];
+ ResourceId mapped_id2 = resource_map[id2];
+ ResourceId mapped_id3 = resource_map[id3];
+ ResourceId mapped_id4 = resource_map[id4];
EXPECT_NE(0u, mapped_id1);
EXPECT_NE(0u, mapped_id2);
EXPECT_NE(0u, mapped_id3);
@@ -909,12 +833,12 @@ TEST_P(ResourceProviderTestNoSyncPoint, TransferGLResources) {
size_t pixel_size = TextureSizeBytes(size, format);
ASSERT_EQ(4U, pixel_size);
- ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
+ ResourceId id1 = child_resource_provider_->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
uint8_t data1[4] = {1, 2, 3, 4};
child_resource_provider_->CopyToResource(id1, data1, size);
- ResourceProvider::ResourceId id2 = child_resource_provider_->CreateResource(
+ ResourceId id2 = child_resource_provider_->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
{
// Ensure locking the memory buffer doesn't create an unnecessary sync
@@ -932,11 +856,10 @@ TEST_P(ResourceProviderTestNoSyncPoint, TransferGLResources) {
child_context_->produceTextureDirectCHROMIUM(
external_texture_id, GL_TEXTURE_EXTERNAL_OES, external_mailbox.name);
const GLuint external_sync_point = child_context_->insertSyncPoint();
- ResourceProvider::ResourceId id3 =
- child_resource_provider_->CreateResourceFromTextureMailbox(
- TextureMailbox(external_mailbox, GL_TEXTURE_EXTERNAL_OES,
- external_sync_point),
- SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback)));
+ ResourceId id3 = child_resource_provider_->CreateResourceFromTextureMailbox(
+ TextureMailbox(external_mailbox, GL_TEXTURE_EXTERNAL_OES,
+ external_sync_point),
+ SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback)));
ReturnedResourceArray returned_to_child;
int child_id =
@@ -976,7 +899,7 @@ TEST_P(ResourceProviderTestNoSyncPoint, TransferGLResources) {
resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
ASSERT_EQ(3u, returned_to_child.size());
- std::map<ResourceProvider::ResourceId, unsigned int> returned_sync_points;
+ std::map<ResourceId, unsigned int> returned_sync_points;
for (const auto& returned : returned_to_child)
returned_sync_points[returned.id] = returned.sync_point;
@@ -1010,7 +933,7 @@ TEST_P(ResourceProviderTest, ReadLockCountStopsReturnToChildOrDelete) {
gfx::Size size(1, 1);
ResourceFormat format = RGBA_8888;
- ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
+ ResourceId id1 = child_resource_provider_->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
uint8_t data1[4] = {1, 2, 3, 4};
child_resource_provider_->CopyToResource(id1, data1, size);
@@ -1055,33 +978,94 @@ TEST_P(ResourceProviderTest, ReadLockCountStopsReturnToChildOrDelete) {
resource_provider_->DestroyChild(child_id);
}
-TEST_P(ResourceProviderTest, AllowOverlayTransfersToParent) {
- // Overlays only supported on the GL path.
+class TestFence : public ResourceProvider::Fence {
+ public:
+ TestFence() {}
+
+ void Set() override {}
+ bool HasPassed() override { return passed; }
+ void Wait() override {}
+
+ bool passed = false;
+
+ private:
+ ~TestFence() override {}
+};
+
+TEST_P(ResourceProviderTest, ReadLockFenceStopsReturnToChildOrDelete) {
if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
return;
+ gfx::Size size(1, 1);
+ ResourceFormat format = RGBA_8888;
- uint32 sync_point = 0;
- TextureMailbox mailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
- mailbox.set_allow_overlay(true);
- scoped_ptr<SingleReleaseCallbackImpl> release_callback =
- SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback));
- ResourceProvider::ResourceId id1 =
- child_resource_provider_->CreateResourceFromTextureMailbox(
- mailbox, release_callback.Pass());
+ ResourceId id1 = child_resource_provider_->CreateResource(
+ size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
+ uint8_t data1[4] = {1, 2, 3, 4};
+ child_resource_provider_->CopyToResource(id1, data1, size);
+ child_resource_provider_->EnableReadLockFencesForTesting(id1);
+ ReturnedResourceArray returned_to_child;
+ int child_id =
+ resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
- TextureMailbox mailbox2(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
- mailbox2.set_allow_overlay(false);
- scoped_ptr<SingleReleaseCallbackImpl> release_callback2 =
- SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback));
- ResourceProvider::ResourceId id2 =
- child_resource_provider_->CreateResourceFromTextureMailbox(
- mailbox2, release_callback2.Pass());
+ // Transfer some resources to the parent.
+ ResourceProvider::ResourceIdArray resource_ids_to_transfer;
+ resource_ids_to_transfer.push_back(id1);
+ TransferableResourceArray list;
+ child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
+ &list);
+ ASSERT_EQ(1u, list.size());
+ EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
+ EXPECT_TRUE(list[0].read_lock_fences_enabled);
+
+ resource_provider_->ReceiveFromChild(child_id, list);
+
+ scoped_refptr<TestFence> fence(new TestFence);
+ resource_provider_->SetReadLockFence(fence.get());
+ {
+ unsigned parent_id = list.front().id;
+ resource_provider_->WaitSyncPointIfNeeded(parent_id);
+ ResourceProvider::ScopedReadLockGL lock(resource_provider_.get(),
+ parent_id);
+ }
+ resource_provider_->DeclareUsedResourcesFromChild(
+ child_id, ResourceProvider::ResourceIdSet());
+ EXPECT_EQ(0u, returned_to_child.size());
+
+ resource_provider_->DeclareUsedResourcesFromChild(
+ child_id, ResourceProvider::ResourceIdSet());
+ EXPECT_EQ(0u, returned_to_child.size());
+ fence->passed = true;
+
+ resource_provider_->DeclareUsedResourcesFromChild(
+ child_id, ResourceProvider::ResourceIdSet());
+ EXPECT_EQ(1u, returned_to_child.size());
+
+ child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
+ child_resource_provider_->DeleteResource(id1);
+ EXPECT_EQ(0u, child_resource_provider_->num_resources());
+}
+
+TEST_P(ResourceProviderTest, ReadLockFenceDestroyChild) {
+ if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
+ return;
+ gfx::Size size(1, 1);
+ ResourceFormat format = RGBA_8888;
+
+ ResourceId id1 = child_resource_provider_->CreateResource(
+ size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
+ uint8_t data[4] = {1, 2, 3, 4};
+ child_resource_provider_->CopyToResource(id1, data, size);
+ child_resource_provider_->EnableReadLockFencesForTesting(id1);
+
+ ResourceId id2 = child_resource_provider_->CreateResource(
+ size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
+ child_resource_provider_->CopyToResource(id2, data, size);
ReturnedResourceArray returned_to_child;
int child_id =
resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
- // Transfer some resources to the parent.
+ // Transfer resources to the parent.
ResourceProvider::ResourceIdArray resource_ids_to_transfer;
resource_ids_to_transfer.push_back(id1);
resource_ids_to_transfer.push_back(id2);
@@ -1089,21 +1073,93 @@ TEST_P(ResourceProviderTest, AllowOverlayTransfersToParent) {
child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
&list);
ASSERT_EQ(2u, list.size());
+ EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
+ EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
+
resource_provider_->ReceiveFromChild(child_id, list);
- EXPECT_TRUE(resource_provider_->AllowOverlay(list[0].id));
- EXPECT_FALSE(resource_provider_->AllowOverlay(list[1].id));
- resource_provider_->DeclareUsedResourcesFromChild(
- child_id, ResourceProvider::ResourceIdSet());
+ scoped_refptr<TestFence> fence(new TestFence);
+ resource_provider_->SetReadLockFence(fence.get());
+ {
+ for (size_t i = 0; i < list.size(); i++) {
+ unsigned parent_id = list[i].id;
+ resource_provider_->WaitSyncPointIfNeeded(parent_id);
+ ResourceProvider::ScopedReadLockGL lock(resource_provider_.get(),
+ parent_id);
+ }
+ }
+ EXPECT_EQ(0u, returned_to_child.size());
+
+ EXPECT_EQ(2u, resource_provider_->num_resources());
+ resource_provider_->DestroyChild(child_id);
+
+ EXPECT_EQ(0u, resource_provider_->num_resources());
EXPECT_EQ(2u, returned_to_child.size());
- child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
+ // id1 should be lost and id2 should not.
+ EXPECT_EQ(returned_to_child[0].lost, returned_to_child[0].id == id1);
+ EXPECT_EQ(returned_to_child[1].lost, returned_to_child[1].id == id1);
+
+ child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
child_resource_provider_->DeleteResource(id1);
child_resource_provider_->DeleteResource(id2);
EXPECT_EQ(0u, child_resource_provider_->num_resources());
+}
- resource_provider_->DestroyChild(child_id);
+TEST_P(ResourceProviderTest, ReadLockFenceContextLost) {
+ if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
+ return;
+ gfx::Size size(1, 1);
+ ResourceFormat format = RGBA_8888;
+
+ ResourceId id1 = child_resource_provider_->CreateResource(
+ size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
+ uint8_t data[4] = {1, 2, 3, 4};
+ child_resource_provider_->CopyToResource(id1, data, size);
+ child_resource_provider_->EnableReadLockFencesForTesting(id1);
+
+ ResourceId id2 = child_resource_provider_->CreateResource(
+ size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
+ child_resource_provider_->CopyToResource(id2, data, size);
+
+ ReturnedResourceArray returned_to_child;
+ int child_id =
+ resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
+
+ // Transfer resources to the parent.
+ ResourceProvider::ResourceIdArray resource_ids_to_transfer;
+ resource_ids_to_transfer.push_back(id1);
+ resource_ids_to_transfer.push_back(id2);
+ TransferableResourceArray list;
+ child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
+ &list);
+ ASSERT_EQ(2u, list.size());
+ EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
+ EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
+
+ resource_provider_->ReceiveFromChild(child_id, list);
+
+ scoped_refptr<TestFence> fence(new TestFence);
+ resource_provider_->SetReadLockFence(fence.get());
+ {
+ for (size_t i = 0; i < list.size(); i++) {
+ unsigned parent_id = list[i].id;
+ resource_provider_->WaitSyncPointIfNeeded(parent_id);
+ ResourceProvider::ScopedReadLockGL lock(resource_provider_.get(),
+ parent_id);
+ }
+ }
+ EXPECT_EQ(0u, returned_to_child.size());
+
+ EXPECT_EQ(2u, resource_provider_->num_resources());
+ resource_provider_->DidLoseOutputSurface();
+ resource_provider_ = nullptr;
+
+ EXPECT_EQ(2u, returned_to_child.size());
+
+ EXPECT_TRUE(returned_to_child[0].lost);
+ EXPECT_TRUE(returned_to_child[1].lost);
}
TEST_P(ResourceProviderTest, TransferSoftwareResources) {
@@ -1115,12 +1171,12 @@ TEST_P(ResourceProviderTest, TransferSoftwareResources) {
size_t pixel_size = TextureSizeBytes(size, format);
ASSERT_EQ(4U, pixel_size);
- ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
+ ResourceId id1 = child_resource_provider_->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
uint8_t data1[4] = { 1, 2, 3, 4 };
child_resource_provider_->CopyToResource(id1, data1, size);
- ResourceProvider::ResourceId id2 = child_resource_provider_->CreateResource(
+ ResourceId id2 = child_resource_provider_->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
uint8_t data2[4] = { 5, 5, 5, 5 };
child_resource_provider_->CopyToResource(id2, data2, size);
@@ -1128,11 +1184,10 @@ TEST_P(ResourceProviderTest, TransferSoftwareResources) {
scoped_ptr<SharedBitmap> shared_bitmap(CreateAndFillSharedBitmap(
shared_bitmap_manager_.get(), gfx::Size(1, 1), 0));
SharedBitmap* shared_bitmap_ptr = shared_bitmap.get();
- ResourceProvider::ResourceId id3 =
- child_resource_provider_->CreateResourceFromTextureMailbox(
- TextureMailbox(shared_bitmap_ptr, gfx::Size(1, 1)),
- SingleReleaseCallbackImpl::Create(base::Bind(
- &SharedBitmapReleaseCallback, base::Passed(&shared_bitmap))));
+ ResourceId id3 = child_resource_provider_->CreateResourceFromTextureMailbox(
+ TextureMailbox(shared_bitmap_ptr, gfx::Size(1, 1)),
+ SingleReleaseCallbackImpl::Create(base::Bind(
+ &SharedBitmapReleaseCallback, base::Passed(&shared_bitmap))));
ReturnedResourceArray returned_to_child;
int child_id =
@@ -1165,9 +1220,9 @@ TEST_P(ResourceProviderTest, TransferSoftwareResources) {
EXPECT_EQ(3u, resource_provider_->num_resources());
ResourceProvider::ResourceIdMap resource_map =
resource_provider_->GetChildToParentMap(child_id);
- ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
- ResourceProvider::ResourceId mapped_id2 = resource_map[id2];
- ResourceProvider::ResourceId mapped_id3 = resource_map[id3];
+ ResourceId mapped_id1 = resource_map[id1];
+ ResourceId mapped_id2 = resource_map[id2];
+ ResourceId mapped_id3 = resource_map[id3];
EXPECT_NE(0u, mapped_id1);
EXPECT_NE(0u, mapped_id2);
EXPECT_NE(0u, mapped_id3);
@@ -1216,11 +1271,11 @@ TEST_P(ResourceProviderTest, TransferSoftwareResources) {
EXPECT_EQ(0u, returned_to_child[0].sync_point);
EXPECT_EQ(0u, returned_to_child[1].sync_point);
EXPECT_EQ(0u, returned_to_child[2].sync_point);
- std::set<ResourceProvider::ResourceId> expected_ids;
+ std::set<ResourceId> expected_ids;
expected_ids.insert(id1);
expected_ids.insert(id2);
expected_ids.insert(id3);
- std::set<ResourceProvider::ResourceId> returned_ids;
+ std::set<ResourceId> returned_ids;
for (unsigned i = 0; i < 3; i++)
returned_ids.insert(returned_to_child[i].id);
EXPECT_EQ(expected_ids, returned_ids);
@@ -1285,11 +1340,11 @@ TEST_P(ResourceProviderTest, TransferSoftwareResources) {
EXPECT_EQ(0u, returned_to_child[0].sync_point);
EXPECT_EQ(0u, returned_to_child[1].sync_point);
EXPECT_EQ(0u, returned_to_child[2].sync_point);
- std::set<ResourceProvider::ResourceId> expected_ids;
+ std::set<ResourceId> expected_ids;
expected_ids.insert(id1);
expected_ids.insert(id2);
expected_ids.insert(id3);
- std::set<ResourceProvider::ResourceId> returned_ids;
+ std::set<ResourceId> returned_ids;
for (unsigned i = 0; i < 3; i++)
returned_ids.insert(returned_to_child[i].id);
EXPECT_EQ(expected_ids, returned_ids);
@@ -1310,21 +1365,16 @@ TEST_P(ResourceProviderTest, TransferGLToSoftware) {
FakeOutputSurface::Create3d(child_context_owned.Pass()));
CHECK(child_output_surface->BindToClient(&child_output_surface_client));
- scoped_ptr<ResourceProvider> child_resource_provider(
- ResourceProvider::Create(child_output_surface.get(),
- shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(),
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> child_resource_provider(ResourceProvider::Create(
+ child_output_surface.get(), shared_bitmap_manager_.get(),
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false));
gfx::Size size(1, 1);
ResourceFormat format = RGBA_8888;
size_t pixel_size = TextureSizeBytes(size, format);
ASSERT_EQ(4U, pixel_size);
- ResourceProvider::ResourceId id1 = child_resource_provider->CreateResource(
+ ResourceId id1 = child_resource_provider->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
uint8_t data1[4] = { 1, 2, 3, 4 };
child_resource_provider->CopyToResource(id1, data1, size);
@@ -1351,7 +1401,7 @@ TEST_P(ResourceProviderTest, TransferGLToSoftware) {
EXPECT_EQ(returned_to_child[0].id, id1);
ResourceProvider::ResourceIdMap resource_map =
resource_provider_->GetChildToParentMap(child_id);
- ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
+ ResourceId mapped_id1 = resource_map[id1];
EXPECT_EQ(0u, mapped_id1);
resource_provider_->DestroyChild(child_id);
@@ -1370,7 +1420,7 @@ TEST_P(ResourceProviderTest, TransferInvalidSoftware) {
size_t pixel_size = TextureSizeBytes(size, format);
ASSERT_EQ(4U, pixel_size);
- ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
+ ResourceId id1 = child_resource_provider_->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
uint8_t data1[4] = { 1, 2, 3, 4 };
child_resource_provider_->CopyToResource(id1, data1, size);
@@ -1396,7 +1446,7 @@ TEST_P(ResourceProviderTest, TransferInvalidSoftware) {
ResourceProvider::ResourceIdMap resource_map =
resource_provider_->GetChildToParentMap(child_id);
- ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
+ ResourceId mapped_id1 = resource_map[id1];
EXPECT_NE(0u, mapped_id1);
{
ResourceProvider::ScopedReadLockSoftware lock(resource_provider_.get(),
@@ -1417,12 +1467,12 @@ TEST_P(ResourceProviderTest, DeleteExportedResources) {
size_t pixel_size = TextureSizeBytes(size, format);
ASSERT_EQ(4U, pixel_size);
- ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
+ ResourceId id1 = child_resource_provider_->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
uint8_t data1[4] = { 1, 2, 3, 4 };
child_resource_provider_->CopyToResource(id1, data1, size);
- ResourceProvider::ResourceId id2 = child_resource_provider_->CreateResource(
+ ResourceId id2 = child_resource_provider_->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
uint8_t data2[4] = {5, 5, 5, 5};
child_resource_provider_->CopyToResource(id2, data2, size);
@@ -1456,8 +1506,8 @@ TEST_P(ResourceProviderTest, DeleteExportedResources) {
EXPECT_EQ(2u, resource_provider_->num_resources());
ResourceProvider::ResourceIdMap resource_map =
resource_provider_->GetChildToParentMap(child_id);
- ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
- ResourceProvider::ResourceId mapped_id2 = resource_map[id2];
+ ResourceId mapped_id1 = resource_map[id1];
+ ResourceId mapped_id2 = resource_map[id2];
EXPECT_NE(0u, mapped_id1);
EXPECT_NE(0u, mapped_id2);
EXPECT_FALSE(resource_provider_->InUseByConsumer(id1));
@@ -1513,12 +1563,12 @@ TEST_P(ResourceProviderTest, DestroyChildWithExportedResources) {
size_t pixel_size = TextureSizeBytes(size, format);
ASSERT_EQ(4U, pixel_size);
- ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
+ ResourceId id1 = child_resource_provider_->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
uint8_t data1[4] = {1, 2, 3, 4};
child_resource_provider_->CopyToResource(id1, data1, size);
- ResourceProvider::ResourceId id2 = child_resource_provider_->CreateResource(
+ ResourceId id2 = child_resource_provider_->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
uint8_t data2[4] = {5, 5, 5, 5};
child_resource_provider_->CopyToResource(id2, data2, size);
@@ -1552,8 +1602,8 @@ TEST_P(ResourceProviderTest, DestroyChildWithExportedResources) {
EXPECT_EQ(2u, resource_provider_->num_resources());
ResourceProvider::ResourceIdMap resource_map =
resource_provider_->GetChildToParentMap(child_id);
- ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
- ResourceProvider::ResourceId mapped_id2 = resource_map[id2];
+ ResourceId mapped_id1 = resource_map[id1];
+ ResourceId mapped_id2 = resource_map[id2];
EXPECT_NE(0u, mapped_id1);
EXPECT_NE(0u, mapped_id2);
EXPECT_FALSE(resource_provider_->InUseByConsumer(id1));
@@ -1626,7 +1676,7 @@ TEST_P(ResourceProviderTest, DeleteTransferredResources) {
size_t pixel_size = TextureSizeBytes(size, format);
ASSERT_EQ(4U, pixel_size);
- ResourceProvider::ResourceId id = child_resource_provider_->CreateResource(
+ ResourceId id = child_resource_provider_->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
uint8_t data[4] = { 1, 2, 3, 4 };
child_resource_provider_->CopyToResource(id, data, size);
@@ -1677,7 +1727,7 @@ TEST_P(ResourceProviderTest, UnuseTransferredResources) {
size_t pixel_size = TextureSizeBytes(size, format);
ASSERT_EQ(4U, pixel_size);
- ResourceProvider::ResourceId id = child_resource_provider_->CreateResource(
+ ResourceId id = child_resource_provider_->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
uint8_t data[4] = {1, 2, 3, 4};
child_resource_provider_->CopyToResource(id, data, size);
@@ -1705,7 +1755,7 @@ TEST_P(ResourceProviderTest, UnuseTransferredResources) {
{
// Parent transfers to top-level.
ASSERT_TRUE(map.find(id) != map.end());
- ResourceProvider::ResourceId parent_id = map.find(id)->second;
+ ResourceId parent_id = map.find(id)->second;
ResourceProvider::ResourceIdArray resource_ids_to_transfer;
resource_ids_to_transfer.push_back(parent_id);
resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
@@ -1743,14 +1793,14 @@ TEST_P(ResourceProviderTest, UnuseTransferredResources) {
// in the parent.
EXPECT_TRUE(returned_to_child.empty());
ASSERT_TRUE(map.find(id) != map.end());
- ResourceProvider::ResourceId parent_id = map.find(id)->second;
+ ResourceId parent_id = map.find(id)->second;
EXPECT_FALSE(resource_provider_->InUseByConsumer(parent_id));
}
{
sent_to_top_level.clear();
// Parent transfers again to top-level.
ASSERT_TRUE(map.find(id) != map.end());
- ResourceProvider::ResourceId parent_id = map.find(id)->second;
+ ResourceId parent_id = map.find(id)->second;
ResourceProvider::ResourceIdArray resource_ids_to_transfer;
resource_ids_to_transfer.push_back(parent_id);
resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
@@ -1766,7 +1816,7 @@ TEST_P(ResourceProviderTest, UnuseTransferredResources) {
// declared used in the parent.
EXPECT_TRUE(returned_to_child.empty());
ASSERT_TRUE(map.find(id) != map.end());
- ResourceProvider::ResourceId parent_id = map.find(id)->second;
+ ResourceId parent_id = map.find(id)->second;
EXPECT_FALSE(resource_provider_->InUseByConsumer(parent_id));
}
{
@@ -1800,12 +1850,8 @@ class ResourceProviderTestTextureFilters : public ResourceProviderTest {
scoped_ptr<ResourceProvider> child_resource_provider(
ResourceProvider::Create(child_output_surface.get(),
- shared_bitmap_manager.get(),
- NULL,
- NULL,
- 0,
- false,
- 1));
+ shared_bitmap_manager.get(), NULL, NULL, 0,
+ false, 1, false));
scoped_ptr<TextureStateTrackingContext> parent_context_owned(
new TextureStateTrackingContext);
@@ -1818,12 +1864,8 @@ class ResourceProviderTestTextureFilters : public ResourceProviderTest {
scoped_ptr<ResourceProvider> parent_resource_provider(
ResourceProvider::Create(parent_output_surface.get(),
- shared_bitmap_manager.get(),
- NULL,
- NULL,
- 0,
- false,
- 1));
+ shared_bitmap_manager.get(), NULL, NULL, 0,
+ false, 1, false));
gfx::Size size(1, 1);
ResourceFormat format = RGBA_8888;
@@ -1833,7 +1875,7 @@ class ResourceProviderTestTextureFilters : public ResourceProviderTest {
size_t pixel_size = TextureSizeBytes(size, format);
ASSERT_EQ(4U, pixel_size);
- ResourceProvider::ResourceId id = child_resource_provider->CreateResource(
+ ResourceId id = child_resource_provider->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
format);
@@ -1915,7 +1957,7 @@ class ResourceProviderTestTextureFilters : public ResourceProviderTest {
}
ResourceProvider::ResourceIdMap resource_map =
parent_resource_provider->GetChildToParentMap(child_id);
- ResourceProvider::ResourceId mapped_id = resource_map[id];
+ ResourceId mapped_id = resource_map[id];
EXPECT_NE(0u, mapped_id);
// The texture is set to |parent_filter| in the parent.
@@ -1997,10 +2039,9 @@ TEST_P(ResourceProviderTest, TransferMailboxResources) {
&release_sync_point,
&lost_resource,
&main_thread_task_runner);
- ResourceProvider::ResourceId resource =
- resource_provider_->CreateResourceFromTextureMailbox(
- TextureMailbox(mailbox, GL_TEXTURE_2D, sync_point),
- SingleReleaseCallbackImpl::Create(callback));
+ ResourceId resource = resource_provider_->CreateResourceFromTextureMailbox(
+ TextureMailbox(mailbox, GL_TEXTURE_2D, sync_point),
+ SingleReleaseCallbackImpl::Create(callback));
EXPECT_EQ(1u, context()->NumTextures());
EXPECT_EQ(0u, release_sync_point);
{
@@ -2107,10 +2148,8 @@ TEST_P(ResourceProviderTest, TransferMailboxResources) {
TEST_P(ResourceProviderTest, LostResourceInParent) {
gfx::Size size(1, 1);
ResourceFormat format = RGBA_8888;
- ResourceProvider::ResourceId resource =
- child_resource_provider_->CreateResource(
- size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
- format);
+ ResourceId resource = child_resource_provider_->CreateResource(
+ size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
child_resource_provider_->AllocateForTesting(resource);
// Expect a GL resource to be lost.
bool should_lose_resource =
@@ -2164,10 +2203,8 @@ TEST_P(ResourceProviderTest, LostResourceInParent) {
TEST_P(ResourceProviderTest, LostResourceInGrandParent) {
gfx::Size size(1, 1);
ResourceFormat format = RGBA_8888;
- ResourceProvider::ResourceId resource =
- child_resource_provider_->CreateResource(
- size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
- format);
+ ResourceId resource = child_resource_provider_->CreateResource(
+ size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
child_resource_provider_->AllocateForTesting(resource);
ReturnedResourceArray returned_to_child;
@@ -2192,7 +2229,7 @@ TEST_P(ResourceProviderTest, LostResourceInGrandParent) {
{
ResourceProvider::ResourceIdMap resource_map =
resource_provider_->GetChildToParentMap(child_id);
- ResourceProvider::ResourceId parent_resource = resource_map[resource];
+ ResourceId parent_resource = resource_map[resource];
EXPECT_NE(0u, parent_resource);
// Transfer to a grandparent.
@@ -2245,8 +2282,8 @@ TEST_P(ResourceProviderTest, LostMailboxInParent) {
bool lost_resource = false;
bool release_called = false;
uint32 sync_point = 0;
- ResourceProvider::ResourceId resource = CreateChildMailbox(
- &release_sync_point, &lost_resource, &release_called, &sync_point);
+ ResourceId resource = CreateChildMailbox(&release_sync_point, &lost_resource,
+ &release_called, &sync_point);
ReturnedResourceArray returned_to_child;
int child_id =
@@ -2298,8 +2335,8 @@ TEST_P(ResourceProviderTest, LostMailboxInGrandParent) {
bool lost_resource = false;
bool release_called = false;
uint32 sync_point = 0;
- ResourceProvider::ResourceId resource = CreateChildMailbox(
- &release_sync_point, &lost_resource, &release_called, &sync_point);
+ ResourceId resource = CreateChildMailbox(&release_sync_point, &lost_resource,
+ &release_called, &sync_point);
ReturnedResourceArray returned_to_child;
int child_id =
@@ -2323,7 +2360,7 @@ TEST_P(ResourceProviderTest, LostMailboxInGrandParent) {
{
ResourceProvider::ResourceIdMap resource_map =
resource_provider_->GetChildToParentMap(child_id);
- ResourceProvider::ResourceId parent_resource = resource_map[resource];
+ ResourceId parent_resource = resource_map[resource];
EXPECT_NE(0u, parent_resource);
// Transfer to a grandparent.
@@ -2388,8 +2425,8 @@ TEST_P(ResourceProviderTest, ShutdownWithExportedResource) {
bool lost_resource = false;
bool release_called = false;
uint32 sync_point = 0;
- ResourceProvider::ResourceId resource = CreateChildMailbox(
- &release_sync_point, &lost_resource, &release_called, &sync_point);
+ ResourceId resource = CreateChildMailbox(&release_sync_point, &lost_resource,
+ &release_called, &sync_point);
// Transfer the resource, so we can't release it properly on shutdown.
ResourceProvider::ResourceIdArray resource_ids_to_transfer;
@@ -2458,20 +2495,15 @@ TEST_P(ResourceProviderTest, ScopedSampler) {
FakeOutputSurface::Create3d(context_owned.Pass()));
CHECK(output_surface->BindToClient(&output_surface_client));
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(),
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager_.get(),
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false));
gfx::Size size(1, 1);
ResourceFormat format = RGBA_8888;
int texture_id = 1;
- ResourceProvider::ResourceId id = resource_provider->CreateResource(
+ ResourceId id = resource_provider->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
// Check that the texture gets created with the right sampler settings.
@@ -2545,21 +2577,16 @@ TEST_P(ResourceProviderTest, ManagedResource) {
FakeOutputSurface::Create3d(context_owned.Pass()));
CHECK(output_surface->BindToClient(&output_surface_client));
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(),
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager_.get(),
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false));
gfx::Size size(1, 1);
ResourceFormat format = RGBA_8888;
int texture_id = 1;
// Check that the texture gets created with the right sampler settings.
- ResourceProvider::ResourceId id = resource_provider->CreateManagedResource(
+ ResourceId id = resource_provider->CreateManagedResource(
size, GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
@@ -2597,14 +2624,9 @@ TEST_P(ResourceProviderTest, TextureWrapMode) {
FakeOutputSurface::Create3d(context_owned.Pass()));
CHECK(output_surface->BindToClient(&output_surface_client));
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(),
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager_.get(),
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false));
gfx::Size size(1, 1);
ResourceFormat format = RGBA_8888;
@@ -2613,7 +2635,7 @@ TEST_P(ResourceProviderTest, TextureWrapMode) {
for (int texture_id = 1; texture_id <= 2; ++texture_id) {
GLint wrap_mode = texture_id == 1 ? GL_CLAMP_TO_EDGE : GL_REPEAT;
// Check that the texture gets created with the right sampler settings.
- ResourceProvider::ResourceId id = resource_provider->CreateGLTexture(
+ ResourceId id = resource_provider->CreateGLTexture(
size, GL_TEXTURE_2D, texture_pool, wrap_mode,
ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
@@ -2652,14 +2674,9 @@ TEST_P(ResourceProviderTest, TextureHint) {
FakeOutputSurface::Create3d(context_owned.Pass()));
CHECK(output_surface->BindToClient(&output_surface_client));
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(),
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager_.get(),
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false));
gfx::Size size(1, 1);
ResourceFormat format = RGBA_8888;
@@ -2673,13 +2690,9 @@ TEST_P(ResourceProviderTest, TextureHint) {
};
for (GLuint texture_id = 1; texture_id <= arraysize(hints); ++texture_id) {
// Check that the texture gets created with the right sampler settings.
- ResourceProvider::ResourceId id =
- resource_provider->CreateGLTexture(size,
- GL_TEXTURE_2D,
- texture_pool,
- GL_CLAMP_TO_EDGE,
- hints[texture_id - 1],
- format);
+ ResourceId id = resource_provider->CreateGLTexture(
+ size, GL_TEXTURE_2D, texture_pool, GL_CLAMP_TO_EDGE,
+ hints[texture_id - 1], format);
EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
EXPECT_CALL(*context,
texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
@@ -2725,14 +2738,10 @@ TEST_P(ResourceProviderTest, TextureMailbox_SharedMemory) {
new SoftwareOutputDevice)));
CHECK(output_surface->BindToClient(&output_surface_client));
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(),
- main_thread_task_runner_.get(),
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager_.get(),
+ gpu_memory_buffer_manager_.get(), main_thread_task_runner_.get(), 0,
+ false, 1, false));
uint32 release_sync_point = 0;
bool lost_resource = false;
@@ -2744,9 +2753,8 @@ TEST_P(ResourceProviderTest, TextureMailbox_SharedMemory) {
&main_thread_task_runner));
TextureMailbox mailbox(shared_bitmap.get(), size);
- ResourceProvider::ResourceId id =
- resource_provider->CreateResourceFromTextureMailbox(
- mailbox, callback.Pass());
+ ResourceId id = resource_provider->CreateResourceFromTextureMailbox(
+ mailbox, callback.Pass());
EXPECT_NE(0u, id);
{
@@ -2780,14 +2788,9 @@ class ResourceProviderTestTextureMailboxGLFilters
FakeOutputSurface::Create3d(context_owned.Pass()));
CHECK(output_surface->BindToClient(&output_surface_client));
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager,
- gpu_memory_buffer_manager,
- main_thread_task_runner,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager, gpu_memory_buffer_manager,
+ main_thread_task_runner, 0, false, 1, false));
unsigned texture_id = 1;
uint32 sync_point = 30;
@@ -2813,9 +2816,8 @@ class ResourceProviderTestTextureMailboxGLFilters
TextureMailbox mailbox(gpu_mailbox, target, sync_point);
mailbox.set_nearest_neighbor(mailbox_nearest_neighbor);
- ResourceProvider::ResourceId id =
- resource_provider->CreateResourceFromTextureMailbox(mailbox,
- callback.Pass());
+ ResourceId id = resource_provider->CreateResourceFromTextureMailbox(
+ mailbox, callback.Pass());
EXPECT_NE(0u, id);
Mock::VerifyAndClearExpectations(context);
@@ -2929,14 +2931,9 @@ TEST_P(ResourceProviderTest, TextureMailbox_GLTextureExternalOES) {
FakeOutputSurface::Create3d(context_owned.Pass()));
CHECK(output_surface->BindToClient(&output_surface_client));
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(),
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager_.get(),
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false));
uint32 sync_point = 30;
unsigned target = GL_TEXTURE_EXTERNAL_OES;
@@ -2954,9 +2951,8 @@ TEST_P(ResourceProviderTest, TextureMailbox_GLTextureExternalOES) {
TextureMailbox mailbox(gpu_mailbox, target, sync_point);
- ResourceProvider::ResourceId id =
- resource_provider->CreateResourceFromTextureMailbox(
- mailbox, callback.Pass());
+ ResourceId id = resource_provider->CreateResourceFromTextureMailbox(
+ mailbox, callback.Pass());
EXPECT_NE(0u, id);
Mock::VerifyAndClearExpectations(context);
@@ -3004,14 +3000,9 @@ TEST_P(ResourceProviderTest,
FakeOutputSurface::Create3d(context_owned.Pass()));
CHECK(output_surface->BindToClient(&output_surface_client));
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(),
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager_.get(),
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false));
uint32 sync_point = 30;
unsigned target = GL_TEXTURE_2D;
@@ -3029,9 +3020,8 @@ TEST_P(ResourceProviderTest,
TextureMailbox mailbox(gpu_mailbox, target, sync_point);
- ResourceProvider::ResourceId id =
- resource_provider->CreateResourceFromTextureMailbox(mailbox,
- callback.Pass());
+ ResourceId id = resource_provider->CreateResourceFromTextureMailbox(
+ mailbox, callback.Pass());
EXPECT_NE(0u, id);
Mock::VerifyAndClearExpectations(context);
@@ -3063,14 +3053,9 @@ TEST_P(ResourceProviderTest, TextureMailbox_WaitSyncPointIfNeeded_NoSyncPoint) {
FakeOutputSurface::Create3d(context_owned.Pass()));
CHECK(output_surface->BindToClient(&output_surface_client));
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(),
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager_.get(),
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false));
uint32 sync_point = 0;
unsigned target = GL_TEXTURE_2D;
@@ -3088,9 +3073,8 @@ TEST_P(ResourceProviderTest, TextureMailbox_WaitSyncPointIfNeeded_NoSyncPoint) {
TextureMailbox mailbox(gpu_mailbox, target, sync_point);
- ResourceProvider::ResourceId id =
- resource_provider->CreateResourceFromTextureMailbox(mailbox,
- callback.Pass());
+ ResourceId id = resource_provider->CreateResourceFromTextureMailbox(
+ mailbox, callback.Pass());
EXPECT_NE(0u, id);
Mock::VerifyAndClearExpectations(context);
@@ -3189,19 +3173,14 @@ TEST_P(ResourceProviderTest, TextureAllocation) {
FakeOutputSurface::Create3d(context_owned.Pass()));
CHECK(output_surface->BindToClient(&output_surface_client));
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(),
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager_.get(),
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false));
gfx::Size size(2, 2);
gfx::Vector2d offset(0, 0);
ResourceFormat format = RGBA_8888;
- ResourceProvider::ResourceId id = 0;
+ ResourceId id = 0;
uint8_t pixels[16] = { 0 };
int texture_id = 123;
@@ -3268,14 +3247,9 @@ TEST_P(ResourceProviderTest, TextureAllocationHint) {
FakeOutputSurface::Create3d(context_owned.Pass()));
CHECK(output_surface->BindToClient(&output_surface_client));
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(),
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager_.get(),
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false));
gfx::Size size(2, 2);
@@ -3289,7 +3263,7 @@ TEST_P(ResourceProviderTest, TextureAllocationHint) {
for (size_t i = 0; i < arraysize(formats); ++i) {
for (GLuint texture_id = 1; texture_id <= arraysize(hints); ++texture_id) {
// Lazy allocation. Don't allocate when creating the resource.
- ResourceProvider::ResourceId id = resource_provider->CreateResource(
+ ResourceId id = resource_provider->CreateResource(
size, GL_CLAMP_TO_EDGE, hints[texture_id - 1], formats[i]);
EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
@@ -3328,14 +3302,9 @@ TEST_P(ResourceProviderTest, TextureAllocationHint_BGRA) {
FakeOutputSurface::Create3d(context_owned.Pass()));
CHECK(output_surface->BindToClient(&output_surface_client));
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(),
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager_.get(),
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false));
gfx::Size size(2, 2);
const ResourceFormat formats[2] = {RGBA_8888, BGRA_8888};
@@ -3349,7 +3318,7 @@ TEST_P(ResourceProviderTest, TextureAllocationHint_BGRA) {
for (size_t i = 0; i < arraysize(formats); ++i) {
for (GLuint texture_id = 1; texture_id <= arraysize(hints); ++texture_id) {
// Lazy allocation. Don't allocate when creating the resource.
- ResourceProvider::ResourceId id = resource_provider->CreateResource(
+ ResourceId id = resource_provider->CreateResource(
size, GL_CLAMP_TO_EDGE, hints[texture_id - 1], formats[i]);
EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
@@ -3384,17 +3353,12 @@ TEST_P(ResourceProviderTest, PixelBuffer_GLTexture) {
gfx::Size size(2, 2);
ResourceFormat format = RGBA_8888;
- ResourceProvider::ResourceId id = 0;
+ ResourceId id = 0;
int texture_id = 123;
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(),
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager_.get(),
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false));
id = resource_provider->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
@@ -3431,17 +3395,12 @@ TEST_P(ResourceProviderTest, ForcingAsyncUploadToComplete) {
gfx::Size size(2, 2);
ResourceFormat format = RGBA_8888;
- ResourceProvider::ResourceId id = 0;
+ ResourceId id = 0;
int texture_id = 123;
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(),
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager_.get(),
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false));
id = resource_provider->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
@@ -3478,17 +3437,12 @@ TEST_P(ResourceProviderTest, PixelBufferLostContext) {
gfx::Size size(2, 2);
ResourceFormat format = RGBA_8888;
- ResourceProvider::ResourceId id = 0;
+ ResourceId id = 0;
int texture_id = 123;
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(),
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager_.get(),
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false));
EXPECT_CALL(*context, NextTextureId()).WillRepeatedly(Return(texture_id));
@@ -3522,22 +3476,23 @@ TEST_P(ResourceProviderTest, Image_GLTexture) {
const int kHeight = 2;
gfx::Size size(kWidth, kHeight);
ResourceFormat format = RGBA_8888;
- ResourceProvider::ResourceId id = 0;
+ ResourceId id = 0;
const unsigned kTextureId = 123u;
const unsigned kImageId = 234u;
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(),
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager_.get(),
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false));
id = resource_provider->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
+ EXPECT_CALL(*context, NextTextureId())
+ .WillOnce(Return(kTextureId))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kTextureId))
+ .Times(1)
+ .RetiresOnSaturation();
EXPECT_CALL(*context, createImageCHROMIUM(_, kWidth, kHeight, GL_RGBA))
.WillOnce(Return(kImageId))
.RetiresOnSaturation();
@@ -3547,11 +3502,8 @@ TEST_P(ResourceProviderTest, Image_GLTexture) {
EXPECT_TRUE(lock.GetGpuMemoryBuffer());
}
- EXPECT_CALL(*context, NextTextureId())
- .WillOnce(Return(kTextureId))
- .RetiresOnSaturation();
- // Once in CreateTextureId and once in BindForSampling
- EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kTextureId)).Times(2)
+ EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kTextureId))
+ .Times(1)
.RetiresOnSaturation();
EXPECT_CALL(*context, bindTexImage2DCHROMIUM(GL_TEXTURE_2D, kImageId))
.Times(1)
@@ -3607,24 +3559,25 @@ TEST_P(ResourceProviderTest, CopyResource_GLTexture) {
const int kHeight = 2;
gfx::Size size(kWidth, kHeight);
ResourceFormat format = RGBA_8888;
- ResourceProvider::ResourceId source_id = 0;
- ResourceProvider::ResourceId dest_id = 0;
+ ResourceId source_id = 0;
+ ResourceId dest_id = 0;
const unsigned kSourceTextureId = 123u;
const unsigned kDestTextureId = 321u;
const unsigned kImageId = 234u;
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(),
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager_.get(),
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false));
source_id = resource_provider->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
+ EXPECT_CALL(*context, NextTextureId())
+ .WillOnce(Return(kSourceTextureId))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kSourceTextureId))
+ .Times(1)
+ .RetiresOnSaturation();
EXPECT_CALL(*context, createImageCHROMIUM(_, kWidth, kHeight, GL_RGBA))
.WillOnce(Return(kImageId))
.RetiresOnSaturation();
@@ -3648,16 +3601,13 @@ TEST_P(ResourceProviderTest, CopyResource_GLTexture) {
GL_UNSIGNED_BYTE, nullptr))
.Times(1)
.RetiresOnSaturation();
- EXPECT_CALL(*context, NextTextureId())
- .WillOnce(Return(kSourceTextureId))
- .RetiresOnSaturation();
EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kSourceTextureId))
- .Times(2)
+ .Times(1)
.RetiresOnSaturation();
EXPECT_CALL(*context, bindTexImage2DCHROMIUM(GL_TEXTURE_2D, kImageId))
.Times(1)
.RetiresOnSaturation();
- resource_provider->CopyResource(source_id, dest_id);
+ resource_provider->CopyResource(source_id, dest_id, gfx::Rect(size));
Mock::VerifyAndClearExpectations(context);
EXPECT_CALL(*context, destroyImageCHROMIUM(kImageId))
@@ -3688,17 +3638,12 @@ TEST_P(ResourceProviderTest, CompressedTextureETC1Allocate) {
CHECK(output_surface->BindToClient(&output_surface_client));
gfx::Size size(4, 4);
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(),
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager_.get(),
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false));
int texture_id = 123;
- ResourceProvider::ResourceId id = resource_provider->CreateResource(
+ ResourceId id = resource_provider->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, ETC1);
EXPECT_NE(0u, id);
EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
@@ -3724,18 +3669,13 @@ TEST_P(ResourceProviderTest, CompressedTextureETC1Upload) {
CHECK(output_surface->BindToClient(&output_surface_client));
gfx::Size size(4, 4);
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(),
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager_.get(),
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false));
int texture_id = 123;
uint8_t pixels[8];
- ResourceProvider::ResourceId id = resource_provider->CreateResource(
+ ResourceId id = resource_provider->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, ETC1);
EXPECT_NE(0u, id);
EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
@@ -3785,16 +3725,11 @@ TEST(ResourceProviderTest, TextureAllocationChunkSize) {
{
size_t kTextureAllocationChunkSize = 1;
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager.get(),
- NULL,
- NULL,
- 0,
- false,
- kTextureAllocationChunkSize));
-
- ResourceProvider::ResourceId id = resource_provider->CreateResource(
+ scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager.get(), NULL, NULL, 0, false,
+ kTextureAllocationChunkSize, false));
+
+ ResourceId id = resource_provider->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
format);
resource_provider->AllocateForTesting(id);
@@ -3806,16 +3741,11 @@ TEST(ResourceProviderTest, TextureAllocationChunkSize) {
{
size_t kTextureAllocationChunkSize = 8;
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager.get(),
- NULL,
- NULL,
- 0,
- false,
- kTextureAllocationChunkSize));
-
- ResourceProvider::ResourceId id = resource_provider->CreateResource(
+ scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager.get(), NULL, NULL, 0, false,
+ kTextureAllocationChunkSize, false));
+
+ ResourceId id = resource_provider->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
format);
resource_provider->AllocateForTesting(id);
diff --git a/chromium/cc/resources/resource_update.cc b/chromium/cc/resources/resource_update.cc
deleted file mode 100644
index 2fe8fe5eebe..00000000000
--- a/chromium/cc/resources/resource_update.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/resources/resource_update.h"
-
-#include "base/logging.h"
-
-namespace cc {
-
-ResourceUpdate ResourceUpdate::Create(PrioritizedResource* resource,
- const SkBitmap* bitmap,
- const gfx::Rect& content_rect,
- const gfx::Rect& source_rect,
- const gfx::Vector2d& dest_offset) {
- CHECK(content_rect.Contains(source_rect));
- ResourceUpdate update;
- update.texture = resource;
- update.bitmap = bitmap;
- update.content_rect = content_rect;
- update.source_rect = source_rect;
- update.dest_offset = dest_offset;
- return update;
-}
-
-ResourceUpdate::ResourceUpdate()
- : texture(NULL),
- bitmap(NULL) {}
-
-ResourceUpdate::~ResourceUpdate() {}
-
-} // namespace cc
diff --git a/chromium/cc/resources/resource_update.h b/chromium/cc/resources/resource_update.h
deleted file mode 100644
index d49114171d4..00000000000
--- a/chromium/cc/resources/resource_update.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_RESOURCES_RESOURCE_UPDATE_H_
-#define CC_RESOURCES_RESOURCE_UPDATE_H_
-
-#include "cc/base/cc_export.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/vector2d.h"
-
-class SkBitmap;
-
-namespace cc {
-
-class PrioritizedResource;
-
-struct CC_EXPORT ResourceUpdate {
- static ResourceUpdate Create(PrioritizedResource* resource,
- const SkBitmap* bitmap,
- const gfx::Rect& content_rect,
- const gfx::Rect& source_rect,
- const gfx::Vector2d& dest_offset);
-
- ResourceUpdate();
- virtual ~ResourceUpdate();
-
- PrioritizedResource* texture;
- const SkBitmap* bitmap;
- gfx::Rect content_rect;
- gfx::Rect source_rect;
- gfx::Vector2d dest_offset;
-};
-
-} // namespace cc
-
-#endif // CC_RESOURCES_RESOURCE_UPDATE_H_
diff --git a/chromium/cc/resources/resource_update_controller.cc b/chromium/cc/resources/resource_update_controller.cc
deleted file mode 100644
index bd6d21df612..00000000000
--- a/chromium/cc/resources/resource_update_controller.cc
+++ /dev/null
@@ -1,164 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/resources/resource_update_controller.h"
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/single_thread_task_runner.h"
-#include "cc/resources/prioritized_resource.h"
-#include "cc/resources/resource_provider.h"
-#include "ui/gfx/frame_time.h"
-
-namespace {
-
-// Number of partial updates we allow.
-const size_t kPartialTextureUpdatesMax = 12;
-
-// Measured in seconds.
-const double kUploaderBusyTickRate = 0.001;
-
-// Number of blocking update intervals to allow.
-const size_t kMaxBlockingUpdateIntervals = 4;
-
-} // namespace
-
-namespace cc {
-
-size_t ResourceUpdateController::MaxPartialTextureUpdates() {
- return kPartialTextureUpdatesMax;
-}
-
-size_t ResourceUpdateController::MaxFullUpdatesPerTick(
- ResourceProvider* resource_provider) {
- return resource_provider->EstimatedUploadsPerTick();
-}
-
-ResourceUpdateController::ResourceUpdateController(
- ResourceUpdateControllerClient* client,
- base::SingleThreadTaskRunner* task_runner,
- scoped_ptr<ResourceUpdateQueue> queue,
- ResourceProvider* resource_provider)
- : client_(client),
- queue_(queue.Pass()),
- resource_provider_(resource_provider),
- texture_updates_per_tick_(MaxFullUpdatesPerTick(resource_provider)),
- first_update_attempt_(true),
- task_runner_(task_runner),
- task_posted_(false),
- ready_to_finalize_(false),
- weak_factory_(this) {}
-
-ResourceUpdateController::~ResourceUpdateController() {}
-
-void ResourceUpdateController::PerformMoreUpdates(
- base::TimeTicks time_limit) {
- time_limit_ = time_limit;
-
- // Update already in progress or we are already done.
- if (task_posted_ || ready_to_finalize_)
- return;
-
- // Call UpdateMoreTexturesNow() directly unless it's the first update
- // attempt. This ensures that we empty the update queue in a finite
- // amount of time.
- if (!first_update_attempt_)
- UpdateMoreTexturesNow();
-
- // Post a 0-delay task when no updates were left. When it runs,
- // ReadyToFinalizeTextureUpdates() will be called.
- if (!UpdateMoreTexturesIfEnoughTimeRemaining()) {
- task_posted_ = true;
- task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&ResourceUpdateController::OnTimerFired,
- weak_factory_.GetWeakPtr()));
- }
-
- first_update_attempt_ = false;
-}
-
-void ResourceUpdateController::DiscardUploadsToEvictedResources() {
- queue_->ClearUploadsToEvictedResources();
-}
-
-void ResourceUpdateController::UpdateTexture(ResourceUpdate update) {
- update.bitmap->lockPixels();
- update.texture->SetPixels(
- resource_provider_,
- static_cast<const uint8_t*>(update.bitmap->getPixels()),
- update.content_rect,
- update.source_rect,
- update.dest_offset);
- update.bitmap->unlockPixels();
-}
-
-void ResourceUpdateController::Finalize() {
- while (queue_->FullUploadSize())
- UpdateTexture(queue_->TakeFirstFullUpload());
-
- while (queue_->PartialUploadSize())
- UpdateTexture(queue_->TakeFirstPartialUpload());
-
- resource_provider_->FlushUploads();
-}
-
-void ResourceUpdateController::OnTimerFired() {
- task_posted_ = false;
- if (!UpdateMoreTexturesIfEnoughTimeRemaining()) {
- ready_to_finalize_ = true;
- client_->ReadyToFinalizeTextureUpdates();
- }
-}
-
-base::TimeTicks ResourceUpdateController::UpdateMoreTexturesCompletionTime() {
- return resource_provider_->EstimatedUploadCompletionTime(
- texture_updates_per_tick_);
-}
-
-size_t ResourceUpdateController::UpdateMoreTexturesSize() const {
- return texture_updates_per_tick_;
-}
-
-size_t ResourceUpdateController::MaxBlockingUpdates() const {
- return UpdateMoreTexturesSize() * kMaxBlockingUpdateIntervals;
-}
-
-bool ResourceUpdateController::UpdateMoreTexturesIfEnoughTimeRemaining() {
- while (resource_provider_->NumBlockingUploads() < MaxBlockingUpdates()) {
- if (!queue_->FullUploadSize())
- return false;
-
- if (!time_limit_.is_null()) {
- base::TimeTicks completion_time = UpdateMoreTexturesCompletionTime();
- if (completion_time > time_limit_)
- return true;
- }
-
- UpdateMoreTexturesNow();
- }
-
- task_posted_ = true;
- task_runner_->PostDelayedTask(
- FROM_HERE,
- base::Bind(&ResourceUpdateController::OnTimerFired,
- weak_factory_.GetWeakPtr()),
- base::TimeDelta::FromMilliseconds(kUploaderBusyTickRate * 1000));
- return true;
-}
-
-void ResourceUpdateController::UpdateMoreTexturesNow() {
- size_t uploads = std::min(
- queue_->FullUploadSize(), UpdateMoreTexturesSize());
-
- if (!uploads)
- return;
-
- while (queue_->FullUploadSize() && uploads--)
- UpdateTexture(queue_->TakeFirstFullUpload());
-
- resource_provider_->FlushUploads();
-}
-
-} // namespace cc
diff --git a/chromium/cc/resources/resource_update_controller.h b/chromium/cc/resources/resource_update_controller.h
deleted file mode 100644
index 1946df47c16..00000000000
--- a/chromium/cc/resources/resource_update_controller.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_RESOURCES_RESOURCE_UPDATE_CONTROLLER_H_
-#define CC_RESOURCES_RESOURCE_UPDATE_CONTROLLER_H_
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "base/time/time.h"
-#include "cc/base/cc_export.h"
-#include "cc/resources/resource_update_queue.h"
-
-namespace base { class SingleThreadTaskRunner; }
-
-namespace cc {
-
-class ResourceProvider;
-
-class ResourceUpdateControllerClient {
- public:
- virtual void ReadyToFinalizeTextureUpdates() = 0;
-
- protected:
- virtual ~ResourceUpdateControllerClient() {}
-};
-
-class CC_EXPORT ResourceUpdateController {
- public:
- static scoped_ptr<ResourceUpdateController> Create(
- ResourceUpdateControllerClient* client,
- base::SingleThreadTaskRunner* task_runner,
- scoped_ptr<ResourceUpdateQueue> queue,
- ResourceProvider* resource_provider) {
- return make_scoped_ptr(new ResourceUpdateController(
- client, task_runner, queue.Pass(), resource_provider));
- }
- static size_t MaxPartialTextureUpdates();
-
- virtual ~ResourceUpdateController();
-
- // Discard uploads to textures that were evicted on the impl thread.
- void DiscardUploadsToEvictedResources();
-
- void PerformMoreUpdates(base::TimeTicks time_limit);
- void Finalize();
-
-
- // Virtual for testing.
- virtual size_t UpdateMoreTexturesSize() const;
- virtual base::TimeTicks UpdateMoreTexturesCompletionTime();
-
- protected:
- ResourceUpdateController(ResourceUpdateControllerClient* client,
- base::SingleThreadTaskRunner* task_runner,
- scoped_ptr<ResourceUpdateQueue> queue,
- ResourceProvider* resource_provider);
-
- private:
- static size_t MaxFullUpdatesPerTick(ResourceProvider* resource_provider);
-
- size_t MaxBlockingUpdates() const;
-
- void UpdateTexture(ResourceUpdate update);
-
- // This returns true when there were textures left to update.
- bool UpdateMoreTexturesIfEnoughTimeRemaining();
- void UpdateMoreTexturesNow();
- void OnTimerFired();
-
- ResourceUpdateControllerClient* client_;
- scoped_ptr<ResourceUpdateQueue> queue_;
- ResourceProvider* resource_provider_;
- base::TimeTicks time_limit_;
- size_t texture_updates_per_tick_;
- bool first_update_attempt_;
- base::SingleThreadTaskRunner* task_runner_;
- bool task_posted_;
- bool ready_to_finalize_;
- base::WeakPtrFactory<ResourceUpdateController> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(ResourceUpdateController);
-};
-
-} // namespace cc
-
-#endif // CC_RESOURCES_RESOURCE_UPDATE_CONTROLLER_H_
diff --git a/chromium/cc/resources/resource_update_controller_unittest.cc b/chromium/cc/resources/resource_update_controller_unittest.cc
deleted file mode 100644
index 1aa0902d469..00000000000
--- a/chromium/cc/resources/resource_update_controller_unittest.cc
+++ /dev/null
@@ -1,516 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/resources/resource_update_controller.h"
-
-#include "base/test/test_simple_task_runner.h"
-#include "cc/resources/prioritized_resource_manager.h"
-#include "cc/test/fake_output_surface.h"
-#include "cc/test/fake_output_surface_client.h"
-#include "cc/test/fake_proxy.h"
-#include "cc/test/scheduler_test_common.h"
-#include "cc/test/test_shared_bitmap_manager.h"
-#include "cc/test/test_web_graphics_context_3d.h"
-#include "cc/test/tiled_layer_test_common.h"
-#include "cc/trees/single_thread_proxy.h" // For DebugScopedSetImplThread
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/khronos/GLES2/gl2ext.h"
-
-using testing::Test;
-
-namespace cc {
-namespace {
-
-const int kFlushPeriodFull = 4;
-const int kFlushPeriodPartial = kFlushPeriodFull;
-
-class ResourceUpdateControllerTest;
-
-class WebGraphicsContext3DForUploadTest : public TestWebGraphicsContext3D {
- public:
- explicit WebGraphicsContext3DForUploadTest(ResourceUpdateControllerTest* test)
- : test_(test) {}
-
- void flush() override;
- void shallowFlushCHROMIUM() override;
- void texSubImage2D(GLenum target,
- GLint level,
- GLint xoffset,
- GLint yoffset,
- GLsizei width,
- GLsizei height,
- GLenum format,
- GLenum type,
- const void* pixels) override;
-
- void getQueryObjectuivEXT(GLuint id, GLenum pname, GLuint* value) override;
-
- private:
- ResourceUpdateControllerTest* test_;
-};
-
-class ResourceUpdateControllerTest : public Test {
- public:
- ResourceUpdateControllerTest()
- : proxy_(),
- queue_(make_scoped_ptr(new ResourceUpdateQueue)),
- resource_manager_(PrioritizedResourceManager::Create(&proxy_)),
- query_results_available_(0),
- full_upload_count_expected_(0),
- partial_count_expected_(0),
- total_upload_count_expected_(0),
- max_upload_count_per_update_(0),
- num_consecutive_flushes_(0),
- num_dangling_uploads_(0),
- num_total_uploads_(0),
- num_total_flushes_(0) {}
-
- ~ResourceUpdateControllerTest() override {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- resource_manager_->ClearAllMemory(resource_provider_.get());
- }
-
- public:
- void OnFlush() {
- // Check for back-to-back flushes.
- EXPECT_EQ(0, num_consecutive_flushes_) << "Back-to-back flushes detected.";
-
- num_dangling_uploads_ = 0;
- num_consecutive_flushes_++;
- num_total_flushes_++;
- }
-
- void OnUpload() {
- // Check for too many consecutive uploads
- if (num_total_uploads_ < full_upload_count_expected_) {
- EXPECT_LT(num_dangling_uploads_, kFlushPeriodFull)
- << "Too many consecutive full uploads detected.";
- } else {
- EXPECT_LT(num_dangling_uploads_, kFlushPeriodPartial)
- << "Too many consecutive partial uploads detected.";
- }
-
- num_consecutive_flushes_ = 0;
- num_dangling_uploads_++;
- num_total_uploads_++;
- }
-
- bool IsQueryResultAvailable() {
- if (!query_results_available_)
- return false;
-
- query_results_available_--;
- return true;
- }
-
- protected:
- void SetUp() override {
- bitmap_.allocN32Pixels(300, 150);
-
- for (int i = 0; i < 4; i++) {
- textures_[i] = PrioritizedResource::Create(resource_manager_.get(),
- gfx::Size(300, 150),
- RGBA_8888);
- textures_[i]->
- set_request_priority(PriorityCalculator::VisiblePriority(true));
- }
- resource_manager_->PrioritizeTextures();
-
- output_surface_ = FakeOutputSurface::Create3d(
- scoped_ptr<TestWebGraphicsContext3D>(
- new WebGraphicsContext3DForUploadTest(this)));
- CHECK(output_surface_->BindToClient(&output_surface_client_));
-
- shared_bitmap_manager_.reset(new TestSharedBitmapManager());
- resource_provider_ = ResourceProvider::Create(output_surface_.get(),
- shared_bitmap_manager_.get(),
- NULL,
- NULL,
- 0,
- false,
- 1);
- }
-
- void AppendFullUploadsOfIndexedTextureToUpdateQueue(int count,
- int texture_index) {
- full_upload_count_expected_ += count;
- total_upload_count_expected_ += count;
-
- const gfx::Rect rect(0, 0, 300, 150);
- const ResourceUpdate upload = ResourceUpdate::Create(
- textures_[texture_index].get(), &bitmap_, rect, rect, gfx::Vector2d());
- for (int i = 0; i < count; i++)
- queue_->AppendFullUpload(upload);
- }
-
- void AppendFullUploadsToUpdateQueue(int count) {
- AppendFullUploadsOfIndexedTextureToUpdateQueue(count, 0);
- }
-
- void AppendPartialUploadsOfIndexedTextureToUpdateQueue(int count,
- int texture_index) {
- partial_count_expected_ += count;
- total_upload_count_expected_ += count;
-
- const gfx::Rect rect(0, 0, 100, 100);
- const ResourceUpdate upload = ResourceUpdate::Create(
- textures_[texture_index].get(), &bitmap_, rect, rect, gfx::Vector2d());
- for (int i = 0; i < count; i++)
- queue_->AppendPartialUpload(upload);
- }
-
- void AppendPartialUploadsToUpdateQueue(int count) {
- AppendPartialUploadsOfIndexedTextureToUpdateQueue(count, 0);
- }
-
- void SetMaxUploadCountPerUpdate(int count) {
- max_upload_count_per_update_ = count;
- }
-
- void UpdateTextures() {
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- scoped_ptr<ResourceUpdateController> update_controller =
- ResourceUpdateController::Create(NULL,
- proxy_.ImplThreadTaskRunner(),
- queue_.Pass(),
- resource_provider_.get());
- update_controller->Finalize();
- }
-
- void MakeQueryResultAvailable() { query_results_available_++; }
-
- protected:
- // Classes required to interact and test the ResourceUpdateController
- FakeProxy proxy_;
- FakeOutputSurfaceClient output_surface_client_;
- scoped_ptr<OutputSurface> output_surface_;
- scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
- scoped_ptr<ResourceProvider> resource_provider_;
- scoped_ptr<ResourceUpdateQueue> queue_;
- scoped_ptr<PrioritizedResource> textures_[4];
- scoped_ptr<PrioritizedResourceManager> resource_manager_;
- SkBitmap bitmap_;
- int query_results_available_;
-
- // Properties / expectations of this test
- int full_upload_count_expected_;
- int partial_count_expected_;
- int total_upload_count_expected_;
- int max_upload_count_per_update_;
-
- // Dynamic properties of this test
- int num_consecutive_flushes_;
- int num_dangling_uploads_;
- int num_total_uploads_;
- int num_total_flushes_;
-};
-
-void WebGraphicsContext3DForUploadTest::flush() { test_->OnFlush(); }
-
-void WebGraphicsContext3DForUploadTest::shallowFlushCHROMIUM() {
- test_->OnFlush();
-}
-
-void WebGraphicsContext3DForUploadTest::texSubImage2D(GLenum target,
- GLint level,
- GLint xoffset,
- GLint yoffset,
- GLsizei width,
- GLsizei height,
- GLenum format,
- GLenum type,
- const void* pixels) {
- test_->OnUpload();
-}
-
-void WebGraphicsContext3DForUploadTest::getQueryObjectuivEXT(GLuint id,
- GLenum pname,
- GLuint* params) {
- if (pname == GL_QUERY_RESULT_AVAILABLE_EXT)
- *params = test_->IsQueryResultAvailable();
-}
-
-// ZERO UPLOADS TESTS
-TEST_F(ResourceUpdateControllerTest, ZeroUploads) {
- AppendFullUploadsToUpdateQueue(0);
- AppendPartialUploadsToUpdateQueue(0);
- UpdateTextures();
-
- EXPECT_EQ(0, num_total_flushes_);
- EXPECT_EQ(0, num_total_uploads_);
-}
-
-// ONE UPLOAD TESTS
-TEST_F(ResourceUpdateControllerTest, OneFullUpload) {
- AppendFullUploadsToUpdateQueue(1);
- AppendPartialUploadsToUpdateQueue(0);
- UpdateTextures();
-
- EXPECT_EQ(1, num_total_flushes_);
- EXPECT_EQ(1, num_total_uploads_);
- EXPECT_EQ(0, num_dangling_uploads_)
- << "Last upload wasn't followed by a flush.";
-}
-
-TEST_F(ResourceUpdateControllerTest, OnePartialUpload) {
- AppendFullUploadsToUpdateQueue(0);
- AppendPartialUploadsToUpdateQueue(1);
- UpdateTextures();
-
- EXPECT_EQ(1, num_total_flushes_);
- EXPECT_EQ(1, num_total_uploads_);
- EXPECT_EQ(0, num_dangling_uploads_)
- << "Last upload wasn't followed by a flush.";
-}
-
-TEST_F(ResourceUpdateControllerTest, OneFullOnePartialUpload) {
- AppendFullUploadsToUpdateQueue(1);
- AppendPartialUploadsToUpdateQueue(1);
- UpdateTextures();
-
- EXPECT_EQ(1, num_total_flushes_);
- EXPECT_EQ(2, num_total_uploads_);
- EXPECT_EQ(0, num_dangling_uploads_)
- << "Last upload wasn't followed by a flush.";
-}
-
-// This class of tests upload a number of textures that is a multiple
-// of the flush period.
-const int full_upload_flush_multipler = 7;
-const int full_count = full_upload_flush_multipler * kFlushPeriodFull;
-
-const int partial_upload_flush_multipler = 11;
-const int partial_count =
- partial_upload_flush_multipler * kFlushPeriodPartial;
-
-TEST_F(ResourceUpdateControllerTest, ManyFullUploads) {
- AppendFullUploadsToUpdateQueue(full_count);
- AppendPartialUploadsToUpdateQueue(0);
- UpdateTextures();
-
- EXPECT_EQ(full_upload_flush_multipler, num_total_flushes_);
- EXPECT_EQ(full_count, num_total_uploads_);
- EXPECT_EQ(0, num_dangling_uploads_)
- << "Last upload wasn't followed by a flush.";
-}
-
-TEST_F(ResourceUpdateControllerTest, ManyPartialUploads) {
- AppendFullUploadsToUpdateQueue(0);
- AppendPartialUploadsToUpdateQueue(partial_count);
- UpdateTextures();
-
- EXPECT_EQ(partial_upload_flush_multipler, num_total_flushes_);
- EXPECT_EQ(partial_count, num_total_uploads_);
- EXPECT_EQ(0, num_dangling_uploads_)
- << "Last upload wasn't followed by a flush.";
-}
-
-TEST_F(ResourceUpdateControllerTest, ManyFullManyPartialUploads) {
- AppendFullUploadsToUpdateQueue(full_count);
- AppendPartialUploadsToUpdateQueue(partial_count);
- UpdateTextures();
-
- EXPECT_EQ(full_upload_flush_multipler + partial_upload_flush_multipler,
- num_total_flushes_);
- EXPECT_EQ(full_count + partial_count, num_total_uploads_);
- EXPECT_EQ(0, num_dangling_uploads_)
- << "Last upload wasn't followed by a flush.";
-}
-
-class FakeResourceUpdateControllerClient
- : public ResourceUpdateControllerClient {
- public:
- FakeResourceUpdateControllerClient() { Reset(); }
- void Reset() { ready_to_finalize_called_ = false; }
- bool ReadyToFinalizeCalled() const { return ready_to_finalize_called_; }
-
- void ReadyToFinalizeTextureUpdates() override {
- ready_to_finalize_called_ = true;
- }
-
- protected:
- bool ready_to_finalize_called_;
-};
-
-class FakeResourceUpdateController : public ResourceUpdateController {
- public:
- static scoped_ptr<FakeResourceUpdateController> Create(
- ResourceUpdateControllerClient* client,
- base::TestSimpleTaskRunner* task_runner,
- scoped_ptr<ResourceUpdateQueue> queue,
- ResourceProvider* resource_provider) {
- return make_scoped_ptr(new FakeResourceUpdateController(
- client, task_runner, queue.Pass(), resource_provider));
- }
-
- void SetNow(base::TimeTicks time) { now_ = time; }
- base::TimeTicks Now() const { return now_; }
- void SetUpdateTextureTime(base::TimeDelta time) {
- update_textures_time_ = time;
- }
- base::TimeTicks UpdateMoreTexturesCompletionTime() override {
- size_t total_updates =
- resource_provider_->NumBlockingUploads() + update_more_textures_size_;
- return now_ + total_updates * update_textures_time_;
- }
- void SetUpdateMoreTexturesSize(size_t size) {
- update_more_textures_size_ = size;
- }
- size_t UpdateMoreTexturesSize() const override {
- return update_more_textures_size_;
- }
-
- protected:
- FakeResourceUpdateController(ResourceUpdateControllerClient* client,
- base::TestSimpleTaskRunner* task_runner,
- scoped_ptr<ResourceUpdateQueue> queue,
- ResourceProvider* resource_provider)
- : ResourceUpdateController(
- client, task_runner, queue.Pass(), resource_provider),
- resource_provider_(resource_provider),
- update_more_textures_size_(0) {}
-
- ResourceProvider* resource_provider_;
- base::TimeTicks now_;
- base::TimeDelta update_textures_time_;
- size_t update_more_textures_size_;
-};
-
-static void RunPendingTask(base::TestSimpleTaskRunner* task_runner,
- FakeResourceUpdateController* controller) {
- EXPECT_TRUE(task_runner->HasPendingTask());
- controller->SetNow(controller->Now() + task_runner->NextPendingTaskDelay());
- task_runner->RunPendingTasks();
-}
-
-TEST_F(ResourceUpdateControllerTest, UpdateMoreTextures) {
- FakeResourceUpdateControllerClient client;
- scoped_refptr<base::TestSimpleTaskRunner> task_runner =
- new base::TestSimpleTaskRunner;
-
- SetMaxUploadCountPerUpdate(1);
- AppendFullUploadsToUpdateQueue(3);
- AppendPartialUploadsToUpdateQueue(0);
-
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- scoped_ptr<FakeResourceUpdateController> controller(
- FakeResourceUpdateController::Create(&client,
- task_runner.get(),
- queue_.Pass(),
- resource_provider_.get()));
-
- controller->SetNow(controller->Now() + base::TimeDelta::FromMilliseconds(1));
- controller->SetUpdateTextureTime(base::TimeDelta::FromMilliseconds(100));
- controller->SetUpdateMoreTexturesSize(1);
- // Not enough time for any updates.
- controller->PerformMoreUpdates(controller->Now() +
- base::TimeDelta::FromMilliseconds(90));
- EXPECT_FALSE(task_runner->HasPendingTask());
-
- controller->SetUpdateTextureTime(base::TimeDelta::FromMilliseconds(100));
- controller->SetUpdateMoreTexturesSize(1);
- // Only enough time for 1 update.
- controller->PerformMoreUpdates(controller->Now() +
- base::TimeDelta::FromMilliseconds(120));
- EXPECT_FALSE(task_runner->HasPendingTask());
- EXPECT_EQ(1, num_total_uploads_);
-
- // Complete one upload.
- MakeQueryResultAvailable();
-
- controller->SetUpdateTextureTime(base::TimeDelta::FromMilliseconds(100));
- controller->SetUpdateMoreTexturesSize(1);
- // Enough time for 2 updates.
- controller->PerformMoreUpdates(controller->Now() +
- base::TimeDelta::FromMilliseconds(220));
- RunPendingTask(task_runner.get(), controller.get());
- EXPECT_FALSE(task_runner->HasPendingTask());
- EXPECT_TRUE(client.ReadyToFinalizeCalled());
- EXPECT_EQ(3, num_total_uploads_);
-}
-
-TEST_F(ResourceUpdateControllerTest, NoMoreUpdates) {
- FakeResourceUpdateControllerClient client;
- scoped_refptr<base::TestSimpleTaskRunner> task_runner =
- new base::TestSimpleTaskRunner;
-
- SetMaxUploadCountPerUpdate(1);
- AppendFullUploadsToUpdateQueue(2);
- AppendPartialUploadsToUpdateQueue(0);
-
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- scoped_ptr<FakeResourceUpdateController> controller(
- FakeResourceUpdateController::Create(&client,
- task_runner.get(),
- queue_.Pass(),
- resource_provider_.get()));
-
- controller->SetNow(controller->Now() + base::TimeDelta::FromMilliseconds(1));
- controller->SetUpdateTextureTime(base::TimeDelta::FromMilliseconds(100));
- controller->SetUpdateMoreTexturesSize(1);
- // Enough time for 3 updates but only 2 necessary.
- controller->PerformMoreUpdates(controller->Now() +
- base::TimeDelta::FromMilliseconds(310));
- RunPendingTask(task_runner.get(), controller.get());
- EXPECT_FALSE(task_runner->HasPendingTask());
- EXPECT_TRUE(client.ReadyToFinalizeCalled());
- EXPECT_EQ(2, num_total_uploads_);
-
- client.Reset();
- controller->SetUpdateTextureTime(base::TimeDelta::FromMilliseconds(100));
- controller->SetUpdateMoreTexturesSize(1);
- // Enough time for updates but no more updates left.
- controller->PerformMoreUpdates(controller->Now() +
- base::TimeDelta::FromMilliseconds(310));
-
- // ReadyToFinalizeTextureUpdates should only be called once.
- EXPECT_FALSE(task_runner->HasPendingTask());
- EXPECT_FALSE(client.ReadyToFinalizeCalled());
- EXPECT_EQ(2, num_total_uploads_);
-}
-
-TEST_F(ResourceUpdateControllerTest, UpdatesCompleteInFiniteTime) {
- FakeResourceUpdateControllerClient client;
- scoped_refptr<base::TestSimpleTaskRunner> task_runner =
- new base::TestSimpleTaskRunner;
-
- SetMaxUploadCountPerUpdate(1);
- AppendFullUploadsToUpdateQueue(2);
- AppendPartialUploadsToUpdateQueue(0);
-
- DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
- scoped_ptr<FakeResourceUpdateController> controller(
- FakeResourceUpdateController::Create(&client,
- task_runner.get(),
- queue_.Pass(),
- resource_provider_.get()));
-
- controller->SetNow(controller->Now() + base::TimeDelta::FromMilliseconds(1));
- controller->SetUpdateTextureTime(base::TimeDelta::FromMilliseconds(500));
- controller->SetUpdateMoreTexturesSize(1);
-
- for (int i = 0; i < 100; i++) {
- if (client.ReadyToFinalizeCalled())
- break;
-
- // Not enough time for any updates.
- controller->PerformMoreUpdates(controller->Now() +
- base::TimeDelta::FromMilliseconds(400));
-
- if (task_runner->HasPendingTask())
- RunPendingTask(task_runner.get(), controller.get());
- }
-
- EXPECT_FALSE(task_runner->HasPendingTask());
- EXPECT_TRUE(client.ReadyToFinalizeCalled());
- EXPECT_EQ(2, num_total_uploads_);
-}
-
-} // namespace
-} // namespace cc
diff --git a/chromium/cc/resources/resource_update_queue.cc b/chromium/cc/resources/resource_update_queue.cc
deleted file mode 100644
index 31727cd808c..00000000000
--- a/chromium/cc/resources/resource_update_queue.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/resources/resource_update_queue.h"
-
-#include "cc/resources/prioritized_resource.h"
-
-namespace cc {
-
-ResourceUpdateQueue::ResourceUpdateQueue() {}
-
-ResourceUpdateQueue::~ResourceUpdateQueue() {}
-
-void ResourceUpdateQueue::AppendFullUpload(const ResourceUpdate& upload) {
- full_entries_.push_back(upload);
-}
-
-void ResourceUpdateQueue::AppendPartialUpload(const ResourceUpdate& upload) {
- partial_entries_.push_back(upload);
-}
-
-void ResourceUpdateQueue::ClearUploadsToEvictedResources() {
- ClearUploadsToEvictedResources(&full_entries_);
- ClearUploadsToEvictedResources(&partial_entries_);
-}
-
-void ResourceUpdateQueue::ClearUploadsToEvictedResources(
- std::deque<ResourceUpdate>* entry_queue) {
- std::deque<ResourceUpdate> temp;
- entry_queue->swap(temp);
- while (temp.size()) {
- ResourceUpdate upload = temp.front();
- temp.pop_front();
- if (!upload.texture->BackingResourceWasEvicted())
- entry_queue->push_back(upload);
- }
-}
-
-ResourceUpdate ResourceUpdateQueue::TakeFirstFullUpload() {
- ResourceUpdate first = full_entries_.front();
- full_entries_.pop_front();
- return first;
-}
-
-ResourceUpdate ResourceUpdateQueue::TakeFirstPartialUpload() {
- ResourceUpdate first = partial_entries_.front();
- partial_entries_.pop_front();
- return first;
-}
-
-bool ResourceUpdateQueue::HasMoreUpdates() const {
- return !full_entries_.empty() || !partial_entries_.empty();
-}
-
-} // namespace cc
diff --git a/chromium/cc/resources/resource_update_queue.h b/chromium/cc/resources/resource_update_queue.h
deleted file mode 100644
index de455ce43fe..00000000000
--- a/chromium/cc/resources/resource_update_queue.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_RESOURCES_RESOURCE_UPDATE_QUEUE_H_
-#define CC_RESOURCES_RESOURCE_UPDATE_QUEUE_H_
-
-#include <deque>
-#include "base/basictypes.h"
-#include "cc/base/cc_export.h"
-#include "cc/resources/resource_update.h"
-
-namespace cc {
-
-class CC_EXPORT ResourceUpdateQueue {
- public:
- ResourceUpdateQueue();
- virtual ~ResourceUpdateQueue();
-
- void AppendFullUpload(const ResourceUpdate& upload);
- void AppendPartialUpload(const ResourceUpdate& upload);
-
- void ClearUploadsToEvictedResources();
-
- ResourceUpdate TakeFirstFullUpload();
- ResourceUpdate TakeFirstPartialUpload();
-
- size_t FullUploadSize() const { return full_entries_.size(); }
- size_t PartialUploadSize() const { return partial_entries_.size(); }
-
- bool HasMoreUpdates() const;
-
- private:
- void ClearUploadsToEvictedResources(std::deque<ResourceUpdate>* entry_queue);
- std::deque<ResourceUpdate> full_entries_;
- std::deque<ResourceUpdate> partial_entries_;
-
- DISALLOW_COPY_AND_ASSIGN(ResourceUpdateQueue);
-};
-
-} // namespace cc
-
-#endif // CC_RESOURCES_RESOURCE_UPDATE_QUEUE_H_
diff --git a/chromium/cc/resources/returned_resource.h b/chromium/cc/resources/returned_resource.h
index e2008b415a3..767d16f8dee 100644
--- a/chromium/cc/resources/returned_resource.h
+++ b/chromium/cc/resources/returned_resource.h
@@ -9,12 +9,13 @@
#include "base/basictypes.h"
#include "cc/base/cc_export.h"
+#include "cc/base/resource_id.h"
namespace cc {
struct CC_EXPORT ReturnedResource {
ReturnedResource() : id(0), sync_point(0), count(0), lost(false) {}
- unsigned id;
+ ResourceId id;
unsigned sync_point;
int count;
bool lost;
diff --git a/chromium/cc/resources/scoped_resource_unittest.cc b/chromium/cc/resources/scoped_resource_unittest.cc
index b95d814914e..197fa1f3b8d 100644
--- a/chromium/cc/resources/scoped_resource_unittest.cc
+++ b/chromium/cc/resources/scoped_resource_unittest.cc
@@ -7,8 +7,8 @@
#include "cc/output/renderer.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_output_surface_client.h"
+#include "cc/test/fake_resource_provider.h"
#include "cc/test/test_shared_bitmap_manager.h"
-#include "cc/test/tiled_layer_test_common.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cc {
@@ -21,14 +21,8 @@ TEST(ScopedResourceTest, NewScopedResource) {
scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
new TestSharedBitmapManager());
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager.get(),
- NULL,
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager.get());
scoped_ptr<ScopedResource> texture =
ScopedResource::Create(resource_provider.get());
@@ -37,7 +31,8 @@ TEST(ScopedResourceTest, NewScopedResource) {
// New scoped textures do not have a size yet.
EXPECT_EQ(gfx::Size(), texture->size());
- EXPECT_EQ(0u, texture->bytes());
+ EXPECT_EQ(0u, Resource::UncheckedMemorySizeBytes(texture->size(),
+ texture->format()));
}
TEST(ScopedResourceTest, CreateScopedResource) {
@@ -47,14 +42,8 @@ TEST(ScopedResourceTest, CreateScopedResource) {
scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
new TestSharedBitmapManager());
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager.get(),
- NULL,
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager.get());
scoped_ptr<ScopedResource> texture =
ScopedResource::Create(resource_provider.get());
texture->Allocate(gfx::Size(30, 30), ResourceProvider::TEXTURE_HINT_IMMUTABLE,
@@ -62,7 +51,8 @@ TEST(ScopedResourceTest, CreateScopedResource) {
// The texture has an allocated byte-size now.
size_t expected_bytes = 30 * 30 * 4;
- EXPECT_EQ(expected_bytes, texture->bytes());
+ EXPECT_EQ(expected_bytes, Resource::UncheckedMemorySizeBytes(
+ texture->size(), texture->format()));
EXPECT_LT(0u, texture->id());
EXPECT_EQ(static_cast<unsigned>(RGBA_8888), texture->format());
@@ -76,14 +66,8 @@ TEST(ScopedResourceTest, ScopedResourceIsDeleted) {
scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
new TestSharedBitmapManager());
- scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager.get(),
- NULL,
- NULL,
- 0,
- false,
- 1));
+ scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager.get());
{
scoped_ptr<ScopedResource> texture =
ScopedResource::Create(resource_provider.get());
diff --git a/chromium/cc/resources/skpicture_content_layer_updater.cc b/chromium/cc/resources/skpicture_content_layer_updater.cc
deleted file mode 100644
index c54f5dcaa7c..00000000000
--- a/chromium/cc/resources/skpicture_content_layer_updater.cc
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/resources/skpicture_content_layer_updater.h"
-
-#include "base/trace_event/trace_event.h"
-#include "cc/debug/rendering_stats_instrumentation.h"
-#include "cc/resources/layer_painter.h"
-#include "cc/resources/prioritized_resource.h"
-#include "cc/resources/resource_update_queue.h"
-#include "third_party/skia/include/core/SkCanvas.h"
-#include "third_party/skia/include/core/SkPictureRecorder.h"
-
-namespace cc {
-
-SkPictureContentLayerUpdater::SkPictureContentLayerUpdater(
- scoped_ptr<LayerPainter> painter,
- int layer_id)
- : ContentLayerUpdater(painter.Pass(), layer_id) {
-}
-
-SkPictureContentLayerUpdater::~SkPictureContentLayerUpdater() {}
-
-void SkPictureContentLayerUpdater::PrepareToUpdate(
- const gfx::Size& content_size,
- const gfx::Rect& paint_rect,
- const gfx::Size& tile_size,
- float contents_width_scale,
- float contents_height_scale) {
- SkPictureRecorder recorder;
- SkCanvas* canvas =
- recorder.beginRecording(paint_rect.width(), paint_rect.height(), NULL, 0);
- DCHECK_EQ(paint_rect.width(), canvas->getBaseLayerSize().width());
- DCHECK_EQ(paint_rect.height(), canvas->getBaseLayerSize().height());
- PaintContents(canvas,
- content_size,
- paint_rect,
- contents_width_scale,
- contents_height_scale);
- picture_ = skia::AdoptRef(recorder.endRecordingAsPicture());
-}
-
-void SkPictureContentLayerUpdater::DrawPicture(SkCanvas* canvas) {
- TRACE_EVENT0("cc", "SkPictureContentLayerUpdater::DrawPicture");
- if (picture_)
- canvas->drawPicture(picture_.get());
-}
-
-} // namespace cc
diff --git a/chromium/cc/resources/skpicture_content_layer_updater.h b/chromium/cc/resources/skpicture_content_layer_updater.h
deleted file mode 100644
index 33480a873c8..00000000000
--- a/chromium/cc/resources/skpicture_content_layer_updater.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_RESOURCES_SKPICTURE_CONTENT_LAYER_UPDATER_H_
-#define CC_RESOURCES_SKPICTURE_CONTENT_LAYER_UPDATER_H_
-
-#include "cc/resources/content_layer_updater.h"
-#include "skia/ext/refptr.h"
-#include "third_party/skia/include/core/SkPicture.h"
-
-class SkCanvas;
-
-namespace cc {
-
-class LayerPainter;
-
-// This class records the content_rect into an SkPicture. Subclass provides
-// SkCanvas to DrawPicture() for tile updating based on this recorded picture.
-class SkPictureContentLayerUpdater : public ContentLayerUpdater {
- protected:
- SkPictureContentLayerUpdater(
- scoped_ptr<LayerPainter> painter,
- int layer_id);
- ~SkPictureContentLayerUpdater() override;
-
- void PrepareToUpdate(const gfx::Size& content_size,
- const gfx::Rect& paint_rect,
- const gfx::Size& tile_size,
- float contents_width_scale,
- float contents_height_scale) override;
- void DrawPicture(SkCanvas* canvas);
-
- private:
- skia::RefPtr<SkPicture> picture_;
-
- DISALLOW_COPY_AND_ASSIGN(SkPictureContentLayerUpdater);
-};
-
-} // namespace cc
-
-#endif // CC_RESOURCES_SKPICTURE_CONTENT_LAYER_UPDATER_H_
diff --git a/chromium/cc/resources/texture_mailbox.cc b/chromium/cc/resources/texture_mailbox.cc
index 9bf242e1d7c..7e4dd29708c 100644
--- a/chromium/cc/resources/texture_mailbox.cc
+++ b/chromium/cc/resources/texture_mailbox.cc
@@ -28,15 +28,28 @@ TextureMailbox::TextureMailbox(const gpu::Mailbox& mailbox,
nearest_neighbor_(false) {
}
+TextureMailbox::TextureMailbox(const gpu::Mailbox& mailbox,
+ uint32 target,
+ uint32 sync_point,
+ const gfx::Size& size_in_pixels,
+ bool allow_overlay)
+ : mailbox_holder_(mailbox, target, sync_point),
+ shared_bitmap_(nullptr),
+ size_in_pixels_(size_in_pixels),
+ allow_overlay_(allow_overlay),
+ nearest_neighbor_(false) {
+ DCHECK_IMPLIES(allow_overlay, !size_in_pixels.IsEmpty());
+}
+
TextureMailbox::TextureMailbox(SharedBitmap* shared_bitmap,
- const gfx::Size& size)
+ const gfx::Size& size_in_pixels)
: shared_bitmap_(shared_bitmap),
- shared_memory_size_(size),
+ size_in_pixels_(size_in_pixels),
allow_overlay_(false),
nearest_neighbor_(false) {
// If an embedder of cc gives an invalid TextureMailbox, we should crash
// here to identify the offender.
- CHECK(SharedBitmap::VerifySizeInBytes(shared_memory_size_));
+ CHECK(SharedBitmap::VerifySizeInBytes(size_in_pixels_));
}
TextureMailbox::~TextureMailbox() {}
@@ -57,7 +70,7 @@ bool TextureMailbox::Equals(const TextureMailbox& other) const {
size_t TextureMailbox::SharedMemorySizeInBytes() const {
// UncheckedSizeInBytes is okay because we VerifySizeInBytes in the
// constructor and the field is immutable.
- return SharedBitmap::UncheckedSizeInBytes(shared_memory_size_);
+ return SharedBitmap::UncheckedSizeInBytes(size_in_pixels_);
}
} // namespace cc
diff --git a/chromium/cc/resources/texture_mailbox.h b/chromium/cc/resources/texture_mailbox.h
index cec60cedaca..47e71acb199 100644
--- a/chromium/cc/resources/texture_mailbox.h
+++ b/chromium/cc/resources/texture_mailbox.h
@@ -22,7 +22,12 @@ class CC_EXPORT TextureMailbox {
TextureMailbox();
explicit TextureMailbox(const gpu::MailboxHolder& mailbox_holder);
TextureMailbox(const gpu::Mailbox& mailbox, uint32 target, uint32 sync_point);
- TextureMailbox(SharedBitmap* shared_bitmap, const gfx::Size& size);
+ TextureMailbox(const gpu::Mailbox& mailbox,
+ uint32 target,
+ uint32 sync_point,
+ const gfx::Size& size_in_pixels,
+ bool allow_overlay);
+ TextureMailbox(SharedBitmap* shared_bitmap, const gfx::Size& size_in_pixels);
~TextureMailbox();
@@ -41,20 +46,21 @@ class CC_EXPORT TextureMailbox {
}
bool allow_overlay() const { return allow_overlay_; }
- void set_allow_overlay(bool allow_overlay) { allow_overlay_ = allow_overlay; }
bool nearest_neighbor() const { return nearest_neighbor_; }
void set_nearest_neighbor(bool nearest_neighbor) {
nearest_neighbor_ = nearest_neighbor;
}
+ // This is valid if allow_overlau() or IsSharedMemory() is true.
+ gfx::Size size_in_pixels() const { return size_in_pixels_; }
+
SharedBitmap* shared_bitmap() const { return shared_bitmap_; }
- gfx::Size shared_memory_size() const { return shared_memory_size_; }
size_t SharedMemorySizeInBytes() const;
private:
gpu::MailboxHolder mailbox_holder_;
SharedBitmap* shared_bitmap_;
- gfx::Size shared_memory_size_;
+ gfx::Size size_in_pixels_;
bool allow_overlay_;
bool nearest_neighbor_;
};
diff --git a/chromium/cc/resources/texture_uploader.cc b/chromium/cc/resources/texture_uploader.cc
deleted file mode 100644
index 89271bdcb54..00000000000
--- a/chromium/cc/resources/texture_uploader.cc
+++ /dev/null
@@ -1,315 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/resources/texture_uploader.h"
-
-#include <algorithm>
-#include <vector>
-
-#include "base/metrics/histogram.h"
-#include "base/trace_event/trace_event.h"
-#include "cc/base/util.h"
-#include "cc/resources/resource.h"
-#include "gpu/GLES2/gl2extchromium.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
-#include "third_party/khronos/GLES2/gl2.h"
-#include "third_party/khronos/GLES2/gl2ext.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/vector2d.h"
-
-using gpu::gles2::GLES2Interface;
-
-namespace {
-
-// How many previous uploads to use when predicting future throughput.
-static const size_t kUploadHistorySizeMax = 1000;
-static const size_t kUploadHistorySizeInitial = 100;
-
-// Global estimated number of textures per second to maintain estimates across
-// subsequent instances of TextureUploader.
-// More than one thread will not access this variable, so we do not need to
-// synchronize access.
-static const double kDefaultEstimatedTexturesPerSecond = 48.0 * 60.0;
-
-// Flush interval when performing texture uploads.
-static const size_t kTextureUploadFlushPeriod = 4;
-
-} // anonymous namespace
-
-namespace cc {
-
-TextureUploader::Query::Query(GLES2Interface* gl)
- : gl_(gl),
- query_id_(0),
- value_(0),
- has_value_(false),
- is_non_blocking_(false) {
- gl_->GenQueriesEXT(1, &query_id_);
-}
-
-TextureUploader::Query::~Query() { gl_->DeleteQueriesEXT(1, &query_id_); }
-
-void TextureUploader::Query::Begin() {
- has_value_ = false;
- is_non_blocking_ = false;
- gl_->BeginQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM, query_id_);
-}
-
-void TextureUploader::Query::End() {
- gl_->EndQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM);
-}
-
-bool TextureUploader::Query::IsPending() {
- unsigned available = 1;
- gl_->GetQueryObjectuivEXT(
- query_id_, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
- return !available;
-}
-
-unsigned TextureUploader::Query::Value() {
- if (!has_value_) {
- gl_->GetQueryObjectuivEXT(query_id_, GL_QUERY_RESULT_EXT, &value_);
- has_value_ = true;
- }
- return value_;
-}
-
-TextureUploader::TextureUploader(GLES2Interface* gl)
- : gl_(gl),
- num_blocking_texture_uploads_(0),
- sub_image_size_(0),
- num_texture_uploads_since_last_flush_(0) {
- for (size_t i = kUploadHistorySizeInitial; i > 0; i--)
- textures_per_second_history_.insert(kDefaultEstimatedTexturesPerSecond);
-}
-
-TextureUploader::~TextureUploader() {}
-
-size_t TextureUploader::NumBlockingUploads() {
- ProcessQueries();
- return num_blocking_texture_uploads_;
-}
-
-void TextureUploader::MarkPendingUploadsAsNonBlocking() {
- for (ScopedPtrDeque<Query>::iterator it = pending_queries_.begin();
- it != pending_queries_.end();
- ++it) {
- if ((*it)->is_non_blocking())
- continue;
-
- num_blocking_texture_uploads_--;
- (*it)->mark_as_non_blocking();
- }
-
- DCHECK(!num_blocking_texture_uploads_);
-}
-
-double TextureUploader::EstimatedTexturesPerSecond() {
- ProcessQueries();
-
- // Use the median as our estimate.
- std::multiset<double>::iterator median = textures_per_second_history_.begin();
- std::advance(median, textures_per_second_history_.size() / 2);
- return *median;
-}
-
-void TextureUploader::BeginQuery() {
- // Check to see if any of the pending queries are free before allocating a
- // new one. If this is not done, queries may be allocated without bound.
- // http://crbug.com/398072
- if (available_queries_.empty())
- ProcessQueries();
-
- if (available_queries_.empty())
- available_queries_.push_back(Query::Create(gl_));
-
- available_queries_.front()->Begin();
-}
-
-void TextureUploader::EndQuery() {
- available_queries_.front()->End();
- pending_queries_.push_back(available_queries_.take_front());
- num_blocking_texture_uploads_++;
-}
-
-void TextureUploader::Upload(const uint8* image,
- const gfx::Rect& image_rect,
- const gfx::Rect& source_rect,
- const gfx::Vector2d& dest_offset,
- ResourceFormat format,
- const gfx::Size& size) {
- CHECK(image_rect.Contains(source_rect));
-
- bool is_full_upload = dest_offset.IsZero() && source_rect.size() == size;
-
- if (is_full_upload)
- BeginQuery();
-
- UploadWithMapTexSubImage(image, image_rect, source_rect, dest_offset, format);
-
- if (is_full_upload)
- EndQuery();
-
- num_texture_uploads_since_last_flush_++;
- if (num_texture_uploads_since_last_flush_ >= kTextureUploadFlushPeriod)
- Flush();
-}
-
-void TextureUploader::Flush() {
- if (!num_texture_uploads_since_last_flush_)
- return;
-
- gl_->ShallowFlushCHROMIUM();
-
- num_texture_uploads_since_last_flush_ = 0;
-}
-
-void TextureUploader::ReleaseCachedQueries() {
- ProcessQueries();
- available_queries_.clear();
-}
-
-void TextureUploader::UploadWithTexSubImage(const uint8* image,
- const gfx::Rect& image_rect,
- const gfx::Rect& source_rect,
- const gfx::Vector2d& dest_offset,
- ResourceFormat format) {
- TRACE_EVENT0("cc", "TextureUploader::UploadWithTexSubImage");
-
- // Early-out if this is a no-op, and assert that |image| be valid if this is
- // not a no-op.
- if (source_rect.IsEmpty())
- return;
- DCHECK(image);
-
- // Offset from image-rect to source-rect.
- gfx::Vector2d offset(source_rect.origin() - image_rect.origin());
-
- const uint8* pixel_source;
- unsigned bytes_per_pixel = BitsPerPixel(format) / 8;
- // Use 4-byte row alignment (OpenGL default) for upload performance.
- // Assuming that GL_UNPACK_ALIGNMENT has not changed from default.
- unsigned upload_image_stride =
- RoundUp(bytes_per_pixel * source_rect.width(), 4u);
-
- if (upload_image_stride == image_rect.width() * bytes_per_pixel &&
- !offset.x()) {
- pixel_source = &image[image_rect.width() * bytes_per_pixel * offset.y()];
- } else {
- size_t needed_size = upload_image_stride * source_rect.height();
- if (sub_image_size_ < needed_size) {
- sub_image_.reset(new uint8[needed_size]);
- sub_image_size_ = needed_size;
- }
- // Strides not equal, so do a row-by-row memcpy from the
- // paint results into a temp buffer for uploading.
- for (int row = 0; row < source_rect.height(); ++row)
- memcpy(&sub_image_[upload_image_stride * row],
- &image[bytes_per_pixel *
- (offset.x() + (offset.y() + row) * image_rect.width())],
- source_rect.width() * bytes_per_pixel);
-
- pixel_source = &sub_image_[0];
- }
-
- gl_->TexSubImage2D(GL_TEXTURE_2D,
- 0,
- dest_offset.x(),
- dest_offset.y(),
- source_rect.width(),
- source_rect.height(),
- GLDataFormat(format),
- GLDataType(format),
- pixel_source);
-}
-
-void TextureUploader::UploadWithMapTexSubImage(const uint8* image,
- const gfx::Rect& image_rect,
- const gfx::Rect& source_rect,
- const gfx::Vector2d& dest_offset,
- ResourceFormat format) {
- TRACE_EVENT0("cc", "TextureUploader::UploadWithMapTexSubImage");
-
- // Early-out if this is a no-op, and assert that |image| be valid if this is
- // not a no-op.
- if (source_rect.IsEmpty())
- return;
- DCHECK(image);
- // Compressed textures have no implementation of mapTexSubImage.
- DCHECK_NE(ETC1, format);
-
- // Offset from image-rect to source-rect.
- gfx::Vector2d offset(source_rect.origin() - image_rect.origin());
-
- unsigned bytes_per_pixel = BitsPerPixel(format) / 8;
- // Use 4-byte row alignment (OpenGL default) for upload performance.
- // Assuming that GL_UNPACK_ALIGNMENT has not changed from default.
- unsigned upload_image_stride =
- RoundUp(bytes_per_pixel * source_rect.width(), 4u);
-
- // Upload tile data via a mapped transfer buffer
- uint8* pixel_dest =
- static_cast<uint8*>(gl_->MapTexSubImage2DCHROMIUM(GL_TEXTURE_2D,
- 0,
- dest_offset.x(),
- dest_offset.y(),
- source_rect.width(),
- source_rect.height(),
- GLDataFormat(format),
- GLDataType(format),
- GL_WRITE_ONLY));
-
- if (!pixel_dest) {
- UploadWithTexSubImage(image, image_rect, source_rect, dest_offset, format);
- return;
- }
-
- if (upload_image_stride == image_rect.width() * bytes_per_pixel &&
- !offset.x()) {
- memcpy(pixel_dest,
- &image[image_rect.width() * bytes_per_pixel * offset.y()],
- source_rect.height() * image_rect.width() * bytes_per_pixel);
- } else {
- // Strides not equal, so do a row-by-row memcpy from the
- // paint results into the pixel_dest.
- for (int row = 0; row < source_rect.height(); ++row) {
- memcpy(&pixel_dest[upload_image_stride * row],
- &image[bytes_per_pixel *
- (offset.x() + (offset.y() + row) * image_rect.width())],
- source_rect.width() * bytes_per_pixel);
- }
- }
-
- gl_->UnmapTexSubImage2DCHROMIUM(pixel_dest);
-}
-
-void TextureUploader::ProcessQueries() {
- while (!pending_queries_.empty()) {
- if (pending_queries_.front()->IsPending())
- break;
-
- unsigned us_elapsed = pending_queries_.front()->Value();
- UMA_HISTOGRAM_CUSTOM_COUNTS(
- "Renderer4.TextureGpuUploadTimeUS", us_elapsed, 0, 100000, 50);
-
- // Clamp the queries to saner values in case the queries fail.
- us_elapsed = std::max(1u, us_elapsed);
- us_elapsed = std::min(15000u, us_elapsed);
-
- if (!pending_queries_.front()->is_non_blocking())
- num_blocking_texture_uploads_--;
-
- // Remove the min and max value from our history and insert the new one.
- double textures_per_second = 1.0 / (us_elapsed * 1e-6);
- if (textures_per_second_history_.size() >= kUploadHistorySizeMax) {
- textures_per_second_history_.erase(textures_per_second_history_.begin());
- textures_per_second_history_.erase(--textures_per_second_history_.end());
- }
- textures_per_second_history_.insert(textures_per_second);
-
- available_queries_.push_back(pending_queries_.take_front());
- }
-}
-
-} // namespace cc
diff --git a/chromium/cc/resources/texture_uploader.h b/chromium/cc/resources/texture_uploader.h
deleted file mode 100644
index ae834083e72..00000000000
--- a/chromium/cc/resources/texture_uploader.h
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_RESOURCES_TEXTURE_UPLOADER_H_
-#define CC_RESOURCES_TEXTURE_UPLOADER_H_
-
-#include <set>
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "cc/base/cc_export.h"
-#include "cc/base/scoped_ptr_deque.h"
-#include "cc/resources/resource_provider.h"
-
-namespace gfx {
-class Rect;
-class Size;
-class Vector2d;
-}
-
-namespace gpu {
-namespace gles2 {
-class GLES2Interface;
-}
-}
-
-namespace cc {
-
-class CC_EXPORT TextureUploader {
- public:
- static scoped_ptr<TextureUploader> Create(gpu::gles2::GLES2Interface* gl) {
- return make_scoped_ptr(new TextureUploader(gl));
- }
- ~TextureUploader();
-
- size_t NumBlockingUploads();
- void MarkPendingUploadsAsNonBlocking();
- double EstimatedTexturesPerSecond();
-
- // Let content_rect be a rectangle, and let content_rect be a sub-rectangle of
- // content_rect, expressed in the same coordinate system as content_rect. Let
- // image be a buffer for content_rect. This function will copy the region
- // corresponding to source_rect to dest_offset in this sub-image.
- void Upload(const uint8* image,
- const gfx::Rect& content_rect,
- const gfx::Rect& source_rect,
- const gfx::Vector2d& dest_offset,
- ResourceFormat format,
- const gfx::Size& size);
-
- void Flush();
- void ReleaseCachedQueries();
-
- private:
- class Query {
- public:
- static scoped_ptr<Query> Create(gpu::gles2::GLES2Interface* gl) {
- return make_scoped_ptr(new Query(gl));
- }
-
- virtual ~Query();
-
- void Begin();
- void End();
- bool IsPending();
- unsigned Value();
- size_t TexturesUploaded();
- void mark_as_non_blocking() { is_non_blocking_ = true; }
- bool is_non_blocking() const { return is_non_blocking_; }
-
- private:
- explicit Query(gpu::gles2::GLES2Interface* gl);
-
- gpu::gles2::GLES2Interface* gl_;
- unsigned query_id_;
- unsigned value_;
- bool has_value_;
- bool is_non_blocking_;
-
- DISALLOW_COPY_AND_ASSIGN(Query);
- };
-
- explicit TextureUploader(gpu::gles2::GLES2Interface* gl);
-
- void BeginQuery();
- void EndQuery();
- void ProcessQueries();
-
- void UploadWithTexSubImage(const uint8* image,
- const gfx::Rect& image_rect,
- const gfx::Rect& source_rect,
- const gfx::Vector2d& dest_offset,
- ResourceFormat format);
- void UploadWithMapTexSubImage(const uint8* image,
- const gfx::Rect& image_rect,
- const gfx::Rect& source_rect,
- const gfx::Vector2d& dest_offset,
- ResourceFormat format);
- void UploadWithTexImageETC1(const uint8* image, const gfx::Size& size);
-
- gpu::gles2::GLES2Interface* gl_;
- ScopedPtrDeque<Query> pending_queries_;
- ScopedPtrDeque<Query> available_queries_;
- std::multiset<double> textures_per_second_history_;
- size_t num_blocking_texture_uploads_;
-
- size_t sub_image_size_;
- scoped_ptr<uint8[]> sub_image_;
-
- size_t num_texture_uploads_since_last_flush_;
-
- DISALLOW_COPY_AND_ASSIGN(TextureUploader);
-};
-
-} // namespace cc
-
-#endif // CC_RESOURCES_TEXTURE_UPLOADER_H_
diff --git a/chromium/cc/resources/texture_uploader_unittest.cc b/chromium/cc/resources/texture_uploader_unittest.cc
deleted file mode 100644
index b1689627d1f..00000000000
--- a/chromium/cc/resources/texture_uploader_unittest.cc
+++ /dev/null
@@ -1,255 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/resources/texture_uploader.h"
-
-#include "cc/base/util.h"
-#include "cc/resources/prioritized_resource.h"
-#include "gpu/command_buffer/client/gles2_interface_stub.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/khronos/GLES2/gl2.h"
-#include "third_party/khronos/GLES2/gl2ext.h"
-
-namespace cc {
-namespace {
-
-class TextureUploadTestContext : public gpu::gles2::GLES2InterfaceStub {
- public:
- TextureUploadTestContext() : result_available_(0), unpack_alignment_(4) {}
-
- void PixelStorei(GLenum pname, GLint param) override {
- switch (pname) {
- case GL_UNPACK_ALIGNMENT:
- // Param should be a power of two <= 8.
- EXPECT_EQ(0, param & (param - 1));
- EXPECT_GE(8, param);
- switch (param) {
- case 1:
- case 2:
- case 4:
- case 8:
- unpack_alignment_ = param;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- }
-
- void GetQueryObjectuivEXT(GLuint, GLenum type, GLuint* value) override {
- switch (type) {
- case GL_QUERY_RESULT_AVAILABLE_EXT:
- *value = result_available_;
- break;
- default:
- *value = 0;
- break;
- }
- }
-
- void TexSubImage2D(GLenum target,
- GLint level,
- GLint xoffset,
- GLint yoffset,
- GLsizei width,
- GLsizei height,
- GLenum format,
- GLenum type,
- const void* pixels) override {
- EXPECT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target);
- EXPECT_EQ(0, level);
- EXPECT_LE(0, width);
- EXPECT_LE(0, height);
- EXPECT_LE(0, xoffset);
- EXPECT_LE(0, yoffset);
- EXPECT_LE(0, width);
- EXPECT_LE(0, height);
-
- // Check for allowed format/type combination.
- unsigned int bytes_per_pixel = 0;
- switch (format) {
- case GL_ALPHA:
- EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
- bytes_per_pixel = 1;
- break;
- case GL_RGB:
- EXPECT_NE(static_cast<unsigned>(GL_UNSIGNED_SHORT_4_4_4_4), type);
- EXPECT_NE(static_cast<unsigned>(GL_UNSIGNED_SHORT_5_5_5_1), type);
- switch (type) {
- case GL_UNSIGNED_BYTE:
- bytes_per_pixel = 3;
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- bytes_per_pixel = 2;
- break;
- }
- break;
- case GL_RGBA:
- EXPECT_NE(static_cast<unsigned>(GL_UNSIGNED_SHORT_5_6_5), type);
- switch (type) {
- case GL_UNSIGNED_BYTE:
- bytes_per_pixel = 4;
- break;
- case GL_UNSIGNED_SHORT_4_4_4_4:
- bytes_per_pixel = 2;
- break;
- case GL_UNSIGNED_SHORT_5_5_5_1:
- bytes_per_pixel = 2;
- break;
- }
- break;
- case GL_LUMINANCE:
- EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
- bytes_per_pixel = 1;
- break;
- case GL_LUMINANCE_ALPHA:
- EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
- bytes_per_pixel = 2;
- break;
- case GL_RED_EXT:
- EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
- bytes_per_pixel = 1;
- break;
- case GL_RG_EXT:
- EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
- bytes_per_pixel = 2;
- break;
- }
-
- // If NULL, we aren't checking texture contents.
- if (pixels == NULL)
- return;
-
- const uint8* bytes = static_cast<const uint8*>(pixels);
- // We'll expect the first byte of every row to be 0x1, and the last byte to
- // be 0x2.
- const unsigned int stride =
- RoundUp(bytes_per_pixel * width, unpack_alignment_);
- for (GLsizei row = 0; row < height; ++row) {
- const uint8* row_bytes =
- bytes + (xoffset * bytes_per_pixel + (yoffset + row) * stride);
- EXPECT_EQ(0x1, row_bytes[0]);
- EXPECT_EQ(0x2, row_bytes[width * bytes_per_pixel - 1]);
- }
- }
-
- void SetResultAvailable(unsigned result_available) {
- result_available_ = result_available;
- }
-
- private:
- unsigned result_available_;
- unsigned unpack_alignment_;
-
- DISALLOW_COPY_AND_ASSIGN(TextureUploadTestContext);
-};
-
-void UploadTexture(TextureUploader* uploader,
- ResourceFormat format,
- const gfx::Size& size,
- const uint8* data) {
- uploader->Upload(
- data, gfx::Rect(size), gfx::Rect(size), gfx::Vector2d(), format, size);
-}
-
-TEST(TextureUploaderTest, NumBlockingUploads) {
- TextureUploadTestContext context;
- scoped_ptr<TextureUploader> uploader = TextureUploader::Create(&context);
-
- context.SetResultAvailable(0);
- EXPECT_EQ(0u, uploader->NumBlockingUploads());
- UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
- EXPECT_EQ(1u, uploader->NumBlockingUploads());
- UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
- EXPECT_EQ(2u, uploader->NumBlockingUploads());
-
- context.SetResultAvailable(1);
- EXPECT_EQ(0u, uploader->NumBlockingUploads());
- UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
- EXPECT_EQ(0u, uploader->NumBlockingUploads());
- UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
- UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
- EXPECT_EQ(0u, uploader->NumBlockingUploads());
-}
-
-TEST(TextureUploaderTest, MarkPendingUploadsAsNonBlocking) {
- TextureUploadTestContext context;
- scoped_ptr<TextureUploader> uploader = TextureUploader::Create(&context);
-
- context.SetResultAvailable(0);
- EXPECT_EQ(0u, uploader->NumBlockingUploads());
- UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
- UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
- EXPECT_EQ(2u, uploader->NumBlockingUploads());
-
- uploader->MarkPendingUploadsAsNonBlocking();
- EXPECT_EQ(0u, uploader->NumBlockingUploads());
- UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
- EXPECT_EQ(1u, uploader->NumBlockingUploads());
-
- context.SetResultAvailable(1);
- EXPECT_EQ(0u, uploader->NumBlockingUploads());
- UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
- uploader->MarkPendingUploadsAsNonBlocking();
- EXPECT_EQ(0u, uploader->NumBlockingUploads());
-}
-
-TEST(TextureUploaderTest, UploadContentsTest) {
- TextureUploadTestContext context;
- scoped_ptr<TextureUploader> uploader = TextureUploader::Create(&context);
-
- uint8 buffer[256 * 256 * 4];
-
- // Upload a tightly packed 256x256 RGBA texture.
- memset(buffer, 0, sizeof(buffer));
- for (int i = 0; i < 256; ++i) {
- // Mark the beginning and end of each row, for the test.
- buffer[i * 4 * 256] = 0x1;
- buffer[(i + 1) * 4 * 256 - 1] = 0x2;
- }
- UploadTexture(uploader.get(), RGBA_8888, gfx::Size(256, 256), buffer);
-
- // Upload a tightly packed 41x43 RGBA texture.
- memset(buffer, 0, sizeof(buffer));
- for (int i = 0; i < 43; ++i) {
- // Mark the beginning and end of each row, for the test.
- buffer[i * 4 * 41] = 0x1;
- buffer[(i + 1) * 4 * 41 - 1] = 0x2;
- }
- UploadTexture(uploader.get(), RGBA_8888, gfx::Size(41, 43), buffer);
-
- // Upload a tightly packed 41x86 ALPHA texture.
- memset(buffer, 0, sizeof(buffer));
- for (int i = 0; i < 86; ++i) {
- // Mark the beginning and end of each row, for the test.
- buffer[i * 1 * 41] = 0x1;
- buffer[(i + 1) * 41 - 1] = 0x2;
- }
- UploadTexture(uploader.get(), ALPHA_8, gfx::Size(41, 86), buffer);
-
- // Upload a tightly packed 82x86 LUMINANCE texture.
- memset(buffer, 0, sizeof(buffer));
- for (int i = 0; i < 86; ++i) {
- // Mark the beginning and end of each row, for the test.
- buffer[i * 1 * 82] = 0x1;
- buffer[(i + 1) * 82 - 1] = 0x2;
- }
- UploadTexture(uploader.get(), LUMINANCE_8, gfx::Size(82, 86), buffer);
-
- // Upload a tightly packed 82x86 RED texture.
- memset(buffer, 0, sizeof(buffer));
- for (int i = 0; i < 86; ++i) {
- // Mark the beginning and end of each row, for the test.
- buffer[i * 1 * 82] = 0x1;
- buffer[(i + 1) * 82 - 1] = 0x2;
- }
- UploadTexture(uploader.get(), RED_8, gfx::Size(82, 86), buffer);
-}
-
-} // namespace
-} // namespace cc
diff --git a/chromium/cc/resources/transferable_resource.cc b/chromium/cc/resources/transferable_resource.cc
index 558d6e87728..89771a78146 100644
--- a/chromium/cc/resources/transferable_resource.cc
+++ b/chromium/cc/resources/transferable_resource.cc
@@ -11,6 +11,7 @@ TransferableResource::TransferableResource()
: id(0),
format(RGBA_8888),
filter(0),
+ read_lock_fences_enabled(false),
is_repeated(false),
is_software(false),
allow_overlay(false) {
diff --git a/chromium/cc/resources/transferable_resource.h b/chromium/cc/resources/transferable_resource.h
index 03b47e616c8..6f38a62f7fc 100644
--- a/chromium/cc/resources/transferable_resource.h
+++ b/chromium/cc/resources/transferable_resource.h
@@ -9,6 +9,7 @@
#include "base/basictypes.h"
#include "cc/base/cc_export.h"
+#include "cc/base/resource_id.h"
#include "cc/resources/resource_format.h"
#include "gpu/command_buffer/common/mailbox_holder.h"
#include "ui/gfx/geometry/size.h"
@@ -28,11 +29,12 @@ struct CC_EXPORT TransferableResource {
static void ReturnResources(const TransferableResourceArray& input,
ReturnedResourceArray* output);
- unsigned id;
+ ResourceId id;
ResourceFormat format;
uint32 filter;
gfx::Size size;
gpu::MailboxHolder mailbox_holder;
+ bool read_lock_fences_enabled;
bool is_repeated;
bool is_software;
bool allow_overlay;
diff --git a/chromium/cc/resources/ui_resource_bitmap.cc b/chromium/cc/resources/ui_resource_bitmap.cc
index e254cf71614..b5a84b93db2 100644
--- a/chromium/cc/resources/ui_resource_bitmap.cc
+++ b/chromium/cc/resources/ui_resource_bitmap.cc
@@ -54,8 +54,7 @@ UIResourceBitmap::UIResourceBitmap(const SkBitmap& skbitmap) {
skia::RefPtr<SkPixelRef> pixel_ref = skia::SharePtr(skbitmap.pixelRef());
const SkImageInfo& info = pixel_ref->info();
- Create(pixel_ref,
- gfx::Size(info.fWidth, info.fHeight),
+ Create(pixel_ref, gfx::Size(info.width(), info.height()),
SkColorTypeToUIResourceFormat(skbitmap.colorType()));
SetOpaque(skbitmap.isOpaque());
diff --git a/chromium/cc/resources/video_resource_updater.cc b/chromium/cc/resources/video_resource_updater.cc
index 06fb6929c95..e973a3d5240 100644
--- a/chromium/cc/resources/video_resource_updater.cc
+++ b/chromium/cc/resources/video_resource_updater.cc
@@ -8,7 +8,7 @@
#include "base/bind.h"
#include "base/trace_event/trace_event.h"
-#include "cc/base/util.h"
+#include "cc/base/math_util.h"
#include "cc/output/gl_renderer.h"
#include "cc/resources/resource_provider.h"
#include "gpu/GLES2/gl2extchromium.h"
@@ -64,13 +64,13 @@ VideoResourceUpdater::PlaneResource::PlaneResource(
mailbox(mailbox),
ref_count(0),
frame_ptr(nullptr),
- plane_index(0) {
+ plane_index(0u) {
}
bool VideoResourceUpdater::PlaneResourceMatchesUniqueID(
const PlaneResource& plane_resource,
const media::VideoFrame* video_frame,
- int plane_index) {
+ size_t plane_index) {
return plane_resource.frame_ptr == video_frame &&
plane_resource.plane_index == plane_index &&
plane_resource.timestamp == video_frame->timestamp();
@@ -78,14 +78,16 @@ bool VideoResourceUpdater::PlaneResourceMatchesUniqueID(
void VideoResourceUpdater::SetPlaneResourceUniqueId(
const media::VideoFrame* video_frame,
- int plane_index,
+ size_t plane_index,
PlaneResource* plane_resource) {
plane_resource->frame_ptr = video_frame;
plane_resource->plane_index = plane_index;
plane_resource->timestamp = video_frame->timestamp();
}
-VideoFrameExternalResources::VideoFrameExternalResources() : type(NONE) {}
+VideoFrameExternalResources::VideoFrameExternalResources()
+ : type(NONE), read_lock_fences_enabled(false) {
+}
VideoFrameExternalResources::~VideoFrameExternalResources() {}
@@ -106,10 +108,9 @@ VideoResourceUpdater::AllocateResource(const gfx::Size& plane_size,
bool has_mailbox) {
// TODO(danakj): Abstract out hw/sw resource create/delete from
// ResourceProvider and stop using ResourceProvider in this class.
- const ResourceProvider::ResourceId resource_id =
- resource_provider_->CreateResource(
- plane_size, GL_CLAMP_TO_EDGE,
- ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
+ const ResourceId resource_id = resource_provider_->CreateResource(
+ plane_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
+ format);
if (resource_id == 0)
return all_resources_.end();
@@ -138,41 +139,15 @@ void VideoResourceUpdater::DeleteResource(ResourceList::iterator resource_it) {
VideoFrameExternalResources VideoResourceUpdater::
CreateExternalResourcesFromVideoFrame(
const scoped_refptr<media::VideoFrame>& video_frame) {
- if (!VerifyFrame(video_frame))
+ if (video_frame->format() == media::VideoFrame::UNKNOWN)
return VideoFrameExternalResources();
-
- if (video_frame->format() == media::VideoFrame::NATIVE_TEXTURE)
+ DCHECK(video_frame->HasTextures() || video_frame->IsMappable());
+ if (video_frame->HasTextures())
return CreateForHardwarePlanes(video_frame);
else
return CreateForSoftwarePlanes(video_frame);
}
-bool VideoResourceUpdater::VerifyFrame(
- const scoped_refptr<media::VideoFrame>& video_frame) {
- switch (video_frame->format()) {
- // Acceptable inputs.
- case media::VideoFrame::YV12:
- case media::VideoFrame::I420:
- case media::VideoFrame::YV12A:
- case media::VideoFrame::YV16:
- case media::VideoFrame::YV12J:
- case media::VideoFrame::YV12HD:
- case media::VideoFrame::YV24:
- case media::VideoFrame::NATIVE_TEXTURE:
-#if defined(VIDEO_HOLE)
- case media::VideoFrame::HOLE:
-#endif // defined(VIDEO_HOLE)
- case media::VideoFrame::ARGB:
- return true;
-
- // Unacceptable inputs. ¯\(°_o)/¯
- case media::VideoFrame::UNKNOWN:
- case media::VideoFrame::NV12:
- break;
- }
- return false;
-}
-
// For frames that we receive in software format, determine the dimensions of
// each plane in the frame.
static gfx::Size SoftwarePlaneDimension(
@@ -189,10 +164,10 @@ static gfx::Size SoftwarePlaneDimension(
VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
const scoped_refptr<media::VideoFrame>& video_frame) {
TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes");
- media::VideoFrame::Format input_frame_format = video_frame->format();
+ const media::VideoFrame::Format input_frame_format = video_frame->format();
#if defined(VIDEO_HOLE)
- if (input_frame_format == media::VideoFrame::HOLE) {
+ if (video_frame->storage_type() == media::VideoFrame::STORAGE_HOLE) {
VideoFrameExternalResources external_resources;
external_resources.type = VideoFrameExternalResources::HOLE;
return external_resources;
@@ -200,18 +175,12 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
#endif // defined(VIDEO_HOLE)
// Only YUV software video frames are supported.
- if (input_frame_format != media::VideoFrame::YV12 &&
- input_frame_format != media::VideoFrame::I420 &&
- input_frame_format != media::VideoFrame::YV12A &&
- input_frame_format != media::VideoFrame::YV12J &&
- input_frame_format != media::VideoFrame::YV12HD &&
- input_frame_format != media::VideoFrame::YV16 &&
- input_frame_format != media::VideoFrame::YV24) {
- NOTREACHED() << input_frame_format;
+ if (!media::VideoFrame::IsYuvPlanar(input_frame_format)) {
+ NOTREACHED() << media::VideoFrame::FormatToString(input_frame_format);
return VideoFrameExternalResources();
}
- bool software_compositor = context_provider_ == NULL;
+ const bool software_compositor = context_provider_ == NULL;
ResourceFormat output_resource_format =
resource_provider_->yuv_resource_format();
@@ -341,8 +310,8 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
size_t bytes_per_pixel = BitsPerPixel(plane_resource.resource_format) / 8;
// Use 4-byte row alignment (OpenGL default) for upload performance.
// Assuming that GL_UNPACK_ALIGNMENT has not changed from default.
- size_t upload_image_stride =
- RoundUp<size_t>(bytes_per_pixel * resource_size_pixels.width(), 4u);
+ size_t upload_image_stride = MathUtil::RoundUp<size_t>(
+ bytes_per_pixel * resource_size_pixels.width(), 4u);
const uint8_t* pixels;
if (upload_image_stride == video_stride_pixels * bytes_per_pixel) {
@@ -399,27 +368,24 @@ void VideoResourceUpdater::ReturnTexture(
VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes(
const scoped_refptr<media::VideoFrame>& video_frame) {
TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForHardwarePlanes");
- media::VideoFrame::Format frame_format = video_frame->format();
-
- DCHECK_EQ(frame_format, media::VideoFrame::NATIVE_TEXTURE);
+ DCHECK(video_frame->HasTextures());
if (!context_provider_)
return VideoFrameExternalResources();
- size_t textures =
- media::VideoFrame::NumTextures(video_frame->texture_format());
+ const size_t textures = media::VideoFrame::NumPlanes(video_frame->format());
DCHECK_GE(textures, 1u);
VideoFrameExternalResources external_resources;
- switch (video_frame->texture_format()) {
- case media::VideoFrame::TEXTURE_RGBA:
- case media::VideoFrame::TEXTURE_RGB:
+ external_resources.read_lock_fences_enabled = true;
+ switch (video_frame->format()) {
+ case media::VideoFrame::ARGB:
+ case media::VideoFrame::XRGB:
DCHECK_EQ(1u, textures);
switch (video_frame->mailbox_holder(0).texture_target) {
case GL_TEXTURE_2D:
- if (video_frame->texture_format() == media::VideoFrame::TEXTURE_RGB)
- external_resources.type = VideoFrameExternalResources::RGB_RESOURCE;
- else
- external_resources.type =
- VideoFrameExternalResources::RGBA_RESOURCE;
+ external_resources.type =
+ (video_frame->format() == media::VideoFrame::XRGB)
+ ? VideoFrameExternalResources::RGB_RESOURCE
+ : VideoFrameExternalResources::RGBA_RESOURCE;
break;
case GL_TEXTURE_EXTERNAL_OES:
external_resources.type =
@@ -433,9 +399,20 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes(
return VideoFrameExternalResources();
}
break;
- case media::VideoFrame::TEXTURE_YUV_420:
+ case media::VideoFrame::I420:
external_resources.type = VideoFrameExternalResources::YUV_RESOURCE;
break;
+#if defined(OS_MACOSX) || defined(OS_CHROMEOS)
+ case media::VideoFrame::NV12:
+#endif
+ case media::VideoFrame::YV12:
+ case media::VideoFrame::YV16:
+ case media::VideoFrame::YV24:
+ case media::VideoFrame::YV12A:
+ case media::VideoFrame::UNKNOWN:
+ DLOG(ERROR) << "Unsupported Texture format"
+ << media::VideoFrame::FormatToString(video_frame->format());
+ return external_resources;
}
DCHECK_NE(VideoFrameExternalResources::NONE, external_resources.type);
@@ -443,9 +420,9 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes(
const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(i);
external_resources.mailboxes.push_back(
TextureMailbox(mailbox_holder.mailbox, mailbox_holder.texture_target,
- mailbox_holder.sync_point));
- external_resources.mailboxes.back().set_allow_overlay(
- video_frame->allow_overlay());
+ mailbox_holder.sync_point, video_frame->coded_size(),
+ video_frame->metadata()->IsTrue(
+ media::VideoFrameMetadata::ALLOW_OVERLAY)));
external_resources.release_callbacks.push_back(
base::Bind(&ReturnTexture, AsWeakPtr(), video_frame));
}
@@ -455,7 +432,7 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes(
// static
void VideoResourceUpdater::RecycleResource(
base::WeakPtr<VideoResourceUpdater> updater,
- ResourceProvider::ResourceId resource_id,
+ ResourceId resource_id,
uint32 sync_point,
bool lost_resource,
BlockingTaskRunner* main_thread_task_runner) {
diff --git a/chromium/cc/resources/video_resource_updater.h b/chromium/cc/resources/video_resource_updater.h
index 13f81b8f06e..ad3d1abfb33 100644
--- a/chromium/cc/resources/video_resource_updater.h
+++ b/chromium/cc/resources/video_resource_updater.h
@@ -53,6 +53,7 @@ class CC_EXPORT VideoFrameExternalResources {
ResourceType type;
std::vector<TextureMailbox> mailboxes;
std::vector<ReleaseCallbackImpl> release_callbacks;
+ bool read_lock_fences_enabled;
// TODO(danakj): Remove these too.
std::vector<unsigned> software_resources;
@@ -88,7 +89,7 @@ class CC_EXPORT VideoResourceUpdater
// frame pointer will only be used for pointer comparison, i.e. the
// underlying data will not be accessed.
const void* frame_ptr;
- int plane_index;
+ size_t plane_index;
base::TimeDelta timestamp;
PlaneResource(unsigned resource_id,
@@ -99,10 +100,10 @@ class CC_EXPORT VideoResourceUpdater
static bool PlaneResourceMatchesUniqueID(const PlaneResource& plane_resource,
const media::VideoFrame* video_frame,
- int plane_index);
+ size_t plane_index);
static void SetPlaneResourceUniqueId(const media::VideoFrame* video_frame,
- int plane_index,
+ size_t plane_index,
PlaneResource* plane_resource);
// This needs to be a container where iterators can be erased without
diff --git a/chromium/cc/resources/video_resource_updater_unittest.cc b/chromium/cc/resources/video_resource_updater_unittest.cc
index 10f7fbdbbcf..3e4574d989c 100644
--- a/chromium/cc/resources/video_resource_updater_unittest.cc
+++ b/chromium/cc/resources/video_resource_updater_unittest.cc
@@ -8,6 +8,7 @@
#include "cc/resources/resource_provider.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_output_surface_client.h"
+#include "cc/test/fake_resource_provider.h"
#include "cc/test/test_shared_bitmap_manager.h"
#include "cc/test/test_web_graphics_context_3d.h"
#include "cc/trees/blocking_task_runner.h"
@@ -71,18 +72,11 @@ class VideoResourceUpdaterTest : public testing::Test {
CHECK(output_surface_software_->BindToClient(&client_));
shared_bitmap_manager_.reset(new SharedBitmapManagerAllocationCounter());
- resource_provider3d_ =
- ResourceProvider::Create(output_surface3d_.get(),
- shared_bitmap_manager_.get(),
- NULL,
- NULL,
- 0,
- false,
- 1);
-
- resource_provider_software_ = ResourceProvider::Create(
- output_surface_software_.get(), shared_bitmap_manager_.get(), NULL,
- NULL, 0, false, 1);
+ resource_provider3d_ = FakeResourceProvider::Create(
+ output_surface3d_.get(), shared_bitmap_manager_.get());
+
+ resource_provider_software_ = FakeResourceProvider::Create(
+ output_surface_software_.get(), shared_bitmap_manager_.get());
}
scoped_refptr<media::VideoFrame> CreateTestYUVVideoFrame() {
@@ -103,8 +97,7 @@ class VideoResourceUpdaterTest : public testing::Test {
y_data, // y_data
u_data, // u_data
v_data, // v_data
- base::TimeDelta(), // timestamp,
- base::Closure()); // no_longer_needed_cb
+ base::TimeDelta()); // timestamp
}
static void ReleaseMailboxCB(unsigned sync_point) {}
@@ -119,14 +112,13 @@ class VideoResourceUpdaterTest : public testing::Test {
const unsigned sync_point = 7;
const unsigned target = GL_TEXTURE_2D;
return media::VideoFrame::WrapNativeTexture(
+ media::VideoFrame::ARGB,
gpu::MailboxHolder(mailbox, target, sync_point),
base::Bind(&ReleaseMailboxCB),
- size, // coded_size
- gfx::Rect(size), // visible_rect
- size, // natural_size
- base::TimeDelta(), // timestamp
- false, // allow_overlay
- true); // has_alpha
+ size, // coded_size
+ gfx::Rect(size), // visible_rect
+ size, // natural_size
+ base::TimeDelta()); // timestamp
}
scoped_refptr<media::VideoFrame> CreateTestYUVHardareVideoFrame() {
@@ -148,11 +140,10 @@ class VideoResourceUpdaterTest : public testing::Test {
gpu::MailboxHolder(mailbox[media::VideoFrame::kVPlane], target,
sync_point),
base::Bind(&ReleaseMailboxCB),
- size, // coded_size
- gfx::Rect(size), // visible_rect
- size, // natural_size
- base::TimeDelta(), // timestamp
- false); // allow_overlay
+ size, // coded_size
+ gfx::Rect(size), // visible_rect
+ size, // natural_size
+ base::TimeDelta()); // timestamp
}
WebGraphicsContext3DUploadCounter* context3d_;
@@ -318,6 +309,7 @@ TEST_F(VideoResourceUpdaterTest, CreateForHardwarePlanes) {
resources = updater.CreateExternalResourcesFromVideoFrame(video_frame);
EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type);
+ EXPECT_TRUE(resources.read_lock_fences_enabled);
EXPECT_EQ(3u, resources.mailboxes.size());
EXPECT_EQ(3u, resources.release_callbacks.size());
EXPECT_EQ(0u, resources.software_resources.size());
diff --git a/chromium/cc/scheduler/begin_frame_source.cc b/chromium/cc/scheduler/begin_frame_source.cc
index 48d834359f4..d9cadc83e72 100644
--- a/chromium/cc/scheduler/begin_frame_source.cc
+++ b/chromium/cc/scheduler/begin_frame_source.cc
@@ -12,7 +12,6 @@
#include "base/trace_event/trace_event_argument.h"
#include "cc/scheduler/delay_based_time_source.h"
#include "cc/scheduler/scheduler.h"
-#include "ui/gfx/frame_time.h"
#ifdef NDEBUG
#define DEBUG_FRAMES(...)
@@ -28,23 +27,23 @@
namespace cc {
-// BeginFrameObserverMixIn -----------------------------------------------
-BeginFrameObserverMixIn::BeginFrameObserverMixIn()
+// BeginFrameObserverBase -----------------------------------------------
+BeginFrameObserverBase::BeginFrameObserverBase()
: last_begin_frame_args_(), dropped_begin_frame_args_(0) {
}
-const BeginFrameArgs BeginFrameObserverMixIn::LastUsedBeginFrameArgs() const {
+const BeginFrameArgs BeginFrameObserverBase::LastUsedBeginFrameArgs() const {
return last_begin_frame_args_;
}
-void BeginFrameObserverMixIn::OnBeginFrame(const BeginFrameArgs& args) {
- DEBUG_FRAMES("BeginFrameObserverMixIn::OnBeginFrame",
+void BeginFrameObserverBase::OnBeginFrame(const BeginFrameArgs& args) {
+ DEBUG_FRAMES("BeginFrameObserverBase::OnBeginFrame",
"last args",
last_begin_frame_args_.AsValue(),
"new args",
args.AsValue());
DCHECK(args.IsValid());
DCHECK(args.frame_time >= last_begin_frame_args_.frame_time);
- bool used = OnBeginFrameMixInDelegate(args);
+ bool used = OnBeginFrameDerivedImpl(args);
if (used) {
last_begin_frame_args_ = args;
} else {
@@ -52,7 +51,7 @@ void BeginFrameObserverMixIn::OnBeginFrame(const BeginFrameArgs& args) {
}
}
-void BeginFrameObserverMixIn::AsValueInto(
+void BeginFrameObserverBase::AsValueInto(
base::trace_event::TracedValue* dict) const {
dict->BeginDictionary("last_begin_frame_args_");
last_begin_frame_args_.AsValueInto(dict);
@@ -60,8 +59,8 @@ void BeginFrameObserverMixIn::AsValueInto(
dict->SetInteger("dropped_begin_frame_args_", dropped_begin_frame_args_);
}
-// BeginFrameSourceMixIn ------------------------------------------------------
-BeginFrameSourceMixIn::BeginFrameSourceMixIn()
+// BeginFrameSourceBase ------------------------------------------------------
+BeginFrameSourceBase::BeginFrameSourceBase()
: observer_(NULL),
needs_begin_frames_(false),
inside_as_value_into_(false) {
@@ -69,12 +68,12 @@ BeginFrameSourceMixIn::BeginFrameSourceMixIn()
DCHECK_EQ(inside_as_value_into_, false);
}
-bool BeginFrameSourceMixIn::NeedsBeginFrames() const {
+bool BeginFrameSourceBase::NeedsBeginFrames() const {
return needs_begin_frames_;
}
-void BeginFrameSourceMixIn::SetNeedsBeginFrames(bool needs_begin_frames) {
- DEBUG_FRAMES("BeginFrameSourceMixIn::SetNeedsBeginFrames",
+void BeginFrameSourceBase::SetNeedsBeginFrames(bool needs_begin_frames) {
+ DEBUG_FRAMES("BeginFrameSourceBase::SetNeedsBeginFrames",
"current state",
needs_begin_frames_,
"new state",
@@ -85,8 +84,8 @@ void BeginFrameSourceMixIn::SetNeedsBeginFrames(bool needs_begin_frames) {
}
}
-void BeginFrameSourceMixIn::AddObserver(BeginFrameObserver* obs) {
- DEBUG_FRAMES("BeginFrameSourceMixIn::AddObserver",
+void BeginFrameSourceBase::AddObserver(BeginFrameObserver* obs) {
+ DEBUG_FRAMES("BeginFrameSourceBase::AddObserver",
"current observer",
observer_,
"to add observer",
@@ -95,8 +94,8 @@ void BeginFrameSourceMixIn::AddObserver(BeginFrameObserver* obs) {
observer_ = obs;
}
-void BeginFrameSourceMixIn::RemoveObserver(BeginFrameObserver* obs) {
- DEBUG_FRAMES("BeginFrameSourceMixIn::RemoveObserver",
+void BeginFrameSourceBase::RemoveObserver(BeginFrameObserver* obs) {
+ DEBUG_FRAMES("BeginFrameSourceBase::RemoveObserver",
"current observer",
observer_,
"to remove observer",
@@ -105,8 +104,8 @@ void BeginFrameSourceMixIn::RemoveObserver(BeginFrameObserver* obs) {
observer_ = NULL;
}
-void BeginFrameSourceMixIn::CallOnBeginFrame(const BeginFrameArgs& args) {
- DEBUG_FRAMES("BeginFrameSourceMixIn::CallOnBeginFrame",
+void BeginFrameSourceBase::CallOnBeginFrame(const BeginFrameArgs& args) {
+ DEBUG_FRAMES("BeginFrameSourceBase::CallOnBeginFrame",
"current observer",
observer_,
"args",
@@ -117,7 +116,7 @@ void BeginFrameSourceMixIn::CallOnBeginFrame(const BeginFrameArgs& args) {
}
// Tracing support
-void BeginFrameSourceMixIn::AsValueInto(
+void BeginFrameSourceBase::AsValueInto(
base::trace_event::TracedValue* dict) const {
// As the observer might try to trace the source, prevent an infinte loop
// from occuring.
@@ -138,7 +137,7 @@ void BeginFrameSourceMixIn::AsValueInto(
dict->SetBoolean("needs_begin_frames", NeedsBeginFrames());
}
-// BackToBackBeginFrameSourceMixIn --------------------------------------------
+// BackToBackBeginFrameSource --------------------------------------------
scoped_ptr<BackToBackBeginFrameSource> BackToBackBeginFrameSource::Create(
base::SingleThreadTaskRunner* task_runner) {
return make_scoped_ptr(new BackToBackBeginFrameSource(task_runner));
@@ -146,7 +145,7 @@ scoped_ptr<BackToBackBeginFrameSource> BackToBackBeginFrameSource::Create(
BackToBackBeginFrameSource::BackToBackBeginFrameSource(
base::SingleThreadTaskRunner* task_runner)
- : BeginFrameSourceMixIn(),
+ : BeginFrameSourceBase(),
task_runner_(task_runner),
send_begin_frame_posted_(false),
weak_factory_(this) {
@@ -159,7 +158,7 @@ BackToBackBeginFrameSource::~BackToBackBeginFrameSource() {
}
base::TimeTicks BackToBackBeginFrameSource::Now() {
- return gfx::FrameTime::Now();
+ return base::TimeTicks::Now();
}
void BackToBackBeginFrameSource::OnNeedsBeginFramesChange(
@@ -201,37 +200,28 @@ void BackToBackBeginFrameSource::DidFinishFrame(size_t remaining_frames) {
void BackToBackBeginFrameSource::AsValueInto(
base::trace_event::TracedValue* dict) const {
dict->SetString("type", "BackToBackBeginFrameSource");
- BeginFrameSourceMixIn::AsValueInto(dict);
+ BeginFrameSourceBase::AsValueInto(dict);
dict->SetBoolean("send_begin_frame_posted_", send_begin_frame_posted_);
}
// SyntheticBeginFrameSource ---------------------------------------------
scoped_ptr<SyntheticBeginFrameSource> SyntheticBeginFrameSource::Create(
base::SingleThreadTaskRunner* task_runner,
- base::TimeTicks initial_vsync_timebase,
base::TimeDelta initial_vsync_interval) {
- scoped_refptr<DelayBasedTimeSource> time_source;
- if (gfx::FrameTime::TimestampsAreHighRes()) {
- time_source = DelayBasedTimeSourceHighRes::Create(initial_vsync_interval,
- task_runner);
- } else {
- time_source =
- DelayBasedTimeSource::Create(initial_vsync_interval, task_runner);
- }
-
- return make_scoped_ptr(new SyntheticBeginFrameSource(time_source));
+ scoped_ptr<DelayBasedTimeSource> time_source =
+ DelayBasedTimeSource::Create(initial_vsync_interval, task_runner);
+ return make_scoped_ptr(new SyntheticBeginFrameSource(time_source.Pass()));
}
SyntheticBeginFrameSource::SyntheticBeginFrameSource(
- scoped_refptr<DelayBasedTimeSource> time_source)
- : BeginFrameSourceMixIn(), time_source_(time_source) {
+ scoped_ptr<DelayBasedTimeSource> time_source)
+ : BeginFrameSourceBase(), time_source_(time_source.Pass()) {
time_source_->SetActive(false);
time_source_->SetClient(this);
}
SyntheticBeginFrameSource::~SyntheticBeginFrameSource() {
- if (NeedsBeginFrames())
- time_source_->SetActive(false);
+ time_source_->SetActive(false);
}
void SyntheticBeginFrameSource::OnUpdateVSyncParameters(
@@ -248,18 +238,19 @@ BeginFrameArgs SyntheticBeginFrameSource::CreateBeginFrameArgs(
time_source_->Interval(), type);
}
-// TimeSourceClient support
+// DelayBasedTimeSourceClient support
void SyntheticBeginFrameSource::OnTimerTick() {
CallOnBeginFrame(CreateBeginFrameArgs(time_source_->LastTickTime(),
BeginFrameArgs::NORMAL));
}
-// BeginFrameSourceMixIn support
+// BeginFrameSourceBase support
void SyntheticBeginFrameSource::OnNeedsBeginFramesChange(
bool needs_begin_frames) {
base::TimeTicks missed_tick_time =
time_source_->SetActive(needs_begin_frames);
if (!missed_tick_time.is_null()) {
+ DCHECK(needs_begin_frames);
CallOnBeginFrame(
CreateBeginFrameArgs(missed_tick_time, BeginFrameArgs::MISSED));
}
@@ -269,7 +260,7 @@ void SyntheticBeginFrameSource::OnNeedsBeginFramesChange(
void SyntheticBeginFrameSource::AsValueInto(
base::trace_event::TracedValue* dict) const {
dict->SetString("type", "SyntheticBeginFrameSource");
- BeginFrameSourceMixIn::AsValueInto(dict);
+ BeginFrameSourceBase::AsValueInto(dict);
dict->BeginDictionary("time_source");
time_source_->AsValueInto(dict);
@@ -282,7 +273,7 @@ scoped_ptr<BeginFrameSourceMultiplexer> BeginFrameSourceMultiplexer::Create() {
}
BeginFrameSourceMultiplexer::BeginFrameSourceMultiplexer()
- : BeginFrameSourceMixIn(),
+ : BeginFrameSourceBase(),
minimum_interval_(base::TimeDelta()),
active_source_(NULL),
source_list_() {
@@ -290,7 +281,7 @@ BeginFrameSourceMultiplexer::BeginFrameSourceMultiplexer()
BeginFrameSourceMultiplexer::BeginFrameSourceMultiplexer(
base::TimeDelta minimum_interval)
- : BeginFrameSourceMixIn(),
+ : BeginFrameSourceBase(),
minimum_interval_(minimum_interval),
active_source_(NULL),
source_list_() {
diff --git a/chromium/cc/scheduler/begin_frame_source.h b/chromium/cc/scheduler/begin_frame_source.h
index d845dacd8e4..f6f1a789da7 100644
--- a/chromium/cc/scheduler/begin_frame_source.h
+++ b/chromium/cc/scheduler/begin_frame_source.h
@@ -11,7 +11,6 @@
#include "base/logging.h"
#include "base/trace_event/trace_event.h"
#include "cc/output/begin_frame_args.h"
-#include "cc/output/vsync_parameter_observer.h"
#include "cc/scheduler/delay_based_time_source.h"
namespace cc {
@@ -53,23 +52,23 @@ class CC_EXPORT BeginFrameObserver {
virtual void AsValueInto(base::trace_event::TracedValue* dict) const = 0;
};
-// Simple mix in which implements a BeginFrameObserver which checks the
+// Simple base class which implements a BeginFrameObserver which checks the
// incoming values meet the BeginFrameObserver requirements and implements the
// required LastUsedBeginFrameArgs behaviour.
//
-// Users of this mix in should;
-// - Implement the OnBeginFrameMixInDelegate function.
+// Users of this class should;
+// - Implement the OnBeginFrameDerivedImpl function.
// - Recommended (but not required) to call
-// BeginFrameObserverMixIn::OnValueInto in their overridden OnValueInto
+// BeginFrameObserverBase::OnValueInto in their overridden OnValueInto
// function.
-class CC_EXPORT BeginFrameObserverMixIn : public BeginFrameObserver {
+class CC_EXPORT BeginFrameObserverBase : public BeginFrameObserver {
public:
- BeginFrameObserverMixIn();
+ BeginFrameObserverBase();
// BeginFrameObserver
// Traces |args| and DCHECK |args| satisfies pre-conditions then calls
- // OnBeginFrameMixInDelegate and updates the last_begin_frame_args_ value on
+ // OnBeginFrameDerivedImpl and updates the last_begin_frame_args_ value on
// true.
void OnBeginFrame(const BeginFrameArgs& args) override;
const BeginFrameArgs LastUsedBeginFrameArgs() const override;
@@ -80,10 +79,13 @@ class CC_EXPORT BeginFrameObserverMixIn : public BeginFrameObserver {
protected:
// Subclasses should override this method!
// Return true if the given argument is (or will be) used.
- virtual bool OnBeginFrameMixInDelegate(const BeginFrameArgs& args) = 0;
+ virtual bool OnBeginFrameDerivedImpl(const BeginFrameArgs& args) = 0;
BeginFrameArgs last_begin_frame_args_;
int64_t dropped_begin_frame_args_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(BeginFrameObserverBase);
};
// Interface for a class which produces BeginFrame calls to a
@@ -125,16 +127,16 @@ class CC_EXPORT BeginFrameSource {
virtual void AsValueInto(base::trace_event::TracedValue* dict) const = 0;
};
-// Simple mix in which implements a BeginFrameSource.
+// Simple base class which implements a BeginFrameSource.
// Implementation classes should:
// - Implement the pure virtual (Set)NeedsBeginFrames methods from
// BeginFrameSource.
// - Use the CallOnBeginFrame method to call to the observer(s).
-// - Recommended (but not required) to call BeginFrameSourceMixIn::AsValueInto
+// - Recommended (but not required) to call BeginFrameSourceBase::AsValueInto
// in their own AsValueInto implementation.
-class CC_EXPORT BeginFrameSourceMixIn : public BeginFrameSource {
+class CC_EXPORT BeginFrameSourceBase : public BeginFrameSource {
public:
- ~BeginFrameSourceMixIn() override {}
+ ~BeginFrameSourceBase() override {}
// BeginFrameSource
bool NeedsBeginFrames() const final;
@@ -149,7 +151,7 @@ class CC_EXPORT BeginFrameSourceMixIn : public BeginFrameSource {
void AsValueInto(base::trace_event::TracedValue* dict) const override;
protected:
- BeginFrameSourceMixIn();
+ BeginFrameSourceBase();
// These methods should be used by subclasses to make the call to the
// observers.
@@ -164,11 +166,13 @@ class CC_EXPORT BeginFrameSourceMixIn : public BeginFrameSource {
private:
bool inside_as_value_into_;
+
+ DISALLOW_COPY_AND_ASSIGN(BeginFrameSourceBase);
};
// A frame source which calls BeginFrame (at the next possible time) as soon as
// remaining frames reaches zero.
-class CC_EXPORT BackToBackBeginFrameSource : public BeginFrameSourceMixIn {
+class CC_EXPORT BackToBackBeginFrameSource : public BeginFrameSourceBase {
public:
static scoped_ptr<BackToBackBeginFrameSource> Create(
base::SingleThreadTaskRunner* task_runner);
@@ -189,54 +193,56 @@ class CC_EXPORT BackToBackBeginFrameSource : public BeginFrameSourceMixIn {
bool send_begin_frame_posted_;
- // BeginFrameSourceMixIn
+ // BeginFrameSourceBase
void OnNeedsBeginFramesChange(bool needs_begin_frames) override;
void BeginFrame();
private:
base::WeakPtrFactory<BackToBackBeginFrameSource> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(BackToBackBeginFrameSource);
};
// A frame source which is locked to an external parameters provides from a
// vsync source and generates BeginFrameArgs for it.
-class CC_EXPORT SyntheticBeginFrameSource : public BeginFrameSourceMixIn,
- public VSyncParameterObserver,
- public TimeSourceClient {
+class CC_EXPORT SyntheticBeginFrameSource : public BeginFrameSourceBase,
+ public DelayBasedTimeSourceClient {
public:
static scoped_ptr<SyntheticBeginFrameSource> Create(
base::SingleThreadTaskRunner* task_runner,
- base::TimeTicks initial_vsync_timebase,
base::TimeDelta initial_vsync_interval);
~SyntheticBeginFrameSource() override;
+ void OnUpdateVSyncParameters(base::TimeTicks new_vsync_timebase,
+ base::TimeDelta new_vsync_interval);
+
// Tracing
void AsValueInto(base::trace_event::TracedValue* dict) const override;
- // VSyncParameterObserver
- void OnUpdateVSyncParameters(base::TimeTicks new_vsync_timebase,
- base::TimeDelta new_vsync_interval) override;
-
- // TimeSourceClient
+ // DelayBasedTimeSourceClient
void OnTimerTick() override;
protected:
explicit SyntheticBeginFrameSource(
- scoped_refptr<DelayBasedTimeSource> time_source);
+ scoped_ptr<DelayBasedTimeSource> time_source);
BeginFrameArgs CreateBeginFrameArgs(base::TimeTicks frame_time,
BeginFrameArgs::BeginFrameArgsType type);
- // BeginFrameSourceMixIn
+ // BeginFrameSourceBase
void OnNeedsBeginFramesChange(bool needs_begin_frames) override;
- scoped_refptr<DelayBasedTimeSource> time_source_;
+ scoped_ptr<DelayBasedTimeSource> time_source_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SyntheticBeginFrameSource);
};
// A "virtual" frame source which lets you switch between multiple other frame
// sources while making sure the BeginFrameArgs stays increasing (possibly
// enforcing minimum boundry between BeginFrameArgs messages).
-class CC_EXPORT BeginFrameSourceMultiplexer : public BeginFrameSourceMixIn,
+class CC_EXPORT BeginFrameSourceMultiplexer : public BeginFrameSourceBase,
public BeginFrameObserver {
public:
static scoped_ptr<BeginFrameSourceMultiplexer> Create();
@@ -259,7 +265,7 @@ class CC_EXPORT BeginFrameSourceMultiplexer : public BeginFrameSourceMixIn,
// BeginFrameSource
void DidFinishFrame(size_t remaining_frames) override;
- // BeginFrameSourceMixIn
+ // BeginFrameSourceBase
void OnNeedsBeginFramesChange(bool needs_begin_frames) override;
// Tracing
@@ -276,6 +282,9 @@ class CC_EXPORT BeginFrameSourceMultiplexer : public BeginFrameSourceMixIn,
BeginFrameSource* active_source_;
std::set<BeginFrameSource*> source_list_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(BeginFrameSourceMultiplexer);
};
} // namespace cc
diff --git a/chromium/cc/scheduler/begin_frame_source_unittest.cc b/chromium/cc/scheduler/begin_frame_source_unittest.cc
index 22126bead45..1f85622878e 100644
--- a/chromium/cc/scheduler/begin_frame_source_unittest.cc
+++ b/chromium/cc/scheduler/begin_frame_source_unittest.cc
@@ -170,16 +170,16 @@ const BeginFrameArgs MockBeginFrameObserver::kDefaultBeginFrameArgs =
-1,
-1);
-// BeginFrameObserverMixIn testing ---------------------------------------
-class MockMinimalBeginFrameObserverMixIn : public BeginFrameObserverMixIn {
+// BeginFrameObserverBase testing ---------------------------------------
+class MockMinimalBeginFrameObserverBase : public BeginFrameObserverBase {
public:
- MOCK_METHOD1(OnBeginFrameMixInDelegate, bool(const BeginFrameArgs&));
+ MOCK_METHOD1(OnBeginFrameDerivedImpl, bool(const BeginFrameArgs&));
int64_t dropped_begin_frame_args() const { return dropped_begin_frame_args_; }
};
-TEST(BeginFrameObserverMixInTest, OnBeginFrameImplementation) {
+TEST(BeginFrameObserverBaseTest, OnBeginFrameImplementation) {
using ::testing::Return;
- MockMinimalBeginFrameObserverMixIn obs;
+ MockMinimalBeginFrameObserverBase obs;
::testing::InSequence ordered; // These calls should be ordered
// Initial conditions
@@ -192,7 +192,7 @@ TEST(BeginFrameObserverMixInTest, OnBeginFrameImplementation) {
BeginFrameArgs args1 =
CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 100, 200, 300);
- EXPECT_CALL(obs, OnBeginFrameMixInDelegate(args1)).WillOnce(Return(true));
+ EXPECT_CALL(obs, OnBeginFrameDerivedImpl(args1)).WillOnce(Return(true));
obs.OnBeginFrame(args1);
EXPECT_EQ(args1, obs.LastUsedBeginFrameArgs());
EXPECT_EQ(0, obs.dropped_begin_frame_args());
@@ -208,21 +208,21 @@ TEST(BeginFrameObserverMixInTest, OnBeginFrameImplementation) {
// Returning false shouldn't update the LastUsedBeginFrameArgs value.
BeginFrameArgs args2 =
CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 200, 300, 400);
- EXPECT_CALL(obs, OnBeginFrameMixInDelegate(args2)).WillOnce(Return(false));
+ EXPECT_CALL(obs, OnBeginFrameDerivedImpl(args2)).WillOnce(Return(false));
obs.OnBeginFrame(args2);
EXPECT_EQ(args1, obs.LastUsedBeginFrameArgs());
EXPECT_EQ(1, obs.dropped_begin_frame_args());
BeginFrameArgs args3 =
CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 150, 300, 400);
- EXPECT_CALL(obs, OnBeginFrameMixInDelegate(args3)).WillOnce(Return(true));
+ EXPECT_CALL(obs, OnBeginFrameDerivedImpl(args3)).WillOnce(Return(true));
obs.OnBeginFrame(args3);
EXPECT_EQ(args3, obs.LastUsedBeginFrameArgs());
EXPECT_EQ(1, obs.dropped_begin_frame_args());
}
// BeginFrameSource testing ----------------------------------------------
-TEST(BeginFrameSourceMixInTest, ObserverManipulation) {
+TEST(BeginFrameSourceBaseTest, ObserverManipulation) {
MockBeginFrameObserver obs;
MockBeginFrameObserver otherObs;
FakeBeginFrameSource source;
@@ -251,7 +251,7 @@ TEST(BeginFrameSourceMixInTest, ObserverManipulation) {
source.RemoveObserver(&otherObs);
}
-TEST(BeginFrameSourceMixInTest, Observer) {
+TEST(BeginFrameSourceBaseTest, Observer) {
FakeBeginFrameSource source;
MockBeginFrameObserver obs;
source.AddObserver(&obs);
@@ -266,12 +266,12 @@ TEST(BeginFrameSourceMixInTest, Observer) {
SEND_BEGIN_FRAME_USED(source, 700, 900, 300);
}
-TEST(BeginFrameSourceMixInTest, NoObserver) {
+TEST(BeginFrameSourceBaseTest, NoObserver) {
FakeBeginFrameSource source;
SEND_BEGIN_FRAME_DROP(source, 100, 200, 300);
}
-TEST(BeginFrameSourceMixInTest, NeedsBeginFrames) {
+TEST(BeginFrameSourceBaseTest, NeedsBeginFrames) {
FakeBeginFrameSource source;
EXPECT_FALSE(source.NeedsBeginFrames());
source.SetNeedsBeginFrames(true);
@@ -280,7 +280,7 @@ TEST(BeginFrameSourceMixInTest, NeedsBeginFrames) {
EXPECT_FALSE(source.NeedsBeginFrames());
}
-class LoopingBeginFrameObserver : public BeginFrameObserverMixIn {
+class LoopingBeginFrameObserver : public BeginFrameObserverBase {
public:
BeginFrameSource* source_;
@@ -292,13 +292,13 @@ class LoopingBeginFrameObserver : public BeginFrameObserverMixIn {
}
protected:
- // BeginFrameObserverMixIn
- bool OnBeginFrameMixInDelegate(const BeginFrameArgs& args) override {
+ // BeginFrameObserverBase
+ bool OnBeginFrameDerivedImpl(const BeginFrameArgs& args) override {
return true;
}
};
-TEST(BeginFrameSourceMixInTest, DetectAsValueIntoLoop) {
+TEST(BeginFrameSourceBaseTest, DetectAsValueIntoLoop) {
LoopingBeginFrameObserver obs;
FakeBeginFrameSource source;
@@ -314,20 +314,21 @@ TEST(BeginFrameSourceMixInTest, DetectAsValueIntoLoop) {
class TestBackToBackBeginFrameSource : public BackToBackBeginFrameSource {
public:
static scoped_ptr<TestBackToBackBeginFrameSource> Create(
- scoped_refptr<TestNowSource> now_src,
+ base::SimpleTestTickClock* now_src,
base::SingleThreadTaskRunner* task_runner) {
return make_scoped_ptr(
new TestBackToBackBeginFrameSource(now_src, task_runner));
}
protected:
- TestBackToBackBeginFrameSource(scoped_refptr<TestNowSource> now_src,
+ TestBackToBackBeginFrameSource(base::SimpleTestTickClock* now_src,
base::SingleThreadTaskRunner* task_runner)
: BackToBackBeginFrameSource(task_runner), now_src_(now_src) {}
- base::TimeTicks Now() override { return now_src_->Now(); }
+ base::TimeTicks Now() override { return now_src_->NowTicks(); }
- scoped_refptr<TestNowSource> now_src_;
+ // Not owned.
+ base::SimpleTestTickClock* now_src_;
};
class BackToBackBeginFrameSourceTest : public ::testing::Test {
@@ -335,18 +336,19 @@ class BackToBackBeginFrameSourceTest : public ::testing::Test {
static const int64_t kDeadline;
static const int64_t kInterval;
- scoped_refptr<TestNowSource> now_src_;
+ scoped_ptr<base::SimpleTestTickClock> now_src_;
scoped_refptr<OrderedSimpleTaskRunner> task_runner_;
scoped_ptr<TestBackToBackBeginFrameSource> source_;
scoped_ptr<MockBeginFrameObserver> obs_;
void SetUp() override {
- now_src_ = TestNowSource::Create(1000);
+ now_src_.reset(new base::SimpleTestTickClock());
+ now_src_->Advance(base::TimeDelta::FromMicroseconds(1000));
task_runner_ =
- make_scoped_refptr(new OrderedSimpleTaskRunner(now_src_, false));
+ make_scoped_refptr(new OrderedSimpleTaskRunner(now_src_.get(), false));
task_runner_->SetRunTaskLimit(1);
- source_ =
- TestBackToBackBeginFrameSource::Create(now_src_, task_runner_.get());
+ source_ = TestBackToBackBeginFrameSource::Create(now_src_.get(),
+ task_runner_.get());
obs_ = make_scoped_ptr(new ::testing::StrictMock<MockBeginFrameObserver>());
source_->AddObserver(obs_.get());
}
@@ -367,7 +369,7 @@ TEST_F(BackToBackBeginFrameSourceTest, SetNeedsBeginFramesSendsBeginFrame) {
task_runner_->RunUntilIdle();
EXPECT_BEGIN_FRAME_USED(*obs_, 1100, 1100 + kDeadline, kInterval);
- now_src_->AdvanceNowMicroseconds(100);
+ now_src_->Advance(base::TimeDelta::FromMicroseconds(100));
source_->DidFinishFrame(0);
task_runner_->RunUntilIdle();
}
@@ -390,7 +392,7 @@ TEST_F(BackToBackBeginFrameSourceTest,
source_->SetNeedsBeginFrames(true);
task_runner_->RunUntilIdle();
- now_src_->AdvanceNowMicroseconds(100);
+ now_src_->Advance(base::TimeDelta::FromMicroseconds(100));
source_->DidFinishFrame(0);
source_->SetNeedsBeginFrames(false);
@@ -404,14 +406,14 @@ TEST_F(BackToBackBeginFrameSourceTest,
source_->SetNeedsBeginFrames(true);
task_runner_->RunUntilIdle();
- now_src_->AdvanceNowMicroseconds(100);
+ now_src_->Advance(base::TimeDelta::FromMicroseconds(100));
source_->SetNeedsBeginFrames(false);
- now_src_->AdvanceNowMicroseconds(10);
+ now_src_->Advance(base::TimeDelta::FromMicroseconds(10));
source_->DidFinishFrame(0);
- now_src_->AdvanceNowMicroseconds(10);
+ now_src_->Advance(base::TimeDelta::FromMicroseconds(10));
source_->SetNeedsBeginFrames(false);
- now_src_->AdvanceNowMicroseconds(10);
+ now_src_->Advance(base::TimeDelta::FromMicroseconds(10));
source_->SetNeedsBeginFrames(true);
EXPECT_BEGIN_FRAME_USED(*obs_, 1130, 1130 + kDeadline, kInterval);
@@ -425,13 +427,13 @@ TEST_F(BackToBackBeginFrameSourceTest,
source_->SetNeedsBeginFrames(true);
task_runner_->RunUntilIdle();
- now_src_->AdvanceNowMicroseconds(100);
+ now_src_->Advance(base::TimeDelta::FromMicroseconds(100));
source_->DidFinishFrame(0);
- now_src_->AdvanceNowMicroseconds(10);
+ now_src_->Advance(base::TimeDelta::FromMicroseconds(10));
source_->SetNeedsBeginFrames(false);
- now_src_->AdvanceNowMicroseconds(10);
+ now_src_->Advance(base::TimeDelta::FromMicroseconds(10));
source_->SetNeedsBeginFrames(true);
- now_src_->AdvanceNowMicroseconds(10);
+ now_src_->Advance(base::TimeDelta::FromMicroseconds(10));
EXPECT_BEGIN_FRAME_USED(*obs_, 1130, 1130 + kDeadline, kInterval);
EXPECT_TRUE(task_runner_->HasPendingTasks());
@@ -449,7 +451,7 @@ TEST_F(BackToBackBeginFrameSourceTest, DidFinishFrameRemainingFrames) {
source_->SetNeedsBeginFrames(true);
task_runner_->RunUntilIdle();
- now_src_->AdvanceNowMicroseconds(100);
+ now_src_->Advance(base::TimeDelta::FromMicroseconds(100));
source_->DidFinishFrame(3);
EXPECT_FALSE(task_runner_->HasPendingTasks());
@@ -469,14 +471,14 @@ TEST_F(BackToBackBeginFrameSourceTest, DidFinishFrameMultipleCallsIdempotent) {
EXPECT_BEGIN_FRAME_USED(*obs_, 1000, 1000 + kDeadline, kInterval);
task_runner_->RunUntilIdle();
- now_src_->AdvanceNowMicroseconds(100);
+ now_src_->Advance(base::TimeDelta::FromMicroseconds(100));
source_->DidFinishFrame(0);
source_->DidFinishFrame(0);
source_->DidFinishFrame(0);
EXPECT_BEGIN_FRAME_USED(*obs_, 1100, 1100 + kDeadline, kInterval);
task_runner_->RunUntilIdle();
- now_src_->AdvanceNowMicroseconds(100);
+ now_src_->Advance(base::TimeDelta::FromMicroseconds(100));
source_->DidFinishFrame(0);
source_->DidFinishFrame(0);
source_->DidFinishFrame(0);
@@ -489,9 +491,9 @@ TEST_F(BackToBackBeginFrameSourceTest, DelayInPostedTaskProducesCorrectFrame) {
source_->SetNeedsBeginFrames(true);
task_runner_->RunUntilIdle();
- now_src_->AdvanceNowMicroseconds(100);
+ now_src_->Advance(base::TimeDelta::FromMicroseconds(100));
source_->DidFinishFrame(0);
- now_src_->AdvanceNowMicroseconds(50);
+ now_src_->Advance(base::TimeDelta::FromMicroseconds(50));
EXPECT_BEGIN_FRAME_USED(*obs_, 1150, 1150 + kDeadline, kInterval);
EXPECT_TRUE(task_runner_->HasPendingTasks());
@@ -501,17 +503,19 @@ TEST_F(BackToBackBeginFrameSourceTest, DelayInPostedTaskProducesCorrectFrame) {
// SyntheticBeginFrameSource testing ------------------------------------------
class SyntheticBeginFrameSourceTest : public ::testing::Test {
public:
- scoped_refptr<TestNowSource> now_src_;
+ scoped_ptr<base::SimpleTestTickClock> now_src_;
scoped_refptr<OrderedSimpleTaskRunner> task_runner_;
scoped_ptr<TestSyntheticBeginFrameSource> source_;
scoped_ptr<MockBeginFrameObserver> obs_;
void SetUp() override {
- now_src_ = TestNowSource::Create(1000);
+ now_src_.reset(new base::SimpleTestTickClock());
+ now_src_->Advance(base::TimeDelta::FromMicroseconds(1000));
task_runner_ =
- make_scoped_refptr(new OrderedSimpleTaskRunner(now_src_, false));
+ make_scoped_refptr(new OrderedSimpleTaskRunner(now_src_.get(), false));
source_ = TestSyntheticBeginFrameSource::Create(
- now_src_, task_runner_.get(), base::TimeDelta::FromMicroseconds(10000));
+ now_src_.get(), task_runner_.get(),
+ base::TimeDelta::FromMicroseconds(10000));
obs_ = make_scoped_ptr(new MockBeginFrameObserver());
source_->AddObserver(obs_.get());
}
@@ -521,7 +525,7 @@ class SyntheticBeginFrameSourceTest : public ::testing::Test {
TEST_F(SyntheticBeginFrameSourceTest,
SetNeedsBeginFramesCallsOnBeginFrameWithMissedTick) {
- now_src_->SetNowMicroseconds(10010);
+ now_src_->Advance(base::TimeDelta::FromMicroseconds(9010));
EXPECT_CALL((*obs_), OnBeginFrame(CreateBeginFrameArgsForTesting(
BEGINFRAME_FROM_HERE, 10000, 20000, 10000,
BeginFrameArgs::MISSED)));
@@ -535,7 +539,7 @@ TEST_F(SyntheticBeginFrameSourceTest,
EXPECT_EQ(10000, task_runner_->NextTaskTime().ToInternalValue());
EXPECT_BEGIN_FRAME_USED(*obs_, 10000, 20000, 10000);
- now_src_->SetNowMicroseconds(10010);
+ now_src_->Advance(base::TimeDelta::FromMicroseconds(9010));
task_runner_->RunPendingTasks();
}
diff --git a/chromium/cc/scheduler/begin_frame_tracker.cc b/chromium/cc/scheduler/begin_frame_tracker.cc
new file mode 100644
index 00000000000..3b526ccad00
--- /dev/null
+++ b/chromium/cc/scheduler/begin_frame_tracker.cc
@@ -0,0 +1,123 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/scheduler/begin_frame_tracker.h"
+
+namespace cc {
+
+BeginFrameTracker::BeginFrameTracker(const tracked_objects::Location& location)
+ : location_(location),
+ location_string_(location.ToString()),
+ current_updated_at_(),
+ current_args_(),
+ current_finished_at_(base::TraceTicks::FromInternalValue(-1)) {
+}
+
+BeginFrameTracker::~BeginFrameTracker() {
+}
+
+void BeginFrameTracker::Start(BeginFrameArgs new_args) {
+ // Trace the frame time being passed between BeginFrameTrackers.
+ TRACE_EVENT_FLOW_STEP0(
+ TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), "BeginFrameArgs",
+ new_args.frame_time.ToInternalValue(), location_string_);
+
+ // Trace this specific begin frame tracker Start/Finish times.
+ TRACE_EVENT_ASYNC_BEGIN2(
+ TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"),
+ location_string_.c_str(), new_args.frame_time.ToInternalValue(),
+ "new args", new_args.AsValue(), "current args", current_args_.AsValue());
+
+ // Check the new BeginFrameArgs are valid and monotonically increasing.
+ DCHECK(new_args.IsValid());
+ DCHECK_LE(current_args_.frame_time, new_args.frame_time);
+
+ DCHECK(HasFinished())
+ << "Tried to start a new frame before finishing an existing frame.";
+ current_updated_at_ = base::TraceTicks::Now();
+ current_args_ = new_args;
+ current_finished_at_ = base::TraceTicks();
+
+ // TODO(mithro): Add UMA tracking of delta between current_updated_at_ time
+ // and the new_args.frame_time argument. This will give us how long after a
+ // BeginFrameArgs message was created before we started processing it.
+}
+
+const BeginFrameArgs& BeginFrameTracker::Current() const {
+ DCHECK(!HasFinished())
+ << "Tried to use BeginFrameArgs after marking the frame finished.";
+ DCHECK(current_args_.IsValid())
+ << "Tried to use BeginFrameArgs before starting a frame!";
+ return current_args_;
+}
+
+void BeginFrameTracker::Finish() {
+ DCHECK(!HasFinished()) << "Tried to finish an already finished frame";
+ current_finished_at_ = base::TraceTicks::Now();
+ TRACE_EVENT_ASYNC_END0(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"),
+ location_string_.c_str(),
+ current_args_.frame_time.ToInternalValue());
+}
+
+const BeginFrameArgs& BeginFrameTracker::Last() const {
+ DCHECK(current_args_.IsValid())
+ << "Tried to use last BeginFrameArgs before starting a frame!";
+ DCHECK(HasFinished())
+ << "Tried to use last BeginFrameArgs before the frame is finished.";
+ return current_args_;
+}
+
+base::TimeDelta BeginFrameTracker::Interval() const {
+ base::TimeDelta interval = current_args_.interval;
+ // Normal interval will be ~16ms, 200Hz (5ms) screens are the fastest
+ // easily available so anything less than that is likely an error.
+ if (interval < base::TimeDelta::FromMilliseconds(1)) {
+ interval = BeginFrameArgs::DefaultInterval();
+ }
+ return interval;
+}
+
+void BeginFrameTracker::AsValueInto(
+ base::TimeTicks now,
+ base::trace_event::TracedValue* state) const {
+ state->SetInteger("updated_at_us", (current_updated_at_ - base::TraceTicks())
+ .InMicroseconds());
+ state->SetInteger("finished_at_us", (current_finished_at_ -
+ base::TraceTicks()).InMicroseconds());
+ if (HasFinished()) {
+ state->SetString("state", "FINISHED");
+ state->BeginDictionary("current_args_");
+ } else {
+ state->SetString("state", "USING");
+ state->BeginDictionary("last_args_");
+ }
+ current_args_.AsValueInto(state);
+ state->EndDictionary();
+
+ base::TimeTicks frame_time = current_args_.frame_time;
+ base::TimeTicks deadline = current_args_.deadline;
+ base::TimeDelta interval = current_args_.interval;
+ state->BeginDictionary("major_timestamps_in_ms");
+ state->SetDouble("0_interval", interval.InMillisecondsF());
+ state->SetDouble("1_now_to_deadline", (deadline - now).InMillisecondsF());
+ state->SetDouble("2_frame_time_to_now", (now - frame_time).InMillisecondsF());
+ state->SetDouble("3_frame_time_to_deadline",
+ (deadline - frame_time).InMillisecondsF());
+ state->SetDouble("4_now", (now - base::TimeTicks()).InMillisecondsF());
+ state->SetDouble("5_frame_time",
+ (frame_time - base::TimeTicks()).InMillisecondsF());
+ state->SetDouble("6_deadline",
+ (deadline - base::TimeTicks()).InMillisecondsF());
+ state->EndDictionary();
+}
+
+const BeginFrameArgs& BeginFrameTracker::DangerousMethodCurrentOrLast() const {
+ if (!HasFinished()) {
+ return Current();
+ } else {
+ return Last();
+ }
+}
+
+} // namespace cc
diff --git a/chromium/cc/scheduler/begin_frame_tracker.h b/chromium/cc/scheduler/begin_frame_tracker.h
new file mode 100644
index 00000000000..617f52b1324
--- /dev/null
+++ b/chromium/cc/scheduler/begin_frame_tracker.h
@@ -0,0 +1,97 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_SCHEDULER_BEGIN_FRAME_TRACKER_H_
+#define CC_SCHEDULER_BEGIN_FRAME_TRACKER_H_
+
+#include <set>
+#include <string>
+
+#include "base/location.h"
+#include "base/trace_event/trace_event.h"
+#include "base/trace_event/trace_event_argument.h"
+#include "cc/output/begin_frame_args.h"
+
+#define BEGINFRAMETRACKER_FROM_HERE FROM_HERE_WITH_EXPLICIT_FUNCTION("")
+
+namespace cc {
+
+// Microclass to trace and check properties for correct BeginFrameArgs (BFA)
+// usage and provide a few helper methods.
+//
+// With DCHECKs enable, this class checks the following "invariants";
+// * BFA are monotonically increasing.
+// * BFA is valid.
+// * The BFA is only used inside a given period.
+// * A new BFA isn't used before the last BFA is finished with.
+//
+// With the tracing category "cc.debug.scheduler.frames" enabled the tracker
+// will output the following trace information;
+// * Time period for which the BFA is in usage.
+// * The flow of BFA as they are passed between tracking objects.
+//
+// TODO(mithro): Record stats about the BeginFrameArgs
+class CC_EXPORT BeginFrameTracker {
+ public:
+ explicit BeginFrameTracker(const tracked_objects::Location& location);
+ ~BeginFrameTracker();
+
+ // The Start and Finish methods manage the period that a BFA should be
+ // accessed for. This allows tight control over the BFA and prevents
+ // accidental usage in the wrong period when code is split across multiple
+ // locations.
+
+ // Start using a new BFA value and check invariant properties.
+ // **Must** only be called after finishing with any previous BFA.
+ void Start(BeginFrameArgs new_args);
+ // Finish using the current BFA.
+ // **Must** only be called while still using a BFA.
+ void Finish();
+
+ // The two accessors methods allow access to the BFA stored inside the
+ // tracker. They are mutually exclusive, at any time it is only valid to call
+ // one or the other. This makes sure you understand exactly which BFA you are
+ // intending to use and verifies that is the case.
+
+ // Get the current BFA object.
+ // **Must** only be called between the start and finish methods calls.
+ const BeginFrameArgs& Current() const;
+ // Get the last used BFA.
+ // **Must** only be called when **not** between the start and finish method
+ // calls.
+ const BeginFrameArgs& Last() const;
+
+ // Helper method to try and return a valid interval property. Defaults to
+ // BFA::DefaultInterval() is no other interval can be found. Can be called at
+ // any time.
+ base::TimeDelta Interval() const;
+
+ void AsValueInto(base::TimeTicks now,
+ base::trace_event::TracedValue* dict) const;
+
+ // The following methods violate principles of how BeginFrameArgs should be
+ // used. These methods should only be used when there is no other choice.
+ bool DangerousMethodHasStarted() const {
+ return !current_updated_at_.is_null();
+ }
+ bool DangerousMethodHasFinished() const { return HasFinished(); }
+ const BeginFrameArgs& DangerousMethodCurrentOrLast() const;
+
+ private:
+ // Return if currently not between the start/end period. This method should
+ // be used extremely sparingly and normal indicates incorrect management of
+ // the BFA object. Can be called at any time.
+ bool HasFinished() const { return !current_finished_at_.is_null(); }
+
+ const tracked_objects::Location location_;
+ const std::string location_string_;
+
+ base::TraceTicks current_updated_at_;
+ BeginFrameArgs current_args_;
+ base::TraceTicks current_finished_at_;
+};
+
+} // namespace cc
+
+#endif // CC_SCHEDULER_BEGIN_FRAME_TRACKER_H_
diff --git a/chromium/cc/scheduler/compositor_timing_history.cc b/chromium/cc/scheduler/compositor_timing_history.cc
new file mode 100644
index 00000000000..b46c8a15cbe
--- /dev/null
+++ b/chromium/cc/scheduler/compositor_timing_history.cc
@@ -0,0 +1,217 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/scheduler/compositor_timing_history.h"
+
+#include "base/metrics/histogram.h"
+#include "base/trace_event/trace_event.h"
+#include "cc/debug/rendering_stats_instrumentation.h"
+
+// The estimates that affect the compositors deadline use the 100th percentile
+// to avoid missing the Browser's deadline.
+// The estimates related to main-thread responsiveness affect whether
+// we attempt to recovery latency or not and use the 50th percentile.
+// TODO(brianderson): Fine tune the percentiles below.
+const size_t kDurationHistorySize = 60;
+const double kBeginMainFrameToCommitEstimationPercentile = 50.0;
+const double kCommitToReadyToActivateEstimationPercentile = 50.0;
+const double kPrepareTilesEstimationPercentile = 100.0;
+const double kActivateEstimationPercentile = 100.0;
+const double kDrawEstimationPercentile = 100.0;
+
+namespace cc {
+
+CompositorTimingHistory::CompositorTimingHistory(
+ RenderingStatsInstrumentation* rendering_stats_instrumentation)
+ : enabled_(false),
+ begin_main_frame_to_commit_duration_history_(kDurationHistorySize),
+ commit_to_ready_to_activate_duration_history_(kDurationHistorySize),
+ prepare_tiles_duration_history_(kDurationHistorySize),
+ activate_duration_history_(kDurationHistorySize),
+ draw_duration_history_(kDurationHistorySize),
+ rendering_stats_instrumentation_(rendering_stats_instrumentation) {
+}
+
+CompositorTimingHistory::~CompositorTimingHistory() {
+}
+
+void CompositorTimingHistory::AsValueInto(
+ base::trace_event::TracedValue* state) const {
+ state->SetDouble("begin_main_frame_to_commit_duration_estimate_ms",
+ BeginMainFrameToCommitDurationEstimate().InMillisecondsF());
+ state->SetDouble("commit_to_ready_to_activate_duration_estimate_ms",
+ CommitToReadyToActivateDurationEstimate().InMillisecondsF());
+ state->SetDouble("prepare_tiles_duration_estimate_ms",
+ PrepareTilesDurationEstimate().InMillisecondsF());
+ state->SetDouble("activate_duration_estimate_ms",
+ ActivateDurationEstimate().InMillisecondsF());
+ state->SetDouble("draw_duration_estimate_ms",
+ DrawDurationEstimate().InMillisecondsF());
+}
+
+base::TimeTicks CompositorTimingHistory::Now() const {
+ return base::TimeTicks::Now();
+}
+
+void CompositorTimingHistory::SetRecordingEnabled(bool enabled) {
+ enabled_ = enabled;
+}
+
+base::TimeDelta
+CompositorTimingHistory::BeginMainFrameToCommitDurationEstimate() const {
+ return begin_main_frame_to_commit_duration_history_.Percentile(
+ kBeginMainFrameToCommitEstimationPercentile);
+}
+
+base::TimeDelta
+CompositorTimingHistory::CommitToReadyToActivateDurationEstimate() const {
+ return commit_to_ready_to_activate_duration_history_.Percentile(
+ kCommitToReadyToActivateEstimationPercentile);
+}
+
+base::TimeDelta CompositorTimingHistory::PrepareTilesDurationEstimate() const {
+ return prepare_tiles_duration_history_.Percentile(
+ kPrepareTilesEstimationPercentile);
+}
+
+base::TimeDelta CompositorTimingHistory::ActivateDurationEstimate() const {
+ return activate_duration_history_.Percentile(kActivateEstimationPercentile);
+}
+
+base::TimeDelta CompositorTimingHistory::DrawDurationEstimate() const {
+ return draw_duration_history_.Percentile(kDrawEstimationPercentile);
+}
+
+void CompositorTimingHistory::WillBeginMainFrame() {
+ DCHECK_EQ(base::TimeTicks(), begin_main_frame_sent_time_);
+ begin_main_frame_sent_time_ = Now();
+}
+
+void CompositorTimingHistory::BeginMainFrameAborted() {
+ DidCommit();
+}
+
+void CompositorTimingHistory::DidCommit() {
+ DCHECK_NE(base::TimeTicks(), begin_main_frame_sent_time_);
+
+ commit_time_ = Now();
+
+ base::TimeDelta begin_main_frame_to_commit_duration =
+ commit_time_ - begin_main_frame_sent_time_;
+
+ // Before adding the new data point to the timing history, see what we would
+ // have predicted for this frame. This allows us to keep track of the accuracy
+ // of our predictions.
+ rendering_stats_instrumentation_->AddBeginMainFrameToCommitDuration(
+ begin_main_frame_to_commit_duration,
+ BeginMainFrameToCommitDurationEstimate());
+
+ if (enabled_) {
+ begin_main_frame_to_commit_duration_history_.InsertSample(
+ begin_main_frame_to_commit_duration);
+ }
+
+ begin_main_frame_sent_time_ = base::TimeTicks();
+}
+
+void CompositorTimingHistory::WillPrepareTiles() {
+ DCHECK_EQ(base::TimeTicks(), start_prepare_tiles_time_);
+ start_prepare_tiles_time_ = Now();
+}
+
+void CompositorTimingHistory::DidPrepareTiles() {
+ DCHECK_NE(base::TimeTicks(), start_prepare_tiles_time_);
+
+ if (enabled_) {
+ base::TimeDelta prepare_tiles_duration = Now() - start_prepare_tiles_time_;
+ prepare_tiles_duration_history_.InsertSample(prepare_tiles_duration);
+ }
+
+ start_prepare_tiles_time_ = base::TimeTicks();
+}
+
+void CompositorTimingHistory::ReadyToActivate() {
+ // We only care about the first ready to activate signal
+ // after a commit.
+ if (commit_time_ == base::TimeTicks())
+ return;
+
+ base::TimeDelta time_since_commit = Now() - commit_time_;
+
+ // Before adding the new data point to the timing history, see what we would
+ // have predicted for this frame. This allows us to keep track of the accuracy
+ // of our predictions.
+ rendering_stats_instrumentation_->AddCommitToActivateDuration(
+ time_since_commit, CommitToReadyToActivateDurationEstimate());
+
+ if (enabled_) {
+ commit_to_ready_to_activate_duration_history_.InsertSample(
+ time_since_commit);
+ }
+
+ commit_time_ = base::TimeTicks();
+}
+
+void CompositorTimingHistory::WillActivate() {
+ DCHECK_EQ(base::TimeTicks(), start_activate_time_);
+ start_activate_time_ = Now();
+}
+
+void CompositorTimingHistory::DidActivate() {
+ DCHECK_NE(base::TimeTicks(), start_activate_time_);
+ if (enabled_) {
+ base::TimeDelta activate_duration = Now() - start_activate_time_;
+ activate_duration_history_.InsertSample(activate_duration);
+ }
+ start_activate_time_ = base::TimeTicks();
+}
+
+void CompositorTimingHistory::WillDraw() {
+ DCHECK_EQ(base::TimeTicks(), start_draw_time_);
+ start_draw_time_ = Now();
+}
+
+void CompositorTimingHistory::DidDraw() {
+ DCHECK_NE(base::TimeTicks(), start_draw_time_);
+ base::TimeDelta draw_duration = Now() - start_draw_time_;
+
+ // Before adding the new data point to the timing history, see what we would
+ // have predicted for this frame. This allows us to keep track of the accuracy
+ // of our predictions.
+ base::TimeDelta draw_duration_estimate = DrawDurationEstimate();
+ rendering_stats_instrumentation_->AddDrawDuration(draw_duration,
+ draw_duration_estimate);
+
+ AddDrawDurationUMA(draw_duration, draw_duration_estimate);
+
+ if (enabled_) {
+ draw_duration_history_.InsertSample(draw_duration);
+ }
+
+ start_draw_time_ = base::TimeTicks();
+}
+
+void CompositorTimingHistory::AddDrawDurationUMA(
+ base::TimeDelta draw_duration,
+ base::TimeDelta draw_duration_estimate) {
+ base::TimeDelta draw_duration_overestimate;
+ base::TimeDelta draw_duration_underestimate;
+ if (draw_duration > draw_duration_estimate)
+ draw_duration_underestimate = draw_duration - draw_duration_estimate;
+ else
+ draw_duration_overestimate = draw_duration_estimate - draw_duration;
+ UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDuration", draw_duration,
+ base::TimeDelta::FromMilliseconds(1),
+ base::TimeDelta::FromMilliseconds(100), 50);
+ UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDurationUnderestimate",
+ draw_duration_underestimate,
+ base::TimeDelta::FromMilliseconds(1),
+ base::TimeDelta::FromMilliseconds(100), 50);
+ UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDurationOverestimate",
+ draw_duration_overestimate,
+ base::TimeDelta::FromMilliseconds(1),
+ base::TimeDelta::FromMilliseconds(100), 50);
+}
+
+} // namespace cc
diff --git a/chromium/cc/scheduler/compositor_timing_history.h b/chromium/cc/scheduler/compositor_timing_history.h
new file mode 100644
index 00000000000..d64c38f1cbe
--- /dev/null
+++ b/chromium/cc/scheduler/compositor_timing_history.h
@@ -0,0 +1,75 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_SCHEDULER_COMPOSITOR_TIMING_HISTORY_H_
+#define CC_SCHEDULER_COMPOSITOR_TIMING_HISTORY_H_
+
+#include "cc/base/rolling_time_delta_history.h"
+
+namespace base {
+namespace trace_event {
+class TracedValue;
+} // namespace trace_event
+} // namespace base
+
+namespace cc {
+
+class RenderingStatsInstrumentation;
+
+class CC_EXPORT CompositorTimingHistory {
+ public:
+ explicit CompositorTimingHistory(
+ RenderingStatsInstrumentation* rendering_stats_instrumentation);
+ virtual ~CompositorTimingHistory();
+
+ void AsValueInto(base::trace_event::TracedValue* state) const;
+
+ virtual base::TimeDelta BeginMainFrameToCommitDurationEstimate() const;
+ virtual base::TimeDelta CommitToReadyToActivateDurationEstimate() const;
+ virtual base::TimeDelta PrepareTilesDurationEstimate() const;
+ virtual base::TimeDelta ActivateDurationEstimate() const;
+ virtual base::TimeDelta DrawDurationEstimate() const;
+
+ void SetRecordingEnabled(bool enabled);
+
+ void WillBeginMainFrame();
+ void BeginMainFrameAborted();
+ void DidCommit();
+ void WillPrepareTiles();
+ void DidPrepareTiles();
+ void ReadyToActivate();
+ void WillActivate();
+ void DidActivate();
+ void WillDraw();
+ void DidDraw();
+
+ protected:
+ virtual base::TimeTicks Now() const;
+
+ void AddDrawDurationUMA(base::TimeDelta draw_duration,
+ base::TimeDelta draw_duration_estimate);
+
+ bool enabled_;
+
+ RollingTimeDeltaHistory begin_main_frame_to_commit_duration_history_;
+ RollingTimeDeltaHistory commit_to_ready_to_activate_duration_history_;
+ RollingTimeDeltaHistory prepare_tiles_duration_history_;
+ RollingTimeDeltaHistory activate_duration_history_;
+ RollingTimeDeltaHistory draw_duration_history_;
+
+ base::TimeTicks begin_main_frame_sent_time_;
+ base::TimeTicks commit_time_;
+ base::TimeTicks start_prepare_tiles_time_;
+ base::TimeTicks start_activate_time_;
+ base::TimeTicks start_draw_time_;
+
+ RenderingStatsInstrumentation* rendering_stats_instrumentation_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(CompositorTimingHistory);
+};
+
+} // namespace cc
+
+#endif // CC_SCHEDULER_COMPOSITOR_TIMING_HISTORY_H_
diff --git a/chromium/cc/scheduler/compositor_timing_history_unittest.cc b/chromium/cc/scheduler/compositor_timing_history_unittest.cc
new file mode 100644
index 00000000000..6045e3a960a
--- /dev/null
+++ b/chromium/cc/scheduler/compositor_timing_history_unittest.cc
@@ -0,0 +1,140 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/scheduler/compositor_timing_history.h"
+
+#include "cc/debug/rendering_stats_instrumentation.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+namespace {
+
+class CompositorTimingHistoryTest;
+
+class TestCompositorTimingHistory : public CompositorTimingHistory {
+ public:
+ TestCompositorTimingHistory(CompositorTimingHistoryTest* test,
+ RenderingStatsInstrumentation* rendering_stats)
+ : CompositorTimingHistory(rendering_stats), test_(test) {}
+
+ protected:
+ base::TimeTicks Now() const override;
+
+ CompositorTimingHistoryTest* test_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestCompositorTimingHistory);
+};
+
+class CompositorTimingHistoryTest : public testing::Test {
+ public:
+ CompositorTimingHistoryTest()
+ : rendering_stats_(RenderingStatsInstrumentation::Create()),
+ timing_history_(this, rendering_stats_.get()) {
+ AdvanceNowBy(base::TimeDelta::FromMilliseconds(1));
+ timing_history_.SetRecordingEnabled(true);
+ }
+
+ void AdvanceNowBy(base::TimeDelta delta) { now_ += delta; }
+
+ base::TimeTicks Now() { return now_; }
+
+ protected:
+ scoped_ptr<RenderingStatsInstrumentation> rendering_stats_;
+ TestCompositorTimingHistory timing_history_;
+ base::TimeTicks now_;
+};
+
+base::TimeTicks TestCompositorTimingHistory::Now() const {
+ return test_->Now();
+}
+
+TEST_F(CompositorTimingHistoryTest, AllSequentialCommit) {
+ base::TimeDelta one_second = base::TimeDelta::FromSeconds(1);
+
+ base::TimeDelta begin_main_frame_to_commit_duration =
+ base::TimeDelta::FromMilliseconds(1);
+ base::TimeDelta prepare_tiles_duration = base::TimeDelta::FromMilliseconds(2);
+ base::TimeDelta prepare_tiles_end_to_ready_to_activate_duration =
+ base::TimeDelta::FromMilliseconds(1);
+ base::TimeDelta commit_to_ready_to_activate_duration =
+ base::TimeDelta::FromMilliseconds(3);
+ base::TimeDelta activate_duration = base::TimeDelta::FromMilliseconds(4);
+ base::TimeDelta draw_duration = base::TimeDelta::FromMilliseconds(5);
+
+ timing_history_.WillBeginMainFrame();
+ AdvanceNowBy(begin_main_frame_to_commit_duration);
+ // timing_history_.BeginMainFrameAborted();
+ timing_history_.DidCommit();
+ timing_history_.WillPrepareTiles();
+ AdvanceNowBy(prepare_tiles_duration);
+ timing_history_.DidPrepareTiles();
+ AdvanceNowBy(prepare_tiles_end_to_ready_to_activate_duration);
+ timing_history_.ReadyToActivate();
+ // Do not count idle time between notification and actual activation.
+ AdvanceNowBy(one_second);
+ timing_history_.WillActivate();
+ AdvanceNowBy(activate_duration);
+ timing_history_.DidActivate();
+ // Do not count idle time between activate and draw.
+ AdvanceNowBy(one_second);
+ timing_history_.WillDraw();
+ AdvanceNowBy(draw_duration);
+ timing_history_.DidDraw();
+
+ EXPECT_EQ(begin_main_frame_to_commit_duration,
+ timing_history_.BeginMainFrameToCommitDurationEstimate());
+ EXPECT_EQ(commit_to_ready_to_activate_duration,
+ timing_history_.CommitToReadyToActivateDurationEstimate());
+ EXPECT_EQ(prepare_tiles_duration,
+ timing_history_.PrepareTilesDurationEstimate());
+ EXPECT_EQ(activate_duration, timing_history_.ActivateDurationEstimate());
+ EXPECT_EQ(draw_duration, timing_history_.DrawDurationEstimate());
+}
+
+TEST_F(CompositorTimingHistoryTest, AllSequentialBeginMainFrameAborted) {
+ base::TimeDelta one_second = base::TimeDelta::FromSeconds(1);
+
+ base::TimeDelta begin_main_frame_to_commit_duration =
+ base::TimeDelta::FromMilliseconds(1);
+ base::TimeDelta prepare_tiles_duration = base::TimeDelta::FromMilliseconds(2);
+ base::TimeDelta prepare_tiles_end_to_ready_to_activate_duration =
+ base::TimeDelta::FromMilliseconds(1);
+ base::TimeDelta commit_to_ready_to_activate_duration =
+ base::TimeDelta::FromMilliseconds(3);
+ base::TimeDelta activate_duration = base::TimeDelta::FromMilliseconds(4);
+ base::TimeDelta draw_duration = base::TimeDelta::FromMilliseconds(5);
+
+ timing_history_.WillBeginMainFrame();
+ AdvanceNowBy(begin_main_frame_to_commit_duration);
+ // BeginMainFrameAborted counts as a commit complete.
+ timing_history_.BeginMainFrameAborted();
+ timing_history_.WillPrepareTiles();
+ AdvanceNowBy(prepare_tiles_duration);
+ timing_history_.DidPrepareTiles();
+ AdvanceNowBy(prepare_tiles_end_to_ready_to_activate_duration);
+ timing_history_.ReadyToActivate();
+ // Do not count idle time between notification and actual activation.
+ AdvanceNowBy(one_second);
+ timing_history_.WillActivate();
+ AdvanceNowBy(activate_duration);
+ timing_history_.DidActivate();
+ // Do not count idle time between activate and draw.
+ AdvanceNowBy(one_second);
+ timing_history_.WillDraw();
+ AdvanceNowBy(draw_duration);
+ timing_history_.DidDraw();
+
+ EXPECT_EQ(begin_main_frame_to_commit_duration,
+ timing_history_.BeginMainFrameToCommitDurationEstimate());
+ EXPECT_EQ(commit_to_ready_to_activate_duration,
+ timing_history_.CommitToReadyToActivateDurationEstimate());
+ EXPECT_EQ(prepare_tiles_duration,
+ timing_history_.PrepareTilesDurationEstimate());
+ EXPECT_EQ(activate_duration, timing_history_.ActivateDurationEstimate());
+ EXPECT_EQ(draw_duration, timing_history_.DrawDurationEstimate());
+}
+
+} // namespace
+} // namespace cc
diff --git a/chromium/cc/scheduler/delay_based_time_source.cc b/chromium/cc/scheduler/delay_based_time_source.cc
index ef43524a878..8e633ef5215 100644
--- a/chromium/cc/scheduler/delay_based_time_source.cc
+++ b/chromium/cc/scheduler/delay_based_time_source.cc
@@ -37,67 +37,43 @@ static const double kPhaseChangeThreshold = 0.25;
// The following methods correspond to the DelayBasedTimeSource that uses
// the base::TimeTicks::Now as the timebase.
-scoped_refptr<DelayBasedTimeSourceHighRes> DelayBasedTimeSourceHighRes::Create(
- base::TimeDelta interval,
- base::SingleThreadTaskRunner* task_runner) {
- return make_scoped_refptr(
- new DelayBasedTimeSourceHighRes(interval, task_runner));
-}
-
-DelayBasedTimeSourceHighRes::DelayBasedTimeSourceHighRes(
- base::TimeDelta interval,
- base::SingleThreadTaskRunner* task_runner)
- : DelayBasedTimeSource(interval, task_runner) {
-}
-
-DelayBasedTimeSourceHighRes::~DelayBasedTimeSourceHighRes() {}
-
-base::TimeTicks DelayBasedTimeSourceHighRes::Now() const {
- return base::TimeTicks::Now();
-}
-
-// The following methods correspond to the DelayBasedTimeSource that uses
-// the base::TimeTicks::Now as the timebase.
-scoped_refptr<DelayBasedTimeSource> DelayBasedTimeSource::Create(
- base::TimeDelta interval,
- base::SingleThreadTaskRunner* task_runner) {
- return make_scoped_refptr(new DelayBasedTimeSource(interval, task_runner));
-}
-
DelayBasedTimeSource::DelayBasedTimeSource(
base::TimeDelta interval,
base::SingleThreadTaskRunner* task_runner)
- : client_(NULL),
- last_tick_time_(base::TimeTicks() - interval),
- current_parameters_(interval, base::TimeTicks()),
- next_parameters_(interval, base::TimeTicks()),
+ : client_(nullptr),
active_(false),
+ timebase_(base::TimeTicks()),
+ interval_(interval),
+ last_tick_time_(base::TimeTicks() - interval),
+ next_tick_time_(base::TimeTicks()),
task_runner_(task_runner),
weak_factory_(this) {
- DCHECK_GT(interval.ToInternalValue(), 0);
+ DCHECK_GT(interval, base::TimeDelta());
}
DelayBasedTimeSource::~DelayBasedTimeSource() {}
base::TimeTicks DelayBasedTimeSource::SetActive(bool active) {
TRACE_EVENT1("cc", "DelayBasedTimeSource::SetActive", "active", active);
+
if (active == active_)
return base::TimeTicks();
+
active_ = active;
if (!active_) {
- weak_factory_.InvalidateWeakPtrs();
+ next_tick_time_ = base::TimeTicks();
+ tick_closure_.Cancel();
return base::TimeTicks();
}
- PostNextTickTask(Now());
+ ResetTickTask(Now());
// Determine if there was a tick that was missed while not active.
- base::TimeTicks last_tick_time_if_always_active =
- current_parameters_.tick_target - current_parameters_.interval;
- base::TimeTicks new_tick_time_threshold =
- last_tick_time_ + current_parameters_.interval / kDoubleTickDivisor;
- if (last_tick_time_if_always_active > new_tick_time_threshold) {
+ base::TimeTicks last_tick_time_if_always_active = next_tick_time_ - interval_;
+ base::TimeTicks last_tick_time_threshold =
+ last_tick_time_ + interval_ / kDoubleTickDivisor;
+ if (last_tick_time_if_always_active > last_tick_time_threshold) {
last_tick_time_ = last_tick_time_if_always_active;
return last_tick_time_;
}
@@ -105,6 +81,10 @@ base::TimeTicks DelayBasedTimeSource::SetActive(bool active) {
return base::TimeTicks();
}
+base::TimeDelta DelayBasedTimeSource::Interval() const {
+ return interval_;
+}
+
bool DelayBasedTimeSource::Active() const { return active_; }
base::TimeTicks DelayBasedTimeSource::LastTickTime() const {
@@ -112,13 +92,13 @@ base::TimeTicks DelayBasedTimeSource::LastTickTime() const {
}
base::TimeTicks DelayBasedTimeSource::NextTickTime() const {
- return Active() ? current_parameters_.tick_target : base::TimeTicks();
+ return next_tick_time_;
}
-void DelayBasedTimeSource::OnTimerFired() {
+void DelayBasedTimeSource::OnTimerTick() {
DCHECK(active_);
- last_tick_time_ = current_parameters_.tick_target;
+ last_tick_time_ = next_tick_time_;
PostNextTickTask(Now());
@@ -127,31 +107,34 @@ void DelayBasedTimeSource::OnTimerFired() {
client_->OnTimerTick();
}
-void DelayBasedTimeSource::SetClient(TimeSourceClient* client) {
+void DelayBasedTimeSource::SetClient(DelayBasedTimeSourceClient* client) {
client_ = client;
}
void DelayBasedTimeSource::SetTimebaseAndInterval(base::TimeTicks timebase,
base::TimeDelta interval) {
- DCHECK_GT(interval.ToInternalValue(), 0);
- next_parameters_.interval = interval;
- next_parameters_.tick_target = timebase;
-
- if (!active_) {
- // If we aren't active, there's no need to reset the timer.
- return;
- }
+ DCHECK_GT(interval, base::TimeDelta());
// If the change in interval is larger than the change threshold,
// request an immediate reset.
- double interval_delta =
- std::abs((interval - current_parameters_.interval).InSecondsF());
+ double interval_delta = std::abs((interval - interval_).InSecondsF());
+ // Comparing with next_tick_time_ is the right thing to do because we want to
+ // know if we want to cancel the existing tick task and schedule a new one.
+ // Also next_tick_time_ = timebase_ mod interval_.
+ double timebase_delta = std::abs((timebase - next_tick_time_).InSecondsF());
+
+ interval_ = interval;
+ timebase_ = timebase;
+
+ // If we aren't active, there's no need to reset the timer.
+ if (!active_)
+ return;
+
double interval_change = interval_delta / interval.InSecondsF();
if (interval_change > kIntervalChangeThreshold) {
TRACE_EVENT_INSTANT0("cc", "DelayBasedTimeSource::IntervalChanged",
TRACE_EVENT_SCOPE_THREAD);
- SetActive(false);
- SetActive(true);
+ ResetTickTask(Now());
return;
}
@@ -161,16 +144,13 @@ void DelayBasedTimeSource::SetTimebaseAndInterval(base::TimeTicks timebase,
// fmod just happens to return something near zero. Assuming the timebase
// is very recent though, which it should be, we'll still be ok because the
// old clock and new clock just happen to line up.
- double target_delta =
- std::abs((timebase - current_parameters_.tick_target).InSecondsF());
double phase_change =
- fmod(target_delta, interval.InSecondsF()) / interval.InSecondsF();
+ fmod(timebase_delta, interval.InSecondsF()) / interval.InSecondsF();
if (phase_change > kPhaseChangeThreshold &&
phase_change < (1.0 - kPhaseChangeThreshold)) {
TRACE_EVENT_INSTANT0("cc", "DelayBasedTimeSource::PhaseChanged",
TRACE_EVENT_SCOPE_THREAD);
- SetActive(false);
- SetActive(true);
+ ResetTickTask(Now());
return;
}
}
@@ -233,47 +213,41 @@ base::TimeTicks DelayBasedTimeSource::Now() const {
// is not reset.
// now=37 tick_target=16.667 new_target=50.000 -->
// tick(), PostDelayedTask(floor(50.000-37)) --> PostDelayedTask(13)
-base::TimeTicks DelayBasedTimeSource::NextTickTarget(base::TimeTicks now) {
- base::TimeTicks new_tick_target = now.SnappedToNextTick(
- next_parameters_.tick_target, next_parameters_.interval);
- DCHECK(now <= new_tick_target)
+base::TimeTicks DelayBasedTimeSource::NextTickTarget(
+ base::TimeTicks now) const {
+ base::TimeTicks next_tick_target =
+ now.SnappedToNextTick(timebase_, interval_);
+ DCHECK(now <= next_tick_target)
<< "now = " << now.ToInternalValue()
- << "; new_tick_target = " << new_tick_target.ToInternalValue()
- << "; new_interval = " << next_parameters_.interval.InMicroseconds()
- << "; tick_target = " << next_parameters_.tick_target.ToInternalValue();
+ << "; new_tick_target = " << next_tick_target.ToInternalValue()
+ << "; new_interval = " << interval_.InMicroseconds()
+ << "; new_timbase = " << timebase_.ToInternalValue();
// Avoid double ticks when:
// 1) Turning off the timer and turning it right back on.
// 2) Jittery data is passed to SetTimebaseAndInterval().
- if (new_tick_target - last_tick_time_ <=
- next_parameters_.interval / kDoubleTickDivisor)
- new_tick_target += next_parameters_.interval;
+ if (next_tick_target - last_tick_time_ <= interval_ / kDoubleTickDivisor)
+ next_tick_target += interval_;
- return new_tick_target;
+ return next_tick_target;
}
void DelayBasedTimeSource::PostNextTickTask(base::TimeTicks now) {
- base::TimeTicks new_tick_target = NextTickTarget(now);
-
+ next_tick_time_ = NextTickTarget(now);
+ DCHECK(next_tick_time_ >= now);
// Post another task *before* the tick and update state
- base::TimeDelta delay;
- if (now <= new_tick_target)
- delay = new_tick_target - now;
- task_runner_->PostDelayedTask(FROM_HERE,
- base::Bind(&DelayBasedTimeSource::OnTimerFired,
- weak_factory_.GetWeakPtr()),
- delay);
-
- next_parameters_.tick_target = new_tick_target;
- current_parameters_ = next_parameters_;
+ base::TimeDelta delay = next_tick_time_ - now;
+ task_runner_->PostDelayedTask(FROM_HERE, tick_closure_.callback(), delay);
}
-std::string DelayBasedTimeSource::TypeString() const {
- return "DelayBasedTimeSource";
+void DelayBasedTimeSource::ResetTickTask(base::TimeTicks now) {
+ tick_closure_.Reset(base::Bind(&DelayBasedTimeSource::OnTimerTick,
+ weak_factory_.GetWeakPtr()));
+ PostNextTickTask(now);
}
-std::string DelayBasedTimeSourceHighRes::TypeString() const {
- return "DelayBasedTimeSourceHighRes";
+std::string DelayBasedTimeSource::TypeString() const {
+ return "DelayBasedTimeSource";
}
void DelayBasedTimeSource::AsValueInto(
@@ -281,20 +255,8 @@ void DelayBasedTimeSource::AsValueInto(
state->SetString("type", TypeString());
state->SetDouble("last_tick_time_us", LastTickTime().ToInternalValue());
state->SetDouble("next_tick_time_us", NextTickTime().ToInternalValue());
-
- state->BeginDictionary("current_parameters");
- state->SetDouble("interval_us",
- current_parameters_.interval.InMicroseconds());
- state->SetDouble("tick_target_us",
- current_parameters_.tick_target.ToInternalValue());
- state->EndDictionary();
-
- state->BeginDictionary("next_parameters");
- state->SetDouble("interval_us", next_parameters_.interval.InMicroseconds());
- state->SetDouble("tick_target_us",
- next_parameters_.tick_target.ToInternalValue());
- state->EndDictionary();
-
+ state->SetDouble("interval_us", interval_.InMicroseconds());
+ state->SetDouble("timebase_us", timebase_.ToInternalValue());
state->SetBoolean("active", active_);
}
diff --git a/chromium/cc/scheduler/delay_based_time_source.h b/chromium/cc/scheduler/delay_based_time_source.h
index 4d7276c97c8..cd474a5c807 100644
--- a/chromium/cc/scheduler/delay_based_time_source.h
+++ b/chromium/cc/scheduler/delay_based_time_source.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/cancelable_callback.h"
#include "base/memory/weak_ptr.h"
#include "base/values.h"
#include "cc/base/cc_export.h"
@@ -19,101 +20,78 @@ class SingleThreadTaskRunner;
}
namespace cc {
-
-class CC_EXPORT TimeSourceClient {
+class CC_EXPORT DelayBasedTimeSourceClient {
public:
virtual void OnTimerTick() = 0;
protected:
- virtual ~TimeSourceClient() {}
+ virtual ~DelayBasedTimeSourceClient() {}
};
// This timer implements a time source that achieves the specified interval
// in face of millisecond-precision delayed callbacks and random queueing
// delays. DelayBasedTimeSource uses base::TimeTicks::Now as its timebase.
-class CC_EXPORT DelayBasedTimeSource
- : public base::RefCounted<DelayBasedTimeSource> {
+class CC_EXPORT DelayBasedTimeSource {
public:
- static scoped_refptr<DelayBasedTimeSource> Create(
- base::TimeDelta interval, base::SingleThreadTaskRunner* task_runner);
+ static scoped_ptr<DelayBasedTimeSource> Create(
+ base::TimeDelta interval,
+ base::SingleThreadTaskRunner* task_runner) {
+ return make_scoped_ptr(new DelayBasedTimeSource(interval, task_runner));
+ }
+
+ virtual ~DelayBasedTimeSource();
+
+ void SetClient(DelayBasedTimeSourceClient* client);
- virtual void SetClient(TimeSourceClient* client);
+ void SetTimebaseAndInterval(base::TimeTicks timebase,
+ base::TimeDelta interval);
- // TimeSource implementation
- virtual void SetTimebaseAndInterval(base::TimeTicks timebase,
- base::TimeDelta interval);
- base::TimeDelta Interval() const { return next_parameters_.interval; }
+ base::TimeDelta Interval() const;
- virtual base::TimeTicks SetActive(bool active);
- virtual bool Active() const;
+ // Returns the time for the last missed tick.
+ base::TimeTicks SetActive(bool active);
+ bool Active() const;
// Get the last and next tick times. NextTickTime() returns null when
// inactive.
- virtual base::TimeTicks LastTickTime() const;
- virtual base::TimeTicks NextTickTime() const;
-
- // Virtual for testing.
- virtual base::TimeTicks Now() const;
+ base::TimeTicks LastTickTime() const;
+ base::TimeTicks NextTickTime() const;
virtual void AsValueInto(base::trace_event::TracedValue* dict) const;
protected:
DelayBasedTimeSource(base::TimeDelta interval,
base::SingleThreadTaskRunner* task_runner);
- virtual ~DelayBasedTimeSource();
+ // Virtual for testing.
+ virtual base::TimeTicks Now() const;
virtual std::string TypeString() const;
- base::TimeTicks NextTickTarget(base::TimeTicks now);
- void PostNextTickTask(base::TimeTicks now);
- void OnTimerFired();
+ private:
+ base::TimeTicks NextTickTarget(base::TimeTicks now) const;
- struct Parameters {
- Parameters(base::TimeDelta interval, base::TimeTicks tick_target)
- : interval(interval), tick_target(tick_target) {}
- base::TimeDelta interval;
- base::TimeTicks tick_target;
- };
+ void PostNextTickTask(base::TimeTicks now);
+ void ResetTickTask(base::TimeTicks now);
- TimeSourceClient* client_;
- base::TimeTicks last_tick_time_;
+ void OnTimerTick();
- // current_parameters_ should only be written by PostNextTickTask.
- // next_parameters_ will take effect on the next call to PostNextTickTask.
- // Maintaining a pending set of parameters allows NextTickTime() to always
- // reflect the actual time we expect OnTimerFired to be called.
- Parameters current_parameters_;
- Parameters next_parameters_;
+ DelayBasedTimeSourceClient* client_;
bool active_;
- base::SingleThreadTaskRunner* task_runner_;
- base::WeakPtrFactory<DelayBasedTimeSource> weak_factory_;
+ base::TimeTicks timebase_;
+ base::TimeDelta interval_;
- private:
- friend class base::RefCounted<DelayBasedTimeSource>;
- DISALLOW_COPY_AND_ASSIGN(DelayBasedTimeSource);
-};
-
-// DelayBasedTimeSource that once used base::TimeTicks::HighResNow as its time
-// source, but is now a no-op.
-// TODO(brianderson): Remove along with gfx::/FrameTime.http://crbug.com/447329
-class DelayBasedTimeSourceHighRes : public DelayBasedTimeSource {
- public:
- static scoped_refptr<DelayBasedTimeSourceHighRes> Create(
- base::TimeDelta interval, base::SingleThreadTaskRunner* task_runner);
+ base::TimeTicks last_tick_time_;
+ base::TimeTicks next_tick_time_;
- base::TimeTicks Now() const override;
+ base::CancelableClosure tick_closure_;
- protected:
- DelayBasedTimeSourceHighRes(base::TimeDelta interval,
- base::SingleThreadTaskRunner* task_runner);
- ~DelayBasedTimeSourceHighRes() override;
+ base::SingleThreadTaskRunner* task_runner_;
- std::string TypeString() const override;
+ base::WeakPtrFactory<DelayBasedTimeSource> weak_factory_;
- private:
- DISALLOW_COPY_AND_ASSIGN(DelayBasedTimeSourceHighRes);
+ DISALLOW_COPY_AND_ASSIGN(DelayBasedTimeSource);
};
} // namespace cc
diff --git a/chromium/cc/scheduler/delay_based_time_source_unittest.cc b/chromium/cc/scheduler/delay_based_time_source_unittest.cc
index f721b11ff7f..948e0205bbf 100644
--- a/chromium/cc/scheduler/delay_based_time_source_unittest.cc
+++ b/chromium/cc/scheduler/delay_based_time_source_unittest.cc
@@ -20,8 +20,8 @@ base::TimeDelta Interval() {
TEST(DelayBasedTimeSourceTest, TaskPostedAndTickCalled) {
scoped_refptr<base::TestSimpleTaskRunner> task_runner =
new base::TestSimpleTaskRunner;
- FakeTimeSourceClient client;
- scoped_refptr<FakeDelayBasedTimeSource> timer =
+ FakeDelayBasedTimeSourceClient client;
+ scoped_ptr<FakeDelayBasedTimeSource> timer =
FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
timer->SetClient(&client);
@@ -38,8 +38,8 @@ TEST(DelayBasedTimeSourceTest, TaskPostedAndTickCalled) {
TEST(DelayBasedTimeSourceTest, TickNotCalledWithTaskPosted) {
scoped_refptr<base::TestSimpleTaskRunner> task_runner =
new base::TestSimpleTaskRunner;
- FakeTimeSourceClient client;
- scoped_refptr<FakeDelayBasedTimeSource> timer =
+ FakeDelayBasedTimeSourceClient client;
+ scoped_ptr<FakeDelayBasedTimeSource> timer =
FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
timer->SetClient(&client);
timer->SetActive(true);
@@ -52,8 +52,8 @@ TEST(DelayBasedTimeSourceTest, TickNotCalledWithTaskPosted) {
TEST(DelayBasedTimeSourceTest, StartTwiceEnqueuesOneTask) {
scoped_refptr<base::TestSimpleTaskRunner> task_runner =
new base::TestSimpleTaskRunner;
- FakeTimeSourceClient client;
- scoped_refptr<FakeDelayBasedTimeSource> timer =
+ FakeDelayBasedTimeSourceClient client;
+ scoped_ptr<FakeDelayBasedTimeSource> timer =
FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
timer->SetClient(&client);
timer->SetActive(true);
@@ -66,8 +66,8 @@ TEST(DelayBasedTimeSourceTest, StartTwiceEnqueuesOneTask) {
TEST(DelayBasedTimeSourceTest, StartWhenRunningDoesntTick) {
scoped_refptr<base::TestSimpleTaskRunner> task_runner =
new base::TestSimpleTaskRunner;
- FakeTimeSourceClient client;
- scoped_refptr<FakeDelayBasedTimeSource> timer =
+ FakeDelayBasedTimeSourceClient client;
+ scoped_ptr<FakeDelayBasedTimeSource> timer =
FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
timer->SetClient(&client);
timer->SetActive(true);
@@ -83,8 +83,8 @@ TEST(DelayBasedTimeSourceTest, StartWhenRunningDoesntTick) {
TEST(DelayBasedTimeSourceTest, NextDelaySaneWhenExactlyOnRequestedTime) {
scoped_refptr<base::TestSimpleTaskRunner> task_runner =
new base::TestSimpleTaskRunner;
- FakeTimeSourceClient client;
- scoped_refptr<FakeDelayBasedTimeSource> timer =
+ FakeDelayBasedTimeSourceClient client;
+ scoped_ptr<FakeDelayBasedTimeSource> timer =
FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
timer->SetClient(&client);
timer->SetActive(true);
@@ -104,8 +104,8 @@ TEST(DelayBasedTimeSourceTest, NextDelaySaneWhenExactlyOnRequestedTime) {
TEST(DelayBasedTimeSourceTest, NextDelaySaneWhenSlightlyAfterRequestedTime) {
scoped_refptr<base::TestSimpleTaskRunner> task_runner =
new base::TestSimpleTaskRunner;
- FakeTimeSourceClient client;
- scoped_refptr<FakeDelayBasedTimeSource> timer =
+ FakeDelayBasedTimeSourceClient client;
+ scoped_ptr<FakeDelayBasedTimeSource> timer =
FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
timer->SetClient(&client);
timer->SetActive(true);
@@ -127,8 +127,8 @@ TEST(DelayBasedTimeSourceTest,
NextDelaySaneWhenExactlyTwiceAfterRequestedTime) {
scoped_refptr<base::TestSimpleTaskRunner> task_runner =
new base::TestSimpleTaskRunner;
- FakeTimeSourceClient client;
- scoped_refptr<FakeDelayBasedTimeSource> timer =
+ FakeDelayBasedTimeSourceClient client;
+ scoped_ptr<FakeDelayBasedTimeSource> timer =
FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
timer->SetClient(&client);
timer->SetActive(true);
@@ -149,8 +149,8 @@ TEST(DelayBasedTimeSourceTest,
NextDelaySaneWhenSlightlyAfterTwiceRequestedTime) {
scoped_refptr<base::TestSimpleTaskRunner> task_runner =
new base::TestSimpleTaskRunner;
- FakeTimeSourceClient client;
- scoped_refptr<FakeDelayBasedTimeSource> timer =
+ FakeDelayBasedTimeSourceClient client;
+ scoped_ptr<FakeDelayBasedTimeSource> timer =
FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
timer->SetClient(&client);
timer->SetActive(true);
@@ -171,8 +171,8 @@ TEST(DelayBasedTimeSourceTest,
TEST(DelayBasedTimeSourceTest, NextDelaySaneWhenHalfAfterRequestedTime) {
scoped_refptr<base::TestSimpleTaskRunner> task_runner =
new base::TestSimpleTaskRunner;
- FakeTimeSourceClient client;
- scoped_refptr<FakeDelayBasedTimeSource> timer =
+ FakeDelayBasedTimeSourceClient client;
+ scoped_ptr<FakeDelayBasedTimeSource> timer =
FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
timer->SetClient(&client);
timer->SetActive(true);
@@ -193,8 +193,8 @@ TEST(DelayBasedTimeSourceTest, NextDelaySaneWhenHalfAfterRequestedTime) {
TEST(DelayBasedTimeSourceTest, SaneHandlingOfJitteryTimebase) {
scoped_refptr<base::TestSimpleTaskRunner> task_runner =
new base::TestSimpleTaskRunner;
- FakeTimeSourceClient client;
- scoped_refptr<FakeDelayBasedTimeSource> timer =
+ FakeDelayBasedTimeSourceClient client;
+ scoped_ptr<FakeDelayBasedTimeSource> timer =
FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
timer->SetClient(&client);
timer->SetActive(true);
@@ -224,8 +224,8 @@ TEST(DelayBasedTimeSourceTest, SaneHandlingOfJitteryTimebase) {
TEST(DelayBasedTimeSourceTest, HandlesSignificantTimebaseChangesImmediately) {
scoped_refptr<base::TestSimpleTaskRunner> task_runner =
new base::TestSimpleTaskRunner;
- FakeTimeSourceClient client;
- scoped_refptr<FakeDelayBasedTimeSource> timer =
+ FakeDelayBasedTimeSourceClient client;
+ scoped_ptr<FakeDelayBasedTimeSource> timer =
FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
timer->SetClient(&client);
timer->SetActive(true);
@@ -268,8 +268,8 @@ TEST(DelayBasedTimeSourceTest, HandlesSignificantTimebaseChangesImmediately) {
TEST(DelayBasedTimeSourceTest, HanldlesSignificantIntervalChangesImmediately) {
scoped_refptr<base::TestSimpleTaskRunner> task_runner =
new base::TestSimpleTaskRunner;
- FakeTimeSourceClient client;
- scoped_refptr<FakeDelayBasedTimeSource> timer =
+ FakeDelayBasedTimeSourceClient client;
+ scoped_ptr<FakeDelayBasedTimeSource> timer =
FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
timer->SetClient(&client);
timer->SetActive(true);
@@ -310,8 +310,8 @@ TEST(DelayBasedTimeSourceTest, HanldlesSignificantIntervalChangesImmediately) {
TEST(DelayBasedTimeSourceTest, JitteryRuntimeWithFutureTimebases) {
scoped_refptr<base::TestSimpleTaskRunner> task_runner =
new base::TestSimpleTaskRunner;
- FakeTimeSourceClient client;
- scoped_refptr<FakeDelayBasedTimeSource> timer =
+ FakeDelayBasedTimeSourceClient client;
+ scoped_ptr<FakeDelayBasedTimeSource> timer =
FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
timer->SetClient(&client);
timer->SetActive(true);
@@ -421,8 +421,8 @@ TEST(DelayBasedTimeSourceTest, AchievesTargetRateWithNoNoise) {
scoped_refptr<base::TestSimpleTaskRunner> task_runner =
new base::TestSimpleTaskRunner;
- FakeTimeSourceClient client;
- scoped_refptr<FakeDelayBasedTimeSource> timer =
+ FakeDelayBasedTimeSourceClient client;
+ scoped_ptr<FakeDelayBasedTimeSource> timer =
FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
timer->SetClient(&client);
timer->SetActive(true);
@@ -446,8 +446,8 @@ TEST(DelayBasedTimeSourceTest, AchievesTargetRateWithNoNoise) {
TEST(DelayBasedTimeSourceTest, TestDeactivateWhilePending) {
scoped_refptr<base::TestSimpleTaskRunner> task_runner =
new base::TestSimpleTaskRunner;
- FakeTimeSourceClient client;
- scoped_refptr<FakeDelayBasedTimeSource> timer =
+ FakeDelayBasedTimeSourceClient client;
+ scoped_ptr<FakeDelayBasedTimeSource> timer =
FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
timer->SetClient(&client);
timer->SetActive(true); // Should post a task.
@@ -461,8 +461,8 @@ TEST(DelayBasedTimeSourceTest, TestDeactivateWhilePending) {
TEST(DelayBasedTimeSourceTest, TestDeactivateAndReactivateBeforeNextTickTime) {
scoped_refptr<base::TestSimpleTaskRunner> task_runner =
new base::TestSimpleTaskRunner;
- FakeTimeSourceClient client;
- scoped_refptr<FakeDelayBasedTimeSource> timer =
+ FakeDelayBasedTimeSourceClient client;
+ scoped_ptr<FakeDelayBasedTimeSource> timer =
FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
timer->SetClient(&client);
@@ -486,8 +486,8 @@ TEST(DelayBasedTimeSourceTest, TestDeactivateAndReactivateBeforeNextTickTime) {
TEST(DelayBasedTimeSourceTest, TestDeactivateAndReactivateAfterNextTickTime) {
scoped_refptr<base::TestSimpleTaskRunner> task_runner =
new base::TestSimpleTaskRunner;
- FakeTimeSourceClient client;
- scoped_refptr<FakeDelayBasedTimeSource> timer =
+ FakeDelayBasedTimeSourceClient client;
+ scoped_ptr<FakeDelayBasedTimeSource> timer =
FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
timer->SetClient(&client);
@@ -511,8 +511,8 @@ TEST(DelayBasedTimeSourceTest, TestDeactivateAndReactivateAfterNextTickTime) {
TEST(DelayBasedTimeSourceTest, TestReturnValueWhenTimerIsDeActivated) {
scoped_refptr<base::TestSimpleTaskRunner> task_runner =
new base::TestSimpleTaskRunner;
- FakeTimeSourceClient client;
- scoped_refptr<FakeDelayBasedTimeSource> timer =
+ FakeDelayBasedTimeSourceClient client;
+ scoped_ptr<FakeDelayBasedTimeSource> timer =
FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
timer->SetClient(&client);
diff --git a/chromium/cc/scheduler/scheduler.cc b/chromium/cc/scheduler/scheduler.cc
index d2520335c0c..2b668e83011 100644
--- a/chromium/cc/scheduler/scheduler.cc
+++ b/chromium/cc/scheduler/scheduler.cc
@@ -14,104 +14,79 @@
#include "base/trace_event/trace_event_argument.h"
#include "cc/debug/devtools_instrumentation.h"
#include "cc/debug/traced_value.h"
+#include "cc/scheduler/compositor_timing_history.h"
#include "cc/scheduler/delay_based_time_source.h"
-#include "ui/gfx/frame_time.h"
namespace cc {
-BeginFrameSource* SchedulerFrameSourcesConstructor::ConstructPrimaryFrameSource(
- Scheduler* scheduler) {
- if (scheduler->settings_.use_external_begin_frame_source) {
- TRACE_EVENT1("cc",
- "Scheduler::Scheduler()",
- "PrimaryFrameSource",
- "ExternalBeginFrameSource");
- DCHECK(scheduler->primary_frame_source_internal_)
- << "Need external BeginFrameSource";
- return scheduler->primary_frame_source_internal_.get();
- } else {
- TRACE_EVENT1("cc",
- "Scheduler::Scheduler()",
- "PrimaryFrameSource",
- "SyntheticBeginFrameSource");
- scoped_ptr<SyntheticBeginFrameSource> synthetic_source =
- SyntheticBeginFrameSource::Create(scheduler->task_runner_.get(),
- scheduler->Now(),
- BeginFrameArgs::DefaultInterval());
-
- DCHECK(!scheduler->vsync_observer_);
- scheduler->vsync_observer_ = synthetic_source.get();
-
- DCHECK(!scheduler->primary_frame_source_internal_);
- scheduler->primary_frame_source_internal_ = synthetic_source.Pass();
- return scheduler->primary_frame_source_internal_.get();
+scoped_ptr<Scheduler> Scheduler::Create(
+ SchedulerClient* client,
+ const SchedulerSettings& settings,
+ int layer_tree_host_id,
+ base::SingleThreadTaskRunner* task_runner,
+ BeginFrameSource* external_frame_source,
+ scoped_ptr<CompositorTimingHistory> compositor_timing_history) {
+ scoped_ptr<SyntheticBeginFrameSource> synthetic_frame_source;
+ if (!settings.use_external_begin_frame_source) {
+ synthetic_frame_source = SyntheticBeginFrameSource::Create(
+ task_runner, BeginFrameArgs::DefaultInterval());
}
-}
-
-BeginFrameSource*
-SchedulerFrameSourcesConstructor::ConstructUnthrottledFrameSource(
- Scheduler* scheduler) {
- TRACE_EVENT1("cc", "Scheduler::Scheduler()", "UnthrottledFrameSource",
- "BackToBackBeginFrameSource");
- DCHECK(!scheduler->unthrottled_frame_source_internal_);
- scheduler->unthrottled_frame_source_internal_ =
- BackToBackBeginFrameSource::Create(scheduler->task_runner_.get());
- return scheduler->unthrottled_frame_source_internal_.get();
+ scoped_ptr<BackToBackBeginFrameSource> unthrottled_frame_source =
+ BackToBackBeginFrameSource::Create(task_runner);
+ return make_scoped_ptr(new Scheduler(
+ client, settings, layer_tree_host_id, task_runner, external_frame_source,
+ synthetic_frame_source.Pass(), unthrottled_frame_source.Pass(),
+ compositor_timing_history.Pass()));
}
Scheduler::Scheduler(
SchedulerClient* client,
- const SchedulerSettings& scheduler_settings,
+ const SchedulerSettings& settings,
int layer_tree_host_id,
- const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
- scoped_ptr<BeginFrameSource> external_begin_frame_source,
- SchedulerFrameSourcesConstructor* frame_sources_constructor)
- : frame_source_(),
- primary_frame_source_(NULL),
- primary_frame_source_internal_(external_begin_frame_source.Pass()),
- vsync_observer_(NULL),
- authoritative_vsync_interval_(base::TimeDelta()),
- last_vsync_timebase_(base::TimeTicks()),
- throttle_frame_production_(false),
- settings_(scheduler_settings),
+ base::SingleThreadTaskRunner* task_runner,
+ BeginFrameSource* external_frame_source,
+ scoped_ptr<SyntheticBeginFrameSource> synthetic_frame_source,
+ scoped_ptr<BackToBackBeginFrameSource> unthrottled_frame_source,
+ scoped_ptr<CompositorTimingHistory> compositor_timing_history)
+ : settings_(settings),
client_(client),
layer_tree_host_id_(layer_tree_host_id),
task_runner_(task_runner),
+ external_frame_source_(external_frame_source),
+ synthetic_frame_source_(synthetic_frame_source.Pass()),
+ unthrottled_frame_source_(unthrottled_frame_source.Pass()),
+ frame_source_(BeginFrameSourceMultiplexer::Create()),
+ throttle_frame_production_(false),
+ compositor_timing_history_(compositor_timing_history.Pass()),
begin_impl_frame_deadline_mode_(
SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE),
- state_machine_(scheduler_settings),
+ begin_impl_frame_tracker_(BEGINFRAMETRACKER_FROM_HERE),
+ state_machine_(settings),
inside_process_scheduled_actions_(false),
inside_action_(SchedulerStateMachine::ACTION_NONE),
weak_factory_(this) {
- TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
- "Scheduler::Scheduler",
- "settings",
- settings_.AsValue());
+ TRACE_EVENT1("cc", "Scheduler::Scheduler", "settings", settings_.AsValue());
DCHECK(client_);
DCHECK(!state_machine_.BeginFrameNeeded());
+ DCHECK_IMPLIES(settings_.use_external_begin_frame_source,
+ external_frame_source_);
+ DCHECK_IMPLIES(!settings_.use_external_begin_frame_source,
+ synthetic_frame_source_);
+ DCHECK(unthrottled_frame_source_);
begin_retro_frame_closure_ =
base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr());
begin_impl_frame_deadline_closure_ = base::Bind(
&Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr());
- advance_commit_state_closure_ = base::Bind(
- &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr());
- frame_source_ = BeginFrameSourceMultiplexer::Create();
frame_source_->AddObserver(this);
+ frame_source_->AddSource(primary_frame_source());
+ primary_frame_source()->SetClientReady();
- // Primary frame source
- primary_frame_source_ =
- frame_sources_constructor->ConstructPrimaryFrameSource(this);
- frame_source_->AddSource(primary_frame_source_);
- primary_frame_source_->SetClientReady();
+ frame_source_->AddSource(unthrottled_frame_source_.get());
+ unthrottled_frame_source_->SetClientReady();
- // Unthrottled frame source
- unthrottled_frame_source_ =
- frame_sources_constructor->ConstructUnthrottledFrameSource(this);
- frame_source_->AddSource(unthrottled_frame_source_);
-
- SetThrottleFrameProduction(scheduler_settings.throttle_frame_production);
+ SetThrottleFrameProduction(settings_.throttle_frame_production);
}
Scheduler::~Scheduler() {
@@ -121,7 +96,7 @@ Scheduler::~Scheduler() {
}
base::TimeTicks Scheduler::Now() const {
- base::TimeTicks now = gfx::FrameTime::Now();
+ base::TimeTicks now = base::TimeTicks::Now();
TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.now"),
"Scheduler::Now",
"now",
@@ -140,8 +115,8 @@ void Scheduler::CommitVSyncParameters(base::TimeTicks timebase,
last_vsync_timebase_ = timebase;
- if (vsync_observer_)
- vsync_observer_->OnUpdateVSyncParameters(timebase, interval);
+ if (synthetic_frame_source_)
+ synthetic_frame_source_->OnUpdateVSyncParameters(timebase, interval);
}
void Scheduler::SetEstimatedParentDrawTime(base::TimeDelta draw_time) {
@@ -156,6 +131,7 @@ void Scheduler::SetCanStart() {
void Scheduler::SetVisible(bool visible) {
state_machine_.SetVisible(visible);
+ UpdateCompositorTimingHistoryRecordingEnabled();
ProcessScheduledActions();
}
@@ -165,6 +141,7 @@ void Scheduler::SetCanDraw(bool can_draw) {
}
void Scheduler::NotifyReadyToActivate() {
+ compositor_timing_history_->ReadyToActivate();
state_machine_.NotifyReadyToActivate();
ProcessScheduledActions();
}
@@ -178,9 +155,9 @@ void Scheduler::NotifyReadyToDraw() {
void Scheduler::SetThrottleFrameProduction(bool throttle) {
throttle_frame_production_ = throttle;
if (throttle) {
- frame_source_->SetActiveSource(primary_frame_source_);
+ frame_source_->SetActiveSource(primary_frame_source());
} else {
- frame_source_->SetActiveSource(unthrottled_frame_source_);
+ frame_source_->SetActiveSource(unthrottled_frame_source_.get());
}
ProcessScheduledActions();
}
@@ -226,6 +203,7 @@ void Scheduler::DidSwapBuffers() {
}
void Scheduler::DidSwapBuffersComplete() {
+ DCHECK_GT(state_machine_.pending_swaps(), 0) << AsValue()->ToString();
state_machine_.DidSwapBuffersComplete();
ProcessScheduledActions();
}
@@ -241,14 +219,24 @@ void Scheduler::NotifyReadyToCommit() {
ProcessScheduledActions();
}
+void Scheduler::DidCommit() {
+ compositor_timing_history_->DidCommit();
+}
+
void Scheduler::BeginMainFrameAborted(CommitEarlyOutReason reason) {
TRACE_EVENT1("cc", "Scheduler::BeginMainFrameAborted", "reason",
CommitEarlyOutReasonToString(reason));
+ compositor_timing_history_->BeginMainFrameAborted();
state_machine_.BeginMainFrameAborted(reason);
ProcessScheduledActions();
}
+void Scheduler::WillPrepareTiles() {
+ compositor_timing_history_->WillPrepareTiles();
+}
+
void Scheduler::DidPrepareTiles() {
+ compositor_timing_history_->DidPrepareTiles();
state_machine_.DidPrepareTiles();
}
@@ -257,6 +245,7 @@ void Scheduler::DidLoseOutputSurface() {
begin_retro_frame_args_.clear();
begin_retro_frame_task_.Cancel();
state_machine_.DidLoseOutputSurface();
+ UpdateCompositorTimingHistoryRecordingEnabled();
ProcessScheduledActions();
}
@@ -265,6 +254,7 @@ void Scheduler::DidCreateAndInitializeOutputSurface() {
DCHECK(!frame_source_->NeedsBeginFrames());
DCHECK(begin_impl_frame_deadline_task_.IsCancelled());
state_machine_.DidCreateAndInitializeOutputSurface();
+ UpdateCompositorTimingHistoryRecordingEnabled();
ProcessScheduledActions();
}
@@ -273,20 +263,8 @@ void Scheduler::NotifyBeginMainFrameStarted() {
state_machine_.NotifyBeginMainFrameStarted();
}
-base::TimeTicks Scheduler::AnticipatedDrawTime() const {
- if (!frame_source_->NeedsBeginFrames() ||
- begin_impl_frame_args_.interval <= base::TimeDelta())
- return base::TimeTicks();
-
- base::TimeTicks now = Now();
- base::TimeTicks timebase = std::max(begin_impl_frame_args_.frame_time,
- begin_impl_frame_args_.deadline);
- int64 intervals = 1 + ((now - timebase) / begin_impl_frame_args_.interval);
- return timebase + (begin_impl_frame_args_.interval * intervals);
-}
-
base::TimeTicks Scheduler::LastBeginImplFrameTime() {
- return begin_impl_frame_args_.frame_time;
+ return begin_impl_frame_tracker_.Current().frame_time;
}
void Scheduler::SetupNextBeginFrameIfNeeded() {
@@ -296,53 +274,37 @@ void Scheduler::SetupNextBeginFrameIfNeeded() {
if (state_machine_.BeginFrameNeeded()) {
// Call SetNeedsBeginFrames(true) as soon as possible.
frame_source_->SetNeedsBeginFrames(true);
+ devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_,
+ true);
} else if (state_machine_.begin_impl_frame_state() ==
SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) {
// Call SetNeedsBeginFrames(false) in between frames only.
frame_source_->SetNeedsBeginFrames(false);
client_->SendBeginMainFrameNotExpectedSoon();
+ devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_,
+ false);
}
}
PostBeginRetroFrameIfNeeded();
}
-// We may need to poll when we can't rely on BeginFrame to advance certain
-// state or to avoid deadlock.
-void Scheduler::SetupPollingMechanisms() {
- // At this point we'd prefer to advance through the commit flow by
- // drawing a frame, however it's possible that the frame rate controller
- // will not give us a BeginFrame until the commit completes. See
- // crbug.com/317430 for an example of a swap ack being held on commit. Thus
- // we set a repeating timer to poll on ProcessScheduledActions until we
- // successfully reach BeginFrame. Synchronous compositor does not use
- // frame rate controller or have the circular wait in the bug.
- if (IsBeginMainFrameSentOrStarted() &&
- !settings_.using_synchronous_renderer_compositor) {
- if (advance_commit_state_task_.IsCancelled() &&
- begin_impl_frame_args_.IsValid()) {
- // Since we'd rather get a BeginImplFrame by the normal mechanism, we
- // set the interval to twice the interval from the previous frame.
- advance_commit_state_task_.Reset(advance_commit_state_closure_);
- task_runner_->PostDelayedTask(FROM_HERE,
- advance_commit_state_task_.callback(),
- begin_impl_frame_args_.interval * 2);
- }
- } else {
- advance_commit_state_task_.Cancel();
- }
-}
-
// BeginFrame is the mechanism that tells us that now is a good time to start
// making a frame. Usually this means that user input for the frame is complete.
// If the scheduler is busy, we queue the BeginFrame to be handled later as
// a BeginRetroFrame.
-bool Scheduler::OnBeginFrameMixInDelegate(const BeginFrameArgs& args) {
+bool Scheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) {
TRACE_EVENT1("cc,benchmark", "Scheduler::BeginFrame", "args", args.AsValue());
+ // Trace this begin frame time through the Chrome stack
+ TRACE_EVENT_FLOW_BEGIN0(
+ TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), "BeginFrameArgs",
+ args.frame_time.ToInternalValue());
+
// TODO(brianderson): Adjust deadline in the DisplayScheduler.
BeginFrameArgs adjusted_args(args);
adjusted_args.deadline -= EstimatedParentDrawTime();
+ adjusted_args.on_critical_path = !ImplLatencyTakesPriority();
// Deliver BeginFrames to children.
// TODO(brianderson): Move this responsibility to the DisplayScheduler.
@@ -389,8 +351,10 @@ void Scheduler::SetChildrenNeedBeginFrames(bool children_need_begin_frames) {
void Scheduler::SetAuthoritativeVSyncInterval(const base::TimeDelta& interval) {
authoritative_vsync_interval_ = interval;
- if (vsync_observer_)
- vsync_observer_->OnUpdateVSyncParameters(last_vsync_timebase_, interval);
+ if (synthetic_frame_source_) {
+ synthetic_frame_source_->OnUpdateVSyncParameters(last_vsync_timebase_,
+ interval);
+ }
}
void Scheduler::SetVideoNeedsBeginFrames(bool video_needs_begin_frames) {
@@ -434,7 +398,7 @@ void Scheduler::BeginRetroFrame() {
while (!begin_retro_frame_args_.empty()) {
const BeginFrameArgs& args = begin_retro_frame_args_.front();
- base::TimeTicks expiration_time = args.frame_time + args.interval;
+ base::TimeTicks expiration_time = args.deadline;
if (now <= expiration_time)
break;
TRACE_EVENT_INSTANT2(
@@ -493,18 +457,21 @@ void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) {
TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
"MainThreadLatency", main_thread_is_in_high_latency_mode);
- advance_commit_state_task_.Cancel();
-
- begin_impl_frame_args_ = args;
- begin_impl_frame_args_.deadline -= client_->DrawDurationEstimate();
+ BeginFrameArgs adjusted_args = args;
+ adjusted_args.deadline -= compositor_timing_history_->DrawDurationEstimate();
- if (!state_machine_.impl_latency_takes_priority() &&
- main_thread_is_in_high_latency_mode &&
- CanCommitAndActivateBeforeDeadline()) {
+ if (ShouldRecoverMainLatency(adjusted_args)) {
+ TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency",
+ TRACE_EVENT_SCOPE_THREAD);
state_machine_.SetSkipNextBeginMainFrameToReduceLatency();
+ } else if (ShouldRecoverImplLatency(adjusted_args)) {
+ TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency",
+ TRACE_EVENT_SCOPE_THREAD);
+ frame_source_->DidFinishFrame(begin_retro_frame_args_.size());
+ return;
}
- BeginImplFrame();
+ BeginImplFrame(adjusted_args);
// The deadline will be scheduled in ProcessScheduledActions.
state_machine_.OnBeginImplFrameDeadlinePending();
@@ -514,8 +481,7 @@ void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) {
void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) {
TRACE_EVENT1("cc,benchmark", "Scheduler::BeginImplFrame", "args",
args.AsValue());
- begin_impl_frame_args_ = args;
- BeginImplFrame();
+ BeginImplFrame(args);
FinishImplFrame();
}
@@ -525,21 +491,22 @@ void Scheduler::FinishImplFrame() {
client_->DidFinishImplFrame();
frame_source_->DidFinishFrame(begin_retro_frame_args_.size());
+ begin_impl_frame_tracker_.Finish();
}
// BeginImplFrame starts a compositor frame that will wait up until a deadline
// for a BeginMainFrame+activation to complete before it times out and draws
// any asynchronous animation and scroll/pinch updates.
-void Scheduler::BeginImplFrame() {
+void Scheduler::BeginImplFrame(const BeginFrameArgs& args) {
DCHECK_EQ(state_machine_.begin_impl_frame_state(),
SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
DCHECK(!BeginImplFrameDeadlinePending());
DCHECK(state_machine_.HasInitializedOutputSurface());
- DCHECK(advance_commit_state_task_.IsCancelled());
+ begin_impl_frame_tracker_.Start(args);
state_machine_.OnBeginImplFrame();
devtools_instrumentation::DidBeginFrame(layer_tree_host_id_);
- client_->WillBeginImplFrame(begin_impl_frame_args_);
+ client_->WillBeginImplFrame(begin_impl_frame_tracker_.Current());
ProcessScheduledActions();
}
@@ -553,7 +520,6 @@ void Scheduler::ScheduleBeginImplFrameDeadline() {
begin_impl_frame_deadline_mode_ =
state_machine_.CurrentBeginImplFrameDeadlineMode();
-
base::TimeTicks deadline;
switch (begin_impl_frame_deadline_mode_) {
case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE:
@@ -566,14 +532,14 @@ void Scheduler::ScheduleBeginImplFrameDeadline() {
break;
case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR:
// We are animating on the impl thread but we can wait for some time.
- deadline = begin_impl_frame_args_.deadline;
+ deadline = begin_impl_frame_tracker_.Current().deadline;
break;
case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE:
// We are blocked for one reason or another and we should wait.
// TODO(brianderson): Handle long deadlines (that are past the next
// frame's frame time) properly instead of using this hack.
- deadline =
- begin_impl_frame_args_.frame_time + begin_impl_frame_args_.interval;
+ deadline = begin_impl_frame_tracker_.Current().frame_time +
+ begin_impl_frame_tracker_.Current().interval;
break;
case SchedulerStateMachine::
BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW:
@@ -630,16 +596,17 @@ void Scheduler::OnBeginImplFrameDeadline() {
FinishImplFrame();
}
-
-void Scheduler::PollToAdvanceCommitState() {
- TRACE_EVENT0("cc", "Scheduler::PollToAdvanceCommitState");
- advance_commit_state_task_.Cancel();
- ProcessScheduledActions();
-}
-
void Scheduler::DrawAndSwapIfPossible() {
+ compositor_timing_history_->WillDraw();
DrawResult result = client_->ScheduledActionDrawAndSwapIfPossible();
state_machine_.DidDrawIfPossibleCompleted(result);
+ compositor_timing_history_->DidDraw();
+}
+
+void Scheduler::DrawAndSwapForced() {
+ compositor_timing_history_->WillDraw();
+ client_->ScheduledActionDrawAndSwapForced();
+ compositor_timing_history_->DidDraw();
}
void Scheduler::SetDeferCommits(bool defer_commits) {
@@ -665,9 +632,6 @@ void Scheduler::ProcessScheduledActions() {
"SchedulerStateMachine",
"state",
AsValue());
- VLOG(2) << "Scheduler::ProcessScheduledActions: "
- << SchedulerStateMachine::ActionToString(action) << " "
- << state_machine_.GetStatesForDebugging();
state_machine_.UpdateState(action);
base::AutoReset<SchedulerStateMachine::Action>
mark_inside_action(&inside_action_, action);
@@ -678,6 +642,7 @@ void Scheduler::ProcessScheduledActions() {
client_->ScheduledActionAnimate();
break;
case SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME:
+ compositor_timing_history_->WillBeginMainFrame();
client_->ScheduledActionSendBeginMainFrame();
break;
case SchedulerStateMachine::ACTION_COMMIT: {
@@ -690,7 +655,9 @@ void Scheduler::ProcessScheduledActions() {
break;
}
case SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE:
+ compositor_timing_history_->WillActivate();
client_->ScheduledActionActivateSyncTree();
+ compositor_timing_history_->DidActivate();
break;
case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE: {
// TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is
@@ -702,7 +669,7 @@ void Scheduler::ProcessScheduledActions() {
break;
}
case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED:
- client_->ScheduledActionDrawAndSwapForced();
+ DrawAndSwapForced();
break;
case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT:
// No action is actually performed, but this allows the state machine to
@@ -721,12 +688,7 @@ void Scheduler::ProcessScheduledActions() {
}
} while (action != SchedulerStateMachine::ACTION_NONE);
- SetupPollingMechanisms();
-
- client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime());
-
ScheduleBeginImplFrameDeadlineIfNeeded();
-
SetupNextBeginFrameIfNeeded();
}
@@ -739,6 +701,8 @@ scoped_refptr<base::trace_event::ConvertableToTraceFormat> Scheduler::AsValue()
}
void Scheduler::AsValueInto(base::trace_event::TracedValue* state) const {
+ base::TimeTicks now = Now();
+
state->BeginDictionary("state_machine");
state_machine_.AsValueInto(state);
state->EndDictionary();
@@ -755,71 +719,92 @@ void Scheduler::AsValueInto(base::trace_event::TracedValue* state) const {
}
state->BeginDictionary("scheduler_state");
- state->SetDouble("time_until_anticipated_draw_time_ms",
- (AnticipatedDrawTime() - Now()).InMillisecondsF());
state->SetDouble("estimated_parent_draw_time_ms",
estimated_parent_draw_time_.InMillisecondsF());
state->SetBoolean("last_set_needs_begin_frame_",
frame_source_->NeedsBeginFrames());
- state->SetInteger("begin_retro_frame_args_", begin_retro_frame_args_.size());
- state->SetBoolean("begin_retro_frame_task_",
+ state->SetInteger("begin_retro_frame_args",
+ static_cast<int>(begin_retro_frame_args_.size()));
+ state->SetBoolean("begin_retro_frame_task",
!begin_retro_frame_task_.IsCancelled());
- state->SetBoolean("begin_impl_frame_deadline_task_",
+ state->SetBoolean("begin_impl_frame_deadline_task",
!begin_impl_frame_deadline_task_.IsCancelled());
- state->SetBoolean("advance_commit_state_task_",
- !advance_commit_state_task_.IsCancelled());
+ state->SetString("inside_action",
+ SchedulerStateMachine::ActionToString(inside_action_));
+
state->BeginDictionary("begin_impl_frame_args");
- begin_impl_frame_args_.AsValueInto(state);
+ begin_impl_frame_tracker_.AsValueInto(now, state);
state->EndDictionary();
- base::TimeTicks now = Now();
- base::TimeTicks frame_time = begin_impl_frame_args_.frame_time;
- base::TimeTicks deadline = begin_impl_frame_args_.deadline;
- base::TimeDelta interval = begin_impl_frame_args_.interval;
- state->BeginDictionary("major_timestamps_in_ms");
- state->SetDouble("0_interval", interval.InMillisecondsF());
- state->SetDouble("1_now_to_deadline", (deadline - now).InMillisecondsF());
- state->SetDouble("2_frame_time_to_now", (now - frame_time).InMillisecondsF());
- state->SetDouble("3_frame_time_to_deadline",
- (deadline - frame_time).InMillisecondsF());
- state->SetDouble("4_now", (now - base::TimeTicks()).InMillisecondsF());
- state->SetDouble("5_frame_time",
- (frame_time - base::TimeTicks()).InMillisecondsF());
- state->SetDouble("6_deadline",
- (deadline - base::TimeTicks()).InMillisecondsF());
+ state->SetString("begin_impl_frame_deadline_mode_",
+ SchedulerStateMachine::BeginImplFrameDeadlineModeToString(
+ begin_impl_frame_deadline_mode_));
state->EndDictionary();
+ state->BeginDictionary("compositor_timing_history");
+ compositor_timing_history_->AsValueInto(state);
state->EndDictionary();
+}
- state->BeginDictionary("client_state");
- state->SetDouble("draw_duration_estimate_ms",
- client_->DrawDurationEstimate().InMillisecondsF());
- state->SetDouble(
- "begin_main_frame_to_commit_duration_estimate_ms",
- client_->BeginMainFrameToCommitDurationEstimate().InMillisecondsF());
- state->SetDouble(
- "commit_to_activate_duration_estimate_ms",
- client_->CommitToActivateDurationEstimate().InMillisecondsF());
- state->EndDictionary();
+void Scheduler::UpdateCompositorTimingHistoryRecordingEnabled() {
+ compositor_timing_history_->SetRecordingEnabled(
+ state_machine_.HasInitializedOutputSurface() && state_machine_.visible());
}
-bool Scheduler::CanCommitAndActivateBeforeDeadline() const {
+bool Scheduler::ShouldRecoverMainLatency(const BeginFrameArgs& args) const {
+ DCHECK(!settings_.using_synchronous_renderer_compositor);
+
+ if (!state_machine_.MainThreadIsInHighLatencyMode())
+ return false;
+
+ // When prioritizing impl thread latency, we currently put the
+ // main thread in a high latency mode. Don't try to fight it.
+ if (state_machine_.impl_latency_takes_priority())
+ return false;
+
+ return CanCommitAndActivateBeforeDeadline(args);
+}
+
+bool Scheduler::ShouldRecoverImplLatency(const BeginFrameArgs& args) const {
+ DCHECK(!settings_.using_synchronous_renderer_compositor);
+
+ // If we are swap throttled at the BeginFrame, that means the impl thread is
+ // very likely in a high latency mode.
+ bool impl_thread_is_likely_high_latency = state_machine_.SwapThrottled();
+ if (!impl_thread_is_likely_high_latency)
+ return false;
+
+ // The deadline may be in the past if our draw time is too long.
+ bool can_draw_before_deadline = args.frame_time < args.deadline;
+
+ // When prioritizing impl thread latency, the deadline doesn't wait
+ // for the main thread.
+ if (state_machine_.impl_latency_takes_priority())
+ return can_draw_before_deadline;
+
+ // If we only have impl-side updates, the deadline doesn't wait for
+ // the main thread.
+ if (state_machine_.OnlyImplSideUpdatesExpected())
+ return can_draw_before_deadline;
+
+ // If we get here, we know the main thread is in a low-latency mode relative
+ // to the impl thread. In this case, only try to also recover impl thread
+ // latency if both the main and impl threads can run serially before the
+ // deadline.
+ return CanCommitAndActivateBeforeDeadline(args);
+}
+
+bool Scheduler::CanCommitAndActivateBeforeDeadline(
+ const BeginFrameArgs& args) const {
// Check if the main thread computation and commit can be finished before the
// impl thread's deadline.
base::TimeTicks estimated_draw_time =
- begin_impl_frame_args_.frame_time +
- client_->BeginMainFrameToCommitDurationEstimate() +
- client_->CommitToActivateDurationEstimate();
-
- TRACE_EVENT2(
- TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
- "CanCommitAndActivateBeforeDeadline",
- "time_left_after_drawing_ms",
- (begin_impl_frame_args_.deadline - estimated_draw_time).InMillisecondsF(),
- "state",
- AsValue());
-
- return estimated_draw_time < begin_impl_frame_args_.deadline;
+ args.frame_time +
+ compositor_timing_history_->BeginMainFrameToCommitDurationEstimate() +
+ compositor_timing_history_->CommitToReadyToActivateDurationEstimate() +
+ compositor_timing_history_->ActivateDurationEstimate();
+
+ return estimated_draw_time < args.deadline;
}
bool Scheduler::IsBeginMainFrameSentOrStarted() const {
diff --git a/chromium/cc/scheduler/scheduler.h b/chromium/cc/scheduler/scheduler.h
index 13daf008cc3..d6fc074c541 100644
--- a/chromium/cc/scheduler/scheduler.h
+++ b/chromium/cc/scheduler/scheduler.h
@@ -14,8 +14,8 @@
#include "base/time/time.h"
#include "cc/base/cc_export.h"
#include "cc/output/begin_frame_args.h"
-#include "cc/output/vsync_parameter_observer.h"
#include "cc/scheduler/begin_frame_source.h"
+#include "cc/scheduler/begin_frame_tracker.h"
#include "cc/scheduler/delay_based_time_source.h"
#include "cc/scheduler/draw_result.h"
#include "cc/scheduler/scheduler_settings.h"
@@ -30,6 +30,8 @@ class SingleThreadTaskRunner;
namespace cc {
+class CompositorTimingHistory;
+
class SchedulerClient {
public:
virtual void WillBeginImplFrame(const BeginFrameArgs& args) = 0;
@@ -42,10 +44,6 @@ class SchedulerClient {
virtual void ScheduledActionBeginOutputSurfaceCreation() = 0;
virtual void ScheduledActionPrepareTiles() = 0;
virtual void ScheduledActionInvalidateOutputSurface() = 0;
- virtual void DidAnticipatedDrawTimeChange(base::TimeTicks time) = 0;
- virtual base::TimeDelta DrawDurationEstimate() = 0;
- virtual base::TimeDelta BeginMainFrameToCommitDurationEstimate() = 0;
- virtual base::TimeDelta CommitToActivateDurationEstimate() = 0;
virtual void DidFinishImplFrame() = 0;
virtual void SendBeginFramesToChildren(const BeginFrameArgs& args) = 0;
virtual void SendBeginMainFrameNotExpectedSoon() = 0;
@@ -54,45 +52,20 @@ class SchedulerClient {
virtual ~SchedulerClient() {}
};
-class Scheduler;
-// This class exists to allow tests to override the frame source construction.
-// A virtual method can't be used as this needs to happen in the constructor
-// (see C++ FAQ / Section 23 - http://goo.gl/fnrwom for why).
-// This class exists solely long enough to construct the frame sources.
-class CC_EXPORT SchedulerFrameSourcesConstructor {
- public:
- virtual ~SchedulerFrameSourcesConstructor() {}
- virtual BeginFrameSource* ConstructPrimaryFrameSource(Scheduler* scheduler);
- virtual BeginFrameSource* ConstructUnthrottledFrameSource(
- Scheduler* scheduler);
-
- protected:
- SchedulerFrameSourcesConstructor() {}
-
- friend class Scheduler;
-};
-
-class CC_EXPORT Scheduler : public BeginFrameObserverMixIn {
+class CC_EXPORT Scheduler : public BeginFrameObserverBase {
public:
static scoped_ptr<Scheduler> Create(
SchedulerClient* client,
const SchedulerSettings& scheduler_settings,
int layer_tree_host_id,
- const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
- scoped_ptr<BeginFrameSource> external_begin_frame_source) {
- SchedulerFrameSourcesConstructor frame_sources_constructor;
- return make_scoped_ptr(new Scheduler(client,
- scheduler_settings,
- layer_tree_host_id,
- task_runner,
- external_begin_frame_source.Pass(),
- &frame_sources_constructor));
- }
+ base::SingleThreadTaskRunner* task_runner,
+ BeginFrameSource* external_frame_source,
+ scoped_ptr<CompositorTimingHistory> compositor_timing_history);
~Scheduler() override;
- // BeginFrameObserverMixin
- bool OnBeginFrameMixInDelegate(const BeginFrameArgs& args) override;
+ // BeginFrameObserverBase
+ bool OnBeginFrameDerivedImpl(const BeginFrameArgs& args) override;
void OnDrawForOutputSurface();
@@ -128,7 +101,9 @@ class CC_EXPORT Scheduler : public BeginFrameObserverMixIn {
void NotifyReadyToCommit();
void BeginMainFrameAborted(CommitEarlyOutReason reason);
+ void DidCommit();
+ void WillPrepareTiles();
void DidPrepareTiles();
void DidLoseOutputSurface();
void DidCreateAndInitializeOutputSurface();
@@ -145,14 +120,12 @@ class CC_EXPORT Scheduler : public BeginFrameObserverMixIn {
bool PrepareTilesPending() const {
return state_machine_.PrepareTilesPending();
}
- bool MainThreadIsInHighLatencyMode() const {
- return state_machine_.MainThreadIsInHighLatencyMode();
- }
bool BeginImplFrameDeadlinePending() const {
return !begin_impl_frame_deadline_task_.IsCancelled();
}
-
- base::TimeTicks AnticipatedDrawTime() const;
+ bool ImplLatencyTakesPriority() const {
+ return state_machine_.impl_latency_takes_priority();
+ }
void NotifyBeginMainFrameStarted();
@@ -176,46 +149,41 @@ class CC_EXPORT Scheduler : public BeginFrameObserverMixIn {
Scheduler(SchedulerClient* client,
const SchedulerSettings& scheduler_settings,
int layer_tree_host_id,
- const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
- scoped_ptr<BeginFrameSource> external_begin_frame_source,
- SchedulerFrameSourcesConstructor* frame_sources_constructor);
+ base::SingleThreadTaskRunner* task_runner,
+ BeginFrameSource* external_frame_source,
+ scoped_ptr<SyntheticBeginFrameSource> synthetic_frame_source,
+ scoped_ptr<BackToBackBeginFrameSource> unthrottled_frame_source,
+ scoped_ptr<CompositorTimingHistory> compositor_timing_history);
- // virtual for testing - Don't call these in the constructor or
- // destructor!
+ // Virtual for testing.
virtual base::TimeTicks Now() const;
- scoped_ptr<BeginFrameSourceMultiplexer> frame_source_;
- BeginFrameSource* primary_frame_source_;
- BeginFrameSource* unthrottled_frame_source_;
+ const SchedulerSettings settings_;
+ SchedulerClient* client_;
+ int layer_tree_host_id_;
+ base::SingleThreadTaskRunner* task_runner_;
+ BeginFrameSource* external_frame_source_;
+ scoped_ptr<SyntheticBeginFrameSource> synthetic_frame_source_;
+ scoped_ptr<BackToBackBeginFrameSource> unthrottled_frame_source_;
- // Storage when frame sources are internal
- scoped_ptr<BeginFrameSource> primary_frame_source_internal_;
- scoped_ptr<BeginFrameSource> unthrottled_frame_source_internal_;
+ scoped_ptr<BeginFrameSourceMultiplexer> frame_source_;
+ bool throttle_frame_production_;
- VSyncParameterObserver* vsync_observer_;
base::TimeDelta authoritative_vsync_interval_;
base::TimeTicks last_vsync_timebase_;
- bool throttle_frame_production_;
-
- const SchedulerSettings settings_;
- SchedulerClient* client_;
- int layer_tree_host_id_;
- scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-
+ scoped_ptr<CompositorTimingHistory> compositor_timing_history_;
base::TimeDelta estimated_parent_draw_time_;
std::deque<BeginFrameArgs> begin_retro_frame_args_;
- BeginFrameArgs begin_impl_frame_args_;
SchedulerStateMachine::BeginImplFrameDeadlineMode
begin_impl_frame_deadline_mode_;
+ BeginFrameTracker begin_impl_frame_tracker_;
base::Closure begin_retro_frame_closure_;
base::Closure begin_impl_frame_deadline_closure_;
- base::Closure advance_commit_state_closure_;
base::CancelableClosure begin_retro_frame_task_;
base::CancelableClosure begin_impl_frame_deadline_task_;
- base::CancelableClosure advance_commit_state_task_;
SchedulerStateMachine state_machine_;
bool inside_process_scheduled_actions_;
@@ -226,16 +194,19 @@ class CC_EXPORT Scheduler : public BeginFrameObserverMixIn {
void ScheduleBeginImplFrameDeadlineIfNeeded();
void SetupNextBeginFrameIfNeeded();
void PostBeginRetroFrameIfNeeded();
- void SetupPollingMechanisms();
void DrawAndSwapIfPossible();
+ void DrawAndSwapForced();
void ProcessScheduledActions();
- bool CanCommitAndActivateBeforeDeadline() const;
+ void UpdateCompositorTimingHistoryRecordingEnabled();
+ bool ShouldRecoverMainLatency(const BeginFrameArgs& args) const;
+ bool ShouldRecoverImplLatency(const BeginFrameArgs& args) const;
+ bool CanCommitAndActivateBeforeDeadline(const BeginFrameArgs& args) const;
void AdvanceCommitStateIfPossible();
bool IsBeginMainFrameSentOrStarted() const;
void BeginRetroFrame();
void BeginImplFrameWithDeadline(const BeginFrameArgs& args);
void BeginImplFrameSynchronous(const BeginFrameArgs& args);
- void BeginImplFrame();
+ void BeginImplFrame(const BeginFrameArgs& args);
void FinishImplFrame();
void OnBeginImplFrameDeadline();
void PollToAdvanceCommitState();
@@ -248,10 +219,15 @@ class CC_EXPORT Scheduler : public BeginFrameObserverMixIn {
return inside_action_ == action;
}
- base::WeakPtrFactory<Scheduler> weak_factory_;
+ BeginFrameSource* primary_frame_source() {
+ if (settings_.use_external_begin_frame_source) {
+ DCHECK(external_frame_source_);
+ return external_frame_source_;
+ }
+ return synthetic_frame_source_.get();
+ }
- friend class SchedulerFrameSourcesConstructor;
- friend class TestSchedulerFrameSourcesConstructor;
+ base::WeakPtrFactory<Scheduler> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(Scheduler);
};
diff --git a/chromium/cc/scheduler/scheduler_settings.cc b/chromium/cc/scheduler/scheduler_settings.cc
index c6c8e8eb2db..d1d3a6f46c3 100644
--- a/chromium/cc/scheduler/scheduler_settings.cc
+++ b/chromium/cc/scheduler/scheduler_settings.cc
@@ -10,13 +10,13 @@ namespace cc {
SchedulerSettings::SchedulerSettings()
: use_external_begin_frame_source(false),
+ main_frame_while_swap_throttled_enabled(false),
main_frame_before_activation_enabled(false),
- impl_side_painting(false),
+ commit_to_active_tree(false),
timeout_and_draw_when_animation_checkerboards(true),
- maximum_number_of_failed_draws_before_draw_is_forced_(3),
using_synchronous_renderer_compositor(false),
throttle_frame_production(true),
- main_thread_should_always_be_low_latency(false),
+ maximum_number_of_failed_draws_before_draw_is_forced(3),
background_frame_interval(base::TimeDelta::FromSeconds(1)) {
}
@@ -28,18 +28,18 @@ SchedulerSettings::AsValue() const {
new base::trace_event::TracedValue();
state->SetBoolean("use_external_begin_frame_source",
use_external_begin_frame_source);
+ state->SetBoolean("main_frame_while_swap_throttled_enabled",
+ main_frame_while_swap_throttled_enabled);
state->SetBoolean("main_frame_before_activation_enabled",
main_frame_before_activation_enabled);
- state->SetBoolean("impl_side_painting", impl_side_painting);
+ state->SetBoolean("commit_to_active_tree", commit_to_active_tree);
state->SetBoolean("timeout_and_draw_when_animation_checkerboards",
timeout_and_draw_when_animation_checkerboards);
- state->SetInteger("maximum_number_of_failed_draws_before_draw_is_forced_",
- maximum_number_of_failed_draws_before_draw_is_forced_);
+ state->SetInteger("maximum_number_of_failed_draws_before_draw_is_forced",
+ maximum_number_of_failed_draws_before_draw_is_forced);
state->SetBoolean("using_synchronous_renderer_compositor",
using_synchronous_renderer_compositor);
state->SetBoolean("throttle_frame_production", throttle_frame_production);
- state->SetBoolean("main_thread_should_always_be_low_latency",
- main_thread_should_always_be_low_latency);
state->SetInteger("background_frame_interval",
background_frame_interval.InMicroseconds());
return state;
diff --git a/chromium/cc/scheduler/scheduler_settings.h b/chromium/cc/scheduler/scheduler_settings.h
index 421409ab4dc..e624cf8b939 100644
--- a/chromium/cc/scheduler/scheduler_settings.h
+++ b/chromium/cc/scheduler/scheduler_settings.h
@@ -24,19 +24,14 @@ class CC_EXPORT SchedulerSettings {
~SchedulerSettings();
bool use_external_begin_frame_source;
+ bool main_frame_while_swap_throttled_enabled;
bool main_frame_before_activation_enabled;
- bool impl_side_painting;
+ bool commit_to_active_tree;
bool timeout_and_draw_when_animation_checkerboards;
- int maximum_number_of_failed_draws_before_draw_is_forced_;
bool using_synchronous_renderer_compositor;
bool throttle_frame_production;
- // In main thread low latency mode the entire
- // BeginMainFrame->Commit->Activation->Draw cycle should complete before
- // starting the next cycle. Additionally, BeginMainFrame and Commit are
- // completed atomically with no other tasks or actions occuring between them.
- bool main_thread_should_always_be_low_latency;
-
+ int maximum_number_of_failed_draws_before_draw_is_forced;
base::TimeDelta background_frame_interval;
scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValue() const;
diff --git a/chromium/cc/scheduler/scheduler_state_machine.cc b/chromium/cc/scheduler/scheduler_state_machine.cc
index e303d3ab48a..d83599c8c71 100644
--- a/chromium/cc/scheduler/scheduler_state_machine.cc
+++ b/chromium/cc/scheduler/scheduler_state_machine.cc
@@ -10,7 +10,6 @@
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"
#include "base/values.h"
-#include "ui/gfx/frame_time.h"
namespace cc {
@@ -29,12 +28,13 @@ SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings)
last_frame_number_invalidate_output_surface_performed_(-1),
animate_funnel_(false),
request_swap_funnel_(false),
- send_begin_main_frame_funnel_(false),
+ send_begin_main_frame_funnel_(true),
invalidate_output_surface_funnel_(false),
prepare_tiles_funnel_(0),
consecutive_checkerboard_animations_(0),
max_pending_swaps_(1),
pending_swaps_(0),
+ swaps_with_current_output_surface_(0),
needs_redraw_(false),
needs_animate_(false),
needs_prepare_tiles_(false),
@@ -48,7 +48,6 @@ SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings)
did_create_and_initialize_first_output_surface_(false),
impl_latency_takes_priority_(false),
skip_next_begin_main_frame_to_reduce_latency_(false),
- skip_begin_main_frame_to_reduce_latency_(false),
continuous_painting_(false),
children_need_begin_frames_(false),
defer_commits_(false),
@@ -218,6 +217,8 @@ void SchedulerStateMachine::AsValueInto(
consecutive_checkerboard_animations_);
state->SetInteger("max_pending_swaps_", max_pending_swaps_);
state->SetInteger("pending_swaps_", pending_swaps_);
+ state->SetInteger("swaps_with_current_output_surface",
+ swaps_with_current_output_surface_);
state->SetBoolean("needs_redraw", needs_redraw_);
state->SetBoolean("needs_animate_", needs_animate_);
state->SetBoolean("needs_prepare_tiles", needs_prepare_tiles_);
@@ -238,8 +239,6 @@ void SchedulerStateMachine::AsValueInto(
impl_latency_takes_priority_);
state->SetBoolean("main_thread_is_in_high_latency_mode",
MainThreadIsInHighLatencyMode());
- state->SetBoolean("skip_begin_main_frame_to_reduce_latency",
- skip_begin_main_frame_to_reduce_latency_);
state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency",
skip_next_begin_main_frame_to_reduce_latency_);
state->SetBoolean("continuous_painting", continuous_painting_);
@@ -337,7 +336,7 @@ bool SchedulerStateMachine::ShouldDraw() const {
return false;
// Do not queue too many swaps.
- if (pending_swaps_ >= max_pending_swaps_)
+ if (SwapThrottled())
return false;
// Except for the cases above, do not draw outside of the BeginImplFrame
@@ -402,15 +401,31 @@ bool SchedulerStateMachine::CouldSendBeginMainFrame() const {
return true;
}
+bool SchedulerStateMachine::SendingBeginMainFrameMightCauseDeadlock() const {
+ // NPAPI is the only case where the UI thread makes synchronous calls to the
+ // Renderer main thread. During that synchronous call, we may not get a
+ // SwapAck for the UI thread, which may prevent BeginMainFrame's from
+ // completing if there's enough back pressure. If the BeginMainFrame can't
+ // make progress, the Renderer can't service the UI thread's synchronous call
+ // and we have deadlock.
+ // This returns true if there's too much backpressure to finish a commit
+ // if we were to initiate a BeginMainFrame.
+ return has_pending_tree_ && active_tree_needs_first_draw_ && SwapThrottled();
+}
+
bool SchedulerStateMachine::ShouldSendBeginMainFrame() const {
if (!CouldSendBeginMainFrame())
return false;
- // Do not send begin main frame too many times in a single frame.
+ // Do not send begin main frame too many times in a single frame or before
+ // the first BeginFrame.
if (send_begin_main_frame_funnel_)
return false;
// Only send BeginMainFrame when there isn't another commit pending already.
+ // Other parts of the state machine indirectly defer the BeginMainFrame
+ // by transitioning to WAITING commit states rather than going
+ // immediately to IDLE.
if (commit_state_ != COMMIT_STATE_IDLE)
return false;
@@ -421,17 +436,22 @@ bool SchedulerStateMachine::ShouldSendBeginMainFrame() const {
return false;
}
- // We should not send BeginMainFrame while we are in
- // BEGIN_IMPL_FRAME_STATE_IDLE since we might have new
- // user input arriving soon.
+ // We should not send BeginMainFrame while we are in the idle state since we
+ // might have new user input arriving soon. It's okay to send BeginMainFrame
+ // for the synchronous compositor because the main thread is always high
+ // latency in that case.
// TODO(brianderson): Allow sending BeginMainFrame while idle when the main
- // thread isn't consuming user input.
- if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_IDLE &&
- BeginFrameNeeded())
+ // thread isn't consuming user input for non-synchronous compositor.
+ if (!settings_.using_synchronous_renderer_compositor &&
+ begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_IDLE) {
return false;
+ }
// We need a new commit for the forced redraw. This honors the
// single commit per interval because the result will be swapped to screen.
+ // TODO(brianderson): Remove this or move it below the
+ // SendingBeginMainFrameMightCauseDeadlock check since we want to avoid
+ // ever returning true from this method if we might cause deadlock.
if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT)
return true;
@@ -439,15 +459,23 @@ bool SchedulerStateMachine::ShouldSendBeginMainFrame() const {
if (!HasInitializedOutputSurface())
return false;
- // SwapAck throttle the BeginMainFrames unless we just swapped.
- // TODO(brianderson): Remove this restriction to improve throughput.
- bool just_swapped_in_deadline =
- begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE &&
- did_perform_swap_in_last_draw_;
- if (pending_swaps_ >= max_pending_swaps_ && !just_swapped_in_deadline)
+ // Make sure the BeginMainFrame can finish eventually if we start it.
+ if (SendingBeginMainFrameMightCauseDeadlock())
return false;
- if (skip_begin_main_frame_to_reduce_latency_)
+ if (!settings_.main_frame_while_swap_throttled_enabled) {
+ // SwapAck throttle the BeginMainFrames unless we just swapped to
+ // potentially improve impl-thread latency over main-thread throughput.
+ // TODO(brianderson): Remove this restriction to improve throughput or
+ // make it conditional on impl_latency_takes_priority_.
+ bool just_swapped_in_deadline =
+ begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE &&
+ did_perform_swap_in_last_draw_;
+ if (SwapThrottled() && !just_swapped_in_deadline)
+ return false;
+ }
+
+ if (skip_next_begin_main_frame_to_reduce_latency_)
return false;
return true;
@@ -463,9 +491,10 @@ bool SchedulerStateMachine::ShouldCommit() const {
return false;
}
- // Prioritize drawing the previous commit before finishing the next commit.
- if (active_tree_needs_first_draw_)
- return false;
+ // If we only have an active tree, it is incorrect to replace it
+ // before we've drawn it.
+ DCHECK_IMPLIES(settings_.commit_to_active_tree,
+ !active_tree_needs_first_draw_);
return true;
}
@@ -608,17 +637,12 @@ void SchedulerStateMachine::UpdateStateOnCommit(bool commit_has_no_updates) {
if (commit_has_no_updates || settings_.main_frame_before_activation_enabled) {
commit_state_ = COMMIT_STATE_IDLE;
- } else if (settings_.impl_side_painting) {
- commit_state_ = COMMIT_STATE_WAITING_FOR_ACTIVATION;
} else {
- commit_state_ = settings_.main_thread_should_always_be_low_latency
- ? COMMIT_STATE_WAITING_FOR_DRAW
- : COMMIT_STATE_IDLE;
+ commit_state_ = COMMIT_STATE_WAITING_FOR_ACTIVATION;
}
- // If we are impl-side-painting but the commit was aborted, then we behave
- // mostly as if we are not impl-side-painting since there is no pending tree.
- has_pending_tree_ = settings_.impl_side_painting && !commit_has_no_updates;
+ // If the commit was aborted, then there is no pending tree.
+ has_pending_tree_ = !commit_has_no_updates;
// Update state related to forced draws.
if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) {
@@ -657,7 +681,7 @@ void SchedulerStateMachine::UpdateStateOnCommit(bool commit_has_no_updates) {
void SchedulerStateMachine::UpdateStateOnActivation() {
if (commit_state_ == COMMIT_STATE_WAITING_FOR_ACTIVATION) {
- commit_state_ = settings_.main_thread_should_always_be_low_latency
+ commit_state_ = settings_.commit_to_active_tree
? COMMIT_STATE_WAITING_FOR_DRAW
: COMMIT_STATE_IDLE;
}
@@ -833,10 +857,6 @@ void SchedulerStateMachine::OnBeginImplFrame() {
// "Drain" the PrepareTiles funnel.
if (prepare_tiles_funnel_ > 0)
prepare_tiles_funnel_--;
-
- skip_begin_main_frame_to_reduce_latency_ =
- skip_next_begin_main_frame_to_reduce_latency_;
- skip_next_begin_main_frame_to_reduce_latency_ = false;
}
void SchedulerStateMachine::OnBeginImplFrameDeadlinePending() {
@@ -860,6 +880,13 @@ void SchedulerStateMachine::OnBeginImplFrameDeadline() {
void SchedulerStateMachine::OnBeginImplFrameIdle() {
begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_IDLE;
+
+ skip_next_begin_main_frame_to_reduce_latency_ = false;
+
+ // If we're entering a state where we won't get BeginFrames set all the
+ // funnels so that we don't perform any actions that we shouldn't.
+ if (!BeginFrameNeeded())
+ send_begin_main_frame_funnel_ = true;
}
SchedulerStateMachine::BeginImplFrameDeadlineMode
@@ -873,7 +900,7 @@ SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode() const {
return BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW;
} else if (ShouldTriggerBeginImplFrameDeadlineImmediately()) {
return BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE;
- } else if (needs_redraw_ && pending_swaps_ < max_pending_swaps_) {
+ } else if (needs_redraw_ && !SwapThrottled()) {
// We have an animation or fast input path on the impl thread that wants
// to draw, so don't wait too long for a new active tree.
// If we are swap throttled we should wait until we are unblocked.
@@ -888,7 +915,6 @@ SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode() const {
bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately()
const {
- // TODO(brianderson): This should take into account multiple commit sources.
if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME)
return false;
@@ -897,7 +923,7 @@ bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately()
return true;
// SwapAck throttle the deadline since we wont draw and swap anyway.
- if (pending_swaps_ >= max_pending_swaps_)
+ if (SwapThrottled())
return false;
if (active_tree_needs_first_draw_)
@@ -962,7 +988,15 @@ bool SchedulerStateMachine::MainThreadIsInHighLatencyMode() const {
return active_tree_needs_first_draw_;
}
-void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; }
+bool SchedulerStateMachine::SwapThrottled() const {
+ return pending_swaps_ >= max_pending_swaps_;
+}
+
+void SchedulerStateMachine::SetVisible(bool visible) {
+ visible_ = visible;
+ // TODO(sunnyps): Change the funnel to a bool to avoid hacks like this.
+ prepare_tiles_funnel_ = 0;
+}
void SchedulerStateMachine::SetCanDraw(bool can_draw) { can_draw_ = can_draw; }
@@ -973,10 +1007,16 @@ void SchedulerStateMachine::SetNeedsAnimate() {
}
void SchedulerStateMachine::SetWaitForReadyToDraw() {
- DCHECK(settings_.impl_side_painting);
wait_for_active_tree_ready_to_draw_ = true;
}
+bool SchedulerStateMachine::OnlyImplSideUpdatesExpected() const {
+ bool has_impl_updates = needs_redraw_ || needs_animate_;
+ bool main_updates_expected =
+ needs_commit_ || commit_state_ != COMMIT_STATE_IDLE || has_pending_tree_;
+ return has_impl_updates && !main_updates_expected;
+}
+
void SchedulerStateMachine::SetNeedsPrepareTiles() {
if (!needs_prepare_tiles_) {
TRACE_EVENT0("cc", "SchedulerStateMachine::SetNeedsPrepareTiles");
@@ -990,6 +1030,8 @@ void SchedulerStateMachine::SetMaxSwapsPending(int max) {
void SchedulerStateMachine::DidSwapBuffers() {
pending_swaps_++;
+ swaps_with_current_output_surface_++;
+
DCHECK_LE(pending_swaps_, max_pending_swaps_);
did_perform_swap_in_last_draw_ = true;
@@ -997,7 +1039,6 @@ void SchedulerStateMachine::DidSwapBuffers() {
}
void SchedulerStateMachine::DidSwapBuffersComplete() {
- DCHECK_GT(pending_swaps_, 0);
pending_swaps_--;
}
@@ -1032,7 +1073,7 @@ void SchedulerStateMachine::DidDrawIfPossibleCompleted(DrawResult result) {
consecutive_checkerboard_animations_++;
if (settings_.timeout_and_draw_when_animation_checkerboards &&
consecutive_checkerboard_animations_ >=
- settings_.maximum_number_of_failed_draws_before_draw_is_forced_) {
+ settings_.maximum_number_of_failed_draws_before_draw_is_forced) {
consecutive_checkerboard_animations_ = 0;
// We need to force a draw, but it doesn't make sense to do this until
// we've committed and have new textures.
@@ -1057,10 +1098,10 @@ void SchedulerStateMachine::NotifyReadyToCommit() {
DCHECK(commit_state_ == COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED)
<< AsValue()->ToString();
commit_state_ = COMMIT_STATE_READY_TO_COMMIT;
- // In main thread low latency mode, commit should happen right after
+ // In commit_to_active_tree mode, commit should happen right after
// BeginFrame, meaning when this function is called, next action should be
// commit.
- if (settings_.main_thread_should_always_be_low_latency)
+ if (settings_.commit_to_active_tree)
DCHECK(ShouldCommit());
}
@@ -1115,6 +1156,7 @@ void SchedulerStateMachine::DidCreateAndInitializeOutputSurface() {
}
did_create_and_initialize_first_output_surface_ = true;
pending_swaps_ = 0;
+ swaps_with_current_output_surface_ = 0;
}
void SchedulerStateMachine::NotifyBeginMainFrameStarted() {
@@ -1137,17 +1179,4 @@ bool SchedulerStateMachine::HasInitializedOutputSurface() const {
return false;
}
-std::string SchedulerStateMachine::GetStatesForDebugging() const {
- return base::StringPrintf("%c %d %d %d %c %c %c %d %d",
- needs_commit_ ? 'T' : 'F',
- static_cast<int>(output_surface_state_),
- static_cast<int>(begin_impl_frame_state_),
- static_cast<int>(commit_state_),
- has_pending_tree_ ? 'T' : 'F',
- pending_tree_is_ready_for_activation_ ? 'T' : 'F',
- active_tree_needs_first_draw_ ? 'T' : 'F',
- max_pending_swaps_,
- pending_swaps_);
-}
-
} // namespace cc
diff --git a/chromium/cc/scheduler/scheduler_state_machine.h b/chromium/cc/scheduler/scheduler_state_machine.h
index cf29ca9b6a5..cf1ab8c5568 100644
--- a/chromium/cc/scheduler/scheduler_state_machine.h
+++ b/chromium/cc/scheduler/scheduler_state_machine.h
@@ -145,6 +145,8 @@ class CC_EXPORT SchedulerStateMachine {
// impl thread to draw, it is in a high latency mode.
bool MainThreadIsInHighLatencyMode() const;
+ bool SwapThrottled() const;
+
// Indicates whether the LayerTreeHostImpl is visible.
void SetVisible(bool visible);
bool visible() const { return visible_; }
@@ -157,6 +159,8 @@ class CC_EXPORT SchedulerStateMachine {
void SetNeedsAnimate();
bool needs_animate() const { return needs_animate_; }
+ bool OnlyImplSideUpdatesExpected() const;
+
// Indicates that prepare-tiles is required. This guarantees another
// PrepareTiles will occur shortly (even if no redraw is required).
void SetNeedsPrepareTiles();
@@ -179,6 +183,8 @@ class CC_EXPORT SchedulerStateMachine {
// Notification from the OutputSurface that a swap has been consumed.
void DidSwapBuffersComplete();
+ int pending_swaps() const { return pending_swaps_; }
+
// Indicates whether to prioritize impl thread latency (i.e., animation
// smoothness) over new content activation.
void SetImplLatencyTakesPriority(bool impl_latency_takes_priority);
@@ -193,6 +199,7 @@ class CC_EXPORT SchedulerStateMachine {
// updates from the main thread to the impl, or to push deltas from the impl
// thread to main.
void SetNeedsCommit();
+ bool needs_commit() const { return needs_commit_; }
// Call this only in response to receiving an ACTION_SEND_BEGIN_MAIN_FRAME
// from NextAction.
@@ -208,6 +215,7 @@ class CC_EXPORT SchedulerStateMachine {
// Allow access of the can_start_ state in tests.
bool CanStartForTesting() const { return can_start_; }
+ // Indicates production should be skipped to recover latency.
void SetSkipNextBeginMainFrameToReduceLatency();
// Indicates whether drawing would, at this time, make sense.
@@ -245,10 +253,6 @@ class CC_EXPORT SchedulerStateMachine {
void SetDeferCommits(bool defer_commits);
- // TODO(zmo): This is temporary for debugging crbug.com/393331.
- // We should remove it afterwards.
- std::string GetStatesForDebugging() const;
-
void SetChildrenNeedBeginFrames(bool children_need_begin_frames);
bool children_need_begin_frames() const {
return children_need_begin_frames_;
@@ -268,6 +272,9 @@ class CC_EXPORT SchedulerStateMachine {
// True if we need to force activations to make forward progress.
bool PendingActivationsShouldBeForced() const;
+ // TODO(brianderson): Remove this once NPAPI support is removed.
+ bool SendingBeginMainFrameMightCauseDeadlock() const;
+
bool ShouldAnimate() const;
bool ShouldBeginOutputSurfaceCreation() const;
bool ShouldDraw() const;
@@ -317,6 +324,7 @@ class CC_EXPORT SchedulerStateMachine {
int consecutive_checkerboard_animations_;
int max_pending_swaps_;
int pending_swaps_;
+ int swaps_with_current_output_surface_;
bool needs_redraw_;
bool needs_animate_;
bool needs_prepare_tiles_;
@@ -330,7 +338,6 @@ class CC_EXPORT SchedulerStateMachine {
bool did_create_and_initialize_first_output_surface_;
bool impl_latency_takes_priority_;
bool skip_next_begin_main_frame_to_reduce_latency_;
- bool skip_begin_main_frame_to_reduce_latency_;
bool continuous_painting_;
bool children_need_begin_frames_;
bool defer_commits_;
diff --git a/chromium/cc/scheduler/scheduler_state_machine_unittest.cc b/chromium/cc/scheduler/scheduler_state_machine_unittest.cc
index 7b332a3fbf3..da40cc15017 100644
--- a/chromium/cc/scheduler/scheduler_state_machine_unittest.cc
+++ b/chromium/cc/scheduler/scheduler_state_machine_unittest.cc
@@ -202,14 +202,15 @@ TEST(SchedulerStateMachineTest, TestNextActionBeginsMainFrameIfNeeded) {
state.SetNeedsRedraw(false);
state.SetVisible(true);
- EXPECT_FALSE(state.BeginFrameNeeded());
-
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
- EXPECT_FALSE(state.BeginFrameNeeded());
- state.OnBeginImplFrame();
+ EXPECT_FALSE(state.NeedsCommit());
+ state.OnBeginImplFrame();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
+
state.OnBeginImplFrameDeadline();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
+ EXPECT_FALSE(state.NeedsCommit());
}
// If commit requested but can_start is still false, do nothing.
@@ -220,13 +221,15 @@ TEST(SchedulerStateMachineTest, TestNextActionBeginsMainFrameIfNeeded) {
state.SetVisible(true);
state.SetNeedsCommit();
- EXPECT_FALSE(state.BeginFrameNeeded());
-
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
- EXPECT_FALSE(state.BeginFrameNeeded());
+ EXPECT_TRUE(state.NeedsCommit());
+
state.OnBeginImplFrame();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
+
state.OnBeginImplFrameDeadline();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
+ EXPECT_TRUE(state.NeedsCommit());
}
// If commit requested, begin a main frame.
@@ -240,16 +243,19 @@ TEST(SchedulerStateMachineTest, TestNextActionBeginsMainFrameIfNeeded) {
state.SetVisible(true);
state.SetNeedsCommit();
- EXPECT_TRUE(state.BeginFrameNeeded());
-
// Expect nothing to happen until after OnBeginImplFrame.
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
- EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
+ EXPECT_TRUE(state.NeedsCommit());
+ EXPECT_TRUE(state.BeginFrameNeeded());
state.OnBeginImplFrame();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
+ EXPECT_COMMIT_STATE(
+ SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
+ EXPECT_FALSE(state.NeedsCommit());
}
// If commit requested and can't draw, still begin a main frame.
@@ -264,26 +270,15 @@ TEST(SchedulerStateMachineTest, TestNextActionBeginsMainFrameIfNeeded) {
state.SetNeedsCommit();
state.SetCanDraw(false);
- EXPECT_TRUE(state.BeginFrameNeeded());
-
// Expect nothing to happen until after OnBeginImplFrame.
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
- EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
+ EXPECT_TRUE(state.BeginFrameNeeded());
state.OnBeginImplFrame();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
- }
-
- // Begin the frame, make sure needs_commit and commit_state update correctly.
- {
- StateMachine state(default_scheduler_settings);
- state.SetCanStart();
- state.UpdateState(state.NextAction());
- state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
- state.SetVisible(true);
- state.UpdateState(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_COMMIT_STATE(
SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
EXPECT_FALSE(state.NeedsCommit());
@@ -293,7 +288,6 @@ TEST(SchedulerStateMachineTest, TestNextActionBeginsMainFrameIfNeeded) {
// Explicitly test main_frame_before_activation_enabled = true
TEST(SchedulerStateMachineTest, MainFrameBeforeActivationEnabled) {
SchedulerSettings scheduler_settings;
- scheduler_settings.impl_side_painting = true;
scheduler_settings.main_frame_before_activation_enabled = true;
StateMachine state(scheduler_settings);
state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
@@ -331,10 +325,11 @@ TEST(SchedulerStateMachineTest, MainFrameBeforeActivationEnabled) {
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
- // Verify NotifyReadyToActivate unblocks activation, draw, and
- // commit in that order.
+ // Verify NotifyReadyToActivate unblocks activation, commit, and
+ // draw in that order.
state.NotifyReadyToActivate();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
@@ -344,7 +339,6 @@ TEST(SchedulerStateMachineTest, MainFrameBeforeActivationEnabled) {
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
state.DidSwapBuffers();
state.DidSwapBuffersComplete();
- EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
}
@@ -450,7 +444,7 @@ TEST(SchedulerStateMachineTest,
TEST(SchedulerStateMachineTest,
TestFailedDrawsEventuallyForceDrawAfterNextCommit) {
SchedulerSettings scheduler_settings;
- scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ = 1;
+ scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced = 1;
StateMachine state(scheduler_settings);
SET_UP_STATE(state)
@@ -486,6 +480,12 @@ TEST(SchedulerStateMachineTest,
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_TRUE(state.RedrawPending());
+ // Activate so we're ready for a new main frame.
+ state.NotifyReadyToActivate();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
+ EXPECT_TRUE(state.RedrawPending());
+
// The redraw should be forced at the end of the next BeginImplFrame.
state.OnBeginImplFrame();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
@@ -502,9 +502,8 @@ TEST(SchedulerStateMachineTest,
TEST(SchedulerStateMachineTest, TestFailedDrawsDoNotRestartForcedDraw) {
SchedulerSettings scheduler_settings;
int draw_limit = 1;
- scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ =
+ scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced =
draw_limit;
- scheduler_settings.impl_side_painting = true;
StateMachine state(scheduler_settings);
SET_UP_STATE(state)
@@ -788,6 +787,8 @@ TEST(SchedulerStateMachineTest,
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
+ state.NotifyReadyToActivate();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
@@ -842,9 +843,11 @@ TEST(SchedulerStateMachineTest, TestSetNeedsCommitIsNotLost) {
SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING);
EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
- // Finish the commit, then make sure we start the next commit immediately
- // and draw on the next BeginImplFrame.
+ // Finish the commit and activate, then make sure we start the next commit
+ // immediately and draw on the next BeginImplFrame.
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
+ state.NotifyReadyToActivate();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
@@ -885,6 +888,10 @@ TEST(SchedulerStateMachineTest, TestFullCycle) {
// Commit.
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
+
+ // Activate.
+ state.NotifyReadyToActivate();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
EXPECT_TRUE(state.active_tree_needs_first_draw());
EXPECT_TRUE(state.needs_redraw());
@@ -906,70 +913,67 @@ TEST(SchedulerStateMachineTest, TestFullCycle) {
EXPECT_FALSE(state.needs_redraw());
}
-TEST(SchedulerStateMachineTest, TestFullCycleWithMainThreadLowLatencyMode) {
- SchedulerSettings scheduler_settings;
- scheduler_settings.main_thread_should_always_be_low_latency = true;
- StateMachine state(scheduler_settings);
+TEST(SchedulerStateMachineTest, CommitWithoutDrawWithPendingTree) {
+ SchedulerSettings default_scheduler_settings;
+ StateMachine state(default_scheduler_settings);
SET_UP_STATE(state)
// Start clean and set commit.
state.SetNeedsCommit();
- // Begin the frame.
+ // Make a main frame, commit and activate it. But don't draw it.
state.OnBeginImplFrame();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
- EXPECT_COMMIT_STATE(
- SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
- EXPECT_FALSE(state.NeedsCommit());
- EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
- // Tell the scheduler the frame finished.
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
- EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT);
-
- // Commit.
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
- EXPECT_TRUE(state.active_tree_needs_first_draw());
- EXPECT_TRUE(state.needs_redraw());
-
- // Now commit should wait for draw.
- EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_DRAW);
-
- // Swap throttled. Do not draw.
- state.DidSwapBuffers();
- state.OnBeginImplFrameDeadline();
- EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
- EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
- state.DidSwapBuffersComplete();
+ state.NotifyReadyToActivate();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
- // Haven't draw since last commit, do not begin new main frame.
+ // Try to make a new main frame before drawing. Since we will commit it to a
+ // pending tree and not clobber the active tree, we're able to start a new
+ // begin frame and commit it.
state.SetNeedsCommit();
state.OnBeginImplFrame();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
- EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
- // At BeginImplFrame deadline, draw.
- state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(
- SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
- state.DidSwapBuffers();
- state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
- state.DidSwapBuffersComplete();
+ SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
+ state.NotifyBeginMainFrameStarted();
+ state.NotifyReadyToCommit();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
+}
- // Now will be able to start main frame.
- EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
- EXPECT_FALSE(state.needs_redraw());
+TEST(SchedulerStateMachineTest, DontCommitWithoutDrawWithoutPendingTree) {
+ SchedulerSettings scheduler_settings;
+ scheduler_settings.commit_to_active_tree = true;
+ StateMachine state(scheduler_settings);
+ SET_UP_STATE(state)
+
+ // Start clean and set commit.
+ state.SetNeedsCommit();
+
+ // Make a main frame, commit and activate it. But don't draw it.
+ state.OnBeginImplFrame();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
+ state.NotifyBeginMainFrameStarted();
+ state.NotifyReadyToCommit();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
+ state.NotifyReadyToActivate();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
+
+ // Try to make a new main frame before drawing, but since we would clobber the
+ // active tree, we will not do so.
+ state.SetNeedsCommit();
+ state.OnBeginImplFrame();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
}
-TEST(SchedulerStateMachineTest,
- TestFullCycleWithMainThreadLowLatencyMode_ImplSidePaint) {
+TEST(SchedulerStateMachineTest, TestFullCycleWithCommitToActive) {
SchedulerSettings scheduler_settings;
- scheduler_settings.main_thread_should_always_be_low_latency = true;
- scheduler_settings.impl_side_painting = true;
+ scheduler_settings.commit_to_active_tree = true;
StateMachine state(scheduler_settings);
SET_UP_STATE(state)
@@ -1074,8 +1078,10 @@ TEST(SchedulerStateMachineTest, TestFullCycleWithCommitRequestInbetween) {
state.NotifyReadyToCommit();
EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT);
- // First commit.
+ // First commit and activate.
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
+ state.NotifyReadyToActivate();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
EXPECT_TRUE(state.active_tree_needs_first_draw());
EXPECT_TRUE(state.needs_redraw());
@@ -1272,8 +1278,6 @@ TEST(SchedulerStateMachineTest, TestContextLostWhenCompletelyIdle) {
TEST(SchedulerStateMachineTest,
TestContextLostWhenIdleAndCommitRequestedWhileRecreating) {
SchedulerSettings default_scheduler_settings;
- // We use impl side painting because it's the more complicated version.
- default_scheduler_settings.impl_side_painting = true;
StateMachine state(default_scheduler_settings);
SET_UP_STATE(state)
@@ -1424,10 +1428,12 @@ TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgress) {
state.SetNeedsRedraw(true);
EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
- // Finish the frame, and commit.
+ // Finish the frame, commit and activate.
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
+ state.NotifyReadyToActivate();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
// We will abort the draw when the output surface is lost if we are
// waiting for the first draw to unblock the main thread.
@@ -1486,10 +1492,12 @@ TEST(SchedulerStateMachineTest,
state.SetNeedsCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
- // Finish the frame, and commit.
+ // Finish the frame, and commit and activate.
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
+ state.NotifyReadyToActivate();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
EXPECT_TRUE(state.active_tree_needs_first_draw());
// Because the output surface is missing, we expect the draw to abort.
@@ -1528,6 +1536,9 @@ TEST(SchedulerStateMachineTest,
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
+ state.NotifyReadyToActivate();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(
@@ -1557,9 +1568,8 @@ TEST(SchedulerStateMachineTest, DontDrawBeforeCommitAfterLostOutputSurface) {
TEST(SchedulerStateMachineTest,
TestPendingActivationsShouldBeForcedAfterLostOutputSurface) {
- SchedulerSettings settings;
- settings.impl_side_painting = true;
- StateMachine state(settings);
+ SchedulerSettings default_scheduler_settings;
+ StateMachine state(default_scheduler_settings);
SET_UP_STATE(state)
state.SetCommitState(
@@ -1632,6 +1642,9 @@ TEST(SchedulerStateMachineTest, TestFinishCommitWhenCommitInProgress) {
state.NotifyReadyToCommit();
EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
state.UpdateState(state.NextAction());
+ state.NotifyReadyToActivate();
+ EXPECT_ACTION(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
+ state.UpdateState(state.NextAction());
EXPECT_TRUE(state.active_tree_needs_first_draw());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
@@ -1685,9 +1698,8 @@ TEST(SchedulerStateMachineTest, ReportIfNotDrawing) {
TEST(SchedulerStateMachineTest,
TestTriggerDeadlineImmediatelyAfterAbortedCommit) {
- SchedulerSettings settings;
- settings.impl_side_painting = true;
- StateMachine state(settings);
+ SchedulerSettings default_scheduler_settings;
+ StateMachine state(default_scheduler_settings);
SET_UP_STATE(state)
// This test mirrors what happens during the first frame of a scroll gesture.
@@ -1739,9 +1751,8 @@ void FinishPreviousCommitAndDrawWithoutExitingDeadline(
}
TEST(SchedulerStateMachineTest, TestImplLatencyTakesPriority) {
- SchedulerSettings settings;
- settings.impl_side_painting = true;
- StateMachine state(settings);
+ SchedulerSettings default_scheduler_settings;
+ StateMachine state(default_scheduler_settings);
SET_UP_STATE(state)
// This test ensures that impl-draws are prioritized over main thread updates
@@ -1813,9 +1824,8 @@ TEST(SchedulerStateMachineTest,
}
TEST(SchedulerStateMachineTest, TestTriggerDeadlineImmediatelyWhenInvisible) {
- SchedulerSettings settings;
- settings.impl_side_painting = true;
- StateMachine state(settings);
+ SchedulerSettings default_scheduler_settings;
+ StateMachine state(default_scheduler_settings);
SET_UP_STATE(state)
state.SetNeedsCommit();
@@ -1832,9 +1842,8 @@ TEST(SchedulerStateMachineTest, TestTriggerDeadlineImmediatelyWhenInvisible) {
}
TEST(SchedulerStateMachineTest, TestSetNeedsAnimate) {
- SchedulerSettings settings;
- settings.impl_side_painting = true;
- StateMachine state(settings);
+ SchedulerSettings default_scheduler_settings;
+ StateMachine state(default_scheduler_settings);
SET_UP_STATE(state)
// Test requesting an animation that, when run, causes us to draw.
@@ -1852,9 +1861,8 @@ TEST(SchedulerStateMachineTest, TestSetNeedsAnimate) {
}
TEST(SchedulerStateMachineTest, TestAnimateBeforeCommit) {
- SchedulerSettings settings;
- settings.impl_side_painting = true;
- StateMachine state(settings);
+ SchedulerSettings default_scheduler_settings;
+ StateMachine state(default_scheduler_settings);
SET_UP_STATE(state)
// Check that animations are updated before we start a commit.
@@ -1876,9 +1884,8 @@ TEST(SchedulerStateMachineTest, TestAnimateBeforeCommit) {
}
TEST(SchedulerStateMachineTest, TestAnimateAfterCommitBeforeDraw) {
- SchedulerSettings settings;
- settings.impl_side_painting = true;
- StateMachine state(settings);
+ SchedulerSettings default_scheduler_settings;
+ StateMachine state(default_scheduler_settings);
SET_UP_STATE(state)
// Check that animations are updated before we start a commit.
@@ -1905,9 +1912,8 @@ TEST(SchedulerStateMachineTest, TestAnimateAfterCommitBeforeDraw) {
}
TEST(SchedulerStateMachineTest, TestSetNeedsAnimateAfterAnimate) {
- SchedulerSettings settings;
- settings.impl_side_painting = true;
- StateMachine state(settings);
+ SchedulerSettings default_scheduler_settings;
+ StateMachine state(default_scheduler_settings);
SET_UP_STATE(state)
// Test requesting an animation after we have already animated during this
diff --git a/chromium/cc/scheduler/scheduler_unittest.cc b/chromium/cc/scheduler/scheduler_unittest.cc
index d2b12d768a5..42a23d423e6 100644
--- a/chromium/cc/scheduler/scheduler_unittest.cc
+++ b/chromium/cc/scheduler/scheduler_unittest.cc
@@ -10,6 +10,7 @@
#include "base/logging.h"
#include "base/memory/scoped_vector.h"
#include "base/message_loop/message_loop.h"
+#include "base/numerics/safe_conversions.h"
#include "base/run_loop.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
@@ -59,17 +60,11 @@ class FakeSchedulerClient : public SchedulerClient {
draw_will_happen_ = true;
swap_will_happen_if_draw_happens_ = true;
num_draws_ = 0;
- log_anticipated_draw_time_change_ = false;
begin_frame_args_sent_to_children_ = BeginFrameArgs();
}
void set_scheduler(TestScheduler* scheduler) { scheduler_ = scheduler; }
- // Most tests don't care about DidAnticipatedDrawTimeChange, so only record it
- // for tests that do.
- void set_log_anticipated_draw_time_change(bool log) {
- log_anticipated_draw_time_change_ = log;
- }
bool needs_begin_frames() {
return scheduler_->frame_source().NeedsBeginFrames();
}
@@ -84,7 +79,7 @@ class FakeSchedulerClient : public SchedulerClient {
int ActionIndex(const char* action) const {
for (size_t i = 0; i < actions_.size(); i++)
if (!strcmp(actions_[i], action))
- return i;
+ return base::checked_cast<int>(i);
return -1;
}
@@ -132,7 +127,10 @@ class FakeSchedulerClient : public SchedulerClient {
PushAction("ScheduledActionDrawAndSwapForced");
return DRAW_SUCCESS;
}
- void ScheduledActionCommit() override { PushAction("ScheduledActionCommit"); }
+ void ScheduledActionCommit() override {
+ PushAction("ScheduledActionCommit");
+ scheduler_->DidCommit();
+ }
void ScheduledActionActivateSyncTree() override {
PushAction("ScheduledActionActivateSyncTree");
}
@@ -141,22 +139,13 @@ class FakeSchedulerClient : public SchedulerClient {
}
void ScheduledActionPrepareTiles() override {
PushAction("ScheduledActionPrepareTiles");
+ scheduler_->WillPrepareTiles();
+ scheduler_->DidPrepareTiles();
}
void ScheduledActionInvalidateOutputSurface() override {
actions_.push_back("ScheduledActionInvalidateOutputSurface");
states_.push_back(scheduler_->AsValue());
}
- void DidAnticipatedDrawTimeChange(base::TimeTicks) override {
- if (log_anticipated_draw_time_change_)
- PushAction("DidAnticipatedDrawTimeChange");
- }
- base::TimeDelta DrawDurationEstimate() override { return base::TimeDelta(); }
- base::TimeDelta BeginMainFrameToCommitDurationEstimate() override {
- return base::TimeDelta();
- }
- base::TimeDelta CommitToActivateDurationEstimate() override {
- return base::TimeDelta();
- }
void SendBeginFramesToChildren(const BeginFrameArgs& args) override {
begin_frame_args_sent_to_children_ = args;
@@ -194,7 +183,6 @@ class FakeSchedulerClient : public SchedulerClient {
bool swap_will_happen_if_draw_happens_;
bool automatic_swap_ack_;
int num_draws_;
- bool log_anticipated_draw_time_change_;
BeginFrameArgs begin_frame_args_sent_to_children_;
base::TimeTicks posted_begin_impl_frame_deadline_;
std::vector<const char*> actions_;
@@ -203,32 +191,7 @@ class FakeSchedulerClient : public SchedulerClient {
TestScheduler* scheduler_;
};
-class SchedulerClientWithFixedEstimates : public FakeSchedulerClient {
- public:
- SchedulerClientWithFixedEstimates(
- base::TimeDelta draw_duration,
- base::TimeDelta begin_main_frame_to_commit_duration,
- base::TimeDelta commit_to_activate_duration)
- : draw_duration_(draw_duration),
- begin_main_frame_to_commit_duration_(
- begin_main_frame_to_commit_duration),
- commit_to_activate_duration_(commit_to_activate_duration) {}
-
- base::TimeDelta DrawDurationEstimate() override { return draw_duration_; }
- base::TimeDelta BeginMainFrameToCommitDurationEstimate() override {
- return begin_main_frame_to_commit_duration_;
- }
- base::TimeDelta CommitToActivateDurationEstimate() override {
- return commit_to_activate_duration_;
- }
-
- private:
- base::TimeDelta draw_duration_;
- base::TimeDelta begin_main_frame_to_commit_duration_;
- base::TimeDelta commit_to_activate_duration_;
-};
-
-class FakeExternalBeginFrameSource : public BeginFrameSourceMixIn {
+class FakeExternalBeginFrameSource : public BeginFrameSourceBase {
public:
explicit FakeExternalBeginFrameSource(FakeSchedulerClient* client)
: client_(client) {}
@@ -253,11 +216,13 @@ class FakeExternalBeginFrameSource : public BeginFrameSourceMixIn {
class SchedulerTest : public testing::Test {
public:
SchedulerTest()
- : now_src_(TestNowSource::Create()),
- task_runner_(new OrderedSimpleTaskRunner(now_src_, true)),
+ : now_src_(new base::SimpleTestTickClock()),
+ task_runner_(new OrderedSimpleTaskRunner(now_src_.get(), true)),
fake_external_begin_frame_source_(nullptr) {
- // A bunch of tests require Now() to be > BeginFrameArgs::DefaultInterval()
- now_src_->AdvanceNow(base::TimeDelta::FromMilliseconds(100));
+ now_src_->Advance(base::TimeDelta::FromMicroseconds(10000));
+ // A bunch of tests require NowTicks()
+ // to be > BeginFrameArgs::DefaultInterval()
+ now_src_->Advance(base::TimeDelta::FromMilliseconds(100));
// Fail if we need to run 100 tasks in a row.
task_runner_->SetRunTaskLimit(100);
}
@@ -266,18 +231,27 @@ class SchedulerTest : public testing::Test {
protected:
TestScheduler* CreateScheduler() {
- scoped_ptr<FakeExternalBeginFrameSource> fake_external_begin_frame_source;
if (scheduler_settings_.use_external_begin_frame_source) {
- fake_external_begin_frame_source.reset(
+ fake_external_begin_frame_source_.reset(
new FakeExternalBeginFrameSource(client_.get()));
- fake_external_begin_frame_source_ =
- fake_external_begin_frame_source.get();
}
- scheduler_ = TestScheduler::Create(now_src_, client_.get(),
- scheduler_settings_, 0, task_runner_,
- fake_external_begin_frame_source.Pass());
+
+ scoped_ptr<FakeCompositorTimingHistory> fake_compositor_timing_history =
+ FakeCompositorTimingHistory::Create();
+ fake_compositor_timing_history_ = fake_compositor_timing_history.get();
+
+ scheduler_ = TestScheduler::Create(
+ now_src_.get(), client_.get(), scheduler_settings_, 0,
+ task_runner_.get(), fake_external_begin_frame_source_.get(),
+ fake_compositor_timing_history.Pass());
DCHECK(scheduler_);
client_->set_scheduler(scheduler_.get());
+
+ // Use large estimates by default to avoid latency recovery
+ // in most tests.
+ base::TimeDelta slow_duration = base::TimeDelta::FromSeconds(1);
+ fake_compositor_timing_history_->SetAllEstimatesTo(slow_duration);
+
return scheduler_.get();
}
@@ -300,7 +274,7 @@ class SchedulerTest : public testing::Test {
}
OrderedSimpleTaskRunner& task_runner() { return *task_runner_; }
- TestNowSource* now_src() { return now_src_.get(); }
+ base::SimpleTestTickClock* now_src() { return now_src_.get(); }
// As this function contains EXPECT macros, to allow debugging it should be
// called inside EXPECT_SCOPED like so;
@@ -336,7 +310,8 @@ class SchedulerTest : public testing::Test {
AdvanceFrame();
scheduler_->NotifyBeginMainFrameStarted();
- scheduler_->NotifyReadyToCommitThenActivateIfNeeded();
+ scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToActivate();
EXPECT_FALSE(scheduler_->CommitPending());
@@ -400,39 +375,37 @@ class SchedulerTest : public testing::Test {
}
}
- void SendNextBeginFrame() {
+ BeginFrameArgs SendNextBeginFrame() {
DCHECK(scheduler_->settings().use_external_begin_frame_source);
// Creep the time forward so that any BeginFrameArgs is not equal to the
// last one otherwise we violate the BeginFrameSource contract.
- now_src_->AdvanceNow(BeginFrameArgs::DefaultInterval());
- fake_external_begin_frame_source_->TestOnBeginFrame(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()));
+ now_src_->Advance(BeginFrameArgs::DefaultInterval());
+ BeginFrameArgs args =
+ CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src());
+ fake_external_begin_frame_source_->TestOnBeginFrame(args);
+ return args;
}
FakeExternalBeginFrameSource* fake_external_begin_frame_source() const {
- return fake_external_begin_frame_source_;
+ return fake_external_begin_frame_source_.get();
}
- void MainFrameInHighLatencyMode(
- int64 begin_main_frame_to_commit_estimate_in_ms,
- int64 commit_to_activate_estimate_in_ms,
- bool impl_latency_takes_priority,
- bool should_send_begin_main_frame);
+ void CheckMainFrameSkippedAfterLateCommit(bool expect_send_begin_main_frame);
+ void ImplFrameSkippedAfterLateSwapAck(bool swap_ack_before_deadline);
+ void ImplFrameIsNotSkippedAfterLateSwapAck();
void BeginFramesNotFromClient(bool use_external_begin_frame_source,
bool throttle_frame_production);
void BeginFramesNotFromClient_SwapThrottled(
bool use_external_begin_frame_source,
bool throttle_frame_production);
- void DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency(
- bool impl_side_painting);
- void DidLoseOutputSurfaceAfterReadyToCommit(bool impl_side_painting);
- scoped_refptr<TestNowSource> now_src_;
+ scoped_ptr<base::SimpleTestTickClock> now_src_;
scoped_refptr<OrderedSimpleTaskRunner> task_runner_;
- FakeExternalBeginFrameSource* fake_external_begin_frame_source_;
+ scoped_ptr<FakeExternalBeginFrameSource> fake_external_begin_frame_source_;
SchedulerSettings scheduler_settings_;
scoped_ptr<FakeSchedulerClient> client_;
scoped_ptr<TestScheduler> scheduler_;
+ FakeCompositorTimingHistory* fake_compositor_timing_history_;
};
TEST_F(SchedulerTest, InitializeOutputSurfaceDoesNotBeginImplFrame) {
@@ -484,13 +457,15 @@ TEST_F(SchedulerTest, SendBeginFramesToChildrenWithoutCommit) {
TEST_F(SchedulerTest, SendBeginFramesToChildrenDeadlineNotAdjusted) {
// Set up client with specified estimates.
- SchedulerClientWithFixedEstimates* client =
- new SchedulerClientWithFixedEstimates(
- base::TimeDelta::FromMilliseconds(1),
- base::TimeDelta::FromMilliseconds(2),
- base::TimeDelta::FromMilliseconds(4));
scheduler_settings_.use_external_begin_frame_source = true;
- SetUpScheduler(make_scoped_ptr(client).Pass(), true);
+ SetUpScheduler(true);
+
+ fake_compositor_timing_history_->SetBeginMainFrameToCommitDurationEstimate(
+ base::TimeDelta::FromMilliseconds(2));
+ fake_compositor_timing_history_->SetCommitToReadyToActivateDurationEstimate(
+ base::TimeDelta::FromMilliseconds(4));
+ fake_compositor_timing_history_->SetDrawDurationEstimate(
+ base::TimeDelta::FromMilliseconds(1));
EXPECT_FALSE(client_->needs_begin_frames());
scheduler_->SetChildrenNeedBeginFrames(true);
@@ -569,6 +544,12 @@ TEST_F(SchedulerTest, RequestCommit) {
EXPECT_TRUE(client_->needs_begin_frames());
client_->Reset();
+ // NotifyReadyToActivate should trigger the activation.
+ scheduler_->NotifyReadyToActivate();
+ EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+ EXPECT_TRUE(client_->needs_begin_frames());
+ client_->Reset();
+
// BeginImplFrame should prepare the draw.
EXPECT_SCOPED(AdvanceFrame());
EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
@@ -579,7 +560,7 @@ TEST_F(SchedulerTest, RequestCommit) {
// BeginImplFrame deadline should draw.
task_runner().RunPendingTasks(); // Run posted deadline.
- EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1);
+ EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_);
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
EXPECT_TRUE(client_->needs_begin_frames());
client_->Reset();
@@ -684,6 +665,13 @@ TEST_F(SchedulerTest, RequestCommitAfterBeginMainFrameSent) {
EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
client_->Reset();
+
+ // Activate it.
+ scheduler_->NotifyReadyToActivate();
+ EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+ EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
+ client_->Reset();
+
task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_ACTION("ScheduledActionAnimate", client_, 0, 2);
EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2);
@@ -708,6 +696,10 @@ TEST_F(SchedulerTest, RequestCommitAfterBeginMainFrameSent) {
EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
client_->Reset();
+ scheduler_->NotifyReadyToActivate();
+ EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+ EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
+ client_->Reset();
task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_ACTION("ScheduledActionAnimate", client_, 0, 2);
EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2);
@@ -728,8 +720,6 @@ class SchedulerClientThatsetNeedsDrawInsideDraw : public FakeSchedulerClient {
SchedulerClientThatsetNeedsDrawInsideDraw()
: FakeSchedulerClient(), request_redraws_(false) {}
- void ScheduledActionSendBeginMainFrame() override {}
-
void SetRequestRedrawsInsideDraw(bool enable) { request_redraws_ = enable; }
DrawResult ScheduledActionDrawAndSwapIfPossible() override {
@@ -745,9 +735,6 @@ class SchedulerClientThatsetNeedsDrawInsideDraw : public FakeSchedulerClient {
return DRAW_SUCCESS;
}
- void ScheduledActionCommit() override {}
- void DidAnticipatedDrawTimeChange(base::TimeTicks) override {}
-
private:
bool request_redraws_;
};
@@ -842,7 +829,6 @@ class SchedulerClientThatSetNeedsCommitInsideDraw : public FakeSchedulerClient {
SchedulerClientThatSetNeedsCommitInsideDraw()
: set_needs_commit_on_next_draw_(false) {}
- void ScheduledActionSendBeginMainFrame() override {}
DrawResult ScheduledActionDrawAndSwapIfPossible() override {
// Only SetNeedsCommit the first time this is called
if (set_needs_commit_on_next_draw_) {
@@ -857,9 +843,6 @@ class SchedulerClientThatSetNeedsCommitInsideDraw : public FakeSchedulerClient {
return DRAW_SUCCESS;
}
- void ScheduledActionCommit() override {}
- void DidAnticipatedDrawTimeChange(base::TimeTicks) override {}
-
void SetNeedsCommitOnNextDraw() { set_needs_commit_on_next_draw_ = true; }
private:
@@ -890,6 +873,7 @@ TEST_F(SchedulerTest, RequestCommitInsideDraw) {
EXPECT_TRUE(client->needs_begin_frames());
scheduler_->NotifyBeginMainFrameStarted();
scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToActivate();
EXPECT_SCOPED(AdvanceFrame());
task_runner().RunPendingTasks(); // Run posted deadline.
@@ -1110,6 +1094,7 @@ TEST_F(SchedulerTest, PrepareTilesOncePerFrame) {
EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
EXPECT_TRUE(scheduler_->PrepareTilesPending());
+ scheduler_->WillPrepareTiles();
scheduler_->DidPrepareTiles(); // An explicit PrepareTiles.
EXPECT_FALSE(scheduler_->PrepareTilesPending());
@@ -1141,10 +1126,10 @@ TEST_F(SchedulerTest, PrepareTilesOncePerFrame) {
EXPECT_FALSE(scheduler_->RedrawPending());
EXPECT_FALSE(scheduler_->PrepareTilesPending());
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
- scheduler_->DidPrepareTiles(); // Corresponds to ScheduledActionPrepareTiles
// If we get another DidPrepareTiles within the same frame, we should
// not PrepareTiles on the next frame.
+ scheduler_->WillPrepareTiles();
scheduler_->DidPrepareTiles(); // An explicit PrepareTiles.
scheduler_->SetNeedsPrepareTiles();
scheduler_->SetNeedsRedraw();
@@ -1168,6 +1153,7 @@ TEST_F(SchedulerTest, PrepareTilesOncePerFrame) {
// frame. This verifies we don't alternate calling PrepareTiles once and
// twice.
EXPECT_TRUE(scheduler_->PrepareTilesPending());
+ scheduler_->WillPrepareTiles();
scheduler_->DidPrepareTiles(); // An explicit PrepareTiles.
EXPECT_FALSE(scheduler_->PrepareTilesPending());
scheduler_->SetNeedsPrepareTiles();
@@ -1207,7 +1193,40 @@ TEST_F(SchedulerTest, PrepareTilesOncePerFrame) {
EXPECT_FALSE(scheduler_->RedrawPending());
EXPECT_FALSE(scheduler_->PrepareTilesPending());
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
- scheduler_->DidPrepareTiles(); // Corresponds to ScheduledActionPrepareTiles
+}
+
+TEST_F(SchedulerTest, PrepareTilesFunnelResetOnVisibilityChange) {
+ scoped_ptr<SchedulerClientNeedsPrepareTilesInDraw> client =
+ make_scoped_ptr(new SchedulerClientNeedsPrepareTilesInDraw);
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(client.Pass(), true);
+
+ // Simulate a few visibility changes and associated PrepareTiles.
+ for (int i = 0; i < 10; i++) {
+ scheduler_->SetVisible(false);
+ scheduler_->WillPrepareTiles();
+ scheduler_->DidPrepareTiles();
+
+ scheduler_->SetVisible(true);
+ scheduler_->WillPrepareTiles();
+ scheduler_->DidPrepareTiles();
+ }
+
+ client_->Reset();
+ scheduler_->SetNeedsRedraw();
+ EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+
+ client_->Reset();
+ AdvanceFrame();
+ EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
+ EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
+
+ client_->Reset();
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 2);
+ EXPECT_ACTION("ScheduledActionPrepareTiles", client_, 1, 2);
}
TEST_F(SchedulerTest, TriggerBeginFrameDeadlineEarly) {
@@ -1228,7 +1247,6 @@ TEST_F(SchedulerTest, WaitForReadyToDrawDoNotPostDeadline) {
SchedulerClientNeedsPrepareTilesInDraw* client =
new SchedulerClientNeedsPrepareTilesInDraw;
scheduler_settings_.use_external_begin_frame_source = true;
- scheduler_settings_.impl_side_painting = true;
SetUpScheduler(make_scoped_ptr(client).Pass(), true);
// SetNeedsCommit should begin the frame on the next BeginImplFrame.
@@ -1270,7 +1288,6 @@ TEST_F(SchedulerTest, WaitForReadyToDrawCancelledWhenLostOutputSurface) {
SchedulerClientNeedsPrepareTilesInDraw* client =
new SchedulerClientNeedsPrepareTilesInDraw;
scheduler_settings_.use_external_begin_frame_source = true;
- scheduler_settings_.impl_side_painting = true;
SetUpScheduler(make_scoped_ptr(client).Pass(), true);
// SetNeedsCommit should begin the frame on the next BeginImplFrame.
@@ -1310,133 +1327,757 @@ TEST_F(SchedulerTest, WaitForReadyToDrawCancelledWhenLostOutputSurface) {
EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
}
-void SchedulerTest::MainFrameInHighLatencyMode(
- int64 begin_main_frame_to_commit_estimate_in_ms,
- int64 commit_to_activate_estimate_in_ms,
- bool impl_latency_takes_priority,
- bool should_send_begin_main_frame) {
- // Set up client with specified estimates (draw duration is set to 1).
- SchedulerClientWithFixedEstimates* client =
- new SchedulerClientWithFixedEstimates(
- base::TimeDelta::FromMilliseconds(1),
- base::TimeDelta::FromMilliseconds(
- begin_main_frame_to_commit_estimate_in_ms),
- base::TimeDelta::FromMilliseconds(commit_to_activate_estimate_in_ms));
-
- scheduler_settings_.use_external_begin_frame_source = true;
- SetUpScheduler(make_scoped_ptr(client).Pass(), true);
-
- scheduler_->SetImplLatencyTakesPriority(impl_latency_takes_priority);
-
+void SchedulerTest::CheckMainFrameSkippedAfterLateCommit(
+ bool expect_send_begin_main_frame) {
// Impl thread hits deadline before commit finishes.
scheduler_->SetNeedsCommit();
EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
EXPECT_SCOPED(AdvanceFrame());
EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
- task_runner().RunPendingTasks(); // Run posted deadline.
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
scheduler_->NotifyBeginMainFrameStarted();
scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToActivate();
+ EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 5);
+ EXPECT_ACTION("WillBeginImplFrame", client_, 1, 5);
+ EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 5);
+ EXPECT_ACTION("ScheduledActionCommit", client_, 3, 5);
+ EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 4, 5);
EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
- EXPECT_TRUE(client->HasAction("ScheduledActionSendBeginMainFrame"));
- client->Reset();
+ client_->Reset();
scheduler_->SetNeedsCommit();
EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
EXPECT_SCOPED(AdvanceFrame());
EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
- task_runner().RunPendingTasks(); // Run posted deadline.
- EXPECT_EQ(scheduler_->MainThreadIsInHighLatencyMode(),
- should_send_begin_main_frame);
- EXPECT_EQ(client->HasAction("ScheduledActionSendBeginMainFrame"),
- should_send_begin_main_frame);
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ EXPECT_EQ(expect_send_begin_main_frame,
+ scheduler_->MainThreadIsInHighLatencyMode());
+ EXPECT_EQ(expect_send_begin_main_frame,
+ client_->HasAction("ScheduledActionSendBeginMainFrame"));
+}
+
+TEST_F(SchedulerTest, MainFrameSkippedAfterLateCommit) {
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+
+ auto fast_duration = base::TimeDelta::FromMilliseconds(1);
+ fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
+
+ bool expect_send_begin_main_frame = false;
+ EXPECT_SCOPED(
+ CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame));
}
TEST_F(SchedulerTest,
- SkipMainFrameIfHighLatencyAndCanCommitAndActivateBeforeDeadline) {
- // Set up client so that estimates indicate that we can commit and activate
- // before the deadline (~8ms by default).
- EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 1, false, false));
+ MainFrameNotSkippedAfterLateCommitInPreferImplLatencyMode) {
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+ scheduler_->SetImplLatencyTakesPriority(true);
+
+ auto fast_duration = base::TimeDelta::FromMilliseconds(1);
+ fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
+
+ bool expect_send_begin_main_frame = true;
+ EXPECT_SCOPED(
+ CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame));
}
-TEST_F(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanCommitTooLong) {
- // Set up client so that estimates indicate that the commit cannot finish
- // before the deadline (~8ms by default).
- EXPECT_SCOPED(MainFrameInHighLatencyMode(10, 1, false, true));
+TEST_F(SchedulerTest,
+ MainFrameNotSkippedAfterLateCommit_CommitEstimateTooLong) {
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+ auto fast_duration = base::TimeDelta::FromMilliseconds(1);
+ fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
+ auto slow_duration = base::TimeDelta::FromSeconds(1);
+ fake_compositor_timing_history_->SetBeginMainFrameToCommitDurationEstimate(
+ slow_duration);
+
+ bool expect_send_begin_main_frame = true;
+ EXPECT_SCOPED(
+ CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame));
}
-TEST_F(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanActivateTooLong) {
- // Set up client so that estimates indicate that the activate cannot finish
- // before the deadline (~8ms by default).
- EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 10, false, true));
+TEST_F(SchedulerTest,
+ MainFrameNotSkippedAfterLateCommit_ReadyToActivateEstimateTooLong) {
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+ auto fast_duration = base::TimeDelta::FromMilliseconds(1);
+ fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
+ auto slow_duration = base::TimeDelta::FromSeconds(1);
+ fake_compositor_timing_history_->SetCommitToReadyToActivateDurationEstimate(
+ slow_duration);
+
+ bool expect_send_begin_main_frame = true;
+ EXPECT_SCOPED(
+ CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame));
}
-TEST_F(SchedulerTest, NotSkipMainFrameInPreferImplLatencyMode) {
- // Set up client so that estimates indicate that we can commit and activate
- // before the deadline (~8ms by default), but also enable impl latency takes
- // priority mode.
- EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 1, true, true));
+TEST_F(SchedulerTest,
+ MainFrameNotSkippedAfterLateCommit_ActivateEstimateTooLong) {
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+ auto fast_duration = base::TimeDelta::FromMilliseconds(1);
+ fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
+ auto slow_duration = base::TimeDelta::FromSeconds(1);
+ fake_compositor_timing_history_->SetActivateDurationEstimate(slow_duration);
+
+ bool expect_send_begin_main_frame = true;
+ EXPECT_SCOPED(
+ CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame));
}
-TEST_F(SchedulerTest, PollForCommitCompletion) {
- // Since we are simulating a long commit, set up a client with draw duration
- // estimates that prevent skipping main frames to get to low latency mode.
- SchedulerClientWithFixedEstimates* client =
- new SchedulerClientWithFixedEstimates(
- base::TimeDelta::FromMilliseconds(1),
- base::TimeDelta::FromMilliseconds(32),
- base::TimeDelta::FromMilliseconds(32));
+TEST_F(SchedulerTest, MainFrameNotSkippedAfterLateCommit_DrawEstimateTooLong) {
scheduler_settings_.use_external_begin_frame_source = true;
- SetUpScheduler(make_scoped_ptr(client).Pass(), true);
+ SetUpScheduler(true);
+ auto fast_duration = base::TimeDelta::FromMilliseconds(1);
+ fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
+ auto slow_duration = base::TimeDelta::FromSeconds(1);
+ fake_compositor_timing_history_->SetDrawDurationEstimate(slow_duration);
+
+ bool expect_send_begin_main_frame = true;
+ EXPECT_SCOPED(
+ CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame));
+}
- client->set_log_anticipated_draw_time_change(true);
+void SchedulerTest::ImplFrameSkippedAfterLateSwapAck(
+ bool swap_ack_before_deadline) {
+ // To get into a high latency state, this test disables automatic swap acks.
+ scheduler_->SetMaxSwapsPending(1);
+ client_->SetAutomaticSwapAck(false);
- BeginFrameArgs frame_args =
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src());
- frame_args.interval = base::TimeDelta::FromMilliseconds(1000);
+ // Draw and swap for first BeginFrame
+ client_->Reset();
+ scheduler_->SetNeedsCommit();
+ scheduler_->SetNeedsRedraw();
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ SendNextBeginFrame();
+ EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 4);
+ EXPECT_ACTION("WillBeginImplFrame", client_, 1, 4);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 2, 4);
+ EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 3, 4);
+
+ client_->Reset();
+ scheduler_->NotifyBeginMainFrameStarted();
+ scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToActivate();
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ EXPECT_ACTION("ScheduledActionCommit", client_, 0, 4);
+ EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 4);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 2, 4);
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 4);
+
+ // Verify we skip every other frame if the swap ack consistently
+ // comes back late.
+ for (int i = 0; i < 10; i++) {
+ // Not calling scheduler_->DidSwapBuffersComplete() until after next
+ // BeginImplFrame puts the impl thread in high latency mode.
+ client_->Reset();
+ scheduler_->SetNeedsCommit();
+ scheduler_->SetNeedsRedraw();
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ SendNextBeginFrame();
+ // Verify that we skip the BeginImplFrame
+ EXPECT_NO_ACTION(client_);
+ EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+
+ // Verify that we do not perform any actions after we are no longer
+ // swap throttled.
+ client_->Reset();
+ if (swap_ack_before_deadline) {
+ // It shouldn't matter if the swap ack comes back before the deadline...
+ scheduler_->DidSwapBuffersComplete();
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ } else {
+ // ... or after the deadline.
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ scheduler_->DidSwapBuffersComplete();
+ }
+ EXPECT_NO_ACTION(client_);
+
+ // Verify that we start the next BeginImplFrame and continue normally
+ // after having just skipped a BeginImplFrame.
+ client_->Reset();
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ SendNextBeginFrame();
+ EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 3);
+ EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 3);
+
+ client_->Reset();
+ scheduler_->NotifyBeginMainFrameStarted();
+ scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToActivate();
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ EXPECT_ACTION("ScheduledActionCommit", client_, 0, 4);
+ EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 4);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 2, 4);
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 4);
+ }
+}
+
+TEST_F(SchedulerTest,
+ ImplFrameSkippedAfterLateSwapAck_FastEstimates_SwapAckThenDeadline) {
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+
+ auto fast_duration = base::TimeDelta::FromMilliseconds(1);
+ fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
+
+ bool swap_ack_before_deadline = true;
+ EXPECT_SCOPED(ImplFrameSkippedAfterLateSwapAck(swap_ack_before_deadline));
+}
+
+TEST_F(SchedulerTest,
+ ImplFrameSkippedAfterLateSwapAck_FastEstimates_DeadlineThenSwapAck) {
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+
+ auto fast_duration = base::TimeDelta::FromMilliseconds(1);
+ fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
+
+ bool swap_ack_before_deadline = false;
+ EXPECT_SCOPED(ImplFrameSkippedAfterLateSwapAck(swap_ack_before_deadline));
+}
+
+TEST_F(SchedulerTest,
+ ImplFrameSkippedAfterLateSwapAck_ImplLatencyTakesPriority) {
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+
+ // Even if every estimate related to the main thread is slow, we should
+ // still expect to recover impl thread latency if the draw is fast and we
+ // are in impl latency takes priority.
+ scheduler_->SetImplLatencyTakesPriority(true);
+ auto slow_duration = base::TimeDelta::FromSeconds(1);
+ fake_compositor_timing_history_->SetAllEstimatesTo(slow_duration);
+ auto fast_duration = base::TimeDelta::FromMilliseconds(1);
+ fake_compositor_timing_history_->SetDrawDurationEstimate(fast_duration);
+
+ bool swap_ack_before_deadline = false;
+ EXPECT_SCOPED(ImplFrameSkippedAfterLateSwapAck(swap_ack_before_deadline));
+}
+
+TEST_F(SchedulerTest,
+ ImplFrameSkippedAfterLateSwapAck_OnlyImplSideUpdatesExpected) {
+ // This tests that we recover impl thread latency when there are no commits.
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+
+ // To get into a high latency state, this test disables automatic swap acks.
+ scheduler_->SetMaxSwapsPending(1);
+ client_->SetAutomaticSwapAck(false);
+
+ // Even if every estimate related to the main thread is slow, we should
+ // still expect to recover impl thread latency if there are no commits from
+ // the main thread.
+ auto slow_duration = base::TimeDelta::FromSeconds(1);
+ fake_compositor_timing_history_->SetAllEstimatesTo(slow_duration);
+ auto fast_duration = base::TimeDelta::FromMilliseconds(1);
+ fake_compositor_timing_history_->SetDrawDurationEstimate(fast_duration);
+
+ // Draw and swap for first BeginFrame
+ client_->Reset();
+ scheduler_->SetNeedsRedraw();
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ SendNextBeginFrame();
+ EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 3);
+ EXPECT_ACTION("WillBeginImplFrame", client_, 1, 3);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 2, 3);
+
+ client_->Reset();
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_);
+
+ // Verify we skip every other frame if the swap ack consistently
+ // comes back late.
+ for (int i = 0; i < 10; i++) {
+ // Not calling scheduler_->DidSwapBuffersComplete() until after next
+ // BeginImplFrame puts the impl thread in high latency mode.
+ client_->Reset();
+ scheduler_->SetNeedsRedraw();
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ SendNextBeginFrame();
+ // Verify that we skip the BeginImplFrame
+ EXPECT_NO_ACTION(client_);
+ EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
- // At this point, we've drawn a frame. Start another commit, but hold off on
- // the NotifyReadyToCommit for now.
+ // Verify that we do not perform any actions after we are no longer
+ // swap throttled.
+ client_->Reset();
+ scheduler_->DidSwapBuffersComplete();
+ EXPECT_NO_ACTION(client_);
+
+ // Verify that we start the next BeginImplFrame and continue normally
+ // after having just skipped a BeginImplFrame.
+ client_->Reset();
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ SendNextBeginFrame();
+ EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
+
+ client_->Reset();
+ // Deadline should be immediate.
+ EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
+ task_runner().RunUntilTime(now_src_->NowTicks());
+ EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
+ EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_);
+ }
+}
+
+void SchedulerTest::ImplFrameIsNotSkippedAfterLateSwapAck() {
+ // To get into a high latency state, this test disables automatic swap acks.
+ scheduler_->SetMaxSwapsPending(1);
+ client_->SetAutomaticSwapAck(false);
+
+ // Draw and swap for first BeginFrame
+ client_->Reset();
+ scheduler_->SetNeedsCommit();
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ SendNextBeginFrame();
+ EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 3);
+ EXPECT_ACTION("WillBeginImplFrame", client_, 1, 3);
+ EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 3);
+
+ client_->Reset();
+ scheduler_->NotifyBeginMainFrameStarted();
+ scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToActivate();
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ EXPECT_ACTION("ScheduledActionCommit", client_, 0, 4);
+ EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 4);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 2, 4);
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 4);
+
+ // Verify impl thread consistently operates in high latency mode
+ // without skipping any frames.
+ for (int i = 0; i < 10; i++) {
+ // Not calling scheduler_->DidSwapBuffersComplete() until after next frame
+ // puts the impl thread in high latency mode.
+ client_->Reset();
+ scheduler_->SetNeedsCommit();
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ SendNextBeginFrame();
+ EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_);
+ EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+
+ client_->Reset();
+ scheduler_->DidSwapBuffersComplete();
+ scheduler_->NotifyBeginMainFrameStarted();
+ scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToActivate();
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+
+ // Verify that we don't skip the actions of the BeginImplFrame
+ EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 0, 5);
+ EXPECT_ACTION("ScheduledActionCommit", client_, 1, 5);
+ EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 2, 5);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 3, 5);
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 4, 5);
+ }
+}
+
+TEST_F(SchedulerTest,
+ ImplFrameIsNotSkippedAfterLateSwapAck_CommitEstimateTooLong) {
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+ auto fast_duration = base::TimeDelta::FromMilliseconds(1);
+ fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
+ auto slow_duration = base::TimeDelta::FromSeconds(1);
+ fake_compositor_timing_history_->SetBeginMainFrameToCommitDurationEstimate(
+ slow_duration);
+ EXPECT_SCOPED(ImplFrameIsNotSkippedAfterLateSwapAck());
+}
+
+TEST_F(SchedulerTest,
+ ImplFrameIsNotSkippedAfterLateSwapAck_ReadyToActivateEstimateTooLong) {
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+ auto fast_duration = base::TimeDelta::FromMilliseconds(1);
+ fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
+ auto slow_duration = base::TimeDelta::FromSeconds(1);
+ fake_compositor_timing_history_->SetCommitToReadyToActivateDurationEstimate(
+ slow_duration);
+ EXPECT_SCOPED(ImplFrameIsNotSkippedAfterLateSwapAck());
+}
+
+TEST_F(SchedulerTest,
+ ImplFrameIsNotSkippedAfterLateSwapAck_ActivateEstimateTooLong) {
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+ auto fast_duration = base::TimeDelta::FromMilliseconds(1);
+ fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
+ auto slow_duration = base::TimeDelta::FromSeconds(1);
+ fake_compositor_timing_history_->SetActivateDurationEstimate(slow_duration);
+ EXPECT_SCOPED(ImplFrameIsNotSkippedAfterLateSwapAck());
+}
+
+TEST_F(SchedulerTest,
+ ImplFrameIsNotSkippedAfterLateSwapAck_DrawEstimateTooLong) {
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+ auto fast_duration = base::TimeDelta::FromMilliseconds(1);
+ fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
+ auto slow_duration = base::TimeDelta::FromSeconds(1);
+ fake_compositor_timing_history_->SetDrawDurationEstimate(slow_duration);
+ EXPECT_SCOPED(ImplFrameIsNotSkippedAfterLateSwapAck());
+}
+
+TEST_F(SchedulerTest,
+ MainFrameThenImplFrameSkippedAfterLateCommitAndLateSwapAck) {
+ // Set up client with custom estimates.
+ // This test starts off with expensive estimates to prevent latency recovery
+ // initially, then lowers the estimates to enable it once both the main
+ // and impl threads are in a high latency mode.
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+
+ auto slow_duration = base::TimeDelta::FromSeconds(1);
+ fake_compositor_timing_history_->SetAllEstimatesTo(slow_duration);
+
+ // To get into a high latency state, this test disables automatic swap acks.
+ scheduler_->SetMaxSwapsPending(1);
+ client_->SetAutomaticSwapAck(false);
+
+ // Impl thread hits deadline before commit finishes to make
+ // MainThreadIsInHighLatencyMode true
+ client_->Reset();
+ scheduler_->SetNeedsCommit();
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ EXPECT_SCOPED(AdvanceFrame());
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
+ scheduler_->NotifyBeginMainFrameStarted();
+ scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToActivate();
+ EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
+
+ EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 5);
+ EXPECT_ACTION("WillBeginImplFrame", client_, 1, 5);
+ EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 5);
+ EXPECT_ACTION("ScheduledActionCommit", client_, 3, 5);
+ EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 4, 5);
+
+ // Draw and swap for first commit, start second commit.
+ client_->Reset();
+ scheduler_->SetNeedsCommit();
+ EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
+ EXPECT_SCOPED(AdvanceFrame());
+ EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ scheduler_->NotifyBeginMainFrameStarted();
+ scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToActivate();
+
+ EXPECT_ACTION("WillBeginImplFrame", client_, 0, 6);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 6);
+ EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 6);
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 6);
+ EXPECT_ACTION("ScheduledActionCommit", client_, 4, 6);
+ EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 5, 6);
+
+ // Don't call scheduler_->DidSwapBuffersComplete() until after next frame
+ // to put the impl thread in a high latency mode.
+ client_->Reset();
+ scheduler_->SetNeedsCommit();
+ EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
+ EXPECT_TRUE(scheduler_->SwapThrottled());
+ EXPECT_SCOPED(AdvanceFrame());
+ EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+
+ EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
+ // Note: BeginMainFrame and swap are skipped here because of
+ // swap ack backpressure, not because of latency recovery.
+ EXPECT_FALSE(client_->HasAction("ScheduledActionSendBeginMainFrame"));
+ EXPECT_FALSE(client_->HasAction("ScheduledActionDrawAndSwapIfPossible"));
+ EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
+
+ // Lower estimates so that the scheduler will attempt latency recovery.
+ auto fast_duration = base::TimeDelta::FromMilliseconds(1);
+ fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
+
+ // Now that both threads are in a high latency mode, make sure we
+ // skip the BeginMainFrame, then the BeginImplFrame, but not both
+ // at the same time.
+
+ // Verify we skip BeginMainFrame first.
+ client_->Reset();
+ // Previous commit request is still outstanding.
+ EXPECT_TRUE(scheduler_->NeedsCommit());
+ EXPECT_TRUE(scheduler_->SwapThrottled());
+ SendNextBeginFrame();
+ EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
+ scheduler_->DidSwapBuffersComplete();
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 3);
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 2, 3);
+
+ // Verify we skip the BeginImplFrame second.
+ client_->Reset();
+ // Previous commit request is still outstanding.
+ EXPECT_TRUE(scheduler_->NeedsCommit());
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ SendNextBeginFrame();
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ scheduler_->DidSwapBuffersComplete();
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+
+ EXPECT_NO_ACTION(client_);
+
+ // Then verify we operate in a low latency mode.
+ client_->Reset();
+ // Previous commit request is still outstanding.
+ EXPECT_TRUE(scheduler_->NeedsCommit());
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ SendNextBeginFrame();
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ scheduler_->NotifyBeginMainFrameStarted();
+ scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToActivate();
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ scheduler_->DidSwapBuffersComplete();
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+
+ EXPECT_ACTION("WillBeginImplFrame", client_, 0, 6);
+ EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 6);
+ EXPECT_ACTION("ScheduledActionCommit", client_, 2, 6);
+ EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 3, 6);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 4, 6);
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 5, 6);
+}
+
+TEST_F(
+ SchedulerTest,
+ Deadlock_CommitMakesProgressWhileSwapTrottledAndActiveTreeNeedsFirstDraw) {
+ // NPAPI plugins on Windows block the Browser UI thread on the Renderer main
+ // thread. This prevents the scheduler from receiving any pending swap acks.
+
+ scheduler_settings_.use_external_begin_frame_source = true;
+ scheduler_settings_.main_frame_while_swap_throttled_enabled = true;
+ SetUpScheduler(true);
+
+ // Disables automatic swap acks so this test can force swap ack throttling
+ // to simulate a blocked Browser ui thread.
+ scheduler_->SetMaxSwapsPending(1);
+ client_->SetAutomaticSwapAck(false);
+
+ // Get a new active tree in main-thread high latency mode and put us
+ // in a swap throttled state.
+ client_->Reset();
EXPECT_FALSE(scheduler_->CommitPending());
scheduler_->SetNeedsCommit();
- fake_external_begin_frame_source()->TestOnBeginFrame(frame_args);
+ scheduler_->SetNeedsRedraw();
+ EXPECT_SCOPED(AdvanceFrame());
EXPECT_TRUE(scheduler_->CommitPending());
+ EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
+ scheduler_->NotifyBeginMainFrameStarted();
+ scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToActivate();
+ EXPECT_FALSE(scheduler_->CommitPending());
+ EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 7);
+ EXPECT_ACTION("WillBeginImplFrame", client_, 1, 7);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 2, 7);
+ EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 3, 7);
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 4, 7);
+ EXPECT_ACTION("ScheduledActionCommit", client_, 5, 7);
+ EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 6, 7);
- // Draw and swap the frame, but don't ack the swap to simulate the Browser
- // blocking on the renderer.
+ // Make sure that we can finish the next commit even while swap throttled.
+ client_->Reset();
+ EXPECT_FALSE(scheduler_->CommitPending());
+ scheduler_->SetNeedsCommit();
+ EXPECT_SCOPED(AdvanceFrame());
+ scheduler_->NotifyBeginMainFrameStarted();
+ scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToActivate();
EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
+ EXPECT_ACTION("WillBeginImplFrame", client_, 0, 5);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 5);
+ EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 5);
+ EXPECT_ACTION("ScheduledActionCommit", client_, 3, 5);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 4, 5);
+
+ // Make sure we do not send a BeginMainFrame while swap throttled and
+ // we have both a pending tree and an active tree.
+ client_->Reset();
+ EXPECT_FALSE(scheduler_->CommitPending());
+ scheduler_->SetNeedsCommit();
+ EXPECT_SCOPED(AdvanceFrame());
+ EXPECT_FALSE(scheduler_->CommitPending());
task_runner().RunPendingTasks(); // Run posted deadline.
+ EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
+}
+
+TEST_F(SchedulerTest,
+ Deadlock_NoBeginMainFrameWhileSwapTrottledAndPipelineFull) {
+ // NPAPI plugins on Windows block the Browser UI thread on the Renderer main
+ // thread. This prevents the scheduler from receiving any pending swap acks.
+
+ // This particular test makes sure we do not send a BeginMainFrame while
+ // swap trottled and we have a pending tree and active tree that
+ // still needs to be drawn for the first time.
+
+ scheduler_settings_.use_external_begin_frame_source = true;
+ scheduler_settings_.main_frame_while_swap_throttled_enabled = true;
+ scheduler_settings_.main_frame_before_activation_enabled = true;
+ SetUpScheduler(true);
+
+ // Disables automatic swap acks so this test can force swap ack throttling
+ // to simulate a blocked Browser ui thread.
+ scheduler_->SetMaxSwapsPending(1);
+ client_->SetAutomaticSwapAck(false);
+
+ // Start a new commit in main-thread high latency mode and hold off on
+ // activation.
+ client_->Reset();
+ EXPECT_FALSE(scheduler_->CommitPending());
+ scheduler_->SetNeedsCommit();
+ scheduler_->SetNeedsRedraw();
+ EXPECT_SCOPED(AdvanceFrame());
+ EXPECT_TRUE(scheduler_->CommitPending());
+ EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
- scheduler_->DidSwapBuffers();
-
- // Spin the event loop a few times and make sure we get more
- // DidAnticipateDrawTimeChange calls every time.
- int actions_so_far = client->num_actions_();
-
- // Does three iterations to make sure that the timer is properly repeating.
- for (int i = 0; i < 3; ++i) {
- EXPECT_EQ((frame_args.interval * 2).InMicroseconds(),
- task_runner().DelayToNextTaskTime().InMicroseconds())
- << scheduler_->AsValue()->ToString();
- task_runner().RunPendingTasks();
- EXPECT_GT(client->num_actions_(), actions_so_far);
- EXPECT_STREQ(client->Action(client->num_actions_() - 1),
- "DidAnticipatedDrawTimeChange");
- actions_so_far = client->num_actions_();
- }
+ scheduler_->DidSwapBuffersComplete();
+ scheduler_->NotifyBeginMainFrameStarted();
+ scheduler_->NotifyReadyToCommit();
+ EXPECT_FALSE(scheduler_->CommitPending());
+ EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 6);
+ EXPECT_ACTION("WillBeginImplFrame", client_, 1, 6);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 2, 6);
+ EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 3, 6);
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 4, 6);
+ EXPECT_ACTION("ScheduledActionCommit", client_, 5, 6);
- // Do the same thing after BeginMainFrame starts but still before activation.
+ // Start another commit while we still have aa pending tree.
+ // Enter a swap throttled state.
+ client_->Reset();
+ EXPECT_FALSE(scheduler_->CommitPending());
+ scheduler_->SetNeedsCommit();
+ scheduler_->SetNeedsRedraw();
+ EXPECT_SCOPED(AdvanceFrame());
+ EXPECT_TRUE(scheduler_->CommitPending());
+ EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
scheduler_->NotifyBeginMainFrameStarted();
- for (int i = 0; i < 3; ++i) {
- EXPECT_EQ((frame_args.interval * 2).InMicroseconds(),
- task_runner().DelayToNextTaskTime().InMicroseconds())
- << scheduler_->AsValue()->ToString();
- task_runner().RunPendingTasks();
- EXPECT_GT(client->num_actions_(), actions_so_far);
- EXPECT_STREQ(client->Action(client->num_actions_() - 1),
- "DidAnticipatedDrawTimeChange");
- actions_so_far = client->num_actions_();
- }
+ EXPECT_ACTION("WillBeginImplFrame", client_, 0, 4);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 4);
+ EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 4);
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 4);
+
+ // Can't commit yet because there's still a pending tree.
+ client_->Reset();
+ scheduler_->NotifyReadyToCommit();
+ EXPECT_NO_ACTION(client_);
+
+ // Activate the pending tree, which also unblocks the commit immediately.
+ client_->Reset();
+ scheduler_->NotifyReadyToActivate();
+ EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 0, 2);
+ EXPECT_ACTION("ScheduledActionCommit", client_, 1, 2);
+
+ // Make sure we do not send a BeginMainFrame while swap throttled and
+ // we have both a pending tree and an active tree that still needs
+ // it's first draw.
+ client_->Reset();
+ EXPECT_FALSE(scheduler_->CommitPending());
+ scheduler_->SetNeedsCommit();
+ EXPECT_SCOPED(AdvanceFrame());
+ EXPECT_FALSE(scheduler_->CommitPending());
+ task_runner().RunPendingTasks(); // Run posted deadline.
+ EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
+}
+
+TEST_F(
+ SchedulerTest,
+ CommitMakesProgressWhenIdleAndHasPendingTreeAndActiveTreeNeedsFirstDraw) {
+ // This verifies we don't block commits longer than we need to
+ // for performance reasons - not deadlock reasons.
+
+ // Since we are simulating a long commit, set up a client with draw duration
+ // estimates that prevent skipping main frames to get to low latency mode.
+ scheduler_settings_.use_external_begin_frame_source = true;
+ scheduler_settings_.main_frame_while_swap_throttled_enabled = true;
+ scheduler_settings_.main_frame_before_activation_enabled = true;
+ SetUpScheduler(true);
+
+ // Disables automatic swap acks so this test can force swap ack throttling
+ // to simulate a blocked Browser ui thread.
+ scheduler_->SetMaxSwapsPending(1);
+ client_->SetAutomaticSwapAck(false);
+
+ // Start a new commit in main-thread high latency mode and hold off on
+ // activation.
+ client_->Reset();
+ EXPECT_FALSE(scheduler_->CommitPending());
+ scheduler_->SetNeedsCommit();
+ scheduler_->SetNeedsRedraw();
+ EXPECT_SCOPED(AdvanceFrame());
+ EXPECT_TRUE(scheduler_->CommitPending());
+ EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
+ scheduler_->DidSwapBuffersComplete();
+ scheduler_->NotifyBeginMainFrameStarted();
+ scheduler_->NotifyReadyToCommit();
+ EXPECT_FALSE(scheduler_->CommitPending());
+ EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 6);
+ EXPECT_ACTION("WillBeginImplFrame", client_, 1, 6);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 2, 6);
+ EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 3, 6);
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 4, 6);
+ EXPECT_ACTION("ScheduledActionCommit", client_, 5, 6);
+
+ // Start another commit while we still have an active tree.
+ client_->Reset();
+ EXPECT_FALSE(scheduler_->CommitPending());
+ scheduler_->SetNeedsCommit();
+ scheduler_->SetNeedsRedraw();
+ EXPECT_SCOPED(AdvanceFrame());
+ EXPECT_TRUE(scheduler_->CommitPending());
+ EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
+ scheduler_->DidSwapBuffersComplete();
+ scheduler_->NotifyBeginMainFrameStarted();
+ EXPECT_ACTION("WillBeginImplFrame", client_, 0, 4);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 4);
+ EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 4);
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 4);
+
+ // Can't commit yet because there's still a pending tree.
+ client_->Reset();
+ scheduler_->NotifyReadyToCommit();
+ EXPECT_NO_ACTION(client_);
+
+ // Activate the pending tree, which also unblocks the commit immediately
+ // while we are in an idle state.
+ client_->Reset();
+ scheduler_->NotifyReadyToActivate();
+ EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 0, 2);
+ EXPECT_ACTION("ScheduledActionCommit", client_, 1, 2);
}
TEST_F(SchedulerTest, BeginRetroFrame) {
@@ -1480,6 +2121,12 @@ TEST_F(SchedulerTest, BeginRetroFrame) {
EXPECT_TRUE(client_->needs_begin_frames());
client_->Reset();
+ // NotifyReadyToActivate should trigger the activation.
+ scheduler_->NotifyReadyToActivate();
+ EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+ EXPECT_TRUE(client_->needs_begin_frames());
+ client_->Reset();
+
// BeginImplFrame should prepare the draw.
task_runner().RunPendingTasks(); // Run posted BeginRetroFrame.
EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
@@ -1538,13 +2185,19 @@ TEST_F(SchedulerTest, BeginRetroFrame_SwapThrottled) {
EXPECT_TRUE(client_->needs_begin_frames());
client_->Reset();
- // NotifyReadyToCommit should trigger the pending commit and draw.
+ // NotifyReadyToCommit should trigger the pending commit.
scheduler_->NotifyBeginMainFrameStarted();
scheduler_->NotifyReadyToCommit();
EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
EXPECT_TRUE(client_->needs_begin_frames());
client_->Reset();
+ // NotifyReadyToActivate should trigger the activation and draw.
+ scheduler_->NotifyReadyToActivate();
+ EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+ EXPECT_TRUE(client_->needs_begin_frames());
+ client_->Reset();
+
// Swapping will put us into a swap throttled state.
// Run posted deadline.
task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
@@ -1568,9 +2221,9 @@ TEST_F(SchedulerTest, BeginRetroFrame_SwapThrottled) {
// Let time pass sufficiently beyond the regular deadline but not beyond the
// late deadline.
- now_src()->AdvanceNow(BeginFrameArgs::DefaultInterval() -
- base::TimeDelta::FromMicroseconds(1));
- task_runner().RunUntilTime(now_src()->Now());
+ now_src()->Advance(BeginFrameArgs::DefaultInterval() -
+ base::TimeDelta::FromMicroseconds(1));
+ task_runner().RunUntilTime(now_src()->NowTicks());
EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
// Take us out of a swap throttled state.
@@ -1581,7 +2234,7 @@ TEST_F(SchedulerTest, BeginRetroFrame_SwapThrottled) {
client_->Reset();
// Verify that the deadline was rescheduled.
- task_runner().RunUntilTime(now_src()->Now());
+ task_runner().RunUntilTime(now_src()->NowTicks());
EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_);
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
EXPECT_TRUE(client_->needs_begin_frames());
@@ -1606,16 +2259,19 @@ TEST_F(SchedulerTest, RetroFrameDoesNotExpireTooEarly) {
scheduler_->NotifyBeginMainFrameStarted();
client_->Reset();
- SendNextBeginFrame();
+ BeginFrameArgs retro_frame_args = SendNextBeginFrame();
// This BeginFrame is queued up as a retro frame.
EXPECT_NO_ACTION(client_);
// The previous deadline is still pending.
EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
client_->Reset();
- // This commit should schedule the (previous) deadline to trigger immediately.
+ // This main frame activating should schedule the (previous) deadline to
+ // trigger immediately.
scheduler_->NotifyReadyToCommit();
- EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
+ scheduler_->NotifyReadyToActivate();
+ EXPECT_ACTION("ScheduledActionCommit", client_, 0, 2);
+ EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 2);
client_->Reset();
// The deadline task should trigger causing a draw.
@@ -1630,10 +2286,8 @@ TEST_F(SchedulerTest, RetroFrameDoesNotExpireTooEarly) {
scheduler_->SetNeedsRedraw();
EXPECT_NO_ACTION(client_);
- // Let's advance sufficiently past the next frame's deadline.
- now_src()->AdvanceNow(BeginFrameArgs::DefaultInterval() -
- BeginFrameArgs::DefaultEstimatedParentDrawTime() +
- base::TimeDelta::FromMicroseconds(1));
+ // Let's advance to the retro frame's deadline.
+ now_src()->Advance(retro_frame_args.deadline - now_src()->NowTicks());
// The retro frame hasn't expired yet.
task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(false));
@@ -1648,7 +2302,7 @@ TEST_F(SchedulerTest, RetroFrameDoesNotExpireTooEarly) {
EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_);
}
-TEST_F(SchedulerTest, RetroFrameDoesNotExpireTooLate) {
+TEST_F(SchedulerTest, RetroFrameExpiresOnTime) {
scheduler_settings_.use_external_begin_frame_source = true;
SetUpScheduler(true);
@@ -1666,16 +2320,19 @@ TEST_F(SchedulerTest, RetroFrameDoesNotExpireTooLate) {
scheduler_->NotifyBeginMainFrameStarted();
client_->Reset();
- SendNextBeginFrame();
+ BeginFrameArgs retro_frame_args = SendNextBeginFrame();
// This BeginFrame is queued up as a retro frame.
EXPECT_NO_ACTION(client_);
// The previous deadline is still pending.
EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
client_->Reset();
- // This commit should schedule the (previous) deadline to trigger immediately.
+ // This main frame activating should schedule the (previous) deadline to
+ // trigger immediately.
scheduler_->NotifyReadyToCommit();
- EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
+ scheduler_->NotifyReadyToActivate();
+ EXPECT_ACTION("ScheduledActionCommit", client_, 0, 2);
+ EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 2);
client_->Reset();
// The deadline task should trigger causing a draw.
@@ -1690,14 +2347,64 @@ TEST_F(SchedulerTest, RetroFrameDoesNotExpireTooLate) {
scheduler_->SetNeedsRedraw();
EXPECT_NO_ACTION(client_);
- // Let's advance sufficiently past the next frame's deadline.
- now_src()->AdvanceNow(BeginFrameArgs::DefaultInterval() +
- base::TimeDelta::FromMicroseconds(1));
+ // Let's advance sufficiently past the retro frame's deadline.
+ now_src()->Advance(retro_frame_args.deadline - now_src()->NowTicks() +
+ base::TimeDelta::FromMicroseconds(1));
// The retro frame should've expired.
EXPECT_NO_ACTION(client_);
}
+TEST_F(SchedulerTest, MissedFrameDoesNotExpireTooEarly) {
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+
+ scheduler_->SetNeedsCommit();
+ EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+
+ BeginFrameArgs missed_frame_args =
+ CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src());
+ missed_frame_args.type = BeginFrameArgs::MISSED;
+
+ // Advance to the deadline.
+ now_src()->Advance(missed_frame_args.deadline - now_src()->NowTicks());
+
+ // Missed frame is handled because it's on time.
+ client_->Reset();
+ fake_external_begin_frame_source_->TestOnBeginFrame(missed_frame_args);
+ EXPECT_TRUE(
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(false)));
+ EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
+ EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
+ EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
+}
+
+TEST_F(SchedulerTest, MissedFrameExpiresOnTime) {
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+
+ scheduler_->SetNeedsCommit();
+ EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+
+ BeginFrameArgs missed_frame_args =
+ CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src());
+ missed_frame_args.type = BeginFrameArgs::MISSED;
+
+ // Advance sufficiently past the deadline.
+ now_src()->Advance(missed_frame_args.deadline - now_src()->NowTicks() +
+ base::TimeDelta::FromMicroseconds(1));
+
+ // Missed frame is dropped because it's too late.
+ client_->Reset();
+ fake_external_begin_frame_source_->TestOnBeginFrame(missed_frame_args);
+ EXPECT_FALSE(
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(false)));
+ EXPECT_NO_ACTION(client_);
+ EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
+}
+
void SchedulerTest::BeginFramesNotFromClient(
bool use_external_begin_frame_source,
bool throttle_frame_production) {
@@ -1732,6 +2439,11 @@ void SchedulerTest::BeginFramesNotFromClient(
EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
client_->Reset();
+ // NotifyReadyToActivate should trigger the activation.
+ scheduler_->NotifyReadyToActivate();
+ EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+ client_->Reset();
+
// BeginImplFrame should prepare the draw.
task_runner().RunPendingTasks(); // Run posted BeginFrame.
EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
@@ -1807,12 +2519,17 @@ void SchedulerTest::BeginFramesNotFromClient_SwapThrottled(
EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
client_->Reset();
- // NotifyReadyToCommit should trigger the pending commit and draw.
+ // NotifyReadyToCommit should trigger the pending commit.
scheduler_->NotifyBeginMainFrameStarted();
scheduler_->NotifyReadyToCommit();
EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
client_->Reset();
+ // NotifyReadyToActivate should trigger the activation and draw.
+ scheduler_->NotifyReadyToActivate();
+ EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+ client_->Reset();
+
// Swapping will put us into a swap throttled state.
// Run posted deadline.
task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
@@ -1833,9 +2550,9 @@ void SchedulerTest::BeginFramesNotFromClient_SwapThrottled(
// Let time pass sufficiently beyond the regular deadline but not beyond the
// late deadline.
- now_src()->AdvanceNow(BeginFrameArgs::DefaultInterval() -
- base::TimeDelta::FromMicroseconds(1));
- task_runner().RunUntilTime(now_src()->Now());
+ now_src()->Advance(BeginFrameArgs::DefaultInterval() -
+ base::TimeDelta::FromMicroseconds(1));
+ task_runner().RunUntilTime(now_src()->NowTicks());
EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
// Take us out of a swap throttled state.
@@ -1847,9 +2564,9 @@ void SchedulerTest::BeginFramesNotFromClient_SwapThrottled(
// Verify that the deadline was rescheduled.
// We can't use RunUntilTime(now) here because the next frame is also
// scheduled if throttle_frame_production = false.
- base::TimeTicks before_deadline = now_src()->Now();
+ base::TimeTicks before_deadline = now_src()->NowTicks();
task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
- base::TimeTicks after_deadline = now_src()->Now();
+ base::TimeTicks after_deadline = now_src()->NowTicks();
EXPECT_EQ(after_deadline, before_deadline);
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
client_->Reset();
@@ -1916,7 +2633,8 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterBeginFrameStarted) {
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted();
scheduler_->NotifyReadyToCommit();
- EXPECT_ACTION("ScheduledActionCommit", client_, 0, 1);
+ EXPECT_ACTION("ScheduledActionCommit", client_, 0, 2);
+ EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 2);
client_->Reset();
task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
@@ -1925,9 +2643,8 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterBeginFrameStarted) {
EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
}
-void SchedulerTest::DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency(
- bool impl_side_painting) {
- scheduler_settings_.impl_side_painting = impl_side_painting;
+TEST_F(SchedulerTest,
+ DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency) {
scheduler_settings_.use_external_begin_frame_source = true;
SetUpScheduler(true);
@@ -1958,7 +2675,7 @@ void SchedulerTest::DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency(
// BeginImplFrame is not started.
client_->Reset();
- task_runner().RunUntilTime(now_src()->Now() +
+ task_runner().RunUntilTime(now_src()->NowTicks() +
base::TimeDelta::FromMilliseconds(10));
EXPECT_NO_ACTION(client_);
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
@@ -1966,31 +2683,12 @@ void SchedulerTest::DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency(
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted();
scheduler_->NotifyReadyToCommit();
- if (impl_side_painting) {
- EXPECT_ACTION("ScheduledActionCommit", client_, 0, 3);
- EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 3);
- EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 2, 3);
- } else {
- EXPECT_ACTION("ScheduledActionCommit", client_, 0, 2);
- EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 1, 2);
- }
-}
-
-TEST_F(SchedulerTest,
- DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency) {
- bool impl_side_painting = false;
- DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency(impl_side_painting);
+ EXPECT_ACTION("ScheduledActionCommit", client_, 0, 3);
+ EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 3);
+ EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 2, 3);
}
-TEST_F(SchedulerTest,
- DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatencyWithImplPaint) {
- bool impl_side_painting = true;
- DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency(impl_side_painting);
-}
-
-void SchedulerTest::DidLoseOutputSurfaceAfterReadyToCommit(
- bool impl_side_painting) {
- scheduler_settings_.impl_side_painting = impl_side_painting;
+TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterReadyToCommit) {
scheduler_settings_.use_external_begin_frame_source = true;
SetUpScheduler(true);
@@ -2011,14 +2709,10 @@ void SchedulerTest::DidLoseOutputSurfaceAfterReadyToCommit(
client_->Reset();
scheduler_->DidLoseOutputSurface();
- // SetNeedsBeginFrames(false) is not called until the end of the frame.
- if (impl_side_painting) {
- // Sync tree should be forced to activate.
- EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
- } else {
- EXPECT_NO_ACTION(client_);
- }
+ // Sync tree should be forced to activate.
+ EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+ // SetNeedsBeginFrames(false) is not called until the end of the frame.
client_->Reset();
task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 3);
@@ -2026,14 +2720,6 @@ void SchedulerTest::DidLoseOutputSurfaceAfterReadyToCommit(
EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
}
-TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterReadyToCommit) {
- DidLoseOutputSurfaceAfterReadyToCommit(false);
-}
-
-TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterReadyToCommitWithImplPainting) {
- DidLoseOutputSurfaceAfterReadyToCommit(true);
-}
-
TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterSetNeedsPrepareTiles) {
scheduler_settings_.use_external_begin_frame_source = true;
SetUpScheduler(true);
@@ -2101,6 +2787,12 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterBeginRetroFramePosted) {
EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
EXPECT_TRUE(client_->needs_begin_frames());
+ // NotifyReadyToActivate should trigger the activation.
+ client_->Reset();
+ scheduler_->NotifyReadyToActivate();
+ EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+ EXPECT_TRUE(client_->needs_begin_frames());
+
client_->Reset();
EXPECT_FALSE(scheduler_->IsBeginRetroFrameArgsEmpty());
scheduler_->DidLoseOutputSurface();
@@ -2155,6 +2847,12 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceDuringBeginRetroFrameRunning) {
EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
EXPECT_TRUE(client_->needs_begin_frames());
+ // NotifyReadyToActivate should trigger the activation.
+ client_->Reset();
+ scheduler_->NotifyReadyToActivate();
+ EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+ EXPECT_TRUE(client_->needs_begin_frames());
+
// BeginImplFrame should prepare the draw.
client_->Reset();
task_runner().RunPendingTasks(); // Run posted BeginRetroFrame.
@@ -2206,6 +2904,12 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceWithSyntheticBeginFrameSource) {
EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
EXPECT_TRUE(scheduler_->frame_source().NeedsBeginFrames());
+ // NotifyReadyToActivate should trigger the activation.
+ client_->Reset();
+ scheduler_->NotifyReadyToActivate();
+ EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+ EXPECT_TRUE(scheduler_->frame_source().NeedsBeginFrames());
+
client_->Reset();
scheduler_->DidLoseOutputSurface();
// SetNeedsBeginFrames(false) is not called until the end of the frame.
@@ -2239,6 +2943,10 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceWhenIdle) {
EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
client_->Reset();
+ scheduler_->NotifyReadyToActivate();
+ EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+
+ client_->Reset();
task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
EXPECT_ACTION("ScheduledActionAnimate", client_, 0, 2);
EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2);
@@ -2252,7 +2960,6 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceWhenIdle) {
}
TEST_F(SchedulerTest, ScheduledActionActivateAfterBecomingInvisible) {
- scheduler_settings_.impl_side_painting = true;
scheduler_settings_.use_external_begin_frame_source = true;
SetUpScheduler(true);
@@ -2413,12 +3120,14 @@ TEST_F(SchedulerTest, SendBeginMainFrameNotExpectedSoon) {
EXPECT_SCOPED(AdvanceFrame());
scheduler_->NotifyBeginMainFrameStarted();
scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToActivate();
task_runner().RunPendingTasks();
- EXPECT_ACTION("WillBeginImplFrame", client_, 0, 5);
- EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 5);
- EXPECT_ACTION("ScheduledActionCommit", client_, 2, 5);
- EXPECT_ACTION("ScheduledActionAnimate", client_, 3, 5);
- EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 4, 5);
+ EXPECT_ACTION("WillBeginImplFrame", client_, 0, 6);
+ EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 6);
+ EXPECT_ACTION("ScheduledActionCommit", client_, 2, 6);
+ EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 3, 6);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 4, 6);
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 5, 6);
client_->Reset();
// The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
@@ -2437,7 +3146,6 @@ TEST_F(SchedulerTest, SendBeginMainFrameNotExpectedSoon) {
TEST_F(SchedulerTest, SynchronousCompositorAnimation) {
scheduler_settings_.using_synchronous_renderer_compositor = true;
scheduler_settings_.use_external_begin_frame_source = true;
- scheduler_settings_.impl_side_painting = true;
SetUpScheduler(true);
scheduler_->SetNeedsAnimate();
@@ -2490,7 +3198,6 @@ TEST_F(SchedulerTest, SynchronousCompositorAnimation) {
TEST_F(SchedulerTest, SynchronousCompositorOnDrawDuringIdle) {
scheduler_settings_.using_synchronous_renderer_compositor = true;
scheduler_settings_.use_external_begin_frame_source = true;
- scheduler_settings_.impl_side_painting = true;
SetUpScheduler(true);
scheduler_->SetNeedsRedraw();
@@ -2513,7 +3220,6 @@ TEST_F(SchedulerTest, SynchronousCompositorOnDrawDuringIdle) {
TEST_F(SchedulerTest, SynchronousCompositorCommit) {
scheduler_settings_.using_synchronous_renderer_compositor = true;
scheduler_settings_.use_external_begin_frame_source = true;
- scheduler_settings_.impl_side_painting = true;
SetUpScheduler(true);
scheduler_->SetNeedsCommit();
@@ -2571,7 +3277,6 @@ TEST_F(SchedulerTest, SynchronousCompositorCommit) {
TEST_F(SchedulerTest, SynchronousCompositorDoubleCommitWithoutDraw) {
scheduler_settings_.using_synchronous_renderer_compositor = true;
scheduler_settings_.use_external_begin_frame_source = true;
- scheduler_settings_.impl_side_painting = true;
SetUpScheduler(true);
scheduler_->SetNeedsCommit();
@@ -2625,17 +3330,11 @@ class SchedulerClientSetNeedsPrepareTilesOnDraw : public FakeSchedulerClient {
scheduler_->SetNeedsPrepareTiles();
return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
}
-
- void ScheduledActionPrepareTiles() override {
- FakeSchedulerClient::ScheduledActionPrepareTiles();
- scheduler_->DidPrepareTiles();
- }
};
TEST_F(SchedulerTest, SynchronousCompositorPrepareTilesOnDraw) {
scheduler_settings_.using_synchronous_renderer_compositor = true;
scheduler_settings_.use_external_begin_frame_source = true;
- scheduler_settings_.impl_side_painting = true;
scoped_ptr<FakeSchedulerClient> client =
make_scoped_ptr(new SchedulerClientSetNeedsPrepareTilesOnDraw);
@@ -2680,21 +3379,80 @@ TEST_F(SchedulerTest, SynchronousCompositorPrepareTilesOnDraw) {
client_->Reset();
}
-TEST_F(SchedulerTest, AuthoritativeVSyncInterval) {
+TEST_F(SchedulerTest, SynchronousCompositorSendBeginMainFrameWhileIdle) {
+ scheduler_settings_.using_synchronous_renderer_compositor = true;
+ scheduler_settings_.use_external_begin_frame_source = true;
+
SetUpScheduler(true);
- base::TimeDelta initial_interval =
- scheduler_->begin_impl_frame_args().interval;
+ scheduler_->SetNeedsRedraw();
+ EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ client_->Reset();
+
+ // Next vsync.
+ EXPECT_SCOPED(AdvanceFrame());
+ EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 3);
+ EXPECT_ACTION("ScheduledActionInvalidateOutputSurface", client_, 2, 3);
+ client_->Reset();
+
+ // Android onDraw.
+ scheduler_->SetNeedsRedraw();
+ scheduler_->OnDrawForOutputSurface();
+ EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_);
+ EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
+ EXPECT_FALSE(scheduler_->PrepareTilesPending());
+ client_->Reset();
+
+ // Simulate SetNeedsCommit due to input event.
+ scheduler_->SetNeedsCommit();
+ EXPECT_SINGLE_ACTION("ScheduledActionSendBeginMainFrame", client_);
+ client_->Reset();
+
+ scheduler_->NotifyBeginMainFrameStarted();
+ scheduler_->NotifyReadyToCommit();
+ EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
+ client_->Reset();
+
+ scheduler_->NotifyReadyToActivate();
+ EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
+ client_->Reset();
+
+ // Next vsync.
+ EXPECT_SCOPED(AdvanceFrame());
+ EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 3);
+ EXPECT_ACTION("ScheduledActionInvalidateOutputSurface", client_, 2, 3);
+ client_->Reset();
+
+ // Android onDraw.
+ scheduler_->SetNeedsRedraw();
+ scheduler_->OnDrawForOutputSurface();
+ EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_);
+ EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
+ EXPECT_FALSE(scheduler_->PrepareTilesPending());
+ client_->Reset();
+
+ // Simulate SetNeedsCommit due to input event.
+ scheduler_->SetNeedsCommit();
+ EXPECT_SINGLE_ACTION("ScheduledActionSendBeginMainFrame", client_);
+ client_->Reset();
+}
+
+TEST_F(SchedulerTest, AuthoritativeVSyncInterval) {
+ SetUpScheduler(true);
+ base::TimeDelta initial_interval = scheduler_->BeginImplFrameInterval();
base::TimeDelta authoritative_interval =
base::TimeDelta::FromMilliseconds(33);
scheduler_->SetNeedsCommit();
EXPECT_SCOPED(AdvanceFrame());
- EXPECT_EQ(initial_interval, scheduler_->begin_impl_frame_args().interval);
+ EXPECT_EQ(initial_interval, scheduler_->BeginImplFrameInterval());
scheduler_->NotifyBeginMainFrameStarted();
scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToActivate();
task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
scheduler_->SetAuthoritativeVSyncInterval(authoritative_interval);
@@ -2703,9 +3461,41 @@ TEST_F(SchedulerTest, AuthoritativeVSyncInterval) {
// At the next BeginFrame, authoritative interval is used instead of previous
// interval.
- EXPECT_NE(initial_interval, scheduler_->begin_impl_frame_args().interval);
- EXPECT_EQ(authoritative_interval,
- scheduler_->begin_impl_frame_args().interval);
+ EXPECT_NE(initial_interval, scheduler_->BeginImplFrameInterval());
+ EXPECT_EQ(authoritative_interval, scheduler_->BeginImplFrameInterval());
+}
+
+TEST_F(SchedulerTest, ImplLatencyTakesPriority) {
+ SetUpScheduler(true);
+ scheduler_->SetImplLatencyTakesPriority(true);
+ EXPECT_TRUE(scheduler_->ImplLatencyTakesPriority());
+
+ scheduler_->SetImplLatencyTakesPriority(false);
+ EXPECT_FALSE(scheduler_->ImplLatencyTakesPriority());
+}
+
+TEST_F(SchedulerTest, BeginFrameArgs_OnCriticalPath) {
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+
+ scheduler_->SetImplLatencyTakesPriority(false);
+ scheduler_->SetChildrenNeedBeginFrames(true);
+
+ EXPECT_SCOPED(AdvanceFrame());
+ EXPECT_TRUE(client_->begin_frame_is_sent_to_children());
+ EXPECT_TRUE(client_->begin_frame_args_sent_to_children().on_critical_path);
+}
+
+TEST_F(SchedulerTest, BeginFrameArgs_NotOnCriticalPath) {
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+
+ scheduler_->SetImplLatencyTakesPriority(true);
+ scheduler_->SetChildrenNeedBeginFrames(true);
+
+ EXPECT_SCOPED(AdvanceFrame());
+ EXPECT_TRUE(client_->begin_frame_is_sent_to_children());
+ EXPECT_FALSE(client_->begin_frame_args_sent_to_children().on_critical_path);
}
} // namespace
diff --git a/chromium/cc/surfaces/BUILD.gn b/chromium/cc/surfaces/BUILD.gn
index e43d4e5741f..0f2c9509f4b 100644
--- a/chromium/cc/surfaces/BUILD.gn
+++ b/chromium/cc/surfaces/BUILD.gn
@@ -18,6 +18,8 @@ component("surfaces") {
"display.cc",
"display.h",
"display_client.h",
+ "display_scheduler.cc",
+ "display_scheduler.h",
"onscreen_display_client.cc",
"onscreen_display_client.h",
"surface.cc",
@@ -45,6 +47,7 @@ component("surfaces") {
"//base",
"//base/third_party/dynamic_annotations",
"//cc",
+ "//gpu/command_buffer/client:gles2_interface",
"//skia",
"//ui/events:events_base",
"//ui/gfx",
diff --git a/chromium/cc/surfaces/OWNERS b/chromium/cc/surfaces/OWNERS
index 023e5fc459f..5e473090ed6 100644
--- a/chromium/cc/surfaces/OWNERS
+++ b/chromium/cc/surfaces/OWNERS
@@ -1 +1 @@
-jamesr@chromium.org
+jbauman@chromium.org
diff --git a/chromium/cc/surfaces/display.cc b/chromium/cc/surfaces/display.cc
index e2b81728393..37a9756950c 100644
--- a/chromium/cc/surfaces/display.cc
+++ b/chromium/cc/surfaces/display.cc
@@ -15,10 +15,11 @@
#include "cc/output/software_renderer.h"
#include "cc/output/texture_mailbox_deleter.h"
#include "cc/surfaces/display_client.h"
+#include "cc/surfaces/display_scheduler.h"
#include "cc/surfaces/surface.h"
#include "cc/surfaces/surface_aggregator.h"
#include "cc/surfaces/surface_manager.h"
-#include "cc/trees/blocking_task_runner.h"
+#include "gpu/command_buffer/client/gles2_interface.h"
namespace cc {
@@ -33,10 +34,9 @@ Display::Display(DisplayClient* client,
gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
settings_(settings),
device_scale_factor_(1.f),
- blocking_main_thread_task_runner_(
- BlockingTaskRunner::Create(base::ThreadTaskRunnerHandle::Get())),
- texture_mailbox_deleter_(
- new TextureMailboxDeleter(base::ThreadTaskRunnerHandle::Get())) {
+ swapped_since_resize_(false),
+ scheduler_(nullptr),
+ texture_mailbox_deleter_(new TextureMailboxDeleter(nullptr)) {
manager_->AddObserver(this);
}
@@ -51,15 +51,23 @@ Display::~Display() {
}
}
-bool Display::Initialize(scoped_ptr<OutputSurface> output_surface) {
+bool Display::Initialize(scoped_ptr<OutputSurface> output_surface,
+ DisplayScheduler* scheduler) {
output_surface_ = output_surface.Pass();
+ scheduler_ = scheduler;
return output_surface_->BindToClient(this);
}
void Display::SetSurfaceId(SurfaceId id, float device_scale_factor) {
+ if (current_surface_id_ == id && device_scale_factor_ == device_scale_factor)
+ return;
+
current_surface_id_ = id;
device_scale_factor_ = device_scale_factor;
- client_->DisplayDamaged();
+
+ UpdateRootSurfaceResourcesLocked();
+ if (scheduler_)
+ scheduler_->EntireDisplayDamaged(id);
}
void Display::Resize(const gfx::Size& size) {
@@ -67,21 +75,34 @@ void Display::Resize(const gfx::Size& size) {
return;
// Need to ensure all pending swaps have executed before the window is
// resized, or D3D11 will scale the swap output.
- if (renderer_ && settings_.finish_rendering_on_resize)
- renderer_->Finish();
+ if (settings_.finish_rendering_on_resize) {
+ if (!swapped_since_resize_ && scheduler_)
+ scheduler_->ForceImmediateSwapIfPossible();
+ if (swapped_since_resize_ && output_surface_ &&
+ output_surface_->context_provider())
+ output_surface_->context_provider()->ContextGL()->ShallowFinishCHROMIUM();
+ }
+ swapped_since_resize_ = false;
current_surface_size_ = size;
- client_->DisplayDamaged();
+ if (scheduler_)
+ scheduler_->EntireDisplayDamaged(current_surface_id_);
+}
+
+void Display::SetExternalClip(const gfx::Rect& clip) {
+ external_clip_ = clip;
}
void Display::InitializeRenderer() {
if (resource_provider_)
return;
+ // Display does not use GpuMemoryBuffers, so persistent map is not relevant.
+ bool use_persistent_map_for_gpu_memory_buffers = false;
scoped_ptr<ResourceProvider> resource_provider = ResourceProvider::Create(
output_surface_.get(), bitmap_manager_, gpu_memory_buffer_manager_,
- blocking_main_thread_task_runner_.get(), settings_.highp_threshold_min,
- settings_.use_rgba_4444_textures,
- settings_.texture_id_allocation_chunk_size);
+ nullptr, settings_.highp_threshold_min, settings_.use_rgba_4444_textures,
+ settings_.texture_id_allocation_chunk_size,
+ use_persistent_map_for_gpu_memory_buffers);
if (!resource_provider)
return;
@@ -105,10 +126,21 @@ void Display::InitializeRenderer() {
}
void Display::DidLoseOutputSurface() {
+ if (scheduler_)
+ scheduler_->OutputSurfaceLost();
+ // WARNING: The client may delete the Display in this method call. Do not
+ // make any additional references to members after this call.
client_->OutputSurfaceLost();
}
-bool Display::Draw() {
+void Display::UpdateRootSurfaceResourcesLocked() {
+ Surface* surface = manager_->GetSurfaceForId(current_surface_id_);
+ bool root_surface_resources_locked = !surface || !surface->GetEligibleFrame();
+ if (scheduler_)
+ scheduler_->SetRootSurfaceResourcesLocked(root_surface_resources_locked);
+}
+
+bool Display::DrawAndSwap() {
if (current_surface_id_.is_null())
return false;
@@ -116,15 +148,12 @@ bool Display::Draw() {
if (!output_surface_)
return false;
- // TODO(skyostil): We should hold a BlockingTaskRunner::CapturePostTasks
- // while Aggregate is called to immediately run release callbacks afterward.
scoped_ptr<CompositorFrame> frame =
aggregator_->Aggregate(current_surface_id_);
if (!frame)
return false;
- TRACE_EVENT0("cc", "Display::Draw");
- benchmark_instrumentation::IssueDisplayRenderingStatsEvent();
+ TRACE_EVENT0("cc", "Display::DrawAndSwap");
// Run callbacks early to allow pipelining.
for (const auto& id_entry : aggregator_->previous_contained_surfaces()) {
@@ -154,9 +183,18 @@ bool Display::Draw() {
bool should_draw = !frame->metadata.latency_info.empty() ||
have_copy_requests || (have_damage && !avoid_swap);
+ // If the surface is suspended then the resources to be used by the draw are
+ // likely destroyed.
+ if (output_surface_->SurfaceIsSuspendForRecycle()) {
+ TRACE_EVENT_INSTANT0("cc", "Surface is suspended for recycle.",
+ TRACE_EVENT_SCOPE_THREAD);
+ should_draw = false;
+ }
+
if (should_draw) {
gfx::Rect device_viewport_rect = gfx::Rect(current_surface_size_);
- gfx::Rect device_clip_rect = device_viewport_rect;
+ gfx::Rect device_clip_rect =
+ external_clip_.IsEmpty() ? device_viewport_rect : external_clip_;
bool disable_picture_quad_image_filtering = false;
renderer_->DecideRenderPassAllocationsForFrame(
@@ -167,6 +205,15 @@ bool Display::Draw() {
}
if (should_draw && !avoid_swap) {
+ swapped_since_resize_ = true;
+ for (auto& latency : frame->metadata.latency_info) {
+ TRACE_EVENT_FLOW_STEP0(
+ "input,benchmark",
+ "LatencyInfo.Flow",
+ TRACE_ID_DONT_MANGLE(latency.trace_id),
+ "Display::DrawAndSwap");
+ }
+ benchmark_instrumentation::IssueDisplayRenderingStatsEvent();
renderer_->SwapBuffers(frame->metadata);
} else {
stored_latency_info_.insert(stored_latency_info_.end(),
@@ -180,11 +227,13 @@ bool Display::Draw() {
}
void Display::DidSwapBuffers() {
- client_->DidSwapBuffers();
+ if (scheduler_)
+ scheduler_->DidSwapBuffers();
}
void Display::DidSwapBuffersComplete() {
- client_->DidSwapBuffersComplete();
+ if (scheduler_)
+ scheduler_->DidSwapBuffersComplete();
}
void Display::CommitVSyncParameters(base::TimeTicks timebase,
@@ -234,27 +283,25 @@ void Display::OnSurfaceDamaged(SurfaceId surface_id, bool* changed) {
if (surface) {
const CompositorFrame* current_frame = surface->GetEligibleFrame();
if (!current_frame || !current_frame->delegated_frame_data ||
- !current_frame->delegated_frame_data->resource_list.size())
+ !current_frame->delegated_frame_data->resource_list.size()) {
aggregator_->ReleaseResources(surface_id);
+ }
}
- client_->DisplayDamaged();
+ if (scheduler_)
+ scheduler_->SurfaceDamaged(surface_id);
*changed = true;
} else if (surface_id == current_surface_id_) {
- client_->DisplayDamaged();
+ if (scheduler_)
+ scheduler_->SurfaceDamaged(surface_id);
*changed = true;
}
+
+ if (surface_id == current_surface_id_)
+ UpdateRootSurfaceResourcesLocked();
}
SurfaceId Display::CurrentSurfaceId() {
return current_surface_id_;
}
-int Display::GetMaxFramesPending() {
- int max_frames_pending =
- output_surface_ ? output_surface_->capabilities().max_frames_pending : 0;
- if (max_frames_pending <= 0)
- max_frames_pending = OutputSurface::DEFAULT_MAX_FRAMES_PENDING;
- return max_frames_pending;
-}
-
} // namespace cc
diff --git a/chromium/cc/surfaces/display.h b/chromium/cc/surfaces/display.h
index 22874a02c01..b849b461afb 100644
--- a/chromium/cc/surfaces/display.h
+++ b/chromium/cc/surfaces/display.h
@@ -11,6 +11,7 @@
#include "cc/output/output_surface_client.h"
#include "cc/output/renderer.h"
#include "cc/resources/returned_resource.h"
+#include "cc/surfaces/display_scheduler.h"
#include "cc/surfaces/surface_aggregator.h"
#include "cc/surfaces/surface_id.h"
#include "cc/surfaces/surface_manager.h"
@@ -27,7 +28,6 @@ class Size;
namespace cc {
-class BlockingTaskRunner;
class DirectRenderer;
class DisplayClient;
class OutputSurface;
@@ -43,7 +43,8 @@ class TextureMailboxDeleter;
// A Display produces a surface that can be used to draw to a physical display
// (OutputSurface). The client is responsible for creating and sizing the
// surface IDs used to draw into the display and deciding when to draw.
-class CC_SURFACES_EXPORT Display : public OutputSurfaceClient,
+class CC_SURFACES_EXPORT Display : public DisplaySchedulerClient,
+ public OutputSurfaceClient,
public RendererClient,
public SurfaceDamageObserver {
public:
@@ -54,16 +55,19 @@ class CC_SURFACES_EXPORT Display : public OutputSurfaceClient,
const RendererSettings& settings);
~Display() override;
- bool Initialize(scoped_ptr<OutputSurface> output_surface);
+ bool Initialize(scoped_ptr<OutputSurface> output_surface,
+ DisplayScheduler* scheduler);
// device_scale_factor is used to communicate to the external window system
// what scale this was rendered at.
void SetSurfaceId(SurfaceId id, float device_scale_factor);
void Resize(const gfx::Size& new_size);
- bool Draw();
+ void SetExternalClip(const gfx::Rect& clip);
SurfaceId CurrentSurfaceId();
- int GetMaxFramesPending();
+
+ // DisplaySchedulerClient implementation.
+ bool DrawAndSwap() override;
// OutputSurfaceClient implementation.
void CommitVSyncParameters(base::TimeTicks timebase,
@@ -92,6 +96,7 @@ class CC_SURFACES_EXPORT Display : public OutputSurfaceClient,
private:
void InitializeRenderer();
+ void UpdateRootSurfaceResourcesLocked();
DisplayClient* client_;
SurfaceManager* manager_;
@@ -101,11 +106,13 @@ class CC_SURFACES_EXPORT Display : public OutputSurfaceClient,
SurfaceId current_surface_id_;
gfx::Size current_surface_size_;
float device_scale_factor_;
+ bool swapped_since_resize_;
+ gfx::Rect external_clip_;
scoped_ptr<OutputSurface> output_surface_;
+ DisplayScheduler* scheduler_;
scoped_ptr<ResourceProvider> resource_provider_;
scoped_ptr<SurfaceAggregator> aggregator_;
scoped_ptr<DirectRenderer> renderer_;
- scoped_ptr<BlockingTaskRunner> blocking_main_thread_task_runner_;
scoped_ptr<TextureMailboxDeleter> texture_mailbox_deleter_;
std::vector<ui::LatencyInfo> stored_latency_info_;
diff --git a/chromium/cc/surfaces/display_client.h b/chromium/cc/surfaces/display_client.h
index 71ee43439d0..61ea4d39970 100644
--- a/chromium/cc/surfaces/display_client.h
+++ b/chromium/cc/surfaces/display_client.h
@@ -14,9 +14,6 @@ struct ManagedMemoryPolicy;
class DisplayClient {
public:
- virtual void DisplayDamaged() = 0;
- virtual void DidSwapBuffers() = 0;
- virtual void DidSwapBuffersComplete() = 0;
virtual void CommitVSyncParameters(base::TimeTicks timebase,
base::TimeDelta interval) = 0;
virtual void OutputSurfaceLost() = 0;
diff --git a/chromium/cc/surfaces/display_scheduler.cc b/chromium/cc/surfaces/display_scheduler.cc
new file mode 100644
index 00000000000..3810e148864
--- /dev/null
+++ b/chromium/cc/surfaces/display_scheduler.cc
@@ -0,0 +1,286 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/surfaces/display_scheduler.h"
+
+#include <vector>
+
+#include "base/stl_util.h"
+#include "base/trace_event/trace_event.h"
+#include "cc/output/output_surface.h"
+
+namespace cc {
+
+DisplayScheduler::DisplayScheduler(DisplaySchedulerClient* client,
+ BeginFrameSource* begin_frame_source,
+ base::SingleThreadTaskRunner* task_runner,
+ int max_pending_swaps)
+ : client_(client),
+ begin_frame_source_(begin_frame_source),
+ task_runner_(task_runner),
+ output_surface_lost_(false),
+ root_surface_resources_locked_(true),
+ inside_begin_frame_deadline_interval_(false),
+ needs_draw_(false),
+ entire_display_damaged_(false),
+ all_active_child_surfaces_ready_to_draw_(false),
+ pending_swaps_(0),
+ max_pending_swaps_(max_pending_swaps),
+ root_surface_damaged_(false),
+ expect_damage_from_root_surface_(false),
+ weak_ptr_factory_(this) {
+ begin_frame_source_->AddObserver(this);
+ begin_frame_deadline_closure_ = base::Bind(
+ &DisplayScheduler::OnBeginFrameDeadline, weak_ptr_factory_.GetWeakPtr());
+}
+
+DisplayScheduler::~DisplayScheduler() {
+ begin_frame_source_->RemoveObserver(this);
+}
+
+// If we try to draw when the root surface resources are locked, the
+// draw will fail.
+void DisplayScheduler::SetRootSurfaceResourcesLocked(bool locked) {
+ root_surface_resources_locked_ = locked;
+ ScheduleBeginFrameDeadline();
+}
+
+// This is used to force an immediate swap before a resize.
+void DisplayScheduler::ForceImmediateSwapIfPossible() {
+ bool in_begin = inside_begin_frame_deadline_interval_;
+ AttemptDrawAndSwap();
+ if (in_begin)
+ begin_frame_source_->DidFinishFrame(0);
+}
+
+// Notification that there was a resize or the root surface changed and
+// that we should just draw immediately.
+void DisplayScheduler::EntireDisplayDamaged(SurfaceId root_surface_id) {
+ TRACE_EVENT0("cc", "DisplayScheduler::EntireDisplayDamaged");
+ needs_draw_ = true;
+ entire_display_damaged_ = true;
+ root_surface_id_ = root_surface_id;
+
+ begin_frame_source_->SetNeedsBeginFrames(!output_surface_lost_);
+ ScheduleBeginFrameDeadline();
+}
+
+// Indicates that there was damage to one of the surfaces.
+// Has some logic to wait for multiple active surfaces before
+// triggering the deadline.
+void DisplayScheduler::SurfaceDamaged(SurfaceId surface_id) {
+ TRACE_EVENT1("cc", "DisplayScheduler::SurfaceDamaged", "surface_id",
+ surface_id.id);
+
+ needs_draw_ = true;
+
+ if (surface_id == root_surface_id_) {
+ root_surface_damaged_ = true;
+ } else {
+ child_surface_ids_damaged_.insert(surface_id);
+
+ // TODO(mithro): Use hints from SetNeedsBeginFrames and SwapAborts.
+ all_active_child_surfaces_ready_to_draw_ = base::STLIncludes(
+ child_surface_ids_damaged_, child_surface_ids_to_expect_damage_from_);
+ }
+
+ begin_frame_source_->SetNeedsBeginFrames(!output_surface_lost_);
+ ScheduleBeginFrameDeadline();
+}
+
+void DisplayScheduler::OutputSurfaceLost() {
+ TRACE_EVENT0("cc", "DisplayScheduler::OutputSurfaceLost");
+ output_surface_lost_ = true;
+ begin_frame_source_->SetNeedsBeginFrames(false);
+ ScheduleBeginFrameDeadline();
+}
+
+void DisplayScheduler::DrawAndSwap() {
+ TRACE_EVENT0("cc", "DisplayScheduler::DrawAndSwap");
+ DCHECK_LT(pending_swaps_, max_pending_swaps_);
+ DCHECK(!output_surface_lost_);
+
+ bool success = client_->DrawAndSwap();
+ if (!success)
+ return;
+
+ child_surface_ids_to_expect_damage_from_ =
+ base::STLSetIntersection<std::vector<SurfaceId>>(
+ child_surface_ids_damaged_, child_surface_ids_damaged_prev_);
+
+ child_surface_ids_damaged_prev_.swap(child_surface_ids_damaged_);
+ child_surface_ids_damaged_.clear();
+
+ needs_draw_ = false;
+ entire_display_damaged_ = false;
+ all_active_child_surfaces_ready_to_draw_ =
+ child_surface_ids_to_expect_damage_from_.empty();
+
+ expect_damage_from_root_surface_ = root_surface_damaged_;
+ root_surface_damaged_ = false;
+}
+
+bool DisplayScheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) {
+ base::TimeTicks now = base::TimeTicks::Now();
+ TRACE_EVENT2("cc", "DisplayScheduler::BeginFrame", "args", args.AsValue(),
+ "now", now);
+
+ // If we get another BeginFrame before the previous deadline,
+ // synchronously trigger the previous deadline before progressing.
+ if (inside_begin_frame_deadline_interval_) {
+ OnBeginFrameDeadline();
+ }
+
+ // Schedule the deadline.
+ current_begin_frame_args_ = args;
+ current_begin_frame_args_.deadline -=
+ BeginFrameArgs::DefaultEstimatedParentDrawTime();
+ inside_begin_frame_deadline_interval_ = true;
+ ScheduleBeginFrameDeadline();
+
+ return true;
+}
+
+base::TimeTicks DisplayScheduler::DesiredBeginFrameDeadlineTime() {
+ if (output_surface_lost_) {
+ TRACE_EVENT_INSTANT0("cc", "Lost output surface", TRACE_EVENT_SCOPE_THREAD);
+ return base::TimeTicks();
+ }
+
+ if (pending_swaps_ >= max_pending_swaps_) {
+ TRACE_EVENT_INSTANT0("cc", "Swap throttled", TRACE_EVENT_SCOPE_THREAD);
+ return current_begin_frame_args_.deadline;
+ }
+
+ if (!needs_draw_) {
+ TRACE_EVENT_INSTANT0("cc", "No damage yet", TRACE_EVENT_SCOPE_THREAD);
+ return current_begin_frame_args_.frame_time +
+ current_begin_frame_args_.interval;
+ }
+
+ if (root_surface_resources_locked_) {
+ TRACE_EVENT_INSTANT0("cc", "Root surface resources locked",
+ TRACE_EVENT_SCOPE_THREAD);
+ return current_begin_frame_args_.frame_time +
+ current_begin_frame_args_.interval;
+ }
+
+ // TODO(mithro): Be smarter about resize deadlines.
+ if (entire_display_damaged_) {
+ TRACE_EVENT_INSTANT0("cc", "Entire display damaged",
+ TRACE_EVENT_SCOPE_THREAD);
+ return base::TimeTicks();
+ }
+
+ bool root_ready_to_draw =
+ !expect_damage_from_root_surface_ || root_surface_damaged_;
+
+ if (all_active_child_surfaces_ready_to_draw_ && root_ready_to_draw) {
+ TRACE_EVENT_INSTANT0("cc", "All active surfaces ready",
+ TRACE_EVENT_SCOPE_THREAD);
+ return base::TimeTicks();
+ }
+
+ // Use an earlier deadline if we are only waiting for the root surface
+ // in case our expect_damage_from_root_surface heuristic is incorrect.
+ // TODO(mithro): Replace this with SetNeedsBeginFrame and SwapAbort
+ // logic.
+ if (all_active_child_surfaces_ready_to_draw_ &&
+ expect_damage_from_root_surface_) {
+ TRACE_EVENT_INSTANT0("cc", "Waiting for damage from root surface",
+ TRACE_EVENT_SCOPE_THREAD);
+ // This adjusts the deadline by DefaultEstimatedParentDrawTime for
+ // a second time. The first one represented the Surfaces draw to display
+ // latency. This one represents root surface commit+raster+draw latency.
+ // We treat the root surface differently since it lives on the same thread
+ // as Surfaces and waiting for it too long may push out the Surfaces draw.
+ // If we also assume the root surface is fast to start a commit after the
+ // beginning of a frame, it'll have a chance to lock its resources, which
+ // will cause us to wait for it to unlock its resources above.
+ // TODO(mithro): Replace hard coded estimates.
+ return current_begin_frame_args_.deadline -
+ BeginFrameArgs::DefaultEstimatedParentDrawTime();
+ }
+
+ TRACE_EVENT_INSTANT0("cc", "More damage expected soon",
+ TRACE_EVENT_SCOPE_THREAD);
+ return current_begin_frame_args_.deadline;
+}
+
+void DisplayScheduler::ScheduleBeginFrameDeadline() {
+ TRACE_EVENT0("cc", "DisplayScheduler::ScheduleBeginFrameDeadline");
+
+ // We need to wait for the next BeginFrame before scheduling a deadline.
+ if (!inside_begin_frame_deadline_interval_) {
+ TRACE_EVENT_INSTANT0("cc", "Waiting for next BeginFrame",
+ TRACE_EVENT_SCOPE_THREAD);
+ DCHECK(begin_frame_deadline_task_.IsCancelled());
+ return;
+ }
+
+ // Determine the deadline we want to use.
+ base::TimeTicks desired_deadline = DesiredBeginFrameDeadlineTime();
+
+ // Avoid re-scheduling the deadline if it's already correctly scheduled.
+ if (!begin_frame_deadline_task_.IsCancelled() &&
+ desired_deadline == begin_frame_deadline_task_time_) {
+ TRACE_EVENT_INSTANT0("cc", "Using existing deadline",
+ TRACE_EVENT_SCOPE_THREAD);
+ return;
+ }
+
+ // Schedule the deadline.
+ begin_frame_deadline_task_time_ = desired_deadline;
+ begin_frame_deadline_task_.Cancel();
+ begin_frame_deadline_task_.Reset(begin_frame_deadline_closure_);
+
+ base::TimeDelta delta =
+ std::max(base::TimeDelta(), desired_deadline - base::TimeTicks::Now());
+ task_runner_->PostDelayedTask(FROM_HERE,
+ begin_frame_deadline_task_.callback(), delta);
+ TRACE_EVENT2("cc", "Using new deadline", "delta", delta.ToInternalValue(),
+ "desired_deadline", desired_deadline);
+}
+
+void DisplayScheduler::AttemptDrawAndSwap() {
+ inside_begin_frame_deadline_interval_ = false;
+ begin_frame_deadline_task_.Cancel();
+ begin_frame_deadline_task_time_ = base::TimeTicks();
+
+ if (needs_draw_ && !output_surface_lost_) {
+ if (pending_swaps_ < max_pending_swaps_ && !root_surface_resources_locked_)
+ DrawAndSwap();
+ } else {
+ // We are going idle, so reset expectations.
+ child_surface_ids_to_expect_damage_from_.clear();
+ child_surface_ids_damaged_prev_.clear();
+ child_surface_ids_damaged_.clear();
+ all_active_child_surfaces_ready_to_draw_ = true;
+ expect_damage_from_root_surface_ = false;
+
+ begin_frame_source_->SetNeedsBeginFrames(false);
+ }
+}
+
+void DisplayScheduler::OnBeginFrameDeadline() {
+ TRACE_EVENT0("cc", "DisplayScheduler::OnBeginFrameDeadline");
+
+ AttemptDrawAndSwap();
+ begin_frame_source_->DidFinishFrame(0);
+}
+
+void DisplayScheduler::DidSwapBuffers() {
+ pending_swaps_++;
+ TRACE_EVENT1("cc", "DisplayScheduler::DidSwapBuffers", "pending_frames",
+ pending_swaps_);
+}
+
+void DisplayScheduler::DidSwapBuffersComplete() {
+ pending_swaps_--;
+ TRACE_EVENT1("cc", "DisplayScheduler::DidSwapBuffersComplete",
+ "pending_frames", pending_swaps_);
+ ScheduleBeginFrameDeadline();
+}
+
+} // namespace cc
diff --git a/chromium/cc/surfaces/display_scheduler.h b/chromium/cc/surfaces/display_scheduler.h
new file mode 100644
index 00000000000..bc509c7b1ca
--- /dev/null
+++ b/chromium/cc/surfaces/display_scheduler.h
@@ -0,0 +1,93 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_SURFACES_DISPLAY_SCHEDULER_H_
+#define CC_SURFACES_DISPLAY_SCHEDULER_H_
+
+#include "base/cancelable_callback.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/single_thread_task_runner.h"
+#include "cc/scheduler/begin_frame_source.h"
+#include "cc/surfaces/surface_id.h"
+#include "cc/surfaces/surfaces_export.h"
+
+namespace cc {
+
+class OutputSurface;
+class BeginFrameSource;
+
+// TODO(brianderson): Reconcile with SurfacesScheduler crbug.com/476676
+class CC_SURFACES_EXPORT DisplaySchedulerClient {
+ public:
+ virtual ~DisplaySchedulerClient() {}
+
+ virtual bool DrawAndSwap() = 0;
+};
+
+class CC_SURFACES_EXPORT DisplayScheduler : public BeginFrameObserverBase {
+ public:
+ DisplayScheduler(DisplaySchedulerClient* client,
+ BeginFrameSource* begin_frame_source,
+ base::SingleThreadTaskRunner* task_runner,
+ int max_pending_swaps);
+ ~DisplayScheduler() override;
+
+ void SetRootSurfaceResourcesLocked(bool locked);
+ void ForceImmediateSwapIfPossible();
+ virtual void EntireDisplayDamaged(SurfaceId root_surface_id);
+ virtual void SurfaceDamaged(SurfaceId surface_id);
+
+ virtual void DidSwapBuffers();
+ void DidSwapBuffersComplete();
+
+ void OutputSurfaceLost();
+
+ // BeginFrameObserverBase implementation
+ bool OnBeginFrameDerivedImpl(const BeginFrameArgs& args) override;
+
+ protected:
+ base::TimeTicks DesiredBeginFrameDeadlineTime();
+ virtual void ScheduleBeginFrameDeadline();
+ void AttemptDrawAndSwap();
+ void OnBeginFrameDeadline();
+ void DrawAndSwap();
+
+ DisplaySchedulerClient* client_;
+ BeginFrameSource* begin_frame_source_;
+ base::SingleThreadTaskRunner* task_runner_;
+
+ BeginFrameArgs current_begin_frame_args_;
+ base::Closure begin_frame_deadline_closure_;
+ base::CancelableClosure begin_frame_deadline_task_;
+ base::TimeTicks begin_frame_deadline_task_time_;
+
+ bool output_surface_lost_;
+ bool root_surface_resources_locked_;
+
+ bool inside_begin_frame_deadline_interval_;
+ bool needs_draw_;
+ bool entire_display_damaged_;
+ bool all_active_child_surfaces_ready_to_draw_;
+
+ int pending_swaps_;
+ int max_pending_swaps_;
+
+ SurfaceId root_surface_id_;
+ bool root_surface_damaged_;
+ bool expect_damage_from_root_surface_;
+
+ std::set<SurfaceId> child_surface_ids_damaged_;
+ std::set<SurfaceId> child_surface_ids_damaged_prev_;
+ std::vector<SurfaceId> child_surface_ids_to_expect_damage_from_;
+
+ base::WeakPtrFactory<DisplayScheduler> weak_ptr_factory_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DisplayScheduler);
+};
+
+} // namespace cc
+
+#endif // CC_SURFACES_DISPLAY_SCHEDULER_H_
diff --git a/chromium/cc/surfaces/display_scheduler_unittest.cc b/chromium/cc/surfaces/display_scheduler_unittest.cc
new file mode 100644
index 00000000000..43a0c9a5cba
--- /dev/null
+++ b/chromium/cc/surfaces/display_scheduler_unittest.cc
@@ -0,0 +1,347 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/surfaces/display_scheduler.h"
+
+#include "base/logging.h"
+#include "base/test/null_task_runner.h"
+#include "base/test/simple_test_tick_clock.h"
+#include "base/trace_event/trace_event.h"
+#include "cc/output/begin_frame_args.h"
+#include "cc/surfaces/display.h"
+#include "cc/test/scheduler_test_common.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+namespace {
+
+const int kMaxPendingSwaps = 1;
+
+class FakeDisplaySchedulerClient : public DisplaySchedulerClient {
+ public:
+ FakeDisplaySchedulerClient() : draw_and_swap_count_(0) {}
+
+ ~FakeDisplaySchedulerClient() override {}
+
+ bool DrawAndSwap() override {
+ draw_and_swap_count_++;
+ return true;
+ }
+
+ void Reset() { draw_and_swap_count_ = 0; }
+
+ int draw_and_swap_count() const { return draw_and_swap_count_; }
+
+ protected:
+ int draw_and_swap_count_;
+};
+
+class TestDisplayScheduler : public DisplayScheduler {
+ public:
+ TestDisplayScheduler(DisplaySchedulerClient* client,
+ BeginFrameSource* begin_frame_source,
+ base::SingleThreadTaskRunner* task_runner,
+ int max_pending_swaps)
+ : DisplayScheduler(client,
+ begin_frame_source,
+ task_runner,
+ max_pending_swaps),
+ scheduler_begin_frame_deadline_count_(0) {}
+
+ base::TimeTicks DesiredBeginFrameDeadlineTimeForTest() {
+ return DesiredBeginFrameDeadlineTime();
+ }
+
+ void BeginFrameDeadlineForTest() { OnBeginFrameDeadline(); }
+
+ void ScheduleBeginFrameDeadline() override {
+ scheduler_begin_frame_deadline_count_++;
+ DisplayScheduler::ScheduleBeginFrameDeadline();
+ }
+
+ int scheduler_begin_frame_deadline_count() {
+ return scheduler_begin_frame_deadline_count_;
+ }
+
+ protected:
+ int scheduler_begin_frame_deadline_count_;
+};
+
+class DisplaySchedulerTest : public testing::Test {
+ public:
+ DisplaySchedulerTest()
+ : now_src_(new base::SimpleTestTickClock()),
+ task_runner_(new base::NullTaskRunner),
+ client_(new FakeDisplaySchedulerClient),
+ scheduler_(new TestDisplayScheduler(client_.get(),
+ &fake_begin_frame_source_,
+ task_runner_.get(),
+ kMaxPendingSwaps)) {
+ now_src_->Advance(base::TimeDelta::FromMicroseconds(10000));
+ }
+
+ ~DisplaySchedulerTest() override {}
+
+ void SetUp() override { scheduler_->SetRootSurfaceResourcesLocked(false); }
+
+ void BeginFrameForTest() {
+ base::TimeTicks frame_time = now_src_->NowTicks();
+ base::TimeDelta interval = BeginFrameArgs::DefaultInterval();
+ base::TimeTicks deadline = frame_time + interval;
+ fake_begin_frame_source_.TestOnBeginFrame(
+ BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, frame_time, deadline,
+ interval, BeginFrameArgs::NORMAL));
+ }
+
+ protected:
+ base::SimpleTestTickClock& now_src() { return *now_src_; }
+ FakeDisplaySchedulerClient& client() { return *client_; }
+ DisplayScheduler& scheduler() { return *scheduler_; }
+
+ FakeBeginFrameSource fake_begin_frame_source_;
+
+ scoped_ptr<base::SimpleTestTickClock> now_src_;
+ scoped_refptr<base::NullTaskRunner> task_runner_;
+ scoped_ptr<FakeDisplaySchedulerClient> client_;
+ scoped_ptr<TestDisplayScheduler> scheduler_;
+};
+
+TEST_F(DisplaySchedulerTest, EntireDisplayDamagedDrawsImmediately) {
+ SurfaceId root_surface_id(1);
+ BeginFrameForTest();
+ EXPECT_LT(now_src().NowTicks(),
+ scheduler_->DesiredBeginFrameDeadlineTimeForTest());
+ scheduler_->EntireDisplayDamaged(root_surface_id);
+ EXPECT_GE(now_src().NowTicks(),
+ scheduler_->DesiredBeginFrameDeadlineTimeForTest());
+}
+
+TEST_F(DisplaySchedulerTest, SurfaceDamaged) {
+ SurfaceId root_surface_id(0);
+ SurfaceId sid1(1);
+ SurfaceId sid2(2);
+
+ // Set the root surface
+ scheduler_->EntireDisplayDamaged(root_surface_id);
+
+ // Get scheduler to detect surface 1 as active by drawing
+ // two frames in a row with damage from surface 1.
+ BeginFrameForTest();
+ scheduler_->SurfaceDamaged(sid1);
+ scheduler_->BeginFrameDeadlineForTest();
+ BeginFrameForTest();
+ scheduler_->SurfaceDamaged(sid1);
+ scheduler_->BeginFrameDeadlineForTest();
+
+ // Damage only from surface 2 (inactive) does not trigger deadline early.
+ BeginFrameForTest();
+ scheduler_->SurfaceDamaged(sid2);
+ EXPECT_LT(now_src().NowTicks(),
+ scheduler_->DesiredBeginFrameDeadlineTimeForTest());
+
+ // Damage from surface 1 triggers deadline early.
+ scheduler_->SurfaceDamaged(sid1);
+ EXPECT_GE(now_src().NowTicks(),
+ scheduler_->DesiredBeginFrameDeadlineTimeForTest());
+ scheduler_->BeginFrameDeadlineForTest();
+
+ // Make both surface 1 and 2 active.
+ BeginFrameForTest();
+ scheduler_->SurfaceDamaged(sid2);
+ scheduler_->SurfaceDamaged(sid1);
+ scheduler_->BeginFrameDeadlineForTest();
+
+ // Deadline doesn't trigger early until surface 1 and 2 are both damaged.
+ BeginFrameForTest();
+ EXPECT_LT(now_src().NowTicks(),
+ scheduler_->DesiredBeginFrameDeadlineTimeForTest());
+ scheduler_->SurfaceDamaged(sid1);
+ EXPECT_LT(now_src().NowTicks(),
+ scheduler_->DesiredBeginFrameDeadlineTimeForTest());
+ scheduler_->SurfaceDamaged(sid2);
+ EXPECT_GE(now_src().NowTicks(),
+ scheduler_->DesiredBeginFrameDeadlineTimeForTest());
+ scheduler_->BeginFrameDeadlineForTest();
+
+ // Make the system idle
+ BeginFrameForTest();
+ scheduler_->BeginFrameDeadlineForTest();
+ BeginFrameForTest();
+ scheduler_->BeginFrameDeadlineForTest();
+
+ // Deadline should trigger early if child surfaces are idle and
+ // we get damage on the root surface.
+ BeginFrameForTest();
+ EXPECT_LT(now_src().NowTicks(),
+ scheduler_->DesiredBeginFrameDeadlineTimeForTest());
+ scheduler_->SurfaceDamaged(root_surface_id);
+ EXPECT_GE(now_src().NowTicks(),
+ scheduler_->DesiredBeginFrameDeadlineTimeForTest());
+ scheduler_->BeginFrameDeadlineForTest();
+}
+
+TEST_F(DisplaySchedulerTest, OutputSurfaceLost) {
+ SurfaceId sid1(1);
+
+ // DrawAndSwap normally.
+ BeginFrameForTest();
+ EXPECT_LT(now_src().NowTicks(),
+ scheduler_->DesiredBeginFrameDeadlineTimeForTest());
+ EXPECT_EQ(0, client_->draw_and_swap_count());
+ scheduler_->SurfaceDamaged(sid1);
+ scheduler_->BeginFrameDeadlineForTest();
+ EXPECT_EQ(1, client_->draw_and_swap_count());
+
+ // Deadline triggers immediately on OutputSurfaceLost.
+ BeginFrameForTest();
+ EXPECT_LT(now_src().NowTicks(),
+ scheduler_->DesiredBeginFrameDeadlineTimeForTest());
+ scheduler_->OutputSurfaceLost();
+ EXPECT_GE(now_src().NowTicks(),
+ scheduler_->DesiredBeginFrameDeadlineTimeForTest());
+
+ // Deadline does not DrawAndSwap after OutputSurfaceLost.
+ EXPECT_EQ(1, client_->draw_and_swap_count());
+ scheduler_->SurfaceDamaged(sid1);
+ scheduler_->BeginFrameDeadlineForTest();
+ EXPECT_EQ(1, client_->draw_and_swap_count());
+}
+
+TEST_F(DisplaySchedulerTest, RootSurfaceResourcesLocked) {
+ SurfaceId sid1(1);
+ base::TimeTicks late_deadline;
+
+ // DrawAndSwap normally.
+ BeginFrameForTest();
+ EXPECT_LT(now_src().NowTicks(),
+ scheduler_->DesiredBeginFrameDeadlineTimeForTest());
+ EXPECT_EQ(0, client_->draw_and_swap_count());
+ scheduler_->SurfaceDamaged(sid1);
+ scheduler_->BeginFrameDeadlineForTest();
+ EXPECT_EQ(1, client_->draw_and_swap_count());
+
+ // Deadline triggers late while root resources are locked.
+ late_deadline = now_src().NowTicks() + BeginFrameArgs::DefaultInterval();
+ BeginFrameForTest();
+ scheduler_->SurfaceDamaged(sid1);
+ EXPECT_GT(late_deadline, scheduler_->DesiredBeginFrameDeadlineTimeForTest());
+ scheduler_->SetRootSurfaceResourcesLocked(true);
+ EXPECT_EQ(late_deadline, scheduler_->DesiredBeginFrameDeadlineTimeForTest());
+
+ // Deadline does not DrawAndSwap while root resources are locked.
+ EXPECT_EQ(1, client_->draw_and_swap_count());
+ scheduler_->SurfaceDamaged(sid1);
+ scheduler_->BeginFrameDeadlineForTest();
+ EXPECT_EQ(1, client_->draw_and_swap_count());
+
+ // Deadline triggers normally when root resources are unlocked.
+ late_deadline = now_src().NowTicks() + BeginFrameArgs::DefaultInterval();
+ BeginFrameForTest();
+ scheduler_->SurfaceDamaged(sid1);
+ EXPECT_EQ(late_deadline, scheduler_->DesiredBeginFrameDeadlineTimeForTest());
+ scheduler_->SetRootSurfaceResourcesLocked(false);
+ EXPECT_EQ(base::TimeTicks(),
+ scheduler_->DesiredBeginFrameDeadlineTimeForTest());
+
+ EXPECT_EQ(1, client_->draw_and_swap_count());
+ scheduler_->BeginFrameDeadlineForTest();
+ EXPECT_EQ(2, client_->draw_and_swap_count());
+}
+
+TEST_F(DisplaySchedulerTest, DidSwapBuffers) {
+ SurfaceId sid1(1);
+ SurfaceId sid2(2);
+ base::TimeTicks expected_deadline;
+
+ // Get scheduler to detect surface 1 and 2 as active.
+ BeginFrameForTest();
+ scheduler_->SurfaceDamaged(sid1);
+ scheduler_->SurfaceDamaged(sid2);
+ scheduler_->BeginFrameDeadlineForTest();
+ BeginFrameForTest();
+ scheduler_->SurfaceDamaged(sid1);
+ scheduler_->SurfaceDamaged(sid2);
+ scheduler_->BeginFrameDeadlineForTest();
+
+ // DrawAndSwap normally.
+ BeginFrameForTest();
+ EXPECT_LT(now_src().NowTicks(),
+ scheduler_->DesiredBeginFrameDeadlineTimeForTest());
+ EXPECT_EQ(2, client_->draw_and_swap_count());
+ scheduler_->SurfaceDamaged(sid1);
+ scheduler_->SurfaceDamaged(sid2);
+ scheduler_->BeginFrameDeadlineForTest();
+ EXPECT_EQ(3, client_->draw_and_swap_count());
+ scheduler_->DidSwapBuffers();
+
+ // Deadline triggers normally when swap throttled.
+ expected_deadline =
+ fake_begin_frame_source_.TestLastUsedBeginFrameArgs().deadline -
+ BeginFrameArgs::DefaultEstimatedParentDrawTime();
+ BeginFrameForTest();
+ // Damage surface 1, but not surface 2 so we avoid triggering deadline
+ // early because all surfaces are ready.
+ scheduler_->SurfaceDamaged(sid1);
+ EXPECT_EQ(expected_deadline,
+ scheduler_->DesiredBeginFrameDeadlineTimeForTest());
+
+ // Don't draw and swap in deadline while swap throttled.
+ EXPECT_EQ(3, client_->draw_and_swap_count());
+ scheduler_->BeginFrameDeadlineForTest();
+ EXPECT_EQ(3, client_->draw_and_swap_count());
+
+ // Deadline triggers normally once not swap throttled.
+ // Damage from previous BeginFrame should cary over, so don't damage again.
+ expected_deadline =
+ fake_begin_frame_source_.TestLastUsedBeginFrameArgs().deadline -
+ BeginFrameArgs::DefaultEstimatedParentDrawTime();
+ scheduler_->DidSwapBuffersComplete();
+ BeginFrameForTest();
+ EXPECT_EQ(expected_deadline,
+ scheduler_->DesiredBeginFrameDeadlineTimeForTest());
+ // Still waiting for surface 2. Once it updates, deadline should trigger
+ // immediately again.
+ scheduler_->SurfaceDamaged(sid2);
+ EXPECT_EQ(scheduler_->DesiredBeginFrameDeadlineTimeForTest(),
+ base::TimeTicks());
+ // Draw and swap now that we aren't throttled.
+ EXPECT_EQ(3, client_->draw_and_swap_count());
+ scheduler_->BeginFrameDeadlineForTest();
+ EXPECT_EQ(4, client_->draw_and_swap_count());
+}
+
+// This test verfies that we try to reschedule the deadline
+// after any event that may change what deadline we want.
+TEST_F(DisplaySchedulerTest, ScheduleBeginFrameDeadline) {
+ SurfaceId root_surface_id(1);
+ SurfaceId sid1(2);
+ int count = 1;
+ EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
+
+ BeginFrameForTest();
+ EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
+
+ scheduler_->BeginFrameDeadlineForTest();
+ scheduler_->DidSwapBuffers();
+ BeginFrameForTest();
+ EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
+
+ scheduler_->DidSwapBuffersComplete();
+ EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
+
+ scheduler_->EntireDisplayDamaged(root_surface_id);
+ EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
+
+ scheduler_->SurfaceDamaged(sid1);
+ EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
+
+ scheduler_->SetRootSurfaceResourcesLocked(true);
+ EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
+
+ scheduler_->OutputSurfaceLost();
+ EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
+}
+
+} // namespace
+} // namespace cc
diff --git a/chromium/cc/surfaces/display_unittest.cc b/chromium/cc/surfaces/display_unittest.cc
index 7b012440907..93ff0f85af1 100644
--- a/chromium/cc/surfaces/display_unittest.cc
+++ b/chromium/cc/surfaces/display_unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/test/null_task_runner.h"
#include "cc/output/compositor_frame.h"
#include "cc/output/copy_output_result.h"
#include "cc/output/delegated_frame_data.h"
@@ -15,10 +16,13 @@
#include "cc/surfaces/surface_id_allocator.h"
#include "cc/surfaces/surface_manager.h"
#include "cc/test/fake_output_surface.h"
+#include "cc/test/scheduler_test_common.h"
#include "cc/test/test_shared_bitmap_manager.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+using testing::AnyNumber;
+
namespace cc {
namespace {
@@ -29,16 +33,23 @@ class EmptySurfaceFactoryClient : public SurfaceFactoryClient {
class DisplayTest : public testing::Test {
public:
- DisplayTest() : factory_(&manager_, &empty_client_) {}
+ DisplayTest()
+ : factory_(&manager_, &empty_client_),
+ task_runner_(new base::NullTaskRunner) {}
- void SetUp() override {
- output_surface_ = FakeOutputSurface::CreateSoftware(
- make_scoped_ptr(new SoftwareOutputDevice));
+ protected:
+ void SetUpContext(scoped_ptr<TestWebGraphicsContext3D> context) {
+ if (context) {
+ output_surface_ = FakeOutputSurface::Create3d(
+ TestContextProvider::Create(context.Pass()));
+ } else {
+ output_surface_ = FakeOutputSurface::CreateSoftware(
+ make_scoped_ptr(new SoftwareOutputDevice));
+ }
shared_bitmap_manager_.reset(new TestSharedBitmapManager);
output_surface_ptr_ = output_surface_.get();
}
- protected:
void SubmitFrame(RenderPassList* pass_list, SurfaceId surface_id) {
scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData);
pass_list->swap(frame_data->render_pass_list);
@@ -55,23 +66,52 @@ class DisplayTest : public testing::Test {
SurfaceFactory factory_;
scoped_ptr<FakeOutputSurface> output_surface_;
FakeOutputSurface* output_surface_ptr_;
+ FakeBeginFrameSource fake_begin_frame_source_;
+ scoped_refptr<base::NullTaskRunner> task_runner_;
scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
};
class TestDisplayClient : public DisplayClient {
public:
- TestDisplayClient() : damaged(false), swapped(false) {}
+ TestDisplayClient() {}
~TestDisplayClient() override {}
- void DisplayDamaged() override { damaged = true; }
- void DidSwapBuffers() override { swapped = true; }
- void DidSwapBuffersComplete() override {}
void CommitVSyncParameters(base::TimeTicks timebase,
base::TimeDelta interval) override {}
void OutputSurfaceLost() override {}
void SetMemoryPolicy(const ManagedMemoryPolicy& policy) override {}
+};
+
+class TestDisplayScheduler : public DisplayScheduler {
+ public:
+ TestDisplayScheduler(DisplaySchedulerClient* client,
+ BeginFrameSource* begin_frame_source,
+ base::NullTaskRunner* task_runner)
+ : DisplayScheduler(client, begin_frame_source, task_runner, 1),
+ damaged(false),
+ entire_display_damaged(false),
+ swapped(false) {}
+
+ ~TestDisplayScheduler() override {}
+
+ void EntireDisplayDamaged(SurfaceId root_surface_id) override {
+ entire_display_damaged = true;
+ }
+
+ void SurfaceDamaged(SurfaceId surface_id) override {
+ damaged = true;
+ needs_draw_ = true;
+ }
+
+ void DidSwapBuffers() override { swapped = true; }
+
+ void ResetDamageForTest() {
+ damaged = false;
+ entire_display_damaged = false;
+ }
bool damaged;
+ bool entire_display_damaged;
bool swapped;
};
@@ -81,22 +121,29 @@ void CopyCallback(bool* called, scoped_ptr<CopyOutputResult> result) {
// Check that frame is damaged and swapped only under correct conditions.
TEST_F(DisplayTest, DisplayDamaged) {
+ SetUpContext(nullptr);
TestDisplayClient client;
RendererSettings settings;
settings.partial_swap_enabled = true;
+ settings.finish_rendering_on_resize = true;
Display display(&client, &manager_, shared_bitmap_manager_.get(), nullptr,
settings);
- display.Initialize(output_surface_.Pass());
+ TestDisplayScheduler scheduler(&display, &fake_begin_frame_source_,
+ task_runner_.get());
+ display.Initialize(output_surface_.Pass(), &scheduler);
SurfaceId surface_id(7u);
- EXPECT_FALSE(client.damaged);
+ EXPECT_FALSE(scheduler.damaged);
+ EXPECT_FALSE(scheduler.entire_display_damaged);
display.SetSurfaceId(surface_id, 1.f);
- EXPECT_TRUE(client.damaged);
+ EXPECT_FALSE(scheduler.damaged);
+ EXPECT_TRUE(scheduler.entire_display_damaged);
- client.damaged = false;
+ scheduler.ResetDamageForTest();
display.Resize(gfx::Size(100, 100));
- EXPECT_TRUE(client.damaged);
+ EXPECT_FALSE(scheduler.damaged);
+ EXPECT_TRUE(scheduler.entire_display_damaged);
factory_.Create(surface_id);
@@ -108,14 +155,15 @@ TEST_F(DisplayTest, DisplayDamaged) {
pass->id = RenderPassId(1, 1);
pass_list.push_back(pass.Pass());
- client.damaged = false;
+ scheduler.ResetDamageForTest();
SubmitFrame(&pass_list, surface_id);
- EXPECT_TRUE(client.damaged);
+ EXPECT_TRUE(scheduler.damaged);
+ EXPECT_FALSE(scheduler.entire_display_damaged);
- EXPECT_FALSE(client.swapped);
+ EXPECT_FALSE(scheduler.swapped);
EXPECT_EQ(0u, output_surface_ptr_->num_sent_frames());
- display.Draw();
- EXPECT_TRUE(client.swapped);
+ display.DrawAndSwap();
+ EXPECT_TRUE(scheduler.swapped);
EXPECT_EQ(1u, output_surface_ptr_->num_sent_frames());
SoftwareFrameData* software_data =
output_surface_ptr_->last_sent_frame().software_frame_data.get();
@@ -132,13 +180,14 @@ TEST_F(DisplayTest, DisplayDamaged) {
pass->id = RenderPassId(1, 1);
pass_list.push_back(pass.Pass());
- client.damaged = false;
+ scheduler.ResetDamageForTest();
SubmitFrame(&pass_list, surface_id);
- EXPECT_TRUE(client.damaged);
+ EXPECT_TRUE(scheduler.damaged);
+ EXPECT_FALSE(scheduler.entire_display_damaged);
- client.swapped = false;
- display.Draw();
- EXPECT_TRUE(client.swapped);
+ scheduler.swapped = false;
+ display.DrawAndSwap();
+ EXPECT_TRUE(scheduler.swapped);
EXPECT_EQ(2u, output_surface_ptr_->num_sent_frames());
software_data =
output_surface_ptr_->last_sent_frame().software_frame_data.get();
@@ -156,13 +205,14 @@ TEST_F(DisplayTest, DisplayDamaged) {
pass->id = RenderPassId(1, 1);
pass_list.push_back(pass.Pass());
- client.damaged = false;
+ scheduler.ResetDamageForTest();
SubmitFrame(&pass_list, surface_id);
- EXPECT_TRUE(client.damaged);
+ EXPECT_TRUE(scheduler.damaged);
+ EXPECT_FALSE(scheduler.entire_display_damaged);
- client.swapped = false;
- display.Draw();
- EXPECT_TRUE(client.swapped);
+ scheduler.swapped = false;
+ display.DrawAndSwap();
+ EXPECT_TRUE(scheduler.swapped);
EXPECT_EQ(2u, output_surface_ptr_->num_sent_frames());
}
@@ -174,13 +224,14 @@ TEST_F(DisplayTest, DisplayDamaged) {
pass->id = RenderPassId(1, 1);
pass_list.push_back(pass.Pass());
- client.damaged = false;
+ scheduler.ResetDamageForTest();
SubmitFrame(&pass_list, surface_id);
- EXPECT_TRUE(client.damaged);
+ EXPECT_TRUE(scheduler.damaged);
+ EXPECT_FALSE(scheduler.entire_display_damaged);
- client.swapped = false;
- display.Draw();
- EXPECT_TRUE(client.swapped);
+ scheduler.swapped = false;
+ display.DrawAndSwap();
+ EXPECT_TRUE(scheduler.swapped);
EXPECT_EQ(2u, output_surface_ptr_->num_sent_frames());
}
@@ -195,13 +246,14 @@ TEST_F(DisplayTest, DisplayDamaged) {
pass->id = RenderPassId(1, 1);
pass_list.push_back(pass.Pass());
- client.damaged = false;
+ scheduler.ResetDamageForTest();
SubmitFrame(&pass_list, surface_id);
- EXPECT_TRUE(client.damaged);
+ EXPECT_TRUE(scheduler.damaged);
+ EXPECT_FALSE(scheduler.entire_display_damaged);
- client.swapped = false;
- display.Draw();
- EXPECT_TRUE(client.swapped);
+ scheduler.swapped = false;
+ display.DrawAndSwap();
+ EXPECT_TRUE(scheduler.swapped);
EXPECT_EQ(3u, output_surface_ptr_->num_sent_frames());
EXPECT_TRUE(copy_called);
}
@@ -214,7 +266,7 @@ TEST_F(DisplayTest, DisplayDamaged) {
pass->id = RenderPassId(1, 1);
pass_list.push_back(pass.Pass());
- client.damaged = false;
+ scheduler.ResetDamageForTest();
scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData);
pass_list.swap(frame_data->render_pass_list);
@@ -224,14 +276,122 @@ TEST_F(DisplayTest, DisplayDamaged) {
factory_.SubmitFrame(surface_id, frame.Pass(),
SurfaceFactory::DrawCallback());
- EXPECT_TRUE(client.damaged);
+ EXPECT_TRUE(scheduler.damaged);
+ EXPECT_FALSE(scheduler.entire_display_damaged);
- client.swapped = false;
- display.Draw();
- EXPECT_TRUE(client.swapped);
+ scheduler.swapped = false;
+ display.DrawAndSwap();
+ EXPECT_TRUE(scheduler.swapped);
EXPECT_EQ(4u, output_surface_ptr_->num_sent_frames());
}
+ // Resize should cause a swap if no frame was swapped at the previous size.
+ {
+ scheduler.swapped = false;
+ display.Resize(gfx::Size(200, 200));
+ EXPECT_FALSE(scheduler.swapped);
+ EXPECT_EQ(4u, output_surface_ptr_->num_sent_frames());
+
+ pass = RenderPass::Create();
+ pass->output_rect = gfx::Rect(0, 0, 200, 200);
+ pass->damage_rect = gfx::Rect(10, 10, 10, 10);
+ pass->id = RenderPassId(1, 1);
+
+ pass_list.push_back(pass.Pass());
+ scheduler.ResetDamageForTest();
+ scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData);
+ pass_list.swap(frame_data->render_pass_list);
+
+ scoped_ptr<CompositorFrame> frame(new CompositorFrame);
+ frame->delegated_frame_data = frame_data.Pass();
+
+ factory_.SubmitFrame(surface_id, frame.Pass(),
+ SurfaceFactory::DrawCallback());
+ EXPECT_TRUE(scheduler.damaged);
+ EXPECT_FALSE(scheduler.entire_display_damaged);
+
+ scheduler.swapped = false;
+ display.Resize(gfx::Size(100, 100));
+ EXPECT_TRUE(scheduler.swapped);
+ EXPECT_EQ(5u, output_surface_ptr_->num_sent_frames());
+ }
+
+ factory_.Destroy(surface_id);
+}
+
+class MockedContext : public TestWebGraphicsContext3D {
+ public:
+ MOCK_METHOD0(shallowFinishCHROMIUM, void());
+};
+
+TEST_F(DisplayTest, Finish) {
+ scoped_ptr<MockedContext> context(new MockedContext());
+ MockedContext* context_ptr = context.get();
+ SetUpContext(context.Pass());
+
+ EXPECT_CALL(*context_ptr, shallowFinishCHROMIUM()).Times(0);
+ TestDisplayClient client;
+ RendererSettings settings;
+ settings.partial_swap_enabled = true;
+ settings.finish_rendering_on_resize = true;
+ Display display(&client, &manager_, shared_bitmap_manager_.get(), nullptr,
+ settings);
+
+ TestDisplayScheduler scheduler(&display, &fake_begin_frame_source_,
+ task_runner_.get());
+ display.Initialize(output_surface_.Pass(), &scheduler);
+
+ SurfaceId surface_id(7u);
+ display.SetSurfaceId(surface_id, 1.f);
+
+ display.Resize(gfx::Size(100, 100));
+ factory_.Create(surface_id);
+
+ {
+ RenderPassList pass_list;
+ scoped_ptr<RenderPass> pass = RenderPass::Create();
+ pass->output_rect = gfx::Rect(0, 0, 100, 100);
+ pass->damage_rect = gfx::Rect(10, 10, 1, 1);
+ pass->id = RenderPassId(1, 1);
+ pass_list.push_back(pass.Pass());
+
+ SubmitFrame(&pass_list, surface_id);
+ }
+
+ display.DrawAndSwap();
+
+ // First resize and draw shouldn't finish.
+ testing::Mock::VerifyAndClearExpectations(context_ptr);
+
+ EXPECT_CALL(*context_ptr, shallowFinishCHROMIUM());
+ display.Resize(gfx::Size(150, 150));
+ testing::Mock::VerifyAndClearExpectations(context_ptr);
+
+ // Another resize without a swap doesn't need to finish.
+ EXPECT_CALL(*context_ptr, shallowFinishCHROMIUM()).Times(0);
+ display.Resize(gfx::Size(200, 200));
+ testing::Mock::VerifyAndClearExpectations(context_ptr);
+
+ EXPECT_CALL(*context_ptr, shallowFinishCHROMIUM()).Times(0);
+ {
+ RenderPassList pass_list;
+ scoped_ptr<RenderPass> pass = RenderPass::Create();
+ pass->output_rect = gfx::Rect(0, 0, 200, 200);
+ pass->damage_rect = gfx::Rect(10, 10, 1, 1);
+ pass->id = RenderPassId(1, 1);
+ pass_list.push_back(pass.Pass());
+
+ SubmitFrame(&pass_list, surface_id);
+ }
+
+ display.DrawAndSwap();
+
+ testing::Mock::VerifyAndClearExpectations(context_ptr);
+
+ EXPECT_CALL(*context_ptr, shallowFinishCHROMIUM());
+ display.Resize(gfx::Size(250, 250));
+ testing::Mock::VerifyAndClearExpectations(context_ptr);
+
factory_.Destroy(surface_id);
}
diff --git a/chromium/cc/surfaces/onscreen_display_client.cc b/chromium/cc/surfaces/onscreen_display_client.cc
index c9f1f7f4a3e..2bd58fe4ca1 100644
--- a/chromium/cc/surfaces/onscreen_display_client.cc
+++ b/chromium/cc/surfaces/onscreen_display_client.cc
@@ -6,6 +6,8 @@
#include "base/trace_event/trace_event.h"
#include "cc/output/output_surface.h"
+#include "cc/scheduler/begin_frame_source.h"
+#include "cc/surfaces/display_scheduler.h"
#include "cc/surfaces/surface_display_output_surface.h"
#include "cc/surfaces/surface_factory.h"
#include "cc/surfaces/surface_manager.h"
@@ -26,42 +28,46 @@ OnscreenDisplayClient::OnscreenDisplayClient(
gpu_memory_buffer_manager,
settings)),
task_runner_(task_runner),
- scheduled_draw_(false),
output_surface_lost_(false),
- deferred_draw_(false),
- pending_frames_(0),
- weak_ptr_factory_(this) {
+ disable_gpu_vsync_(settings.disable_gpu_vsync) {
}
OnscreenDisplayClient::~OnscreenDisplayClient() {
}
bool OnscreenDisplayClient::Initialize() {
- return display_->Initialize(output_surface_.Pass());
+ int max_frames_pending =
+ output_surface_ ? output_surface_->capabilities().max_frames_pending : 0;
+ if (max_frames_pending <= 0)
+ max_frames_pending = OutputSurface::DEFAULT_MAX_FRAMES_PENDING;
+
+ BeginFrameSource* frame_source;
+ if (disable_gpu_vsync_) {
+ unthrottled_frame_source_ =
+ BackToBackBeginFrameSource::Create(task_runner_.get());
+ frame_source = unthrottled_frame_source_.get();
+ } else {
+ synthetic_frame_source_ = SyntheticBeginFrameSource::Create(
+ task_runner_.get(), BeginFrameArgs::DefaultInterval());
+ frame_source = synthetic_frame_source_.get();
+ }
+
+ scheduler_.reset(new DisplayScheduler(
+ display_.get(), frame_source, task_runner_.get(), max_frames_pending));
+
+ return display_->Initialize(output_surface_.Pass(), scheduler_.get());
}
void OnscreenDisplayClient::CommitVSyncParameters(base::TimeTicks timebase,
base::TimeDelta interval) {
- surface_display_output_surface_->ReceivedVSyncParameters(timebase, interval);
-}
-
-void OnscreenDisplayClient::DisplayDamaged() {
- if (scheduled_draw_ || deferred_draw_)
- return;
- TRACE_EVENT0("content", "OnscreenDisplayClient::DisplayDamaged");
- if (pending_frames_ >= display_->GetMaxFramesPending()) {
- deferred_draw_ = true;
- } else {
- ScheduleDraw();
+ if (interval == base::TimeDelta()) {
+ // TODO(brianderson): We should not be receiving 0 intervals.
+ interval = BeginFrameArgs::DefaultInterval();
}
-}
-void OnscreenDisplayClient::ScheduleDraw() {
- DCHECK(!deferred_draw_);
- DCHECK(!scheduled_draw_);
- scheduled_draw_ = true;
- task_runner_->PostTask(FROM_HERE, base::Bind(&OnscreenDisplayClient::Draw,
- weak_ptr_factory_.GetWeakPtr()));
+ surface_display_output_surface_->ReceivedVSyncParameters(timebase, interval);
+ if (synthetic_frame_source_.get())
+ synthetic_frame_source_->OnUpdateVSyncParameters(timebase, interval);
}
void OnscreenDisplayClient::OutputSurfaceLost() {
@@ -69,26 +75,6 @@ void OnscreenDisplayClient::OutputSurfaceLost() {
surface_display_output_surface_->DidLoseOutputSurface();
}
-void OnscreenDisplayClient::Draw() {
- TRACE_EVENT0("content", "OnscreenDisplayClient::Draw");
- if (output_surface_lost_)
- return;
- scheduled_draw_ = false;
- display_->Draw();
-}
-
-void OnscreenDisplayClient::DidSwapBuffers() {
- pending_frames_++;
-}
-
-void OnscreenDisplayClient::DidSwapBuffersComplete() {
- pending_frames_--;
- if ((pending_frames_ < display_->GetMaxFramesPending()) && deferred_draw_) {
- deferred_draw_ = false;
- ScheduleDraw();
- }
-}
-
void OnscreenDisplayClient::SetMemoryPolicy(const ManagedMemoryPolicy& policy) {
surface_display_output_surface_->SetMemoryPolicy(policy);
}
diff --git a/chromium/cc/surfaces/onscreen_display_client.h b/chromium/cc/surfaces/onscreen_display_client.h
index c699d99e197..c2f69f1bf2c 100644
--- a/chromium/cc/surfaces/onscreen_display_client.h
+++ b/chromium/cc/surfaces/onscreen_display_client.h
@@ -14,8 +14,12 @@
#include "cc/surfaces/display.h"
#include "cc/surfaces/surfaces_export.h"
+class VSyncParameterObserver;
+
namespace cc {
+class BeginFrameSource;
class ContextProvider;
+class DisplayScheduler;
class SurfaceManager;
class SurfaceDisplayOutputSurface;
@@ -40,9 +44,6 @@ class CC_SURFACES_EXPORT OnscreenDisplayClient
}
// DisplayClient implementation.
- void DisplayDamaged() override;
- void DidSwapBuffers() override;
- void DidSwapBuffersComplete() override;
void CommitVSyncParameters(base::TimeTicks timebase,
base::TimeDelta interval) override;
void OutputSurfaceLost() override;
@@ -50,24 +51,18 @@ class CC_SURFACES_EXPORT OnscreenDisplayClient
bool output_surface_lost() { return output_surface_lost_; }
- private:
- void ScheduleDraw();
- void Draw();
-
protected:
scoped_ptr<OutputSurface> output_surface_;
scoped_ptr<Display> display_;
+ scoped_ptr<SyntheticBeginFrameSource> synthetic_frame_source_;
+ scoped_ptr<BackToBackBeginFrameSource> unthrottled_frame_source_;
+ scoped_ptr<DisplayScheduler> scheduler_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
SurfaceDisplayOutputSurface* surface_display_output_surface_;
- bool scheduled_draw_;
bool output_surface_lost_;
- // True if a draw should be scheduled, but it's hit the limit on max frames
- // pending.
- bool deferred_draw_;
- int pending_frames_;
-
- base::WeakPtrFactory<OnscreenDisplayClient> weak_ptr_factory_;
+ bool disable_gpu_vsync_;
+ private:
DISALLOW_COPY_AND_ASSIGN(OnscreenDisplayClient);
};
diff --git a/chromium/cc/surfaces/surface.cc b/chromium/cc/surfaces/surface.cc
index 97575813f48..16987cb84e4 100644
--- a/chromium/cc/surfaces/surface.cc
+++ b/chromium/cc/surfaces/surface.cc
@@ -21,8 +21,8 @@ static const int kFrameIndexStart = 2;
Surface::Surface(SurfaceId id, SurfaceFactory* factory)
: surface_id_(id),
factory_(factory->AsWeakPtr()),
- frame_index_(kFrameIndexStart) {
-}
+ frame_index_(kFrameIndexStart),
+ destroyed_(false) {}
Surface::~Surface() {
ClearCopyRequests();
@@ -60,6 +60,16 @@ void Surface::QueueFrame(scoped_ptr<CompositorFrame> frame,
!current_frame_->delegated_frame_data->render_pass_list.empty())
++frame_index_;
+ std::vector<SurfaceId> new_referenced_surfaces;
+ if (current_frame_) {
+ for (auto& render_pass :
+ current_frame_->delegated_frame_data->render_pass_list) {
+ new_referenced_surfaces.insert(new_referenced_surfaces.end(),
+ render_pass->referenced_surfaces.begin(),
+ render_pass->referenced_surfaces.end());
+ }
+ }
+
if (previous_frame) {
ReturnedResourceArray previous_resources;
TransferableResource::ReturnResources(
@@ -71,10 +81,18 @@ void Surface::QueueFrame(scoped_ptr<CompositorFrame> frame,
draw_callback_.Run(SurfaceDrawStatus::DRAW_SKIPPED);
draw_callback_ = callback;
- if (current_frame_) {
+ bool referenced_surfaces_changed =
+ (referenced_surfaces_ != new_referenced_surfaces);
+ referenced_surfaces_ = new_referenced_surfaces;
+ std::vector<uint32_t> satisfies_sequences;
+ if (current_frame_)
+ current_frame_->metadata.satisfies_sequences.swap(satisfies_sequences);
+ if (referenced_surfaces_changed || !satisfies_sequences.empty()) {
+ // Notify the manager that sequences were satisfied either if some new
+ // sequences were satisfied, or if the set of referenced surfaces changed
+ // to force a GC to happen.
factory_->manager()->DidSatisfySequences(
- SurfaceIdAllocator::NamespaceForId(surface_id_),
- &current_frame_->metadata.satisfies_sequences);
+ SurfaceIdAllocator::NamespaceForId(surface_id_), &satisfies_sequences);
}
}
@@ -134,11 +152,15 @@ void Surface::AddDestructionDependency(SurfaceSequence sequence) {
}
void Surface::SatisfyDestructionDependencies(
- base::hash_set<SurfaceSequence>* sequences) {
+ base::hash_set<SurfaceSequence>* sequences,
+ base::hash_set<uint32_t>* valid_id_namespaces) {
destruction_dependencies_.erase(
- std::remove_if(
- destruction_dependencies_.begin(), destruction_dependencies_.end(),
- [sequences](SurfaceSequence seq) { return !!sequences->erase(seq); }),
+ std::remove_if(destruction_dependencies_.begin(),
+ destruction_dependencies_.end(),
+ [sequences, valid_id_namespaces](SurfaceSequence seq) {
+ return (!!sequences->erase(seq) ||
+ !valid_id_namespaces->count(seq.id_namespace));
+ }),
destruction_dependencies_.end());
}
diff --git a/chromium/cc/surfaces/surface.h b/chromium/cc/surfaces/surface.h
index 8e6d7a46cbf..d9099f3122b 100644
--- a/chromium/cc/surfaces/surface.h
+++ b/chromium/cc/surfaces/surface.h
@@ -67,11 +67,19 @@ class CC_SURFACES_EXPORT Surface {
// Satisfy all destruction dependencies that are contained in sequences, and
// remove them from sequences.
void SatisfyDestructionDependencies(
- base::hash_set<SurfaceSequence>* sequences);
+ base::hash_set<SurfaceSequence>* sequences,
+ base::hash_set<uint32_t>* valid_id_namespaces);
size_t GetDestructionDependencyCount() const {
return destruction_dependencies_.size();
}
+ const std::vector<SurfaceId>& referenced_surfaces() const {
+ return referenced_surfaces_;
+ }
+
+ bool destroyed() const { return destroyed_; }
+ void set_destroyed(bool destroyed) { destroyed_ = destroyed; }
+
private:
void ClearCopyRequests();
@@ -80,8 +88,11 @@ class CC_SURFACES_EXPORT Surface {
// TODO(jamesr): Support multiple frames in flight.
scoped_ptr<CompositorFrame> current_frame_;
int frame_index_;
+ bool destroyed_;
std::vector<SurfaceSequence> destruction_dependencies_;
+ std::vector<SurfaceId> referenced_surfaces_;
+
DrawCallback draw_callback_;
DISALLOW_COPY_AND_ASSIGN(Surface);
diff --git a/chromium/cc/surfaces/surface_aggregator.cc b/chromium/cc/surfaces/surface_aggregator.cc
index 941e2d89fab..ddfac7670b4 100644
--- a/chromium/cc/surfaces/surface_aggregator.cc
+++ b/chromium/cc/surfaces/surface_aggregator.cc
@@ -131,72 +131,6 @@ int SurfaceAggregator::ChildIdForSurface(Surface* surface) {
}
}
-static ResourceProvider::ResourceId ResourceRemapHelper(
- const ResourceProvider::ResourceIdMap& child_to_parent_map,
- ResourceProvider::ResourceId id) {
- ResourceProvider::ResourceIdMap::const_iterator it =
- child_to_parent_map.find(id);
- DCHECK(it != child_to_parent_map.end());
-
- DCHECK_EQ(it->first, id);
- ResourceProvider::ResourceId remapped_id = it->second;
- return remapped_id;
-}
-
-static ResourceProvider::ResourceId ValidateResourceHelper(
- bool* invalid_frame,
- const ResourceProvider::ResourceIdMap& child_to_parent_map,
- ResourceProvider::ResourceIdSet* resources_in_frame,
- ResourceProvider::ResourceId id) {
- ResourceProvider::ResourceIdMap::const_iterator it =
- child_to_parent_map.find(id);
- if (it == child_to_parent_map.end()) {
- *invalid_frame = true;
- return id;
- }
- resources_in_frame->insert(id);
- return id;
-}
-
-bool SurfaceAggregator::ValidateResources(
- Surface* surface,
- const DelegatedFrameData* frame_data) {
- if (!provider_) // TODO(jamesr): hack for unit tests that don't set up rp
- return false;
-
- int child_id = ChildIdForSurface(surface);
- if (surface->factory())
- surface->factory()->RefResources(frame_data->resource_list);
- provider_->ReceiveFromChild(child_id, frame_data->resource_list);
-
- ResourceProvider::ResourceIdSet referenced_resources;
- size_t reserve_size = frame_data->resource_list.size();
-#if defined(COMPILER_MSVC)
- referenced_resources.reserve(reserve_size);
-#elif defined(COMPILER_GCC)
- // Pre-standard hash-tables only implement resize, which behaves similarly
- // to reserve for these keys. Resizing to 0 may also be broken (particularly
- // on stlport).
- // TODO(jbauman): Replace with reserve when C++11 is supported everywhere.
- if (reserve_size)
- referenced_resources.resize(reserve_size);
-#endif
-
- bool invalid_frame = false;
- DrawQuad::ResourceIteratorCallback remap =
- base::Bind(&ValidateResourceHelper, &invalid_frame,
- base::ConstRef(provider_->GetChildToParentMap(child_id)),
- &referenced_resources);
- for (const auto& render_pass : frame_data->render_pass_list) {
- for (const auto& quad : render_pass->quad_list)
- quad->IterateResources(remap);
- }
-
- if (!invalid_frame)
- provider_->DeclareUsedResourcesFromChild(child_id, referenced_resources);
-
- return invalid_frame;
-}
gfx::Rect SurfaceAggregator::DamageRectForSurface(const Surface* surface,
const RenderPass& source,
@@ -236,8 +170,7 @@ void SurfaceAggregator::HandleSurfaceQuad(
surface->TakeCopyOutputRequests(&copy_requests);
const RenderPassList& render_pass_list = frame_data->render_pass_list;
- bool invalid_frame = ValidateResources(surface, frame_data);
- if (invalid_frame) {
+ if (!valid_surfaces_.count(surface->surface_id())) {
for (auto& request : copy_requests) {
request.second->SendEmptyResult();
delete request.second;
@@ -246,18 +179,15 @@ void SurfaceAggregator::HandleSurfaceQuad(
}
SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first;
- DrawQuad::ResourceIteratorCallback remap;
- if (provider_) {
- int child_id = ChildIdForSurface(surface);
- remap =
- base::Bind(&ResourceRemapHelper,
- base::ConstRef(provider_->GetChildToParentMap(child_id)));
- }
+ // TODO(vmpstr): provider check is a hack for unittests that don't set up a
+ // resource provider.
+ ResourceProvider::ResourceIdMap empty_map;
+ const ResourceProvider::ResourceIdMap& child_to_parent_map =
+ provider_ ? provider_->GetChildToParentMap(ChildIdForSurface(surface))
+ : empty_map;
+ bool merge_pass =
+ surface_quad->shared_quad_state->opacity == 1.f && copy_requests.empty();
- bool merge_pass = surface_quad->opacity() == 1.f && copy_requests.empty();
-
- gfx::Rect surface_damage = DamageRectForSurface(
- surface, *render_pass_list.back(), surface_quad->visible_rect);
const RenderPassList& referenced_passes = render_pass_list;
size_t passes_to_copy =
merge_pass ? referenced_passes.size() - 1 : referenced_passes.size();
@@ -280,41 +210,44 @@ void SurfaceAggregator::HandleSurfaceQuad(
// transform of the surface quad into account to update their transform to
// the root surface.
copy_pass->transform_to_root_target.ConcatTransform(
- surface_quad->quadTransform());
+ surface_quad->shared_quad_state->quad_to_target_transform);
copy_pass->transform_to_root_target.ConcatTransform(target_transform);
copy_pass->transform_to_root_target.ConcatTransform(
dest_pass->transform_to_root_target);
- CopyQuadsToPass(source.quad_list, source.shared_quad_state_list, remap,
- gfx::Transform(), ClipData(), copy_pass.get(), surface_id);
-
- if (j == referenced_passes.size() - 1)
- surface_damage = gfx::UnionRects(surface_damage, copy_pass->damage_rect);
+ CopyQuadsToPass(source.quad_list, source.shared_quad_state_list,
+ child_to_parent_map, gfx::Transform(), ClipData(),
+ copy_pass.get(), surface_id);
dest_pass_list_->push_back(copy_pass.Pass());
}
+ gfx::Transform surface_transform =
+ surface_quad->shared_quad_state->quad_to_target_transform;
+ surface_transform.ConcatTransform(target_transform);
+
const RenderPass& last_pass = *render_pass_list.back();
if (merge_pass) {
// TODO(jamesr): Clean up last pass special casing.
const QuadList& quads = last_pass.quad_list;
- gfx::Transform surface_transform = surface_quad->quadTransform();
- surface_transform.ConcatTransform(target_transform);
-
// Intersect the transformed visible rect and the clip rect to create a
// smaller cliprect for the quad.
ClipData surface_quad_clip_rect(
- true, MathUtil::MapEnclosingClippedRect(surface_quad->quadTransform(),
- surface_quad->visible_rect));
- if (surface_quad->isClipped())
- surface_quad_clip_rect.rect.Intersect(surface_quad->clipRect());
+ true, MathUtil::MapEnclosingClippedRect(
+ surface_quad->shared_quad_state->quad_to_target_transform,
+ surface_quad->visible_rect));
+ if (surface_quad->shared_quad_state->is_clipped) {
+ surface_quad_clip_rect.rect.Intersect(
+ surface_quad->shared_quad_state->clip_rect);
+ }
ClipData quads_clip =
CalculateClipRect(clip_rect, surface_quad_clip_rect, target_transform);
- CopyQuadsToPass(quads, last_pass.shared_quad_state_list, remap,
- surface_transform, quads_clip, dest_pass, surface_id);
+ CopyQuadsToPass(quads, last_pass.shared_quad_state_list,
+ child_to_parent_map, surface_transform, quads_clip,
+ dest_pass, surface_id);
} else {
RenderPassId remapped_pass_id = RemapPassId(last_pass.id, surface_id);
@@ -336,10 +269,7 @@ void SurfaceAggregator::HandleSurfaceQuad(
gfx::Vector2dF(),
FilterOperations());
}
- dest_pass->damage_rect =
- gfx::UnionRects(dest_pass->damage_rect,
- MathUtil::MapEnclosingClippedRect(
- surface_quad->quadTransform(), surface_damage));
+
referenced_surfaces_.erase(it);
}
@@ -358,7 +288,7 @@ void SurfaceAggregator::CopySharedQuadState(
// target space of the pass. This will be identity except when copying the
// root draw pass from a surface into a pass when the surface draw quad's
// transform is not identity.
- copy_shared_quad_state->content_to_target_transform.ConcatTransform(
+ copy_shared_quad_state->quad_to_target_transform.ConcatTransform(
target_transform);
ClipData new_clip_rect = CalculateClipRect(
@@ -371,7 +301,7 @@ void SurfaceAggregator::CopySharedQuadState(
void SurfaceAggregator::CopyQuadsToPass(
const QuadList& source_quad_list,
const SharedQuadStateList& source_shared_quad_state_list,
- const DrawQuad::ResourceIteratorCallback& remap,
+ const ResourceProvider::ResourceIdMap& child_to_parent_map,
const gfx::Transform& target_transform,
const ClipData& clip_rect,
RenderPass* dest_pass,
@@ -404,27 +334,24 @@ void SurfaceAggregator::CopyQuadsToPass(
RenderPassId remapped_pass_id =
RemapPassId(original_pass_id, surface_id);
- gfx::Rect pass_damage;
- for (const auto* pass : *dest_pass_list_) {
- if (pass->id == remapped_pass_id) {
- pass_damage = pass->damage_rect;
- break;
- }
- }
-
dest_quad = dest_pass->CopyFromAndAppendRenderPassDrawQuad(
pass_quad, dest_pass->shared_quad_state_list.back(),
remapped_pass_id);
- dest_pass->damage_rect =
- gfx::UnionRects(dest_pass->damage_rect,
- MathUtil::MapEnclosingClippedRect(
- dest_quad->quadTransform(), pass_damage));
} else {
dest_quad = dest_pass->CopyFromAndAppendDrawQuad(
quad, dest_pass->shared_quad_state_list.back());
}
- if (!remap.is_null())
- dest_quad->IterateResources(remap);
+ if (!child_to_parent_map.empty()) {
+ for (ResourceId& resource_id : dest_quad->resources) {
+ ResourceProvider::ResourceIdMap::const_iterator it =
+ child_to_parent_map.find(resource_id);
+ DCHECK(it != child_to_parent_map.end());
+
+ DCHECK_EQ(it->first, resource_id);
+ ResourceId remapped_id = it->second;
+ resource_id = remapped_id;
+ }
+ }
}
}
}
@@ -437,19 +364,16 @@ void SurfaceAggregator::CopyPasses(const DelegatedFrameData* frame_data,
surface->TakeCopyOutputRequests(&copy_requests);
const RenderPassList& source_pass_list = frame_data->render_pass_list;
- bool invalid_frame = ValidateResources(surface, frame_data);
- DCHECK(!invalid_frame);
- if (invalid_frame)
+ DCHECK(valid_surfaces_.count(surface->surface_id()));
+ if (!valid_surfaces_.count(surface->surface_id()))
return;
- DrawQuad::ResourceIteratorCallback remap;
- if (provider_) {
- int child_id = ChildIdForSurface(surface);
- remap =
- base::Bind(&ResourceRemapHelper,
- base::ConstRef(provider_->GetChildToParentMap(child_id)));
- }
-
+ // TODO(vmpstr): provider check is a hack for unittests that don't set up a
+ // resource provider.
+ ResourceProvider::ResourceIdMap empty_map;
+ const ResourceProvider::ResourceIdMap& child_to_parent_map =
+ provider_ ? provider_->GetChildToParentMap(ChildIdForSurface(surface))
+ : empty_map;
for (size_t i = 0; i < source_pass_list.size(); ++i) {
const RenderPass& source = *source_pass_list[i];
@@ -462,17 +386,13 @@ void SurfaceAggregator::CopyPasses(const DelegatedFrameData* frame_data,
RenderPassId remapped_pass_id =
RemapPassId(source.id, surface->surface_id());
- gfx::Rect damage_rect =
- (i < source_pass_list.size() - 1)
- ? gfx::Rect()
- : DamageRectForSurface(surface, source, source.output_rect);
- copy_pass->SetAll(remapped_pass_id, source.output_rect, damage_rect,
+ copy_pass->SetAll(remapped_pass_id, source.output_rect, gfx::Rect(),
source.transform_to_root_target,
source.has_transparent_background);
- CopyQuadsToPass(source.quad_list, source.shared_quad_state_list, remap,
- gfx::Transform(), ClipData(), copy_pass.get(),
- surface->surface_id());
+ CopyQuadsToPass(source.quad_list, source.shared_quad_state_list,
+ child_to_parent_map, gfx::Transform(), ClipData(),
+ copy_pass.get(), surface->surface_id());
dest_pass_list_->push_back(copy_pass.Pass());
}
@@ -495,6 +415,104 @@ void SurfaceAggregator::RemoveUnreferencedChildren() {
}
}
+// Validate the resources of the current surface and its descendants, and
+// calculate their combined damage rect.
+gfx::Rect SurfaceAggregator::ValidateAndCalculateDamageRect(
+ SurfaceId surface_id) {
+ if (referenced_surfaces_.count(surface_id))
+ return gfx::Rect();
+ Surface* surface = manager_->GetSurfaceForId(surface_id);
+ if (!surface)
+ return gfx::Rect();
+ const CompositorFrame* surface_frame = surface->GetEligibleFrame();
+ if (!surface_frame)
+ return gfx::Rect();
+ const DelegatedFrameData* frame_data =
+ surface_frame->delegated_frame_data.get();
+ if (!frame_data)
+ return gfx::Rect();
+ int child_id = 0;
+ // TODO(jbauman): hack for unit tests that don't set up rp
+ if (provider_) {
+ child_id = ChildIdForSurface(surface);
+ if (surface->factory())
+ surface->factory()->RefResources(frame_data->resource_list);
+ provider_->ReceiveFromChild(child_id, frame_data->resource_list);
+ }
+
+ ResourceProvider::ResourceIdSet referenced_resources;
+ size_t reserve_size = frame_data->resource_list.size();
+#if defined(COMPILER_MSVC)
+ referenced_resources.reserve(reserve_size);
+#elif defined(COMPILER_GCC)
+ // Pre-standard hash-tables only implement resize, which behaves similarly
+ // to reserve for these keys. Resizing to 0 may also be broken (particularly
+ // on stlport).
+ // TODO(jbauman): Replace with reserve when C++11 is supported everywhere.
+ if (reserve_size)
+ referenced_resources.resize(reserve_size);
+#endif
+
+ bool invalid_frame = false;
+ ResourceProvider::ResourceIdMap empty_map;
+ const ResourceProvider::ResourceIdMap& child_to_parent_map =
+ provider_ ? provider_->GetChildToParentMap(child_id) : empty_map;
+
+ // Each pair in the vector is a child surface and the transform from its
+ // target to the root target of this surface.
+ std::vector<std::pair<SurfaceId, gfx::Transform>> child_surfaces;
+ for (const auto& render_pass : frame_data->render_pass_list) {
+ for (const auto& quad : render_pass->quad_list) {
+ if (quad->material == DrawQuad::SURFACE_CONTENT) {
+ const SurfaceDrawQuad* surface_quad =
+ SurfaceDrawQuad::MaterialCast(quad);
+ gfx::Transform target_to_surface_transform(
+ surface_quad->shared_quad_state->quad_to_target_transform,
+ render_pass->transform_to_root_target);
+ child_surfaces.push_back(std::make_pair(surface_quad->surface_id,
+ target_to_surface_transform));
+ }
+
+ if (!provider_)
+ continue;
+ for (ResourceId resource_id : quad->resources) {
+ if (!child_to_parent_map.count(resource_id)) {
+ invalid_frame = true;
+ break;
+ }
+ referenced_resources.insert(resource_id);
+ }
+ }
+ }
+
+ if (invalid_frame)
+ return gfx::Rect();
+ valid_surfaces_.insert(surface->surface_id());
+
+ if (provider_)
+ provider_->DeclareUsedResourcesFromChild(child_id, referenced_resources);
+
+ gfx::Rect damage_rect;
+ if (!frame_data->render_pass_list.empty()) {
+ damage_rect =
+ DamageRectForSurface(surface, *frame_data->render_pass_list.back(),
+ frame_data->render_pass_list.back()->output_rect);
+ }
+
+ // Avoid infinite recursion by adding current surface to
+ // referenced_surfaces_.
+ SurfaceSet::iterator it =
+ referenced_surfaces_.insert(surface->surface_id()).first;
+ for (const auto& surface_info : child_surfaces) {
+ gfx::Rect surface_damage =
+ ValidateAndCalculateDamageRect(surface_info.first);
+ damage_rect.Union(
+ MathUtil::MapEnclosingClippedRect(surface_info.second, surface_damage));
+ }
+ referenced_surfaces_.erase(it);
+ return damage_rect;
+}
+
scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate(SurfaceId surface_id) {
Surface* surface = manager_->GetSurfaceForId(surface_id);
DCHECK(surface);
@@ -509,18 +527,21 @@ scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate(SurfaceId surface_id) {
DCHECK(root_surface_frame->delegated_frame_data);
- SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first;
-
dest_resource_list_ = &frame->delegated_frame_data->resource_list;
dest_pass_list_ = &frame->delegated_frame_data->render_pass_list;
- CopyPasses(root_surface_frame->delegated_frame_data.get(), surface);
+ valid_surfaces_.clear();
+ gfx::Rect damage_rect = ValidateAndCalculateDamageRect(surface_id);
+ SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first;
+ CopyPasses(root_surface_frame->delegated_frame_data.get(), surface);
referenced_surfaces_.erase(it);
+
DCHECK(referenced_surfaces_.empty());
if (dest_pass_list_->empty())
return nullptr;
+ dest_pass_list_->back()->damage_rect = damage_rect;
dest_pass_list_ = NULL;
RemoveUnreferencedChildren();
diff --git a/chromium/cc/surfaces/surface_aggregator.h b/chromium/cc/surfaces/surface_aggregator.h
index 8ceb4eb471e..17ea4c43125 100644
--- a/chromium/cc/surfaces/surface_aggregator.h
+++ b/chromium/cc/surfaces/surface_aggregator.h
@@ -64,21 +64,21 @@ class CC_SURFACES_EXPORT SurfaceAggregator {
const gfx::Transform& target_transform,
const ClipData& clip_rect,
RenderPass* dest_render_pass);
- void CopyQuadsToPass(const QuadList& source_quad_list,
- const SharedQuadStateList& source_shared_quad_state_list,
- const DrawQuad::ResourceIteratorCallback& remap,
- const gfx::Transform& target_transform,
- const ClipData& clip_rect,
- RenderPass* dest_pass,
- SurfaceId surface_id);
+ void CopyQuadsToPass(
+ const QuadList& source_quad_list,
+ const SharedQuadStateList& source_shared_quad_state_list,
+ const base::hash_map<ResourceId, ResourceId>& resource_to_child_map,
+ const gfx::Transform& target_transform,
+ const ClipData& clip_rect,
+ RenderPass* dest_pass,
+ SurfaceId surface_id);
+ gfx::Rect ValidateAndCalculateDamageRect(SurfaceId surface_id);
void CopyPasses(const DelegatedFrameData* frame_data, Surface* surface);
// Remove Surfaces that were referenced before but aren't currently
// referenced from the ResourceProvider.
void RemoveUnreferencedChildren();
- bool ValidateResources(Surface* surface,
- const DelegatedFrameData* frame_data);
int ChildIdForSurface(Surface* surface);
gfx::Rect DamageRectForSurface(const Surface* surface,
const RenderPass& source,
@@ -110,6 +110,9 @@ class CC_SURFACES_EXPORT SurfaceAggregator {
SurfaceIndexMap previous_contained_surfaces_;
SurfaceIndexMap contained_surfaces_;
+ // After surface validation, every Surface in this set is valid.
+ base::hash_set<SurfaceId> valid_surfaces_;
+
// This is the pass list for the aggregated frame.
RenderPassList* dest_pass_list_;
diff --git a/chromium/cc/surfaces/surface_aggregator_perftest.cc b/chromium/cc/surfaces/surface_aggregator_perftest.cc
index 87a8932132c..b5fddf51dc6 100644
--- a/chromium/cc/surfaces/surface_aggregator_perftest.cc
+++ b/chromium/cc/surfaces/surface_aggregator_perftest.cc
@@ -13,6 +13,7 @@
#include "cc/surfaces/surface_manager.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_output_surface_client.h"
+#include "cc/test/fake_resource_provider.h"
#include "cc/test/test_shared_bitmap_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/perf/perf_test.h"
@@ -33,9 +34,8 @@ class SurfaceAggregatorPerfTest : public testing::Test {
output_surface_->BindToClient(&output_surface_client_);
shared_bitmap_manager_.reset(new TestSharedBitmapManager);
- resource_provider_ = ResourceProvider::Create(
- output_surface_.get(), shared_bitmap_manager_.get(), nullptr, nullptr,
- 0, false, 1);
+ resource_provider_ = FakeResourceProvider::Create(
+ output_surface_.get(), shared_bitmap_manager_.get());
aggregator_.reset(
new SurfaceAggregator(&manager_, resource_provider_.get()));
}
@@ -70,8 +70,8 @@ class SurfaceAggregatorPerfTest : public testing::Test {
bool flipped = false;
bool nearest_neighbor = false;
quad->SetAll(sqs, rect, opaque_rect, visible_rect, needs_blending, j,
- premultiplied_alpha, uv_top_left, uv_bottom_right,
- background_color, vertex_opacity, flipped,
+ gfx::Size(), false, premultiplied_alpha, uv_top_left,
+ uv_bottom_right, background_color, vertex_opacity, flipped,
nearest_neighbor);
}
sqs = pass->CreateAndAppendSharedQuadState();
diff --git a/chromium/cc/surfaces/surface_aggregator_test_helpers.cc b/chromium/cc/surfaces/surface_aggregator_test_helpers.cc
index b21b37e28d6..f7da1a25c84 100644
--- a/chromium/cc/surfaces/surface_aggregator_test_helpers.cc
+++ b/chromium/cc/surfaces/surface_aggregator_test_helpers.cc
@@ -26,22 +26,17 @@ void AddTestSurfaceQuad(TestRenderPass* pass,
const gfx::Size& surface_size,
float opacity,
SurfaceId surface_id) {
- gfx::Transform content_to_target_transform;
- gfx::Size content_bounds = surface_size;
- gfx::Rect visible_content_rect = gfx::Rect(surface_size);
+ gfx::Transform layer_to_target_transform;
+ gfx::Size layer_bounds = surface_size;
+ gfx::Rect visible_layer_rect = gfx::Rect(surface_size);
gfx::Rect clip_rect = gfx::Rect(surface_size);
bool is_clipped = false;
SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
SharedQuadState* shared_quad_state = pass->CreateAndAppendSharedQuadState();
- shared_quad_state->SetAll(content_to_target_transform,
- content_bounds,
- visible_content_rect,
- clip_rect,
- is_clipped,
- opacity,
- blend_mode,
- 0);
+ shared_quad_state->SetAll(layer_to_target_transform, layer_bounds,
+ visible_layer_rect, clip_rect, is_clipped, opacity,
+ blend_mode, 0);
SurfaceDrawQuad* surface_quad =
pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
diff --git a/chromium/cc/surfaces/surface_aggregator_test_helpers.h b/chromium/cc/surfaces/surface_aggregator_test_helpers.h
index 05c83440616..6d00c4f70f6 100644
--- a/chromium/cc/surfaces/surface_aggregator_test_helpers.h
+++ b/chromium/cc/surfaces/surface_aggregator_test_helpers.h
@@ -55,11 +55,7 @@ struct Quad {
RenderPassId render_pass_id;
private:
- Quad()
- : material(DrawQuad::INVALID),
- opacity(1.f),
- color(SK_ColorWHITE),
- render_pass_id(-1, -1) {}
+ Quad() : material(DrawQuad::INVALID), opacity(1.f), color(SK_ColorWHITE) {}
};
struct Pass {
diff --git a/chromium/cc/surfaces/surface_aggregator_unittest.cc b/chromium/cc/surfaces/surface_aggregator_unittest.cc
index 40a3d572bda..e4ade82116e 100644
--- a/chromium/cc/surfaces/surface_aggregator_unittest.cc
+++ b/chromium/cc/surfaces/surface_aggregator_unittest.cc
@@ -19,6 +19,7 @@
#include "cc/surfaces/surface_manager.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_output_surface_client.h"
+#include "cc/test/fake_resource_provider.h"
#include "cc/test/render_pass_test_common.h"
#include "cc/test/render_pass_test_utils.h"
#include "cc/test/test_shared_bitmap_manager.h"
@@ -689,9 +690,9 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, RenderPassIdMapping) {
void AddSolidColorQuadWithBlendMode(const gfx::Size& size,
RenderPass* pass,
const SkXfermode::Mode blend_mode) {
- const gfx::Transform content_to_target_transform;
- const gfx::Size content_bounds(size);
- const gfx::Rect visible_content_rect(size);
+ const gfx::Transform layer_to_target_transform;
+ const gfx::Size layer_bounds(size);
+ const gfx::Rect visible_layer_rect(size);
const gfx::Rect clip_rect(size);
bool is_clipped = false;
@@ -699,21 +700,13 @@ void AddSolidColorQuadWithBlendMode(const gfx::Size& size,
bool force_anti_aliasing_off = false;
SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState();
- sqs->SetAll(content_to_target_transform,
- content_bounds,
- visible_content_rect,
- clip_rect,
- is_clipped,
- opacity,
- blend_mode,
- 0);
+ sqs->SetAll(layer_to_target_transform, layer_bounds, visible_layer_rect,
+ clip_rect, is_clipped, opacity, blend_mode, 0);
SolidColorDrawQuad* color_quad =
pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
- color_quad->SetNew(pass->shared_quad_state_list.back(),
- visible_content_rect,
- visible_content_rect,
- SK_ColorGREEN,
+ color_quad->SetNew(pass->shared_quad_state_list.back(), visible_layer_rect,
+ visible_layer_rect, SK_ColorGREEN,
force_anti_aliasing_off);
}
@@ -888,12 +881,12 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateMultiplePassWithTransform) {
child_nonroot_pass->transform_to_root_target.Translate(8, 0);
SharedQuadState* child_nonroot_pass_sqs =
child_nonroot_pass->shared_quad_state_list.front();
- child_nonroot_pass_sqs->content_to_target_transform.Translate(5, 0);
+ child_nonroot_pass_sqs->quad_to_target_transform.Translate(5, 0);
RenderPass* child_root_pass = child_pass_list.at(1u);
SharedQuadState* child_root_pass_sqs =
child_root_pass->shared_quad_state_list.front();
- child_root_pass_sqs->content_to_target_transform.Translate(8, 0);
+ child_root_pass_sqs->quad_to_target_transform.Translate(8, 0);
child_root_pass_sqs->is_clipped = true;
child_root_pass_sqs->clip_rect = gfx::Rect(0, 0, 5, 5);
@@ -926,7 +919,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateMultiplePassWithTransform) {
gfx::Rect(0, 1, 100, 7);
SharedQuadState* middle_root_pass_sqs =
middle_root_pass->shared_quad_state_list.front();
- middle_root_pass_sqs->content_to_target_transform.Scale(2, 3);
+ middle_root_pass_sqs->quad_to_target_transform.Scale(2, 3);
scoped_ptr<DelegatedFrameData> middle_frame_data(new DelegatedFrameData);
middle_pass_list.swap(middle_frame_data->render_pass_list);
@@ -955,10 +948,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateMultiplePassWithTransform) {
root_pass_list.at(0)
->shared_quad_state_list.front()
- ->content_to_target_transform.Translate(0, 7);
+ ->quad_to_target_transform.Translate(0, 7);
root_pass_list.at(0)
->shared_quad_state_list.ElementAt(1)
- ->content_to_target_transform.Translate(0, 10);
+ ->quad_to_target_transform.Translate(0, 10);
root_pass_list.at(0)->quad_list.ElementAt(1)->visible_rect =
gfx::Rect(0, 0, 8, 100);
@@ -1004,7 +997,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateMultiplePassWithTransform) {
gfx::Transform expected_aggregated_first_pass_sqs_transform;
expected_aggregated_first_pass_sqs_transform.Translate(5, 0);
EXPECT_EQ(expected_aggregated_first_pass_sqs_transform.ToString(),
- aggregated_first_pass_sqs->content_to_target_transform.ToString());
+ aggregated_first_pass_sqs->quad_to_target_transform.ToString());
// The first pass's transform to the root target should include the aggregated
// transform, including the transform from the child pass to the root.
@@ -1035,7 +1028,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateMultiplePassWithTransform) {
iter != aggregated_pass_list[1]->quad_list.cend();
++iter) {
EXPECT_EQ(expected_root_pass_quad_transforms[iter.index()].ToString(),
- iter->quadTransform().ToString())
+ iter->shared_quad_state->quad_to_target_transform.ToString())
<< iter.index();
}
@@ -1056,12 +1049,9 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateMultiplePassWithTransform) {
// Tests that damage rects are aggregated correctly when surfaces change.
TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) {
- SurfaceId child_surface_id = allocator_.GenerateId();
- factory_.Create(child_surface_id);
- RenderPassId child_pass_id = RenderPassId(1, 1);
- test::Quad child_quads[] = {test::Quad::RenderPassQuad(child_pass_id)};
+ test::Quad child_quads[] = {test::Quad::RenderPassQuad(RenderPassId(1, 1))};
test::Pass child_passes[] = {
- test::Pass(child_quads, arraysize(child_quads), child_pass_id)};
+ test::Pass(child_quads, arraysize(child_quads), RenderPassId(1, 1))};
RenderPassList child_pass_list;
AddPasses(&child_pass_list,
@@ -1072,7 +1062,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) {
RenderPass* child_root_pass = child_pass_list.at(0u);
SharedQuadState* child_root_pass_sqs =
child_root_pass->shared_quad_state_list.front();
- child_root_pass_sqs->content_to_target_transform.Translate(8, 0);
+ child_root_pass_sqs->quad_to_target_transform.Translate(8, 0);
scoped_ptr<DelegatedFrameData> child_frame_data(new DelegatedFrameData);
child_pass_list.swap(child_frame_data->render_pass_list);
@@ -1080,16 +1070,47 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) {
scoped_ptr<CompositorFrame> child_frame(new CompositorFrame);
child_frame->delegated_frame_data = child_frame_data.Pass();
+ SurfaceId child_surface_id = allocator_.GenerateId();
+ factory_.Create(child_surface_id);
factory_.SubmitFrame(child_surface_id, child_frame.Pass(),
SurfaceFactory::DrawCallback());
- RenderPassId pass_id(5, 10);
- test::Quad first_quads[] = {test::Quad::SurfaceQuad(child_surface_id, 1.f)};
- test::Quad root_quads[] = {test::Quad::RenderPassQuad(pass_id)};
+ test::Quad parent_surface_quads[] = {
+ test::Quad::SurfaceQuad(child_surface_id, 1.f)};
+ test::Pass parent_surface_passes[] = {
+ test::Pass(parent_surface_quads, arraysize(parent_surface_quads),
+ RenderPassId(1, 1))};
+
+ RenderPassList parent_surface_pass_list;
+ AddPasses(&parent_surface_pass_list,
+ gfx::Rect(SurfaceSize()),
+ parent_surface_passes,
+ arraysize(parent_surface_passes));
+
+ // Parent surface is only used to test if the transform is applied correctly
+ // to the child surface's damage.
+ scoped_ptr<DelegatedFrameData> parent_surface_frame_data(
+ new DelegatedFrameData);
+ parent_surface_pass_list.swap(parent_surface_frame_data->render_pass_list);
+
+ scoped_ptr<CompositorFrame> parent_surface_frame(new CompositorFrame);
+ parent_surface_frame->delegated_frame_data = parent_surface_frame_data.Pass();
+
+ SurfaceId parent_surface_id = allocator_.GenerateId();
+ factory_.Create(parent_surface_id);
+ factory_.SubmitFrame(parent_surface_id, parent_surface_frame.Pass(),
+ SurfaceFactory::DrawCallback());
+
+ test::Quad root_surface_quads[] = {
+ test::Quad::SurfaceQuad(parent_surface_id, 1.f)};
+ test::Quad root_render_pass_quads[] = {
+ test::Quad::RenderPassQuad(RenderPassId(1, 1))};
test::Pass root_passes[] = {
- test::Pass(first_quads, arraysize(first_quads), pass_id),
- test::Pass(root_quads, arraysize(root_quads))};
+ test::Pass(root_surface_quads, arraysize(root_surface_quads),
+ RenderPassId(1, 1)),
+ test::Pass(root_render_pass_quads, arraysize(root_render_pass_quads),
+ RenderPassId(2, 1))};
RenderPassList root_pass_list;
AddPasses(&root_pass_list,
@@ -1099,7 +1120,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) {
root_pass_list.at(0)
->shared_quad_state_list.front()
- ->content_to_target_transform.Translate(0, 10);
+ ->quad_to_target_transform.Translate(0, 10);
root_pass_list.at(0)->damage_rect = gfx::Rect(5, 5, 10, 10);
root_pass_list.at(1)->damage_rect = gfx::Rect(5, 5, 100, 100);
@@ -1137,7 +1158,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) {
RenderPass* child_root_pass = child_pass_list.at(0u);
SharedQuadState* child_root_pass_sqs =
child_root_pass->shared_quad_state_list.front();
- child_root_pass_sqs->content_to_target_transform.Translate(8, 0);
+ child_root_pass_sqs->quad_to_target_transform.Translate(8, 0);
child_root_pass->damage_rect = gfx::Rect(10, 10, 10, 10);
scoped_ptr<DelegatedFrameData> child_frame_data(new DelegatedFrameData);
@@ -1177,7 +1198,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) {
root_pass_list.at(0)
->shared_quad_state_list.front()
- ->content_to_target_transform.Translate(0, 10);
+ ->quad_to_target_transform.Translate(0, 10);
root_pass_list.at(0)->damage_rect = gfx::Rect(0, 0, 1, 1);
scoped_ptr<DelegatedFrameData> root_frame_data(new DelegatedFrameData);
@@ -1199,7 +1220,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) {
root_pass_list.at(0)
->shared_quad_state_list.front()
- ->content_to_target_transform.Translate(0, 10);
+ ->quad_to_target_transform.Translate(0, 10);
root_pass_list.at(0)->damage_rect = gfx::Rect(1, 1, 1, 1);
scoped_ptr<DelegatedFrameData> root_frame_data(new DelegatedFrameData);
@@ -1280,13 +1301,8 @@ class SurfaceAggregatorWithResourcesTest : public testing::Test {
output_surface_->BindToClient(&output_surface_client_);
shared_bitmap_manager_.reset(new TestSharedBitmapManager);
- resource_provider_ = ResourceProvider::Create(output_surface_.get(),
- shared_bitmap_manager_.get(),
- NULL,
- NULL,
- 0,
- false,
- 1);
+ resource_provider_ = FakeResourceProvider::Create(
+ output_surface_.get(), shared_bitmap_manager_.get());
aggregator_.reset(
new SurfaceAggregator(&manager_, resource_provider_.get()));
@@ -1320,7 +1336,7 @@ class ResourceTrackingSurfaceFactoryClient : public SurfaceFactoryClient {
DISALLOW_COPY_AND_ASSIGN(ResourceTrackingSurfaceFactoryClient);
};
-void SubmitFrameWithResources(ResourceProvider::ResourceId* resource_ids,
+void SubmitFrameWithResources(ResourceId* resource_ids,
size_t num_resource_ids,
bool valid,
SurfaceId child_id,
@@ -1356,19 +1372,10 @@ void SubmitFrameWithResources(ResourceProvider::ResourceId* resource_ids,
const float vertex_opacity[4] = {0.f, 0.f, 1.f, 1.f};
bool flipped = false;
bool nearest_neighbor = false;
- quad->SetAll(sqs,
- rect,
- opaque_rect,
- visible_rect,
- needs_blending,
- resource_ids[i],
- premultiplied_alpha,
- uv_top_left,
- uv_bottom_right,
- background_color,
- vertex_opacity,
- flipped,
- nearest_neighbor);
+ quad->SetAll(sqs, rect, opaque_rect, visible_rect, needs_blending,
+ resource_ids[i], gfx::Size(), false, premultiplied_alpha,
+ uv_top_left, uv_bottom_right, background_color, vertex_opacity,
+ flipped, nearest_neighbor);
}
frame_data->render_pass_list.push_back(pass.Pass());
scoped_ptr<CompositorFrame> frame(new CompositorFrame);
@@ -1383,7 +1390,7 @@ TEST_F(SurfaceAggregatorWithResourcesTest, TakeResourcesOneSurface) {
SurfaceId surface_id(7u);
factory.Create(surface_id);
- ResourceProvider::ResourceId ids[] = {11, 12, 13};
+ ResourceId ids[] = {11, 12, 13};
SubmitFrameWithResources(ids, arraysize(ids), true, SurfaceId(), &factory,
surface_id);
@@ -1397,7 +1404,7 @@ TEST_F(SurfaceAggregatorWithResourcesTest, TakeResourcesOneSurface) {
frame = aggregator_->Aggregate(surface_id);
ASSERT_EQ(3u, client.returned_resources().size());
- ResourceProvider::ResourceId returned_ids[3];
+ ResourceId returned_ids[3];
for (size_t i = 0; i < 3; ++i) {
returned_ids[i] = client.returned_resources()[i].id;
}
@@ -1447,10 +1454,10 @@ TEST_F(SurfaceAggregatorWithResourcesTest, TwoSurfaces) {
SurfaceId surface_id2(8u);
factory.Create(surface_id2);
- ResourceProvider::ResourceId ids[] = {11, 12, 13};
+ ResourceId ids[] = {11, 12, 13};
SubmitFrameWithResources(ids, arraysize(ids), true, SurfaceId(), &factory,
surface_id);
- ResourceProvider::ResourceId ids2[] = {14, 15, 16};
+ ResourceId ids2[] = {14, 15, 16};
SubmitFrameWithResources(ids2, arraysize(ids2), true, SurfaceId(), &factory,
surface_id2);
@@ -1465,7 +1472,7 @@ TEST_F(SurfaceAggregatorWithResourcesTest, TwoSurfaces) {
// surface_id wasn't referenced, so its resources should be returned.
ASSERT_EQ(3u, client.returned_resources().size());
- ResourceProvider::ResourceId returned_ids[3];
+ ResourceId returned_ids[3];
for (size_t i = 0; i < 3; ++i) {
returned_ids[i] = client.returned_resources()[i].id;
}
@@ -1488,15 +1495,15 @@ TEST_F(SurfaceAggregatorWithResourcesTest, InvalidChildSurface) {
SurfaceId child_surface_id(9u);
factory.Create(child_surface_id);
- ResourceProvider::ResourceId ids[] = {14, 15, 16};
+ ResourceId ids[] = {14, 15, 16};
SubmitFrameWithResources(ids, arraysize(ids), true, SurfaceId(), &factory,
child_surface_id);
- ResourceProvider::ResourceId ids2[] = {17, 18, 19};
+ ResourceId ids2[] = {17, 18, 19};
SubmitFrameWithResources(ids2, arraysize(ids2), false, child_surface_id,
&factory, middle_surface_id);
- ResourceProvider::ResourceId ids3[] = {20, 21, 22};
+ ResourceId ids3[] = {20, 21, 22};
SubmitFrameWithResources(ids3, arraysize(ids3), true, middle_surface_id,
&factory, root_surface_id);
diff --git a/chromium/cc/surfaces/surface_display_output_surface.cc b/chromium/cc/surfaces/surface_display_output_surface.cc
index e1f90da7614..e21d15d8afb 100644
--- a/chromium/cc/surfaces/surface_display_output_surface.cc
+++ b/chromium/cc/surfaces/surface_display_output_surface.cc
@@ -59,14 +59,14 @@ void SurfaceDisplayOutputSurface::SwapBuffers(CompositorFrame* frame) {
display_client_->display()->SetSurfaceId(surface_id_,
frame->metadata.device_scale_factor);
+ client_->DidSwapBuffers();
+
scoped_ptr<CompositorFrame> frame_copy(new CompositorFrame());
frame->AssignTo(frame_copy.get());
factory_.SubmitFrame(
surface_id_, frame_copy.Pass(),
base::Bind(&SurfaceDisplayOutputSurface::SwapBuffersComplete,
base::Unretained(this)));
-
- client_->DidSwapBuffers();
}
bool SurfaceDisplayOutputSurface::BindToClient(OutputSurfaceClient* client) {
diff --git a/chromium/cc/surfaces/surface_display_output_surface_unittest.cc b/chromium/cc/surfaces/surface_display_output_surface_unittest.cc
index ed801e91474..922dd9e8d5f 100644
--- a/chromium/cc/surfaces/surface_display_output_surface_unittest.cc
+++ b/chromium/cc/surfaces/surface_display_output_surface_unittest.cc
@@ -47,7 +47,8 @@ class FakeOnscreenDisplayClient : public OnscreenDisplayClient {
class SurfaceDisplayOutputSurfaceTest : public testing::Test {
public:
SurfaceDisplayOutputSurfaceTest()
- : task_runner_(new OrderedSimpleTaskRunner()),
+ : now_src_(new base::SimpleTestTickClock()),
+ task_runner_(new OrderedSimpleTaskRunner(now_src_.get(), true)),
allocator_(0),
display_size_(1920, 1080),
display_rect_(display_size_),
@@ -98,6 +99,7 @@ class SurfaceDisplayOutputSurfaceTest : public testing::Test {
}
protected:
+ scoped_ptr<base::SimpleTestTickClock> now_src_;
scoped_refptr<OrderedSimpleTaskRunner> task_runner_;
SurfaceIdAllocator allocator_;
@@ -130,6 +132,21 @@ TEST_F(SurfaceDisplayOutputSurfaceTest, NoDamageDoesNotTriggerSwapBuffers) {
EXPECT_EQ(1u, output_surface_->num_sent_frames());
}
+TEST_F(SurfaceDisplayOutputSurfaceTest, SuspendedDoesNotTriggerSwapBuffers) {
+ SwapBuffersWithDamage(display_rect_);
+ EXPECT_EQ(1u, output_surface_->num_sent_frames());
+ output_surface_->set_suspended_for_recycle(true);
+ task_runner_->RunUntilIdle();
+ EXPECT_EQ(1u, output_surface_->num_sent_frames());
+ SwapBuffersWithDamage(display_rect_);
+ task_runner_->RunUntilIdle();
+ EXPECT_EQ(1u, output_surface_->num_sent_frames());
+ output_surface_->set_suspended_for_recycle(false);
+ SwapBuffersWithDamage(display_rect_);
+ task_runner_->RunUntilIdle();
+ EXPECT_EQ(2u, output_surface_->num_sent_frames());
+}
+
TEST_F(SurfaceDisplayOutputSurfaceTest,
LockingResourcesDoesNotIndirectlyCauseDamage) {
surface_display_output_surface_.ForceReclaimResources();
diff --git a/chromium/cc/surfaces/surface_factory_unittest.cc b/chromium/cc/surfaces/surface_factory_unittest.cc
index b9c6bf5c207..c2951aead48 100644
--- a/chromium/cc/surfaces/surface_factory_unittest.cc
+++ b/chromium/cc/surfaces/surface_factory_unittest.cc
@@ -5,6 +5,7 @@
#include "base/bind.h"
#include "cc/output/compositor_frame.h"
#include "cc/output/delegated_frame_data.h"
+#include "cc/resources/resource_provider.h"
#include "cc/surfaces/surface.h"
#include "cc/surfaces/surface_factory.h"
#include "cc/surfaces/surface_factory_client.h"
@@ -48,7 +49,7 @@ class SurfaceFactoryTest : public testing::Test {
factory_.Destroy(surface_id_);
}
- void SubmitFrameWithResources(ResourceProvider::ResourceId* resource_ids,
+ void SubmitFrameWithResources(ResourceId* resource_ids,
size_t num_resource_ids) {
scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData);
for (size_t i = 0u; i < num_resource_ids; ++i) {
@@ -63,7 +64,7 @@ class SurfaceFactoryTest : public testing::Test {
SurfaceFactory::DrawCallback());
}
- void UnrefResources(ResourceProvider::ResourceId* ids_to_unref,
+ void UnrefResources(ResourceId* ids_to_unref,
int* counts_to_unref,
size_t num_ids_to_unref) {
ReturnedResourceArray unref_array;
@@ -76,10 +77,9 @@ class SurfaceFactoryTest : public testing::Test {
factory_.UnrefResources(unref_array);
}
- void CheckReturnedResourcesMatchExpected(
- ResourceProvider::ResourceId* expected_returned_ids,
- int* expected_returned_counts,
- size_t expected_resources) {
+ void CheckReturnedResourcesMatchExpected(ResourceId* expected_returned_ids,
+ int* expected_returned_counts,
+ size_t expected_resources) {
const ReturnedResourceArray& actual_resources =
client_.returned_resources();
ASSERT_EQ(expected_resources, actual_resources.size());
@@ -107,7 +107,7 @@ class SurfaceFactoryTest : public testing::Test {
// Tests submitting a frame with resources followed by one with no resources
// with no resource provider action in between.
TEST_F(SurfaceFactoryTest, ResourceLifetimeSimple) {
- ResourceProvider::ResourceId first_frame_ids[] = {1, 2, 3};
+ ResourceId first_frame_ids[] = {1, 2, 3};
SubmitFrameWithResources(first_frame_ids, arraysize(first_frame_ids));
// All of the resources submitted in the first frame are still in use at this
@@ -120,7 +120,7 @@ TEST_F(SurfaceFactoryTest, ResourceLifetimeSimple) {
// available to be returned.
SubmitFrameWithResources(NULL, 0);
- ResourceProvider::ResourceId expected_returned_ids[] = {1, 2, 3};
+ ResourceId expected_returned_ids[] = {1, 2, 3};
int expected_returned_counts[] = {1, 1, 1};
CheckReturnedResourcesMatchExpected(expected_returned_ids,
expected_returned_counts,
@@ -130,7 +130,7 @@ TEST_F(SurfaceFactoryTest, ResourceLifetimeSimple) {
// Tests submitting a frame with resources followed by one with no resources
// with the resource provider holding everything alive.
TEST_F(SurfaceFactoryTest, ResourceLifetimeSimpleWithProviderHoldingAlive) {
- ResourceProvider::ResourceId first_frame_ids[] = {1, 2, 3};
+ ResourceId first_frame_ids[] = {1, 2, 3};
SubmitFrameWithResources(first_frame_ids, arraysize(first_frame_ids));
// All of the resources submitted in the first frame are still in use at this
@@ -152,7 +152,7 @@ TEST_F(SurfaceFactoryTest, ResourceLifetimeSimpleWithProviderHoldingAlive) {
int release_counts[] = {1, 1, 1};
UnrefResources(first_frame_ids, release_counts, arraysize(first_frame_ids));
- ResourceProvider::ResourceId expected_returned_ids[] = {1, 2, 3};
+ ResourceId expected_returned_ids[] = {1, 2, 3};
int expected_returned_counts[] = {1, 1, 1};
CheckReturnedResourcesMatchExpected(expected_returned_ids,
expected_returned_counts,
@@ -162,7 +162,7 @@ TEST_F(SurfaceFactoryTest, ResourceLifetimeSimpleWithProviderHoldingAlive) {
// Tests referencing a resource, unref'ing it to zero, then using it again
// before returning it to the client.
TEST_F(SurfaceFactoryTest, ResourceReusedBeforeReturn) {
- ResourceProvider::ResourceId first_frame_ids[] = {7};
+ ResourceId first_frame_ids[] = {7};
SubmitFrameWithResources(first_frame_ids, arraysize(first_frame_ids));
// This removes all references to resource id 7.
@@ -189,14 +189,14 @@ TEST_F(SurfaceFactoryTest, ResourceReusedBeforeReturn) {
// Tests having resources referenced multiple times, as if referenced by
// multiple providers.
TEST_F(SurfaceFactoryTest, ResourceRefMultipleTimes) {
- ResourceProvider::ResourceId first_frame_ids[] = {3, 4};
+ ResourceId first_frame_ids[] = {3, 4};
SubmitFrameWithResources(first_frame_ids, arraysize(first_frame_ids));
// Ref resources from the first frame twice.
RefCurrentFrameResources();
RefCurrentFrameResources();
- ResourceProvider::ResourceId second_frame_ids[] = {4, 5};
+ ResourceId second_frame_ids[] = {4, 5};
SubmitFrameWithResources(second_frame_ids, arraysize(second_frame_ids));
// Ref resources from the second frame 3 times.
@@ -217,7 +217,7 @@ TEST_F(SurfaceFactoryTest, ResourceRefMultipleTimes) {
// 5 -> 3
{
SCOPED_TRACE("unref all 3");
- ResourceProvider::ResourceId ids_to_unref[] = {3, 4, 5};
+ ResourceId ids_to_unref[] = {3, 4, 5};
int counts[] = {1, 1, 1};
UnrefResources(ids_to_unref, counts, arraysize(ids_to_unref));
@@ -226,7 +226,7 @@ TEST_F(SurfaceFactoryTest, ResourceRefMultipleTimes) {
UnrefResources(ids_to_unref, counts, arraysize(ids_to_unref));
- ResourceProvider::ResourceId expected_returned_ids[] = {3};
+ ResourceId expected_returned_ids[] = {3};
int expected_returned_counts[] = {1};
CheckReturnedResourcesMatchExpected(expected_returned_ids,
expected_returned_counts,
@@ -238,11 +238,11 @@ TEST_F(SurfaceFactoryTest, ResourceRefMultipleTimes) {
// 5 -> 1
{
SCOPED_TRACE("unref 4 and 5");
- ResourceProvider::ResourceId ids_to_unref[] = {4, 5};
+ ResourceId ids_to_unref[] = {4, 5};
int counts[] = {1, 1};
UnrefResources(ids_to_unref, counts, arraysize(ids_to_unref));
- ResourceProvider::ResourceId expected_returned_ids[] = {5};
+ ResourceId expected_returned_ids[] = {5};
int expected_returned_counts[] = {1};
CheckReturnedResourcesMatchExpected(expected_returned_ids,
expected_returned_counts,
@@ -253,11 +253,11 @@ TEST_F(SurfaceFactoryTest, ResourceRefMultipleTimes) {
// the returned count is correct.
{
SCOPED_TRACE("unref only 4");
- ResourceProvider::ResourceId ids_to_unref[] = {4};
+ ResourceId ids_to_unref[] = {4};
int counts[] = {2};
UnrefResources(ids_to_unref, counts, arraysize(ids_to_unref));
- ResourceProvider::ResourceId expected_returned_ids[] = {4};
+ ResourceId expected_returned_ids[] = {4};
int expected_returned_counts[] = {2};
CheckReturnedResourcesMatchExpected(expected_returned_ids,
expected_returned_counts,
@@ -266,7 +266,7 @@ TEST_F(SurfaceFactoryTest, ResourceRefMultipleTimes) {
}
TEST_F(SurfaceFactoryTest, ResourceLifetime) {
- ResourceProvider::ResourceId first_frame_ids[] = {1, 2, 3};
+ ResourceId first_frame_ids[] = {1, 2, 3};
SubmitFrameWithResources(first_frame_ids, arraysize(first_frame_ids));
// All of the resources submitted in the first frame are still in use at this
@@ -278,12 +278,12 @@ TEST_F(SurfaceFactoryTest, ResourceLifetime) {
// The second frame references some of the same resources, but some different
// ones. We expect to receive back resource 1 with a count of 1 since it was
// only referenced by the first frame.
- ResourceProvider::ResourceId second_frame_ids[] = {2, 3, 4};
+ ResourceId second_frame_ids[] = {2, 3, 4};
SubmitFrameWithResources(second_frame_ids, arraysize(second_frame_ids));
{
SCOPED_TRACE("second frame");
- ResourceProvider::ResourceId expected_returned_ids[] = {1};
+ ResourceId expected_returned_ids[] = {1};
int expected_returned_counts[] = {1};
CheckReturnedResourcesMatchExpected(expected_returned_ids,
expected_returned_counts,
@@ -294,12 +294,12 @@ TEST_F(SurfaceFactoryTest, ResourceLifetime) {
// receive back all resources from the first and second frames. Resource IDs 2
// and 3 will have counts of 2, since they were used in both frames, and
// resource ID 4 will have a count of 1.
- ResourceProvider::ResourceId third_frame_ids[] = {10, 11, 12, 13};
+ ResourceId third_frame_ids[] = {10, 11, 12, 13};
SubmitFrameWithResources(third_frame_ids, arraysize(third_frame_ids));
{
SCOPED_TRACE("third frame");
- ResourceProvider::ResourceId expected_returned_ids[] = {2, 3, 4};
+ ResourceId expected_returned_ids[] = {2, 3, 4};
int expected_returned_counts[] = {2, 2, 1};
CheckReturnedResourcesMatchExpected(expected_returned_ids,
expected_returned_counts,
@@ -309,7 +309,7 @@ TEST_F(SurfaceFactoryTest, ResourceLifetime) {
// Simulate a ResourceProvider taking a ref on all of the resources.
RefCurrentFrameResources();
- ResourceProvider::ResourceId fourth_frame_ids[] = {12, 13};
+ ResourceId fourth_frame_ids[] = {12, 13};
SubmitFrameWithResources(fourth_frame_ids, arraysize(fourth_frame_ids));
EXPECT_EQ(0u, client_.returned_resources().size());
@@ -323,14 +323,14 @@ TEST_F(SurfaceFactoryTest, ResourceLifetime) {
// Release resources associated with the first RefCurrentFrameResources() call
// first.
{
- ResourceProvider::ResourceId ids_to_unref[] = {10, 11, 12, 13};
+ ResourceId ids_to_unref[] = {10, 11, 12, 13};
int counts[] = {1, 1, 1, 1};
UnrefResources(ids_to_unref, counts, arraysize(ids_to_unref));
}
{
SCOPED_TRACE("fourth frame, first unref");
- ResourceProvider::ResourceId expected_returned_ids[] = {10, 11};
+ ResourceId expected_returned_ids[] = {10, 11};
int expected_returned_counts[] = {1, 1};
CheckReturnedResourcesMatchExpected(expected_returned_ids,
expected_returned_counts,
@@ -338,7 +338,7 @@ TEST_F(SurfaceFactoryTest, ResourceLifetime) {
}
{
- ResourceProvider::ResourceId ids_to_unref[] = {12, 13};
+ ResourceId ids_to_unref[] = {12, 13};
int counts[] = {1, 1};
UnrefResources(ids_to_unref, counts, arraysize(ids_to_unref));
}
@@ -352,7 +352,7 @@ TEST_F(SurfaceFactoryTest, ResourceLifetime) {
{
SCOPED_TRACE("fourth frame, second unref");
- ResourceProvider::ResourceId expected_returned_ids[] = {12, 13};
+ ResourceId expected_returned_ids[] = {12, 13};
int expected_returned_counts[] = {2, 2};
CheckReturnedResourcesMatchExpected(expected_returned_ids,
expected_returned_counts,
@@ -410,6 +410,8 @@ TEST_F(SurfaceFactoryTest, DestroySequence) {
SurfaceId id2(5);
factory_.Create(id2);
+ manager_.RegisterSurfaceIdNamespace(0);
+
// Check that waiting before the sequence is satisfied works.
manager_.GetSurfaceForId(id2)
->AddDestructionDependency(SurfaceSequence(0, 4));
@@ -434,5 +436,77 @@ TEST_F(SurfaceFactoryTest, DestroySequence) {
DCHECK(!manager_.GetSurfaceForId(id2));
}
+// Tests that Surface ID namespace invalidation correctly allows
+// Sequences to be ignored.
+TEST_F(SurfaceFactoryTest, InvalidIdNamespace) {
+ uint32_t id_namespace = 9u;
+ SurfaceId id(5);
+ factory_.Create(id);
+
+ manager_.RegisterSurfaceIdNamespace(id_namespace);
+ manager_.GetSurfaceForId(id)
+ ->AddDestructionDependency(SurfaceSequence(id_namespace, 4));
+ factory_.Destroy(id);
+
+ // Verify the dependency has prevented the surface from getting destroyed.
+ EXPECT_TRUE(manager_.GetSurfaceForId(id));
+
+ manager_.InvalidateSurfaceIdNamespace(id_namespace);
+
+ // Verify that the invalidated namespace caused the unsatisfied sequence
+ // to be ignored.
+ EXPECT_FALSE(manager_.GetSurfaceForId(id));
+}
+
+TEST_F(SurfaceFactoryTest, DestroyCycle) {
+ SurfaceId id2(5);
+ factory_.Create(id2);
+
+ manager_.RegisterSurfaceIdNamespace(0);
+
+ manager_.GetSurfaceForId(id2)
+ ->AddDestructionDependency(SurfaceSequence(0, 4));
+
+ // Give id2 a frame that references surface_id_.
+ {
+ scoped_ptr<RenderPass> render_pass(RenderPass::Create());
+ render_pass->referenced_surfaces.push_back(surface_id_);
+ scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData);
+ frame_data->render_pass_list.push_back(render_pass.Pass());
+ scoped_ptr<CompositorFrame> frame(new CompositorFrame);
+ frame->delegated_frame_data = frame_data.Pass();
+ factory_.SubmitFrame(id2, frame.Pass(), SurfaceFactory::DrawCallback());
+ }
+ factory_.Destroy(id2);
+
+ // Give surface_id_ a frame that references id2.
+ {
+ scoped_ptr<RenderPass> render_pass(RenderPass::Create());
+ render_pass->referenced_surfaces.push_back(id2);
+ scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData);
+ frame_data->render_pass_list.push_back(render_pass.Pass());
+ scoped_ptr<CompositorFrame> frame(new CompositorFrame);
+ frame->delegated_frame_data = frame_data.Pass();
+ factory_.SubmitFrame(surface_id_, frame.Pass(),
+ SurfaceFactory::DrawCallback());
+ }
+ factory_.Destroy(surface_id_);
+ EXPECT_TRUE(manager_.GetSurfaceForId(id2));
+ // surface_id_ should be retained by reference from id2.
+ EXPECT_TRUE(manager_.GetSurfaceForId(surface_id_));
+
+ // Satisfy last destruction dependency for id2.
+ std::vector<uint32_t> to_satisfy;
+ to_satisfy.push_back(4);
+ manager_.DidSatisfySequences(0, &to_satisfy);
+
+ // id2 and surface_id_ are in a reference cycle that has no surface
+ // sequences holding on to it, so they should be destroyed.
+ EXPECT_TRUE(!manager_.GetSurfaceForId(id2));
+ EXPECT_TRUE(!manager_.GetSurfaceForId(surface_id_));
+
+ surface_id_ = SurfaceId();
+}
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/surfaces/surface_id_allocator.cc b/chromium/cc/surfaces/surface_id_allocator.cc
index af9e91bd5c2..04f60d9fad7 100644
--- a/chromium/cc/surfaces/surface_id_allocator.cc
+++ b/chromium/cc/surfaces/surface_id_allocator.cc
@@ -4,10 +4,23 @@
#include "cc/surfaces/surface_id_allocator.h"
+#include "cc/surfaces/surface_manager.h"
+
namespace cc {
SurfaceIdAllocator::SurfaceIdAllocator(uint32_t id_namespace)
- : id_namespace_(id_namespace), next_id_(1u) {
+ : id_namespace_(id_namespace), next_id_(1u), manager_(nullptr) {
+}
+
+void SurfaceIdAllocator::RegisterSurfaceIdNamespace(SurfaceManager* manager) {
+ DCHECK(!manager_);
+ manager_ = manager;
+ manager_->RegisterSurfaceIdNamespace(id_namespace_);
+}
+
+SurfaceIdAllocator::~SurfaceIdAllocator() {
+ if (manager_)
+ manager_->InvalidateSurfaceIdNamespace(id_namespace_);
}
SurfaceId SurfaceIdAllocator::GenerateId() {
diff --git a/chromium/cc/surfaces/surface_id_allocator.h b/chromium/cc/surfaces/surface_id_allocator.h
index 96a241f299f..31b1e8717d1 100644
--- a/chromium/cc/surfaces/surface_id_allocator.h
+++ b/chromium/cc/surfaces/surface_id_allocator.h
@@ -10,22 +10,34 @@
namespace cc {
+class SurfaceManager;
+
// This is a helper class for generating surface IDs within a specified
// namespace. This is not threadsafe, to use from multiple threads wrap this
// class in a mutex.
class CC_SURFACES_EXPORT SurfaceIdAllocator {
public:
explicit SurfaceIdAllocator(uint32_t id_namespace);
+ ~SurfaceIdAllocator();
SurfaceId GenerateId();
static uint32_t NamespaceForId(SurfaceId id);
+ // This needs to be called before any sequences with this allocator's
+ // namespace will be used to enforce destruction dependencies.
+ // When this SurfaceIdAllocator is destroyed, its namespace is
+ // automatically invalidated and any remaining sequences with that
+ // namespace will be ignored. This method does not need to be called in
+ // contexts where there is no SurfaceManager (e.g. a renderer process).
+ void RegisterSurfaceIdNamespace(SurfaceManager* manager);
+
uint32_t id_namespace() const { return id_namespace_; }
private:
const uint32_t id_namespace_;
uint32_t next_id_;
+ SurfaceManager* manager_;
DISALLOW_COPY_AND_ASSIGN(SurfaceIdAllocator);
};
diff --git a/chromium/cc/surfaces/surface_manager.cc b/chromium/cc/surfaces/surface_manager.cc
index 117d82ab659..9ced46e41ba 100644
--- a/chromium/cc/surfaces/surface_manager.cc
+++ b/chromium/cc/surfaces/surface_manager.cc
@@ -40,8 +40,9 @@ void SurfaceManager::DeregisterSurface(SurfaceId surface_id) {
void SurfaceManager::Destroy(scoped_ptr<Surface> surface) {
DCHECK(thread_checker_.CalledOnValidThread());
+ surface->set_destroyed(true);
surfaces_to_destroy_.push_back(surface.release());
- SearchForSatisfaction();
+ GarbageCollectSurfaces();
}
void SurfaceManager::DidSatisfySequences(uint32_t id_namespace,
@@ -53,14 +54,60 @@ void SurfaceManager::DidSatisfySequences(uint32_t id_namespace,
satisfied_sequences_.insert(SurfaceSequence(id_namespace, *it));
}
sequence->clear();
- SearchForSatisfaction();
+ GarbageCollectSurfaces();
}
-void SurfaceManager::SearchForSatisfaction() {
+void SurfaceManager::RegisterSurfaceIdNamespace(uint32_t id_namespace) {
+ bool inserted = valid_surface_id_namespaces_.insert(id_namespace).second;
+ DCHECK(inserted);
+}
+
+void SurfaceManager::InvalidateSurfaceIdNamespace(uint32_t id_namespace) {
+ valid_surface_id_namespaces_.erase(id_namespace);
+ GarbageCollectSurfaces();
+}
+
+void SurfaceManager::GarbageCollectSurfaces() {
+ // Simple mark and sweep GC.
+ // TODO(jbauman): Reduce the amount of work when nothing needs to be
+ // destroyed.
+ std::vector<SurfaceId> live_surfaces;
+ std::set<SurfaceId> live_surfaces_set;
+
+ // GC roots are surfaces that have not been destroyed, or have not had all
+ // their destruction dependencies satisfied.
+ for (auto& map_entry : surface_map_) {
+ map_entry.second->SatisfyDestructionDependencies(
+ &satisfied_sequences_, &valid_surface_id_namespaces_);
+ if (!map_entry.second->destroyed() ||
+ map_entry.second->GetDestructionDependencyCount()) {
+ live_surfaces_set.insert(map_entry.first);
+ live_surfaces.push_back(map_entry.first);
+ }
+ }
+
+ // Mark all surfaces reachable from live surfaces by adding them to
+ // live_surfaces and live_surfaces_set.
+ for (size_t i = 0; i < live_surfaces.size(); i++) {
+ Surface* surf = surface_map_[live_surfaces[i]];
+ DCHECK(surf);
+
+ for (SurfaceId id : surf->referenced_surfaces()) {
+ if (live_surfaces_set.count(id))
+ continue;
+
+ Surface* surf2 = GetSurfaceForId(id);
+ if (surf2) {
+ live_surfaces.push_back(id);
+ live_surfaces_set.insert(id);
+ }
+ }
+ }
+
+ // Destroy all remaining unreachable surfaces.
for (SurfaceDestroyList::iterator dest_it = surfaces_to_destroy_.begin();
dest_it != surfaces_to_destroy_.end();) {
- (*dest_it)->SatisfyDestructionDependencies(&satisfied_sequences_);
- if (!(*dest_it)->GetDestructionDependencyCount()) {
+ if (!live_surfaces_set.count((*dest_it)->surface_id())) {
scoped_ptr<Surface> surf(*dest_it);
DeregisterSurface(surf->surface_id());
dest_it = surfaces_to_destroy_.erase(dest_it);
diff --git a/chromium/cc/surfaces/surface_manager.h b/chromium/cc/surfaces/surface_manager.h
index d7d78c42e28..8430ea619ab 100644
--- a/chromium/cc/surfaces/surface_manager.h
+++ b/chromium/cc/surfaces/surface_manager.h
@@ -49,12 +49,18 @@ class CC_SURFACES_EXPORT SurfaceManager {
void DidSatisfySequences(uint32_t id_namespace,
std::vector<uint32_t>* sequence);
+ void RegisterSurfaceIdNamespace(uint32_t id_namespace);
+
+ // Invalidate a namespace that might still have associated sequences,
+ // possibly because a renderer process has crashed.
+ void InvalidateSurfaceIdNamespace(uint32_t id_namespace);
+
private:
- void SearchForSatisfaction();
+ void GarbageCollectSurfaces();
typedef base::hash_map<SurfaceId, Surface*> SurfaceMap;
SurfaceMap surface_map_;
- ObserverList<SurfaceDamageObserver> observer_list_;
+ base::ObserverList<SurfaceDamageObserver> observer_list_;
base::ThreadChecker thread_checker_;
// List of surfaces to be destroyed, along with what sequences they're still
@@ -66,6 +72,11 @@ class CC_SURFACES_EXPORT SurfaceManager {
// waited on.
base::hash_set<SurfaceSequence> satisfied_sequences_;
+ // Set of valid surface ID namespaces. When a namespace is removed from
+ // this set, any remaining sequences with that namespace are considered
+ // satisfied.
+ base::hash_set<uint32_t> valid_surface_id_namespaces_;
+
DISALLOW_COPY_AND_ASSIGN(SurfaceManager);
};
diff --git a/chromium/cc/surfaces/surface_resource_holder.cc b/chromium/cc/surfaces/surface_resource_holder.cc
index 50d31a584ee..c257b6082eb 100644
--- a/chromium/cc/surfaces/surface_resource_holder.cc
+++ b/chromium/cc/surfaces/surface_resource_holder.cc
@@ -49,7 +49,7 @@ void SurfaceResourceHolder::UnrefResources(
for (ReturnedResourceArray::const_iterator it = resources.begin();
it != resources.end();
++it) {
- ResourceProvider::ResourceId id = it->id;
+ unsigned id = it->id;
ResourceIdCountMap::iterator count_it = resource_id_use_count_map_.find(id);
if (count_it == resource_id_use_count_map_.end())
continue;
diff --git a/chromium/cc/surfaces/surface_resource_holder.h b/chromium/cc/surfaces/surface_resource_holder.h
index 20c9f291848..95cdb827c07 100644
--- a/chromium/cc/surfaces/surface_resource_holder.h
+++ b/chromium/cc/surfaces/surface_resource_holder.h
@@ -7,8 +7,9 @@
#include "base/containers/hash_tables.h"
#include "base/macros.h"
-#include "cc/resources/resource_provider.h"
+#include "cc/base/resource_id.h"
#include "cc/resources/returned_resource.h"
+#include "cc/resources/transferable_resource.h"
#include "cc/surfaces/surfaces_export.h"
namespace cc {
@@ -39,8 +40,7 @@ class CC_SURFACES_EXPORT SurfaceResourceHolder {
// Keeps track of the number of users currently in flight for each resource
// ID we've received from the client. When this counter hits zero for a
// particular resource, that ID is available to return to the client.
- typedef base::hash_map<ResourceProvider::ResourceId, ResourceRefs>
- ResourceIdCountMap;
+ typedef base::hash_map<ResourceId, ResourceRefs> ResourceIdCountMap;
ResourceIdCountMap resource_id_use_count_map_;
DISALLOW_COPY_AND_ASSIGN(SurfaceResourceHolder);
diff --git a/chromium/cc/surfaces/surfaces_pixeltest.cc b/chromium/cc/surfaces/surfaces_pixeltest.cc
index 528684b2c85..bf8ad57fb91 100644
--- a/chromium/cc/surfaces/surfaces_pixeltest.cc
+++ b/chromium/cc/surfaces/surfaces_pixeltest.cc
@@ -41,21 +41,15 @@ SharedQuadState* CreateAndAppendTestSharedQuadState(
RenderPass* render_pass,
const gfx::Transform& transform,
const gfx::Size& size) {
- const gfx::Size content_bounds = size;
- const gfx::Rect visible_content_rect = gfx::Rect(size);
+ const gfx::Size layer_bounds = size;
+ const gfx::Rect visible_layer_rect = gfx::Rect(size);
const gfx::Rect clip_rect = gfx::Rect(size);
bool is_clipped = false;
float opacity = 1.f;
const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState();
- shared_state->SetAll(transform,
- content_bounds,
- visible_content_rect,
- clip_rect,
- is_clipped,
- opacity,
- blend_mode,
- 0);
+ shared_state->SetAll(transform, layer_bounds, visible_layer_rect, clip_rect,
+ is_clipped, opacity, blend_mode, 0);
return shared_state;
}
diff --git a/chromium/cc/tiles/layer_tiling_data.cc b/chromium/cc/tiles/layer_tiling_data.cc
deleted file mode 100644
index 494ded8456d..00000000000
--- a/chromium/cc/tiles/layer_tiling_data.cc
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/tiles/layer_tiling_data.h"
-
-#include <vector>
-
-#include "base/logging.h"
-#include "cc/base/region.h"
-#include "cc/base/simple_enclosed_region.h"
-
-namespace cc {
-
-scoped_ptr<LayerTilingData> LayerTilingData::Create(const gfx::Size& tile_size,
- BorderTexelOption border) {
- return make_scoped_ptr(new LayerTilingData(tile_size, border));
-}
-
-LayerTilingData::LayerTilingData(const gfx::Size& tile_size,
- BorderTexelOption border)
- : tiling_data_(tile_size, gfx::Size(), border == HAS_BORDER_TEXELS) {
- SetTileSize(tile_size);
-}
-
-LayerTilingData::~LayerTilingData() {}
-
-void LayerTilingData::SetTileSize(const gfx::Size& size) {
- if (tile_size() == size)
- return;
-
- reset();
-
- tiling_data_.SetMaxTextureSize(size);
-}
-
-gfx::Size LayerTilingData::tile_size() const {
- return tiling_data_.max_texture_size();
-}
-
-void LayerTilingData::SetBorderTexelOption(
- BorderTexelOption border_texel_option) {
- bool border_texels = border_texel_option == HAS_BORDER_TEXELS;
- if (has_border_texels() == border_texels)
- return;
-
- reset();
- tiling_data_.SetHasBorderTexels(border_texels);
-}
-
-const LayerTilingData& LayerTilingData::operator=
- (const LayerTilingData & tiler) {
- tiling_data_ = tiler.tiling_data_;
-
- return *this;
-}
-
-void LayerTilingData::AddTile(scoped_ptr<Tile> tile, int i, int j) {
- DCHECK(!TileAt(i, j));
- tile->move_to(i, j);
- tiles_.add(std::make_pair(i, j), tile.Pass());
-}
-
-scoped_ptr<LayerTilingData::Tile> LayerTilingData::TakeTile(int i, int j) {
- return tiles_.take_and_erase(std::make_pair(i, j));
-}
-
-LayerTilingData::Tile* LayerTilingData::TileAt(int i, int j) const {
- return tiles_.get(std::make_pair(i, j));
-}
-
-void LayerTilingData::ContentRectToTileIndices(const gfx::Rect& content_rect,
- int* left,
- int* top,
- int* right,
- int* bottom) const {
- // An empty rect doesn't result in an empty set of tiles, so don't pass an
- // empty rect.
- // TODO(enne): Possibly we should fill a vector of tiles instead, since the
- // normal use of this function is to enumerate some tiles.
- DCHECK(!content_rect.IsEmpty());
-
- *left = tiling_data_.TileXIndexFromSrcCoord(content_rect.x());
- *top = tiling_data_.TileYIndexFromSrcCoord(content_rect.y());
- *right = tiling_data_.TileXIndexFromSrcCoord(content_rect.right() - 1);
- *bottom = tiling_data_.TileYIndexFromSrcCoord(content_rect.bottom() - 1);
-}
-
-gfx::Rect LayerTilingData::TileRect(const Tile* tile) const {
- gfx::Rect tile_rect = tiling_data_.TileBoundsWithBorder(tile->i(), tile->j());
- tile_rect.set_size(tile_size());
- return tile_rect;
-}
-
-void LayerTilingData::SetTilingSize(const gfx::Size& tiling_size) {
- tiling_data_.SetTilingSize(tiling_size);
- if (tiling_size.IsEmpty()) {
- tiles_.clear();
- return;
- }
-
- // Any tiles completely outside our new bounds are invalid and should be
- // dropped.
- int left, top, right, bottom;
- ContentRectToTileIndices(
- gfx::Rect(tiling_size), &left, &top, &right, &bottom);
- std::vector<TileMapKey> invalid_tile_keys;
- for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
- if (it->first.first > right || it->first.second > bottom)
- invalid_tile_keys.push_back(it->first);
- }
- for (size_t i = 0; i < invalid_tile_keys.size(); ++i)
- tiles_.erase(invalid_tile_keys[i]);
-}
-
-} // namespace cc
diff --git a/chromium/cc/tiles/layer_tiling_data.h b/chromium/cc/tiles/layer_tiling_data.h
deleted file mode 100644
index 5e944a569bf..00000000000
--- a/chromium/cc/tiles/layer_tiling_data.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_TILES_LAYER_TILING_DATA_H_
-#define CC_TILES_LAYER_TILING_DATA_H_
-
-#include <utility>
-
-#include "base/basictypes.h"
-#include "base/containers/hash_tables.h"
-#include "base/containers/scoped_ptr_hash_map.h"
-#include "base/memory/scoped_ptr.h"
-#include "cc/base/cc_export.h"
-#include "cc/base/simple_enclosed_region.h"
-#include "cc/base/tiling_data.h"
-#include "ui/gfx/geometry/rect.h"
-
-namespace cc {
-
-class CC_EXPORT LayerTilingData {
- public:
- enum BorderTexelOption {
- HAS_BORDER_TEXELS,
- NO_BORDER_TEXELS
- };
-
- ~LayerTilingData();
-
- static scoped_ptr<LayerTilingData> Create(const gfx::Size& tile_size,
- BorderTexelOption option);
-
- bool has_empty_bounds() const { return tiling_data_.has_empty_bounds(); }
- int num_tiles_x() const { return tiling_data_.num_tiles_x(); }
- int num_tiles_y() const { return tiling_data_.num_tiles_y(); }
- gfx::Rect tile_bounds(int i, int j) const {
- return tiling_data_.TileBounds(i, j);
- }
- gfx::Vector2d texture_offset(int x_index, int y_index) const {
- return tiling_data_.TextureOffset(x_index, y_index);
- }
-
- // Change the tile size. This may invalidate all the existing tiles.
- void SetTileSize(const gfx::Size& size);
- gfx::Size tile_size() const;
- // Change the border texel setting. This may invalidate all existing tiles.
- void SetBorderTexelOption(BorderTexelOption option);
- bool has_border_texels() const { return !!tiling_data_.border_texels(); }
-
- bool is_empty() const { return has_empty_bounds() || !tiles().size(); }
-
- const LayerTilingData& operator=(const LayerTilingData&);
-
- class Tile {
- public:
- Tile() : i_(-1), j_(-1) {}
- virtual ~Tile() {}
-
- int i() const { return i_; }
- int j() const { return j_; }
- void move_to(int i, int j) {
- i_ = i;
- j_ = j;
- }
-
- private:
- int i_;
- int j_;
- DISALLOW_COPY_AND_ASSIGN(Tile);
- };
- typedef std::pair<int, int> TileMapKey;
- typedef base::ScopedPtrHashMap<TileMapKey, scoped_ptr<Tile>> TileMap;
-
- void AddTile(scoped_ptr<Tile> tile, int i, int j);
- scoped_ptr<Tile> TakeTile(int i, int j);
- Tile* TileAt(int i, int j) const;
- const TileMap& tiles() const { return tiles_; }
-
- void SetTilingSize(const gfx::Size& tiling_size);
- gfx::Size tiling_size() const { return tiling_data_.tiling_size(); }
-
- void ContentRectToTileIndices(const gfx::Rect& rect,
- int* left,
- int* top,
- int* right,
- int* bottom) const;
- gfx::Rect TileRect(const Tile* tile) const;
-
- void reset() { tiles_.clear(); }
-
- protected:
- LayerTilingData(const gfx::Size& tile_size, BorderTexelOption option);
-
- TileMap tiles_;
- TilingData tiling_data_;
-
- DISALLOW_COPY(LayerTilingData);
-};
-
-} // namespace cc
-
-#endif // CC_TILES_LAYER_TILING_DATA_H_
diff --git a/chromium/cc/tiles/picture_layer_tiling.cc b/chromium/cc/tiles/picture_layer_tiling.cc
index c585e559e8b..ef31f58256b 100644
--- a/chromium/cc/tiles/picture_layer_tiling.cc
+++ b/chromium/cc/tiles/picture_layer_tiling.cc
@@ -9,7 +9,10 @@
#include <limits>
#include <set>
+#include "base/containers/hash_tables.h"
+#include "base/containers/small_map.h"
#include "base/logging.h"
+#include "base/numerics/safe_conversions.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"
#include "cc/base/math_util.h"
@@ -67,7 +70,8 @@ PictureLayerTiling::PictureLayerTiling(
has_visible_rect_tiles_(false),
has_skewport_rect_tiles_(false),
has_soon_border_rect_tiles_(false),
- has_eventually_rect_tiles_(false) {
+ has_eventually_rect_tiles_(false),
+ all_tiles_done_(true) {
DCHECK(!raster_source->IsSolidColor());
gfx::Size content_bounds = gfx::ToCeiledSize(
gfx::ScaleSize(raster_source_->GetSize(), contents_scale));
@@ -108,6 +112,7 @@ Tile* PictureLayerTiling::CreateTile(int i, int j) {
if (!raster_source_->CoversRect(tile_rect, contents_scale_))
return nullptr;
+ all_tiles_done_ = false;
ScopedTilePtr tile = client_->CreateTile(contents_scale_, tile_rect);
Tile* raw_ptr = tile.get();
tile->set_tiling_index(i, j);
@@ -120,13 +125,13 @@ void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() {
for (TilingData::Iterator iter(&tiling_data_, live_tiles_rect_,
include_borders);
iter; ++iter) {
- TileMapKey key = iter.index();
+ TileMapKey key(iter.index());
TileMap::iterator find = tiles_.find(key);
if (find != tiles_.end())
continue;
- if (ShouldCreateTileAt(key.first, key.second))
- CreateTile(key.first, key.second);
+ if (ShouldCreateTileAt(key.index_x, key.index_y))
+ CreateTile(key.index_x, key.index_y);
}
VerifyLiveTilesRect(false);
}
@@ -150,13 +155,16 @@ void PictureLayerTiling::TakeTilesAndPropertiesFrom(
if (tiles_.empty()) {
tiles_.swap(pending_twin->tiles_);
+ all_tiles_done_ = pending_twin->all_tiles_done_;
} else {
while (!pending_twin->tiles_.empty()) {
TileMapKey key = pending_twin->tiles_.begin()->first;
tiles_.set(key, pending_twin->tiles_.take_and_erase(key));
}
+ all_tiles_done_ &= pending_twin->all_tiles_done_;
}
DCHECK(pending_twin->tiles_.empty());
+ pending_twin->all_tiles_done_ = true;
if (create_missing_tiles)
CreateMissingTilesInLiveTilesRect();
@@ -259,39 +267,53 @@ void PictureLayerTiling::RemoveTilesInRegion(const Region& layer_invalidation,
// twin, so it's slated for removal in the future.
if (live_tiles_rect_.IsEmpty())
return;
- std::vector<TileMapKey> new_tile_keys;
+ // Pick 16 for the size of the SmallMap before it promotes to a hash_map.
+ // 4x4 tiles should cover most small invalidations, and walking a vector of
+ // 16 is fast enough. If an invalidation is huge we will fall back to a
+ // hash_map instead of a vector in the SmallMap.
+ base::SmallMap<base::hash_map<TileMapKey, gfx::Rect>, 16> remove_tiles;
gfx::Rect expanded_live_tiles_rect =
tiling_data_.ExpandRectIgnoringBordersToTileBounds(live_tiles_rect_);
for (Region::Iterator iter(layer_invalidation); iter.has_rect();
iter.next()) {
gfx::Rect layer_rect = iter.rect();
- gfx::Rect content_rect =
+ // The pixels which are invalid in content space.
+ gfx::Rect invalid_content_rect =
gfx::ScaleToEnclosingRect(layer_rect, contents_scale_);
// Consider tiles inside the live tiles rect even if only their border
// pixels intersect the invalidation. But don't consider tiles outside
// the live tiles rect with the same conditions, as they won't exist.
+ gfx::Rect coverage_content_rect = invalid_content_rect;
int border_pixels = tiling_data_.border_texels();
- content_rect.Inset(-border_pixels, -border_pixels);
+ coverage_content_rect.Inset(-border_pixels, -border_pixels);
// Avoid needless work by not bothering to invalidate where there aren't
// tiles.
- content_rect.Intersect(expanded_live_tiles_rect);
- if (content_rect.IsEmpty())
+ coverage_content_rect.Intersect(expanded_live_tiles_rect);
+ if (coverage_content_rect.IsEmpty())
continue;
// Since the content_rect includes border pixels already, don't include
// borders when iterating to avoid double counting them.
bool include_borders = false;
- for (
- TilingData::Iterator iter(&tiling_data_, content_rect, include_borders);
- iter; ++iter) {
- if (RemoveTileAt(iter.index_x(), iter.index_y())) {
- if (recreate_tiles)
- new_tile_keys.push_back(iter.index());
- }
+ for (TilingData::Iterator iter(&tiling_data_, coverage_content_rect,
+ include_borders);
+ iter; ++iter) {
+ // This also adds the TileMapKey to the map.
+ remove_tiles[TileMapKey(iter.index())].Union(invalid_content_rect);
}
}
- for (const auto& key : new_tile_keys)
- CreateTile(key.first, key.second);
+ for (const auto& pair : remove_tiles) {
+ const TileMapKey& key = pair.first;
+ const gfx::Rect& invalid_content_rect = pair.second;
+ // TODO(danakj): This old_tile will not exist if we are committing to a
+ // pending tree since there is no tile there to remove, which prevents
+ // tiles from knowing the invalidation rect and content id. crbug.com/490847
+ ScopedTilePtr old_tile = TakeTileAt(key.index_x, key.index_y);
+ if (recreate_tiles && old_tile) {
+ if (Tile* tile = CreateTile(key.index_x, key.index_y))
+ tile->SetInvalidated(invalid_content_rect, old_tile->id());
+ }
+ }
}
bool PictureLayerTiling::ShouldCreateTileAt(int i, int j) const {
@@ -489,6 +511,13 @@ gfx::RectF PictureLayerTiling::CoverageIterator::texture_rect() const {
return texture_rect;
}
+ScopedTilePtr PictureLayerTiling::TakeTileAt(int i, int j) {
+ TileMap::iterator found = tiles_.find(TileMapKey(i, j));
+ if (found == tiles_.end())
+ return nullptr;
+ return tiles_.take_and_erase(found);
+}
+
bool PictureLayerTiling::RemoveTileAt(int i, int j) {
TileMap::iterator found = tiles_.find(TileMapKey(i, j));
if (found == tiles_.end())
@@ -500,6 +529,7 @@ bool PictureLayerTiling::RemoveTileAt(int i, int j) {
void PictureLayerTiling::Reset() {
live_tiles_rect_ = gfx::Rect();
tiles_.clear();
+ all_tiles_done_ = true;
}
gfx::Rect PictureLayerTiling::ComputeSkewport(
@@ -566,13 +596,19 @@ bool PictureLayerTiling::ComputeTilePriorityRects(
float ideal_contents_scale,
double current_frame_time_in_seconds,
const Occlusion& occlusion_in_layer_space) {
+ // If we have, or had occlusions, mark the tiles as 'not done' to ensure that
+ // we reiterate the tiles for rasterization.
+ if (occlusion_in_layer_space.HasOcclusion() ||
+ current_occlusion_in_layer_space_.HasOcclusion()) {
+ set_all_tiles_done(false);
+ }
+
if (!NeedsUpdateForFrameAtTimeAndViewport(current_frame_time_in_seconds,
viewport_in_layer_space)) {
// This should never be zero for the purposes of has_ever_been_updated().
DCHECK_NE(current_frame_time_in_seconds, 0.0);
return false;
}
-
gfx::Rect visible_rect_in_content_space =
gfx::ScaleToEnclosingRect(viewport_in_layer_space, contents_scale_);
@@ -665,8 +701,8 @@ void PictureLayerTiling::SetLiveTilesRect(
live_tiles_rect_);
iter; ++iter) {
TileMapKey key(iter.index());
- if (ShouldCreateTileAt(key.first, key.second))
- CreateTile(key.first, key.second);
+ if (ShouldCreateTileAt(key.index_x, key.index_y))
+ CreateTile(key.index_x, key.index_y);
}
live_tiles_rect_ = new_live_tiles_rect;
@@ -678,19 +714,19 @@ void PictureLayerTiling::VerifyLiveTilesRect(bool is_on_recycle_tree) const {
for (auto it = tiles_.begin(); it != tiles_.end(); ++it) {
if (!it->second)
continue;
- DCHECK(it->first.first < tiling_data_.num_tiles_x())
- << this << " " << it->first.first << "," << it->first.second
- << " num_tiles_x " << tiling_data_.num_tiles_x() << " live_tiles_rect "
+ TileMapKey key = it->first;
+ DCHECK(key.index_x < tiling_data_.num_tiles_x())
+ << this << " " << key.index_x << "," << key.index_y << " num_tiles_x "
+ << tiling_data_.num_tiles_x() << " live_tiles_rect "
<< live_tiles_rect_.ToString();
- DCHECK(it->first.second < tiling_data_.num_tiles_y())
- << this << " " << it->first.first << "," << it->first.second
- << " num_tiles_y " << tiling_data_.num_tiles_y() << " live_tiles_rect "
+ DCHECK(key.index_y < tiling_data_.num_tiles_y())
+ << this << " " << key.index_x << "," << key.index_y << " num_tiles_y "
+ << tiling_data_.num_tiles_y() << " live_tiles_rect "
<< live_tiles_rect_.ToString();
- DCHECK(tiling_data_.TileBounds(it->first.first, it->first.second)
+ DCHECK(tiling_data_.TileBounds(key.index_x, key.index_y)
.Intersects(live_tiles_rect_))
- << this << " " << it->first.first << "," << it->first.second
- << " tile bounds "
- << tiling_data_.TileBounds(it->first.first, it->first.second).ToString()
+ << this << " " << key.index_x << "," << key.index_y << " tile bounds "
+ << tiling_data_.TileBounds(key.index_x, key.index_y).ToString()
<< " live_tiles_rect " << live_tiles_rect_.ToString();
}
#endif
@@ -845,25 +881,22 @@ TilePriority PictureLayerTiling::ComputePriorityForTile(
const Tile* tile,
PriorityRectType priority_rect_type) const {
// TODO(vmpstr): See if this can be moved to iterators.
- TilePriority::PriorityBin max_tile_priority_bin =
- client_->GetMaxTilePriorityBin();
-
DCHECK_EQ(ComputePriorityRectTypeForTile(tile), priority_rect_type);
DCHECK_EQ(TileAt(tile->tiling_i_index(), tile->tiling_j_index()), tile);
- TilePriority::PriorityBin priority_bin = max_tile_priority_bin;
-
+ TilePriority::PriorityBin priority_bin = client_->HasValidTilePriorities()
+ ? TilePriority::NOW
+ : TilePriority::EVENTUALLY;
switch (priority_rect_type) {
case VISIBLE_RECT:
return TilePriority(resolution_, priority_bin, 0);
case PENDING_VISIBLE_RECT:
- if (max_tile_priority_bin <= TilePriority::SOON)
- return TilePriority(resolution_, TilePriority::SOON, 0);
- priority_bin = TilePriority::EVENTUALLY;
- break;
+ if (priority_bin < TilePriority::SOON)
+ priority_bin = TilePriority::SOON;
+ return TilePriority(resolution_, priority_bin, 0);
case SKEWPORT_RECT:
case SOON_BORDER_RECT:
- if (max_tile_priority_bin <= TilePriority::SOON)
+ if (priority_bin < TilePriority::SOON)
priority_bin = TilePriority::SOON;
break;
case EVENTUALLY_RECT:
@@ -914,7 +947,7 @@ void PictureLayerTiling::GetAllPrioritizedTilesForTracing(
void PictureLayerTiling::AsValueInto(
base::trace_event::TracedValue* state) const {
- state->SetInteger("num_tiles", tiles_.size());
+ state->SetInteger("num_tiles", base::saturated_cast<int>(tiles_.size()));
state->SetDouble("content_scale", contents_scale_);
MathUtil::AddToTracedValue("visible_rect", current_visible_rect_, state);
MathUtil::AddToTracedValue("skewport_rect", current_skewport_rect_, state);
diff --git a/chromium/cc/tiles/picture_layer_tiling.h b/chromium/cc/tiles/picture_layer_tiling.h
index 33a81879f20..721f9e1e340 100644
--- a/chromium/cc/tiles/picture_layer_tiling.h
+++ b/chromium/cc/tiles/picture_layer_tiling.h
@@ -45,13 +45,42 @@ class CC_EXPORT PictureLayerTilingClient {
virtual const Region* GetPendingInvalidation() = 0;
virtual const PictureLayerTiling* GetPendingOrActiveTwinTiling(
const PictureLayerTiling* tiling) const = 0;
- virtual TilePriority::PriorityBin GetMaxTilePriorityBin() const = 0;
+ virtual bool HasValidTilePriorities() const = 0;
virtual bool RequiresHighResToDraw() const = 0;
protected:
virtual ~PictureLayerTilingClient() {}
};
+struct TileMapKey {
+ TileMapKey(int x, int y) : index_x(x), index_y(y) {}
+ explicit TileMapKey(const std::pair<int, int>& index)
+ : index_x(index.first), index_y(index.second) {}
+
+ bool operator==(const TileMapKey& other) const {
+ return index_x == other.index_x && index_y == other.index_y;
+ }
+
+ int index_x;
+ int index_y;
+};
+
+} // namespace cc
+
+namespace BASE_HASH_NAMESPACE {
+template <>
+struct hash<cc::TileMapKey> {
+ size_t operator()(const cc::TileMapKey& key) const {
+ uint16 value1 = static_cast<uint16>(key.index_x);
+ uint16 value2 = static_cast<uint16>(key.index_y);
+ uint32 value1_32 = value1;
+ return (value1_32 << 16) | value2;
+ }
+};
+} // namespace BASE_HASH_NAMESPACE
+
+namespace cc {
+
class CC_EXPORT PictureLayerTiling {
public:
static const int kBorderTexels = 1;
@@ -101,6 +130,20 @@ class CC_EXPORT PictureLayerTiling {
}
bool has_tiles() const { return !tiles_.empty(); }
+ // all_tiles_done() can return false negatives.
+ bool all_tiles_done() const { return all_tiles_done_; }
+ void set_all_tiles_done(bool all_tiles_done) {
+ all_tiles_done_ = all_tiles_done;
+ }
+
+ void VerifyNoTileNeedsRaster() const {
+#if DCHECK_IS_ON()
+ for (const auto tile_pair : tiles_) {
+ DCHECK(!tile_pair.second->draw_info().NeedsRaster() ||
+ IsTileOccluded(tile_pair.second));
+ }
+#endif // DCHECK_IS_ON()
+ }
// For testing functionality.
void CreateAllTilesForTesting() {
@@ -132,6 +175,14 @@ class CC_EXPORT PictureLayerTiling {
const gfx::Rect& GetCurrentVisibleRectForTesting() const {
return current_visible_rect_;
}
+ void SetTilePriorityRectsForTesting(
+ const gfx::Rect& visible_rect_in_content_space,
+ const gfx::Rect& skewport,
+ const gfx::Rect& soon_border_rect,
+ const gfx::Rect& eventually_rect) {
+ SetTilePriorityRects(1.0f, visible_rect_in_content_space, skewport,
+ soon_border_rect, eventually_rect, Occlusion());
+ }
// Iterate over all tiles to fill content_rect. Even if tiles are invalid
// (i.e. no valid resource) this tiling should still iterate over them.
@@ -225,7 +276,6 @@ class CC_EXPORT PictureLayerTiling {
EVENTUALLY_RECT
};
- using TileMapKey = std::pair<int, int>;
using TileMap = base::ScopedPtrHashMap<TileMapKey, ScopedTilePtr>;
struct FrameVisibleRect {
@@ -243,6 +293,7 @@ class CC_EXPORT PictureLayerTiling {
void SetLiveTilesRect(const gfx::Rect& live_tiles_rect);
void VerifyLiveTilesRect(bool is_on_recycle_tree) const;
Tile* CreateTile(int i, int j);
+ ScopedTilePtr TakeTileAt(int i, int j);
// Returns true if the Tile existed and was removed from the tiling.
bool RemoveTileAt(int i, int j);
bool TilingMatchesTileIndices(const PictureLayerTiling* twin) const;
@@ -359,6 +410,7 @@ class CC_EXPORT PictureLayerTiling {
bool has_skewport_rect_tiles_;
bool has_soon_border_rect_tiles_;
bool has_eventually_rect_tiles_;
+ bool all_tiles_done_;
private:
DISALLOW_ASSIGN(PictureLayerTiling);
diff --git a/chromium/cc/tiles/picture_layer_tiling_perftest.cc b/chromium/cc/tiles/picture_layer_tiling_perftest.cc
index 0aae512030e..f27c227edcc 100644
--- a/chromium/cc/tiles/picture_layer_tiling_perftest.cc
+++ b/chromium/cc/tiles/picture_layer_tiling_perftest.cc
@@ -9,9 +9,11 @@
#include "cc/test/fake_output_surface_client.h"
#include "cc/test/fake_picture_layer_tiling_client.h"
#include "cc/test/fake_picture_pile_impl.h"
+#include "cc/test/fake_resource_provider.h"
#include "cc/test/test_context_provider.h"
#include "cc/test/test_shared_bitmap_manager.h"
#include "cc/tiles/picture_layer_tiling.h"
+#include "cc/trees/layer_tree_settings.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/perf/perf_test.h"
@@ -35,13 +37,8 @@ class PictureLayerTilingPerfTest : public testing::Test {
CHECK(output_surface_->BindToClient(&output_surface_client_));
shared_bitmap_manager_.reset(new TestSharedBitmapManager());
- resource_provider_ = ResourceProvider::Create(output_surface_.get(),
- shared_bitmap_manager_.get(),
- NULL,
- NULL,
- 0,
- false,
- 1).Pass();
+ resource_provider_ = FakeResourceProvider::Create(
+ output_surface_.get(), shared_bitmap_manager_.get());
}
void SetUp() override {
diff --git a/chromium/cc/tiles/picture_layer_tiling_set.cc b/chromium/cc/tiles/picture_layer_tiling_set.cc
index b794b137ff0..c820e81ce1a 100644
--- a/chromium/cc/tiles/picture_layer_tiling_set.cc
+++ b/chromium/cc/tiles/picture_layer_tiling_set.cc
@@ -137,8 +137,14 @@ void PictureLayerTilingSet::UpdateTilingsToCurrentRasterSourceForCommit(
// Invalidate tiles and update them to the new raster source.
for (PictureLayerTiling* tiling : tilings_) {
+ DCHECK_IMPLIES(tree_ == PENDING_TREE, !tiling->has_tiles());
tiling->SetRasterSourceAndResize(raster_source);
- tiling->Invalidate(layer_invalidation);
+
+ // We can commit on either active or pending trees, but only active one can
+ // have tiles at this point.
+ if (tree_ == ACTIVE_TREE)
+ tiling->Invalidate(layer_invalidation);
+
// This is needed for cases where the live tiles rect didn't change but
// recordings exist in the raster source that did not exist on the last
// raster source.
@@ -192,8 +198,7 @@ void PictureLayerTilingSet::CleanUpTilings(
float max_acceptable_high_res_scale,
const std::vector<PictureLayerTiling*>& needed_tilings,
bool should_have_low_res,
- PictureLayerTilingSet* twin_set,
- PictureLayerTilingSet* recycled_twin_set) {
+ PictureLayerTilingSet* twin_set) {
float twin_low_res_scale = 0.f;
if (twin_set) {
PictureLayerTiling* tiling =
@@ -227,15 +232,6 @@ void PictureLayerTilingSet::CleanUpTilings(
}
for (auto* tiling : to_remove) {
- PictureLayerTiling* recycled_twin_tiling =
- recycled_twin_set
- ? recycled_twin_set->FindTilingWithScale(tiling->contents_scale())
- : nullptr;
- // Remove the tiling from the recycle tree. Note that we ignore resolution,
- // since we don't need to maintain high/low res on the recycle set.
- if (recycled_twin_tiling)
- recycled_twin_set->Remove(recycled_twin_tiling);
-
DCHECK_NE(HIGH_RESOLUTION, tiling->resolution());
Remove(tiling);
}
@@ -386,12 +382,11 @@ PictureLayerTilingSet::CoverageIterator::CoverageIterator(
: set_(set),
contents_scale_(contents_scale),
ideal_contents_scale_(ideal_contents_scale),
- current_tiling_(-1) {
+ current_tiling_(std::numeric_limits<size_t>::max()) {
missing_region_.Union(content_rect);
- for (ideal_tiling_ = 0;
- static_cast<size_t>(ideal_tiling_) < set_->tilings_.size();
- ++ideal_tiling_) {
+ size_t tilings_size = set_->tilings_.size();
+ for (ideal_tiling_ = 0; ideal_tiling_ < tilings_size; ++ideal_tiling_) {
PictureLayerTiling* tiling = set_->tilings_[ideal_tiling_];
if (tiling->contents_scale() < ideal_contents_scale_) {
if (ideal_tiling_ > 0)
@@ -400,11 +395,7 @@ PictureLayerTilingSet::CoverageIterator::CoverageIterator(
}
}
- DCHECK_LE(set_->tilings_.size(),
- static_cast<size_t>(std::numeric_limits<int>::max()));
-
- int num_tilings = set_->tilings_.size();
- if (ideal_tiling_ == num_tilings && ideal_tiling_ > 0)
+ if (ideal_tiling_ == tilings_size && ideal_tiling_ > 0)
ideal_tiling_--;
++(*this);
@@ -448,20 +439,20 @@ TileResolution PictureLayerTilingSet::CoverageIterator::resolution() const {
PictureLayerTiling* PictureLayerTilingSet::CoverageIterator::CurrentTiling()
const {
- if (current_tiling_ < 0)
+ if (current_tiling_ == std::numeric_limits<size_t>::max())
return NULL;
- if (static_cast<size_t>(current_tiling_) >= set_->tilings_.size())
+ if (current_tiling_ >= set_->tilings_.size())
return NULL;
return set_->tilings_[current_tiling_];
}
-int PictureLayerTilingSet::CoverageIterator::NextTiling() const {
+size_t PictureLayerTilingSet::CoverageIterator::NextTiling() const {
// Order returned by this method is:
// 1. Ideal tiling index
// 2. Tiling index < Ideal in decreasing order (higher res than ideal)
// 3. Tiling index > Ideal in increasing order (lower res than ideal)
// 4. Tiling index > tilings.size() (invalid index)
- if (current_tiling_ < 0)
+ if (current_tiling_ == std::numeric_limits<size_t>::max())
return ideal_tiling_;
else if (current_tiling_ > ideal_tiling_)
return current_tiling_ + 1;
@@ -473,7 +464,7 @@ int PictureLayerTilingSet::CoverageIterator::NextTiling() const {
PictureLayerTilingSet::CoverageIterator&
PictureLayerTilingSet::CoverageIterator::operator++() {
- bool first_time = current_tiling_ < 0;
+ bool first_time = current_tiling_ == std::numeric_limits<size_t>::max();
if (!*this && !first_time)
return *this;
@@ -507,7 +498,7 @@ PictureLayerTilingSet::CoverageIterator::operator++() {
}
// No more valid tiles, return this checkerboard rect.
- if (current_tiling_ >= static_cast<int>(set_->tilings_.size()))
+ if (current_tiling_ >= set_->tilings_.size())
return *this;
}
@@ -517,7 +508,7 @@ PictureLayerTilingSet::CoverageIterator::operator++() {
region_iter_.next();
// Done, found next checkerboard rect to return.
- if (current_tiling_ >= static_cast<int>(set_->tilings_.size()))
+ if (current_tiling_ >= set_->tilings_.size())
return *this;
// Construct a new iterator for the next tiling, but we need to loop
@@ -532,8 +523,7 @@ PictureLayerTilingSet::CoverageIterator::operator++() {
}
PictureLayerTilingSet::CoverageIterator::operator bool() const {
- return current_tiling_ < static_cast<int>(set_->tilings_.size()) ||
- region_iter_.has_rect();
+ return current_tiling_ < set_->tilings_.size() || region_iter_.has_rect();
}
void PictureLayerTilingSet::AsValueInto(
@@ -557,9 +547,10 @@ PictureLayerTilingSet::TilingRange PictureLayerTilingSet::GetTilingRange(
// Doesn't seem to be the case right now but if it ever becomes a performance
// problem to compute these ranges each time this function is called, we can
// compute them only when the tiling set has changed instead.
+ size_t tilings_size = tilings_.size();
TilingRange high_res_range(0, 0);
TilingRange low_res_range(tilings_.size(), tilings_.size());
- for (size_t i = 0; i < tilings_.size(); ++i) {
+ for (size_t i = 0; i < tilings_size; ++i) {
const PictureLayerTiling* tiling = tilings_[i];
if (tiling->resolution() == HIGH_RESOLUTION)
high_res_range = TilingRange(i, i + 1);
@@ -591,7 +582,7 @@ PictureLayerTilingSet::TilingRange PictureLayerTilingSet::GetTilingRange(
range = low_res_range;
break;
case LOWER_THAN_LOW_RES:
- range = TilingRange(low_res_range.end, tilings_.size());
+ range = TilingRange(low_res_range.end, tilings_size);
break;
}
diff --git a/chromium/cc/tiles/picture_layer_tiling_set.h b/chromium/cc/tiles/picture_layer_tiling_set.h
index 2347d53798d..dcaf77586ff 100644
--- a/chromium/cc/tiles/picture_layer_tiling_set.h
+++ b/chromium/cc/tiles/picture_layer_tiling_set.h
@@ -31,10 +31,10 @@ class CC_EXPORT PictureLayerTilingSet {
LOWER_THAN_LOW_RES
};
struct TilingRange {
- TilingRange(int start, int end) : start(start), end(end) {}
+ TilingRange(size_t start, size_t end) : start(start), end(end) {}
- int start;
- int end;
+ size_t start;
+ size_t end;
};
static scoped_ptr<PictureLayerTilingSet> Create(
@@ -52,8 +52,7 @@ class CC_EXPORT PictureLayerTilingSet {
float max_acceptable_high_res_scale,
const std::vector<PictureLayerTiling*>& needed_tilings,
bool should_have_low_res,
- PictureLayerTilingSet* twin_set,
- PictureLayerTilingSet* recycled_twin_set);
+ PictureLayerTilingSet* twin_set);
void RemoveNonIdealTilings();
// This function is called on the active tree during activation.
@@ -153,14 +152,14 @@ class CC_EXPORT PictureLayerTilingSet {
PictureLayerTiling* CurrentTiling() const;
private:
- int NextTiling() const;
+ size_t NextTiling() const;
const PictureLayerTilingSet* set_;
float contents_scale_;
float ideal_contents_scale_;
PictureLayerTiling::CoverageIterator tiling_iter_;
- int current_tiling_;
- int ideal_tiling_;
+ size_t current_tiling_;
+ size_t ideal_tiling_;
Region current_region_;
Region missing_region_;
diff --git a/chromium/cc/tiles/picture_layer_tiling_set_unittest.cc b/chromium/cc/tiles/picture_layer_tiling_set_unittest.cc
index c04870e3d16..e7593cde80b 100644
--- a/chromium/cc/tiles/picture_layer_tiling_set_unittest.cc
+++ b/chromium/cc/tiles/picture_layer_tiling_set_unittest.cc
@@ -12,7 +12,9 @@
#include "cc/test/fake_output_surface_client.h"
#include "cc/test/fake_picture_layer_tiling_client.h"
#include "cc/test/fake_picture_pile_impl.h"
+#include "cc/test/fake_resource_provider.h"
#include "cc/test/test_shared_bitmap_manager.h"
+#include "cc/trees/layer_tree_settings.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/size_conversions.h"
@@ -86,26 +88,26 @@ TEST(PictureLayerTilingSetTest, TilingRange) {
higher_than_high_res_range =
set->GetTilingRange(PictureLayerTilingSet::HIGHER_THAN_HIGH_RES);
- EXPECT_EQ(0, higher_than_high_res_range.start);
- EXPECT_EQ(1, higher_than_high_res_range.end);
+ EXPECT_EQ(0u, higher_than_high_res_range.start);
+ EXPECT_EQ(1u, higher_than_high_res_range.end);
high_res_range = set->GetTilingRange(PictureLayerTilingSet::HIGH_RES);
- EXPECT_EQ(1, high_res_range.start);
- EXPECT_EQ(2, high_res_range.end);
+ EXPECT_EQ(1u, high_res_range.start);
+ EXPECT_EQ(2u, high_res_range.end);
between_high_and_low_res_range =
set->GetTilingRange(PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES);
- EXPECT_EQ(2, between_high_and_low_res_range.start);
- EXPECT_EQ(3, between_high_and_low_res_range.end);
+ EXPECT_EQ(2u, between_high_and_low_res_range.start);
+ EXPECT_EQ(3u, between_high_and_low_res_range.end);
low_res_range = set->GetTilingRange(PictureLayerTilingSet::LOW_RES);
- EXPECT_EQ(3, low_res_range.start);
- EXPECT_EQ(4, low_res_range.end);
+ EXPECT_EQ(3u, low_res_range.start);
+ EXPECT_EQ(4u, low_res_range.end);
lower_than_low_res_range =
set->GetTilingRange(PictureLayerTilingSet::LOWER_THAN_LOW_RES);
- EXPECT_EQ(4, lower_than_low_res_range.start);
- EXPECT_EQ(5, lower_than_low_res_range.end);
+ EXPECT_EQ(4u, lower_than_low_res_range.start);
+ EXPECT_EQ(5u, lower_than_low_res_range.end);
scoped_ptr<PictureLayerTilingSet> set_without_low_res =
CreateTilingSet(&client);
@@ -117,26 +119,26 @@ TEST(PictureLayerTilingSetTest, TilingRange) {
higher_than_high_res_range = set_without_low_res->GetTilingRange(
PictureLayerTilingSet::HIGHER_THAN_HIGH_RES);
- EXPECT_EQ(0, higher_than_high_res_range.start);
- EXPECT_EQ(1, higher_than_high_res_range.end);
+ EXPECT_EQ(0u, higher_than_high_res_range.start);
+ EXPECT_EQ(1u, higher_than_high_res_range.end);
high_res_range =
set_without_low_res->GetTilingRange(PictureLayerTilingSet::HIGH_RES);
- EXPECT_EQ(1, high_res_range.start);
- EXPECT_EQ(2, high_res_range.end);
+ EXPECT_EQ(1u, high_res_range.start);
+ EXPECT_EQ(2u, high_res_range.end);
between_high_and_low_res_range = set_without_low_res->GetTilingRange(
PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES);
- EXPECT_EQ(2, between_high_and_low_res_range.start);
- EXPECT_EQ(4, between_high_and_low_res_range.end);
+ EXPECT_EQ(2u, between_high_and_low_res_range.start);
+ EXPECT_EQ(4u, between_high_and_low_res_range.end);
low_res_range =
set_without_low_res->GetTilingRange(PictureLayerTilingSet::LOW_RES);
- EXPECT_EQ(0, low_res_range.end - low_res_range.start);
+ EXPECT_EQ(0u, low_res_range.end - low_res_range.start);
lower_than_low_res_range = set_without_low_res->GetTilingRange(
PictureLayerTilingSet::LOWER_THAN_LOW_RES);
- EXPECT_EQ(0, lower_than_low_res_range.end - lower_than_low_res_range.start);
+ EXPECT_EQ(0u, lower_than_low_res_range.end - lower_than_low_res_range.start);
scoped_ptr<PictureLayerTilingSet> set_with_only_high_and_low_res =
CreateTilingSet(&client);
@@ -147,28 +149,28 @@ TEST(PictureLayerTilingSetTest, TilingRange) {
higher_than_high_res_range = set_with_only_high_and_low_res->GetTilingRange(
PictureLayerTilingSet::HIGHER_THAN_HIGH_RES);
- EXPECT_EQ(0,
+ EXPECT_EQ(0u,
higher_than_high_res_range.end - higher_than_high_res_range.start);
high_res_range = set_with_only_high_and_low_res->GetTilingRange(
PictureLayerTilingSet::HIGH_RES);
- EXPECT_EQ(0, high_res_range.start);
- EXPECT_EQ(1, high_res_range.end);
+ EXPECT_EQ(0u, high_res_range.start);
+ EXPECT_EQ(1u, high_res_range.end);
between_high_and_low_res_range =
set_with_only_high_and_low_res->GetTilingRange(
PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES);
- EXPECT_EQ(0, between_high_and_low_res_range.end -
- between_high_and_low_res_range.start);
+ EXPECT_EQ(0u, between_high_and_low_res_range.end -
+ between_high_and_low_res_range.start);
low_res_range = set_with_only_high_and_low_res->GetTilingRange(
PictureLayerTilingSet::LOW_RES);
- EXPECT_EQ(1, low_res_range.start);
- EXPECT_EQ(2, low_res_range.end);
+ EXPECT_EQ(1u, low_res_range.start);
+ EXPECT_EQ(2u, low_res_range.end);
lower_than_low_res_range = set_with_only_high_and_low_res->GetTilingRange(
PictureLayerTilingSet::LOWER_THAN_LOW_RES);
- EXPECT_EQ(0, lower_than_low_res_range.end - lower_than_low_res_range.start);
+ EXPECT_EQ(0u, lower_than_low_res_range.end - lower_than_low_res_range.start);
scoped_ptr<PictureLayerTilingSet> set_with_only_high_res =
CreateTilingSet(&client);
@@ -177,26 +179,26 @@ TEST(PictureLayerTilingSetTest, TilingRange) {
higher_than_high_res_range = set_with_only_high_res->GetTilingRange(
PictureLayerTilingSet::HIGHER_THAN_HIGH_RES);
- EXPECT_EQ(0,
+ EXPECT_EQ(0u,
higher_than_high_res_range.end - higher_than_high_res_range.start);
high_res_range =
set_with_only_high_res->GetTilingRange(PictureLayerTilingSet::HIGH_RES);
- EXPECT_EQ(0, high_res_range.start);
- EXPECT_EQ(1, high_res_range.end);
+ EXPECT_EQ(0u, high_res_range.start);
+ EXPECT_EQ(1u, high_res_range.end);
between_high_and_low_res_range = set_with_only_high_res->GetTilingRange(
PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES);
- EXPECT_EQ(0, between_high_and_low_res_range.end -
- between_high_and_low_res_range.start);
+ EXPECT_EQ(0u, between_high_and_low_res_range.end -
+ between_high_and_low_res_range.start);
low_res_range =
set_with_only_high_res->GetTilingRange(PictureLayerTilingSet::LOW_RES);
- EXPECT_EQ(0, low_res_range.end - low_res_range.start);
+ EXPECT_EQ(0u, low_res_range.end - low_res_range.start);
lower_than_low_res_range = set_with_only_high_res->GetTilingRange(
PictureLayerTilingSet::LOWER_THAN_LOW_RES);
- EXPECT_EQ(0, lower_than_low_res_range.end - lower_than_low_res_range.start);
+ EXPECT_EQ(0u, lower_than_low_res_range.end - lower_than_low_res_range.start);
}
class PictureLayerTilingSetTestWithResources : public testing::Test {
@@ -214,13 +216,8 @@ class PictureLayerTilingSetTestWithResources : public testing::Test {
scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
new TestSharedBitmapManager());
scoped_ptr<ResourceProvider> resource_provider =
- ResourceProvider::Create(output_surface.get(),
- shared_bitmap_manager.get(),
- NULL,
- NULL,
- 0,
- false,
- 1);
+ FakeResourceProvider::Create(output_surface.get(),
+ shared_bitmap_manager.get());
FakePictureLayerTilingClient client(resource_provider.get());
client.SetTileSize(gfx::Size(256, 256));
@@ -334,6 +331,12 @@ TEST(PictureLayerTilingSetTest, TileSizeChange) {
EXPECT_EQ(tile_size1, tile->content_rect().size());
// Update to a new source frame with a new tile size.
+ // Note that setting a new raster source can typically only happen after
+ // activation, since we can't set the raster source twice on the pending tree
+ // without activating. For test, just remove and add a new tiling instead.
+ pending_set->RemoveAllTilings();
+ pending_set->AddTiling(1.f, pile);
+ pending_set->tiling_at(0)->set_resolution(HIGH_RESOLUTION);
pending_client.SetTileSize(tile_size2);
pending_set->UpdateTilingsToCurrentRasterSourceForCommit(pile.get(), Region(),
1.f, 1.f);
diff --git a/chromium/cc/tiles/picture_layer_tiling_unittest.cc b/chromium/cc/tiles/picture_layer_tiling_unittest.cc
index e19f9303014..1c8a3978eb2 100644
--- a/chromium/cc/tiles/picture_layer_tiling_unittest.cc
+++ b/chromium/cc/tiles/picture_layer_tiling_unittest.cc
@@ -14,6 +14,7 @@
#include "cc/test/test_shared_bitmap_manager.h"
#include "cc/tiles/picture_layer_tiling.h"
#include "cc/tiles/picture_layer_tiling_set.h"
+#include "cc/trees/layer_tree_settings.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/quad_f.h"
#include "ui/gfx/geometry/rect_conversions.h"
diff --git a/chromium/cc/tiles/tile.cc b/chromium/cc/tiles/tile.cc
index da4c08018d5..6052e5e0457 100644
--- a/chromium/cc/tiles/tile.cc
+++ b/chromium/cc/tiles/tile.cc
@@ -6,6 +6,7 @@
#include <algorithm>
+#include "base/numerics/safe_conversions.h"
#include "base/trace_event/trace_event_argument.h"
#include "cc/base/math_util.h"
#include "cc/debug/traced_value.h"
@@ -13,7 +14,7 @@
namespace cc {
-Tile::Id Tile::s_next_id_ = 0;
+Tile::Id Tile::s_next_id_ = 1;
Tile::Tile(TileManager* tile_manager,
const gfx::Size& desired_texture_size,
@@ -34,6 +35,7 @@ Tile::Tile(TileManager* tile_manager,
required_for_activation_(false),
required_for_draw_(false),
id_(s_next_id_++),
+ invalidated_id_(0),
scheduled_priority_(0) {
}
@@ -61,12 +63,17 @@ void Tile::AsValueInto(base::trace_event::TracedValue* value) const {
draw_info().has_resource() || HasRasterTask());
value->SetInteger("scheduled_priority", scheduled_priority_);
value->SetBoolean("use_picture_analysis", use_picture_analysis());
- value->SetInteger("gpu_memory_usage", GPUMemoryUsageInBytes());
+ value->SetInteger("gpu_memory_usage",
+ base::saturated_cast<int>(GPUMemoryUsageInBytes()));
}
size_t Tile::GPUMemoryUsageInBytes() const {
- if (draw_info_.resource_)
- return draw_info_.resource_->bytes();
+ if (draw_info_.resource_) {
+ // We can use UncheckedSizeInBytes, since the tile size is determined by the
+ // compositor.
+ return Resource::UncheckedMemorySizeBytes(draw_info_.resource_->size(),
+ draw_info_.resource_->format());
+ }
return 0;
}
diff --git a/chromium/cc/tiles/tile.h b/chromium/cc/tiles/tile.h
index 68c4fc13e34..e53c2ac52f8 100644
--- a/chromium/cc/tiles/tile.h
+++ b/chromium/cc/tiles/tile.h
@@ -68,6 +68,17 @@ class CC_EXPORT Tile {
int tiling_i_index() const { return tiling_i_index_; }
int tiling_j_index() const { return tiling_j_index_; }
+ void SetInvalidated(const gfx::Rect& invalid_content_rect,
+ Id previous_tile_id) {
+ invalidated_content_rect_ = invalid_content_rect;
+ invalidated_id_ = previous_tile_id;
+ }
+
+ Id invalidated_id() const { return invalidated_id_; }
+ const gfx::Rect& invalidated_content_rect() const {
+ return invalidated_content_rect_;
+ }
+
private:
friend class TileManager;
friend class FakeTileManager;
@@ -103,6 +114,12 @@ class CC_EXPORT Tile {
Id id_;
static Id s_next_id_;
+ // The rect bounding the changes in this Tile vs the previous tile it
+ // replaced.
+ gfx::Rect invalidated_content_rect_;
+ // The |id_| of the Tile that was invalidated and replaced by this tile.
+ Id invalidated_id_;
+
unsigned scheduled_priority_;
scoped_refptr<RasterTask> raster_task_;
diff --git a/chromium/cc/tiles/tile_draw_info.cc b/chromium/cc/tiles/tile_draw_info.cc
index e523079aac9..6b12e73f5c6 100644
--- a/chromium/cc/tiles/tile_draw_info.cc
+++ b/chromium/cc/tiles/tile_draw_info.cc
@@ -4,16 +4,25 @@
#include "cc/tiles/tile_draw_info.h"
+#include "base/metrics/histogram.h"
#include "cc/base/math_util.h"
namespace cc {
TileDrawInfo::TileDrawInfo()
- : mode_(RESOURCE_MODE), solid_color_(SK_ColorWHITE) {
+ : mode_(RESOURCE_MODE),
+ solid_color_(SK_ColorWHITE),
+ contents_swizzled_(false),
+ was_ever_ready_to_draw_(false),
+ was_ever_used_to_draw_(false) {
}
TileDrawInfo::~TileDrawInfo() {
DCHECK(!resource_);
+ if (was_ever_ready_to_draw_) {
+ UMA_HISTOGRAM_BOOLEAN("Renderer4.ReadyToDrawTileDrawStatus",
+ was_ever_used_to_draw_);
+ }
}
void TileDrawInfo::AsValueInto(base::trace_event::TracedValue* state) const {
diff --git a/chromium/cc/tiles/tile_draw_info.h b/chromium/cc/tiles/tile_draw_info.h
index f094efd6f38..dcb755ad34e 100644
--- a/chromium/cc/tiles/tile_draw_info.h
+++ b/chromium/cc/tiles/tile_draw_info.h
@@ -48,7 +48,7 @@ class CC_EXPORT TileDrawInfo {
return false;
}
- ResourceProvider::ResourceId resource_id() const {
+ ResourceId resource_id() const {
DCHECK(mode_ == RESOURCE_MODE);
DCHECK(resource_);
return resource_->id();
@@ -65,10 +65,7 @@ class CC_EXPORT TileDrawInfo {
return solid_color_;
}
- bool contents_swizzled() const {
- DCHECK(resource_);
- return !PlatformColor::SameComponentOrder(resource_->format());
- }
+ bool contents_swizzled() const { return contents_swizzled_; }
bool requires_resource() const {
return mode_ == RESOURCE_MODE || mode_ == OOM_MODE;
@@ -83,6 +80,9 @@ class CC_EXPORT TileDrawInfo {
void AsValueInto(base::trace_event::TracedValue* state) const;
+ void set_was_ever_ready_to_draw() { was_ever_ready_to_draw_ = true; }
+ void set_was_ever_used_to_draw() { was_ever_used_to_draw_ = true; }
+
private:
friend class Tile;
friend class TileManager;
@@ -99,6 +99,11 @@ class CC_EXPORT TileDrawInfo {
Mode mode_;
SkColor solid_color_;
scoped_ptr<ScopedResource> resource_;
+ bool contents_swizzled_;
+
+ // Used for gathering UMA stats.
+ bool was_ever_ready_to_draw_;
+ bool was_ever_used_to_draw_;
};
} // namespace cc
diff --git a/chromium/cc/tiles/tile_manager.cc b/chromium/cc/tiles/tile_manager.cc
index a67563a4402..23d2eca12bc 100644
--- a/chromium/cc/tiles/tile_manager.cc
+++ b/chromium/cc/tiles/tile_manager.cc
@@ -12,7 +12,9 @@
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/metrics/histogram.h"
+#include "base/numerics/safe_conversions.h"
#include "base/trace_event/trace_event_argument.h"
+#include "cc/base/histograms.h"
#include "cc/debug/devtools_instrumentation.h"
#include "cc/debug/frame_viewer_instrumentation.h"
#include "cc/debug/traced_value.h"
@@ -29,16 +31,26 @@ namespace {
// a tile is of solid color.
const bool kUseColorEstimator = true;
+DEFINE_SCOPED_UMA_HISTOGRAM_AREA_TIMER(
+ ScopedRasterTaskTimer,
+ "Compositing.RasterTask.RasterUs",
+ "Compositing.RasterTask.RasterPixelsPerMs");
+
class RasterTaskImpl : public RasterTask {
public:
RasterTaskImpl(
const Resource* resource,
RasterSource* raster_source,
const gfx::Rect& content_rect,
+ const gfx::Rect& invalid_content_rect,
float contents_scale,
TileResolution tile_resolution,
int layer_id,
- const void* tile_id,
+ uint64_t source_prepare_tiles_id,
+ const void* tile,
+ uint64_t new_content_id,
+ uint64_t previous_content_id,
+ uint64_t resource_content_id,
int source_frame_number,
bool analyze_picture,
const base::Callback<void(const RasterSource::SolidColorAnalysis&, bool)>&
@@ -47,17 +59,23 @@ class RasterTaskImpl : public RasterTask {
: RasterTask(resource, dependencies),
raster_source_(raster_source),
content_rect_(content_rect),
+ invalid_content_rect_(invalid_content_rect),
contents_scale_(contents_scale),
tile_resolution_(tile_resolution),
layer_id_(layer_id),
- tile_id_(tile_id),
+ source_prepare_tiles_id_(source_prepare_tiles_id),
+ tile_(tile),
+ new_content_id_(new_content_id),
+ previous_content_id_(previous_content_id),
+ resource_content_id_(resource_content_id),
source_frame_number_(source_frame_number),
analyze_picture_(analyze_picture),
reply_(reply) {}
// Overridden from Task:
void RunOnWorkerThread() override {
- TRACE_EVENT0("cc", "RasterizerTaskImpl::RunOnWorkerThread");
+ TRACE_EVENT1("cc", "RasterizerTaskImpl::RunOnWorkerThread",
+ "source_prepare_tiles_id", source_prepare_tiles_id_);
DCHECK(raster_source_.get());
DCHECK(raster_buffer_);
@@ -74,7 +92,8 @@ class RasterTaskImpl : public RasterTask {
// Overridden from TileTask:
void ScheduleOnOriginThread(TileTaskClient* client) override {
DCHECK(!raster_buffer_);
- raster_buffer_ = client->AcquireBufferForRaster(resource());
+ raster_buffer_ = client->AcquireBufferForRaster(
+ resource(), resource_content_id_, previous_content_id_);
}
void CompleteOnOriginThread(TileTaskClient* client) override {
client->ReleaseBufferForRaster(raster_buffer_.Pass());
@@ -90,7 +109,7 @@ class RasterTaskImpl : public RasterTask {
private:
void Analyze(const RasterSource* raster_source) {
frame_viewer_instrumentation::ScopedAnalyzeTask analyze_task(
- tile_id_, tile_resolution_, source_frame_number_, layer_id_);
+ tile_, tile_resolution_, source_frame_number_, layer_id_);
DCHECK(raster_source);
@@ -102,21 +121,29 @@ class RasterTaskImpl : public RasterTask {
void Raster(const RasterSource* raster_source) {
frame_viewer_instrumentation::ScopedRasterTask raster_task(
- tile_id_, tile_resolution_, source_frame_number_, layer_id_);
+ tile_, tile_resolution_, source_frame_number_, layer_id_);
+ ScopedRasterTaskTimer timer;
+ timer.SetArea(content_rect_.size().GetArea());
DCHECK(raster_source);
raster_buffer_->Playback(raster_source_.get(), content_rect_,
+ invalid_content_rect_, new_content_id_,
contents_scale_);
}
RasterSource::SolidColorAnalysis analysis_;
scoped_refptr<RasterSource> raster_source_;
gfx::Rect content_rect_;
+ gfx::Rect invalid_content_rect_;
float contents_scale_;
TileResolution tile_resolution_;
int layer_id_;
- const void* tile_id_;
+ uint64_t source_prepare_tiles_id_;
+ const void* tile_;
+ uint64_t new_content_id_;
+ uint64_t previous_content_id_;
+ uint64_t resource_content_id_;
int source_frame_number_;
bool analyze_picture_;
const base::Callback<void(const RasterSource::SolidColorAnalysis&, bool)>
@@ -129,13 +156,16 @@ class RasterTaskImpl : public RasterTask {
class ImageDecodeTaskImpl : public ImageDecodeTask {
public:
ImageDecodeTaskImpl(SkPixelRef* pixel_ref,
+ uint64_t source_prepare_tiles_id,
const base::Callback<void(bool was_canceled)>& reply)
: pixel_ref_(skia::SharePtr(pixel_ref)),
+ source_prepare_tiles_id_(source_prepare_tiles_id),
reply_(reply) {}
// Overridden from Task:
void RunOnWorkerThread() override {
- TRACE_EVENT0("cc", "ImageDecodeTaskImpl::RunOnWorkerThread");
+ TRACE_EVENT1("cc", "ImageDecodeTaskImpl::RunOnWorkerThread",
+ "source_prepare_tiles_id", source_prepare_tiles_id_);
devtools_instrumentation::ScopedImageDecodeTask image_decode_task(
pixel_ref_.get());
@@ -158,6 +188,7 @@ class ImageDecodeTaskImpl : public ImageDecodeTask {
private:
skia::RefPtr<SkPixelRef> pixel_ref_;
+ uint64_t source_prepare_tiles_id_;
const base::Callback<void(bool was_canceled)> reply_;
DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl);
@@ -186,8 +217,10 @@ scoped_refptr<base::trace_event::ConvertableToTraceFormat>
RasterTaskCompletionStatsAsValue(const RasterTaskCompletionStats& stats) {
scoped_refptr<base::trace_event::TracedValue> state =
new base::trace_event::TracedValue();
- state->SetInteger("completed_count", stats.completed_count);
- state->SetInteger("canceled_count", stats.canceled_count);
+ state->SetInteger("completed_count",
+ base::saturated_cast<int>(stats.completed_count));
+ state->SetInteger("canceled_count",
+ base::saturated_cast<int>(stats.canceled_count));
return state;
}
@@ -195,47 +228,42 @@ RasterTaskCompletionStatsAsValue(const RasterTaskCompletionStats& stats) {
scoped_ptr<TileManager> TileManager::Create(
TileManagerClient* client,
base::SequencedTaskRunner* task_runner,
- ResourcePool* resource_pool,
- TileTaskRunner* tile_task_runner,
size_t scheduled_raster_task_limit) {
- return make_scoped_ptr(new TileManager(client, task_runner, resource_pool,
- tile_task_runner,
- scheduled_raster_task_limit));
+ return make_scoped_ptr(
+ new TileManager(client, task_runner, scheduled_raster_task_limit));
}
TileManager::TileManager(
TileManagerClient* client,
const scoped_refptr<base::SequencedTaskRunner>& task_runner,
- ResourcePool* resource_pool,
- TileTaskRunner* tile_task_runner,
size_t scheduled_raster_task_limit)
: client_(client),
task_runner_(task_runner),
- resource_pool_(resource_pool),
- tile_task_runner_(tile_task_runner),
+ resource_pool_(nullptr),
+ tile_task_runner_(nullptr),
scheduled_raster_task_limit_(scheduled_raster_task_limit),
all_tiles_that_need_to_be_rasterized_are_scheduled_(true),
did_check_for_completed_tasks_since_last_schedule_tasks_(true),
did_oom_on_last_assign_(false),
- ready_to_activate_check_notifier_(
- task_runner_.get(),
- base::Bind(&TileManager::CheckIfReadyToActivate,
- base::Unretained(this))),
- ready_to_draw_check_notifier_(
- task_runner_.get(),
- base::Bind(&TileManager::CheckIfReadyToDraw, base::Unretained(this))),
more_tiles_need_prepare_check_notifier_(
task_runner_.get(),
base::Bind(&TileManager::CheckIfMoreTilesNeedToBePrepared,
base::Unretained(this))),
- did_notify_ready_to_activate_(false),
- did_notify_ready_to_draw_(false) {
- tile_task_runner_->SetClient(this);
+ signals_check_notifier_(task_runner_.get(),
+ base::Bind(&TileManager::CheckAndIssueSignals,
+ base::Unretained(this))),
+ has_scheduled_tile_tasks_(false),
+ prepare_tiles_count_(0u) {
}
TileManager::~TileManager() {
- // Reset global state and manage. This should cause
- // our memory usage to drop to zero.
+ FinishTasksAndCleanUp();
+}
+
+void TileManager::FinishTasksAndCleanUp() {
+ if (!tile_task_runner_)
+ return;
+
global_state_ = GlobalStateThatImpactsTilePriority();
TileTaskQueue empty;
@@ -249,6 +277,23 @@ TileManager::~TileManager() {
FreeResourcesForReleasedTiles();
CleanUpReleasedTiles();
+
+ tile_task_runner_ = nullptr;
+ resource_pool_ = nullptr;
+ more_tiles_need_prepare_check_notifier_.Cancel();
+ signals_check_notifier_.Cancel();
+}
+
+void TileManager::SetResources(ResourcePool* resource_pool,
+ TileTaskRunner* tile_task_runner,
+ size_t scheduled_raster_task_limit) {
+ DCHECK(!tile_task_runner_);
+ DCHECK(tile_task_runner);
+
+ scheduled_raster_task_limit_ = scheduled_raster_task_limit;
+ resource_pool_ = resource_pool;
+ tile_task_runner_ = tile_task_runner;
+ tile_task_runner_->SetClient(this);
}
void TileManager::Release(Tile* tile) {
@@ -295,35 +340,58 @@ void TileManager::CleanUpReleasedTiles() {
void TileManager::DidFinishRunningTileTasks(TaskSet task_set) {
TRACE_EVENT1("cc", "TileManager::DidFinishRunningTileTasks", "task_set",
TaskSetName(task_set));
+ DCHECK(resource_pool_);
+ DCHECK(tile_task_runner_);
switch (task_set) {
case ALL: {
+ has_scheduled_tile_tasks_ = false;
+
bool memory_usage_above_limit =
resource_pool_->total_memory_usage_bytes() >
global_state_.soft_memory_limit_in_bytes;
if (all_tiles_that_need_to_be_rasterized_are_scheduled_ &&
- !memory_usage_above_limit)
+ !memory_usage_above_limit) {
+ // TODO(ericrk): We should find a better way to safely handle re-entrant
+ // notifications than always having to schedule a new task.
+ // http://crbug.com/498439
+ signals_.all_tile_tasks_completed = true;
+ signals_check_notifier_.Schedule();
return;
+ }
more_tiles_need_prepare_check_notifier_.Schedule();
return;
}
case REQUIRED_FOR_ACTIVATION:
- ready_to_activate_check_notifier_.Schedule();
+ signals_.ready_to_activate = true;
+ signals_check_notifier_.Schedule();
return;
+
case REQUIRED_FOR_DRAW:
- ready_to_draw_check_notifier_.Schedule();
+ signals_.ready_to_draw = true;
+ signals_check_notifier_.Schedule();
return;
}
NOTREACHED();
}
-void TileManager::PrepareTiles(
+bool TileManager::PrepareTiles(
const GlobalStateThatImpactsTilePriority& state) {
- TRACE_EVENT0("cc", "TileManager::PrepareTiles");
+ ++prepare_tiles_count_;
+
+ TRACE_EVENT1("cc", "TileManager::PrepareTiles", "prepare_tiles_id",
+ prepare_tiles_count_);
+
+ if (!tile_task_runner_) {
+ TRACE_EVENT_INSTANT0("cc", "PrepareTiles aborted",
+ TRACE_EVENT_SCOPE_THREAD);
+ return false;
+ }
+ signals_.reset();
global_state_ = state;
// We need to call CheckForCompletedTasks() once in-between each call
@@ -353,32 +421,30 @@ void TileManager::PrepareTiles(
// Schedule tile tasks.
ScheduleTasks(tiles_that_need_to_be_rasterized);
- did_notify_ready_to_activate_ = false;
- did_notify_ready_to_draw_ = false;
-
TRACE_EVENT_INSTANT1("cc", "DidPrepareTiles", TRACE_EVENT_SCOPE_THREAD,
"state", BasicStateAsValue());
TRACE_COUNTER_ID1("cc", "unused_memory_bytes", this,
resource_pool_->total_memory_usage_bytes() -
resource_pool_->acquired_memory_usage_bytes());
+ return true;
}
-void TileManager::UpdateVisibleTiles(
- const GlobalStateThatImpactsTilePriority& state) {
- TRACE_EVENT0("cc", "TileManager::UpdateVisibleTiles");
+void TileManager::Flush() {
+ TRACE_EVENT0("cc", "TileManager::Flush");
+
+ if (!tile_task_runner_) {
+ TRACE_EVENT_INSTANT0("cc", "Flush aborted", TRACE_EVENT_SCOPE_THREAD);
+ return;
+ }
tile_task_runner_->CheckForCompletedTasks();
did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
- TRACE_EVENT_INSTANT1(
- "cc",
- "DidUpdateVisibleTiles",
- TRACE_EVENT_SCOPE_THREAD,
- "stats",
- RasterTaskCompletionStatsAsValue(update_visible_tiles_stats_));
- update_visible_tiles_stats_ = RasterTaskCompletionStats();
+ TRACE_EVENT_INSTANT1("cc", "DidFlush", TRACE_EVENT_SCOPE_THREAD, "stats",
+ RasterTaskCompletionStatsAsValue(flush_stats_));
+ flush_stats_ = RasterTaskCompletionStats();
}
scoped_refptr<base::trace_event::ConvertableToTraceFormat>
@@ -391,7 +457,7 @@ TileManager::BasicStateAsValue() const {
void TileManager::BasicStateAsValueInto(
base::trace_event::TracedValue* state) const {
- state->SetInteger("tile_count", tiles_.size());
+ state->SetInteger("tile_count", base::saturated_cast<int>(tiles_.size()));
state->SetBoolean("did_oom_on_last_assign", did_oom_on_last_assign_);
state->BeginDictionary("global_state");
global_state_.AsValueInto(state);
@@ -468,6 +534,9 @@ void TileManager::AssignGpuMemoryToTiles(
PrioritizedTileVector* tiles_that_need_to_be_rasterized) {
TRACE_EVENT_BEGIN0("cc", "TileManager::AssignGpuMemoryToTiles");
+ DCHECK(resource_pool_);
+ DCHECK(tile_task_runner_);
+
// Maintain the list of released resources that can potentially be re-used
// or deleted. If this operation becomes expensive too, only do this after
// some resource(s) was returned. Note that in that case, one also need to
@@ -564,6 +633,7 @@ void TileManager::AssignGpuMemoryToTiles(
memory_stats_from_last_assign_.total_budget_in_bytes =
global_state_.hard_memory_limit_in_bytes;
memory_stats_from_last_assign_.total_bytes_used = memory_usage.memory_bytes();
+ DCHECK_GE(memory_stats_from_last_assign_.total_bytes_used, 0);
memory_stats_from_last_assign_.had_enough_memory =
had_enough_memory_to_schedule_tiles_needed_now;
@@ -577,7 +647,7 @@ void TileManager::AssignGpuMemoryToTiles(
void TileManager::FreeResourcesForTile(Tile* tile) {
TileDrawInfo& draw_info = tile->draw_info();
if (draw_info.resource_)
- resource_pool_->ReleaseResource(draw_info.resource_.Pass());
+ resource_pool_->ReleaseResource(draw_info.resource_.Pass(), tile->id());
}
void TileManager::FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(
@@ -599,6 +669,11 @@ void TileManager::ScheduleTasks(
raster_queue_.Reset();
+ // Even when scheduling an empty set of tiles, the TTWP does some work, and
+ // will always trigger a DidFinishRunningTileTasks notification. Because of
+ // this we unconditionally set |has_scheduled_tile_tasks_| to true.
+ has_scheduled_tile_tasks_ = true;
+
// Build a new task queue containing all task currently needed. Tasks
// are added in order of priority, highest priority task first.
for (auto& prioritized_tile : tiles_that_need_to_be_rasterized) {
@@ -641,19 +716,32 @@ scoped_refptr<ImageDecodeTask> TileManager::CreateImageDecodeTask(
Tile* tile,
SkPixelRef* pixel_ref) {
return make_scoped_refptr(new ImageDecodeTaskImpl(
- pixel_ref,
+ pixel_ref, prepare_tiles_count_,
base::Bind(&TileManager::OnImageDecodeTaskCompleted,
- base::Unretained(this),
- tile->layer_id(),
+ base::Unretained(this), tile->layer_id(),
base::Unretained(pixel_ref))));
}
scoped_refptr<RasterTask> TileManager::CreateRasterTask(
const PrioritizedTile& prioritized_tile) {
Tile* tile = prioritized_tile.tile();
- scoped_ptr<ScopedResource> resource =
- resource_pool_->AcquireResource(tile->desired_texture_size(),
- tile_task_runner_->GetResourceFormat());
+ uint64_t resource_content_id = 0;
+ scoped_ptr<ScopedResource> resource;
+ if (tile->invalidated_id()) {
+ // TODO(danakj): For resources that are in use, we should still grab them
+ // and copy from them instead of rastering everything. crbug.com/492754
+ resource =
+ resource_pool_->TryAcquireResourceWithContentId(tile->invalidated_id());
+ }
+ if (resource) {
+ resource_content_id = tile->invalidated_id();
+ DCHECK_EQ(tile_task_runner_->GetResourceFormat(), resource->format());
+ DCHECK_EQ(tile->desired_texture_size().ToString(),
+ resource->size().ToString());
+ } else {
+ resource = resource_pool_->AcquireResource(
+ tile->desired_texture_size(), tile_task_runner_->GetResourceFormat());
+ }
const ScopedResource* const_resource = resource.get();
// Create and queue all image decode tasks that this tile depends on.
@@ -681,9 +769,11 @@ scoped_refptr<RasterTask> TileManager::CreateRasterTask(
return make_scoped_refptr(new RasterTaskImpl(
const_resource, prioritized_tile.raster_source(), tile->content_rect(),
- tile->contents_scale(), prioritized_tile.priority().resolution,
- tile->layer_id(), static_cast<const void*>(tile),
- tile->source_frame_number(), tile->use_picture_analysis(),
+ tile->invalidated_content_rect(), tile->contents_scale(),
+ prioritized_tile.priority().resolution, tile->layer_id(),
+ prepare_tiles_count_, static_cast<const void*>(tile), tile->id(),
+ tile->invalidated_id(), resource_content_id, tile->source_frame_number(),
+ tile->use_picture_analysis(),
base::Bind(&TileManager::OnRasterTaskCompleted, base::Unretained(this),
tile->id(), base::Passed(&resource)),
&decode_tasks));
@@ -722,8 +812,8 @@ void TileManager::OnRasterTaskCompleted(
tile->raster_task_ = nullptr;
if (was_canceled) {
- ++update_visible_tiles_stats_.canceled_count;
- resource_pool_->ReleaseResource(resource.Pass());
+ ++flush_stats_.canceled_count;
+ resource_pool_->ReleaseResource(resource.Pass(), tile->invalidated_id());
return;
}
@@ -736,17 +826,24 @@ void TileManager::UpdateTileDrawInfo(
const RasterSource::SolidColorAnalysis& analysis) {
TileDrawInfo& draw_info = tile->draw_info();
- ++update_visible_tiles_stats_.completed_count;
+ ++flush_stats_.completed_count;
if (analysis.is_solid_color) {
draw_info.set_solid_color(analysis.solid_color);
- if (resource)
- resource_pool_->ReleaseResource(resource.Pass());
+ if (resource) {
+ // Pass the old tile id here because the tile is solid color so we did not
+ // raster anything into the tile resource.
+ resource_pool_->ReleaseResource(resource.Pass(), tile->invalidated_id());
+ }
} else {
DCHECK(resource);
draw_info.set_use_resource();
draw_info.resource_ = resource.Pass();
+ draw_info.contents_swizzled_ =
+ tile_task_runner_->GetResourceRequiresSwizzle();
}
+ DCHECK(draw_info.IsReadyToDraw());
+ draw_info.set_was_ever_ready_to_draw();
client_->NotifyTileStateChanged(tile);
}
@@ -757,6 +854,9 @@ ScopedTilePtr TileManager::CreateTile(const gfx::Size& desired_texture_size,
int layer_id,
int source_frame_number,
int flags) {
+ // We need to have a tile task worker pool to do anything meaningful with
+ // tiles.
+ DCHECK(tile_task_runner_);
ScopedTilePtr tile(new Tile(this, desired_texture_size, content_rect,
contents_scale, layer_id, source_frame_number,
flags));
@@ -798,6 +898,7 @@ bool TileManager::AreRequiredTilesReadyToDraw(
#endif
return true;
}
+
bool TileManager::IsReadyToActivate() const {
TRACE_EVENT0("cc", "TileManager::IsReadyToActivate");
return AreRequiredTilesReadyToDraw(
@@ -810,48 +911,43 @@ bool TileManager::IsReadyToDraw() const {
RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW);
}
-void TileManager::NotifyReadyToActivate() {
- TRACE_EVENT0("cc", "TileManager::NotifyReadyToActivate");
- if (did_notify_ready_to_activate_)
- return;
- client_->NotifyReadyToActivate();
- did_notify_ready_to_activate_ = true;
-}
-
-void TileManager::NotifyReadyToDraw() {
- TRACE_EVENT0("cc", "TileManager::NotifyReadyToDraw");
- if (did_notify_ready_to_draw_)
- return;
- client_->NotifyReadyToDraw();
- did_notify_ready_to_draw_ = true;
-}
-
-void TileManager::CheckIfReadyToActivate() {
- TRACE_EVENT0("cc", "TileManager::CheckIfReadyToActivate");
-
+void TileManager::CheckAndIssueSignals() {
+ TRACE_EVENT0("cc", "TileManager::CheckAndIssueSignals");
tile_task_runner_->CheckForCompletedTasks();
did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
- if (did_notify_ready_to_activate_)
- return;
- if (!IsReadyToActivate())
- return;
-
- NotifyReadyToActivate();
-}
-
-void TileManager::CheckIfReadyToDraw() {
- TRACE_EVENT0("cc", "TileManager::CheckIfReadyToDraw");
-
- tile_task_runner_->CheckForCompletedTasks();
- did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
+ // Ready to activate.
+ if (signals_.ready_to_activate && !signals_.did_notify_ready_to_activate) {
+ signals_.ready_to_activate = false;
+ if (IsReadyToActivate()) {
+ TRACE_EVENT0("cc",
+ "TileManager::CheckAndIssueSignals - ready to activate");
+ signals_.did_notify_ready_to_activate = true;
+ client_->NotifyReadyToActivate();
+ }
+ }
- if (did_notify_ready_to_draw_)
- return;
- if (!IsReadyToDraw())
- return;
+ // Ready to draw.
+ if (signals_.ready_to_draw && !signals_.did_notify_ready_to_draw) {
+ signals_.ready_to_draw = false;
+ if (IsReadyToDraw()) {
+ TRACE_EVENT0("cc", "TileManager::CheckAndIssueSignals - ready to draw");
+ signals_.did_notify_ready_to_draw = true;
+ client_->NotifyReadyToDraw();
+ }
+ }
- NotifyReadyToDraw();
+ // All tile tasks completed.
+ if (signals_.all_tile_tasks_completed &&
+ !signals_.did_notify_all_tile_tasks_completed) {
+ signals_.all_tile_tasks_completed = false;
+ if (!has_scheduled_tile_tasks_) {
+ TRACE_EVENT0(
+ "cc", "TileManager::CheckAndIssueSignals - all tile tasks completed");
+ signals_.did_notify_all_tile_tasks_completed = true;
+ client_->NotifyAllTileTasksCompleted();
+ }
+ }
}
void TileManager::CheckIfMoreTilesNeedToBePrepared() {
@@ -885,6 +981,9 @@ void TileManager::CheckIfMoreTilesNeedToBePrepared() {
resource_pool_->ReduceResourceUsage();
+ signals_.all_tile_tasks_completed = true;
+ signals_check_notifier_.Schedule();
+
// We don't reserve memory for required-for-activation tiles during
// accelerated gestures, so we just postpone activation when we don't
// have these tiles, and activate after the accelerated gesture.
@@ -919,21 +1018,36 @@ void TileManager::CheckIfMoreTilesNeedToBePrepared() {
}
DCHECK(IsReadyToActivate());
- ready_to_activate_check_notifier_.Schedule();
+ // TODO(ericrk): Investigate why we need to schedule this (not just call it
+ // inline). http://crbug.com/498439
+ signals_.ready_to_activate = true;
+ signals_check_notifier_.Schedule();
}
TileManager::MemoryUsage::MemoryUsage() : memory_bytes_(0), resource_count_(0) {
}
-TileManager::MemoryUsage::MemoryUsage(int64 memory_bytes, int resource_count)
- : memory_bytes_(memory_bytes), resource_count_(resource_count) {
+TileManager::MemoryUsage::MemoryUsage(size_t memory_bytes,
+ size_t resource_count)
+ : memory_bytes_(static_cast<int64>(memory_bytes)),
+ resource_count_(static_cast<int>(resource_count)) {
+ // MemoryUsage is constructed using size_ts, since it deals with memory and
+ // the inputs are typically size_t. However, during the course of usage (in
+ // particular operator-=) can cause internal values to become negative. Thus,
+ // member variables are signed.
+ DCHECK_LE(memory_bytes,
+ static_cast<size_t>(std::numeric_limits<int64>::max()));
+ DCHECK_LE(resource_count,
+ static_cast<size_t>(std::numeric_limits<int>::max()));
}
// static
TileManager::MemoryUsage TileManager::MemoryUsage::FromConfig(
const gfx::Size& size,
ResourceFormat format) {
- return MemoryUsage(Resource::MemorySizeBytes(size, format), 1);
+ // We can use UncheckedMemorySizeBytes here since this is used with a tile
+ // size which is determined by the compositor (it's at most max texture size).
+ return MemoryUsage(Resource::UncheckedMemorySizeBytes(size, format), 1);
}
// static
@@ -972,4 +1086,17 @@ bool TileManager::MemoryUsage::Exceeds(const MemoryUsage& limit) const {
resource_count_ > limit.resource_count_;
}
+TileManager::Signals::Signals() {
+ reset();
+}
+
+void TileManager::Signals::reset() {
+ ready_to_activate = false;
+ did_notify_ready_to_activate = false;
+ ready_to_draw = false;
+ did_notify_ready_to_draw = false;
+ all_tile_tasks_completed = false;
+ did_notify_all_tile_tasks_completed = false;
+}
+
} // namespace cc
diff --git a/chromium/cc/tiles/tile_manager.h b/chromium/cc/tiles/tile_manager.h
index 8611b3a3615..a69e5a27dcf 100644
--- a/chromium/cc/tiles/tile_manager.h
+++ b/chromium/cc/tiles/tile_manager.h
@@ -43,6 +43,10 @@ class CC_EXPORT TileManagerClient {
// Called when all tiles marked as required for draw are ready to draw.
virtual void NotifyReadyToDraw() = 0;
+ // Called when all tile tasks started by the most recent call to PrepareTiles
+ // are completed.
+ virtual void NotifyAllTileTasksCompleted() = 0;
+
// Called when the visible representation of a tile might have changed. Some
// examples are:
// - Tile version initialized.
@@ -102,8 +106,6 @@ class CC_EXPORT TileManager : public TileTaskRunnerClient {
static scoped_ptr<TileManager> Create(TileManagerClient* client,
base::SequencedTaskRunner* task_runner,
- ResourcePool* resource_pool,
- TileTaskRunner* tile_task_runner,
size_t scheduled_raster_task_limit);
~TileManager() override;
@@ -112,9 +114,23 @@ class CC_EXPORT TileManager : public TileTaskRunnerClient {
// activation are prepared, or failed to prepare due to OOM.
// - Runs client_->NotifyReadyToDraw() when all tiles required draw are
// prepared, or failed to prepare due to OOM.
- void PrepareTiles(const GlobalStateThatImpactsTilePriority& state);
+ bool PrepareTiles(const GlobalStateThatImpactsTilePriority& state);
+
+ // Synchronously finish any in progress work, cancel the rest, and clean up as
+ // much resources as possible. Also, prevents any future work until a
+ // SetResources call.
+ void FinishTasksAndCleanUp();
+
+ // Set the new given resource pool and tile task runner. Note that
+ // FinishTasksAndCleanUp must be called in between consecutive calls to
+ // SetResources.
+ void SetResources(ResourcePool* resource_pool,
+ TileTaskRunner* tile_task_runner,
+ size_t scheduled_raster_task_limit);
- void UpdateVisibleTiles(const GlobalStateThatImpactsTilePriority& state);
+ // This causes any completed raster work to finalize, so that tiles get up to
+ // date draw information.
+ void Flush();
ScopedTilePtr CreateTile(const gfx::Size& desired_texture_size,
const gfx::Rect& content_rect,
@@ -179,11 +195,17 @@ class CC_EXPORT TileManager : public TileTaskRunnerClient {
CheckIfMoreTilesNeedToBePrepared();
}
+ void SetMoreTilesNeedToBeRasterizedForTesting() {
+ all_tiles_that_need_to_be_rasterized_are_scheduled_ = false;
+ }
+
+ bool HasScheduledTileTasksForTesting() const {
+ return has_scheduled_tile_tasks_;
+ }
+
protected:
TileManager(TileManagerClient* client,
const scoped_refptr<base::SequencedTaskRunner>& task_runner,
- ResourcePool* resource_pool,
- TileTaskRunner* tile_task_runner,
size_t scheduled_raster_task_limit);
void FreeResourcesForReleasedTiles();
@@ -213,7 +235,7 @@ class CC_EXPORT TileManager : public TileTaskRunnerClient {
class MemoryUsage {
public:
MemoryUsage();
- MemoryUsage(int64 memory_bytes, int resource_count);
+ MemoryUsage(size_t memory_bytes, size_t resource_count);
static MemoryUsage FromConfig(const gfx::Size& size, ResourceFormat format);
static MemoryUsage FromTile(const Tile* tile);
@@ -261,11 +283,8 @@ class CC_EXPORT TileManager : public TileTaskRunnerClient {
MemoryUsage* usage);
bool TilePriorityViolatesMemoryPolicy(const TilePriority& priority);
bool AreRequiredTilesReadyToDraw(RasterTilePriorityQueue::Type type) const;
- void NotifyReadyToActivate();
- void NotifyReadyToDraw();
- void CheckIfReadyToActivate();
- void CheckIfReadyToDraw();
void CheckIfMoreTilesNeedToBePrepared();
+ void CheckAndIssueSignals();
TileManagerClient* client_;
scoped_refptr<base::SequencedTaskRunner> task_runner_;
@@ -291,7 +310,7 @@ class CC_EXPORT TileManager : public TileTaskRunnerClient {
typedef base::hash_map<int, int> LayerCountMap;
LayerCountMap used_layer_counts_;
- RasterTaskCompletionStats update_visible_tiles_stats_;
+ RasterTaskCompletionStats flush_stats_;
std::vector<Tile*> released_tiles_;
@@ -300,12 +319,26 @@ class CC_EXPORT TileManager : public TileTaskRunnerClient {
std::vector<scoped_refptr<RasterTask>> orphan_raster_tasks_;
- UniqueNotifier ready_to_activate_check_notifier_;
- UniqueNotifier ready_to_draw_check_notifier_;
UniqueNotifier more_tiles_need_prepare_check_notifier_;
- bool did_notify_ready_to_activate_;
- bool did_notify_ready_to_draw_;
+ struct Signals {
+ Signals();
+
+ void reset();
+
+ bool ready_to_activate;
+ bool did_notify_ready_to_activate;
+ bool ready_to_draw;
+ bool did_notify_ready_to_draw;
+ bool all_tile_tasks_completed;
+ bool did_notify_all_tile_tasks_completed;
+ } signals_;
+
+ UniqueNotifier signals_check_notifier_;
+
+ bool has_scheduled_tile_tasks_;
+
+ uint64_t prepare_tiles_count_;
DISALLOW_COPY_AND_ASSIGN(TileManager);
};
diff --git a/chromium/cc/tiles/tile_manager_perftest.cc b/chromium/cc/tiles/tile_manager_perftest.cc
index 7b75a7a09bb..eea9b94922b 100644
--- a/chromium/cc/tiles/tile_manager_perftest.cc
+++ b/chromium/cc/tiles/tile_manager_perftest.cc
@@ -16,7 +16,6 @@
#include "cc/test/fake_picture_pile_impl.h"
#include "cc/test/fake_tile_manager.h"
#include "cc/test/fake_tile_manager_client.h"
-#include "cc/test/impl_side_painting_settings.h"
#include "cc/test/test_shared_bitmap_manager.h"
#include "cc/test/test_task_graph_runner.h"
#include "cc/test/test_tile_priorities.h"
@@ -27,8 +26,6 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/perf/perf_test.h"
-#include "ui/gfx/frame_time.h"
-
namespace cc {
namespace {
@@ -67,13 +64,16 @@ class FakeTileTaskRunnerImpl : public TileTaskRunner, public TileTaskClient {
}
completed_tasks_.clear();
}
- ResourceFormat GetResourceFormat() override {
- return RGBA_8888;
+ ResourceFormat GetResourceFormat() const override { return RGBA_8888; }
+ bool GetResourceRequiresSwizzle() const override {
+ return !PlatformColor::SameComponentOrder(GetResourceFormat());
}
// Overridden from TileTaskClient:
scoped_ptr<RasterBuffer> AcquireBufferForRaster(
- const Resource* resource) override {
+ const Resource* resource,
+ uint64_t new_content_id,
+ uint64_t previous_content_id) override {
return nullptr;
}
void ReleaseBufferForRaster(scoped_ptr<RasterBuffer> buffer) override {}
@@ -91,7 +91,7 @@ class TileManagerPerfTest : public testing::Test {
max_tiles_(10000),
id_(7),
proxy_(base::ThreadTaskRunnerHandle::Get()),
- host_impl_(ImplSidePaintingSettings(10000),
+ host_impl_(LayerTreeSettings(),
&proxy_,
&shared_bitmap_manager_,
&task_graph_runner_),
@@ -385,20 +385,18 @@ class TileManagerPerfTest : public testing::Test {
int approximate_tile_count_per_layer) {
std::vector<FakePictureLayerImpl*> layers =
CreateLayers(layer_count, approximate_tile_count_per_layer);
+
timer_.Reset();
bool resourceless_software_draw = false;
do {
- BeginFrameArgs args =
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
- host_impl_.WillBeginImplFrame(args);
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
for (const auto& layer : layers)
layer->UpdateTiles(resourceless_software_draw);
GlobalStateThatImpactsTilePriority global_state(GlobalStateForTest());
tile_manager()->PrepareTiles(global_state);
- tile_manager()->UpdateVisibleTiles(global_state);
+ tile_manager()->Flush();
timer_.NextLap();
- host_impl_.DidFinishImplFrame();
} while (!timer_.HasTimeLimitExpired());
perf_test::PrintResult("prepare_tiles", "", test_name,
diff --git a/chromium/cc/tiles/tile_manager_unittest.cc b/chromium/cc/tiles/tile_manager_unittest.cc
index bddf29f53b6..4a663cefaf5 100644
--- a/chromium/cc/tiles/tile_manager_unittest.cc
+++ b/chromium/cc/tiles/tile_manager_unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/run_loop.h"
#include "base/thread_task_runner_handle.h"
#include "cc/resources/resource_pool.h"
#include "cc/test/begin_frame_args_test.h"
@@ -13,7 +14,6 @@
#include "cc/test/fake_picture_layer_tiling_client.h"
#include "cc/test/fake_picture_pile_impl.h"
#include "cc/test/fake_tile_manager.h"
-#include "cc/test/impl_side_painting_settings.h"
#include "cc/test/test_shared_bitmap_manager.h"
#include "cc/test/test_task_graph_runner.h"
#include "cc/test/test_tile_priorities.h"
@@ -23,12 +23,13 @@
#include "cc/tiles/tile_priority.h"
#include "cc/tiles/tiling_set_raster_queue_all.h"
#include "cc/trees/layer_tree_impl.h"
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cc {
namespace {
-class LowResTilingsSettings : public ImplSidePaintingSettings {
+class LowResTilingsSettings : public LayerTreeSettings {
public:
LowResTilingsSettings() { create_low_res_tiling = true; }
};
@@ -595,10 +596,7 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueueInvalidation) {
}
TEST_F(TileManagerTilePriorityQueueTest, ActivationComesBeforeEventually) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
gfx::Size layer_bounds(1000, 1000);
SetupDefaultTrees(layer_bounds);
@@ -616,9 +614,7 @@ TEST_F(TileManagerTilePriorityQueueTest, ActivationComesBeforeEventually) {
// Set a small viewport, so we have soon and eventually tiles.
host_impl_.SetViewportSize(gfx::Size(200, 200));
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
bool update_lcd_text = false;
host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
@@ -824,10 +820,7 @@ TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueue) {
TEST_F(TileManagerTilePriorityQueueTest,
EvictionTilePriorityQueueWithOcclusion) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
gfx::Size tile_size(102, 102);
gfx::Size layer_bounds(1000, 1000);
@@ -847,9 +840,7 @@ TEST_F(TileManagerTilePriorityQueueTest,
static_cast<FakePictureLayerImpl*>(pending_layer_->children()[0]);
pending_child_layer->SetDrawsContent(true);
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
bool update_lcd_text = false;
host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
@@ -963,10 +954,7 @@ TEST_F(TileManagerTilePriorityQueueTest,
TEST_F(TileManagerTilePriorityQueueTest,
EvictionTilePriorityQueueWithTransparentLayer) {
- base::TimeTicks time_ticks;
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
gfx::Size tile_size(102, 102);
gfx::Size layer_bounds(1000, 1000);
@@ -985,17 +973,13 @@ TEST_F(TileManagerTilePriorityQueueTest,
// considered to be valid.
pending_child_layer->SetDrawsContent(true);
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
bool update_lcd_text = false;
host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
pending_child_layer->SetOpacity(0.0);
- time_ticks += base::TimeDelta::FromMilliseconds(1);
- host_impl_.SetCurrentBeginFrameArgs(
- CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ host_impl_.AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
// Renew all of the tile priorities.
@@ -1405,7 +1389,7 @@ TEST_F(TileManagerTilePriorityQueueTest,
ManagedMemoryPolicy policy = host_impl_.ActualManagedMemoryPolicy();
policy.bytes_limit_when_visible =
- Resource::MemorySizeBytes(gfx::Size(256, 256), RGBA_8888);
+ Resource::UncheckedMemorySizeBytes(gfx::Size(256, 256), RGBA_8888);
host_impl_.SetMemoryPolicy(policy);
EXPECT_FALSE(host_impl_.is_likely_to_require_a_draw());
@@ -1419,7 +1403,118 @@ TEST_F(TileManagerTilePriorityQueueTest,
host_impl_.tile_manager()->CheckIfMoreTilesNeedToBePreparedForTesting();
EXPECT_FALSE(host_impl_.is_likely_to_require_a_draw());
- host_impl_.resource_pool()->ReleaseResource(resource.Pass());
+ host_impl_.resource_pool()->ReleaseResource(resource.Pass(), 0);
+}
+
+TEST_F(TileManagerTilePriorityQueueTest, RasterQueueAllUsesCorrectTileBounds) {
+ // Verify that we use the real tile bounds when advancing phases during the
+ // tile iteration.
+ gfx::Size layer_bounds(1, 1);
+
+ scoped_refptr<FakePicturePileImpl> pile =
+ FakePicturePileImpl::CreateFilledPileWithDefaultTileSize(layer_bounds);
+
+ FakePictureLayerTilingClient pending_client;
+ pending_client.SetTileSize(gfx::Size(64, 64));
+
+ auto tiling_set = PictureLayerTilingSet::Create(
+ WhichTree::ACTIVE_TREE, &pending_client, 1.0f, 1.0f, 1000);
+ pending_client.set_twin_tiling_set(tiling_set.get());
+
+ auto tiling = tiling_set->AddTiling(1.0f, pile);
+
+ tiling->CreateAllTilesForTesting();
+ tiling->set_resolution(HIGH_RESOLUTION);
+
+ // The tile is (0, 0, 1, 1), create an intersecting and non-intersecting
+ // rectangle to test the advance phase with. The tile size is (64, 64), so
+ // both rectangles intersect the tile content size, but only one should
+ // intersect the actual size.
+ gfx::Rect non_intersecting_rect(2, 2, 10, 10);
+ gfx::Rect intersecting_rect(0, 0, 10, 10);
+ {
+ tiling->SetTilePriorityRectsForTesting(
+ non_intersecting_rect, // Visible rect.
+ intersecting_rect, // Skewport rect.
+ intersecting_rect, // Soon rect.
+ intersecting_rect); // Eventually rect.
+ scoped_ptr<TilingSetRasterQueueAll> queue(
+ new TilingSetRasterQueueAll(tiling_set.get(), false));
+ EXPECT_FALSE(queue->IsEmpty());
+ }
+ {
+ tiling->SetTilePriorityRectsForTesting(
+ non_intersecting_rect, // Visible rect.
+ non_intersecting_rect, // Skewport rect.
+ intersecting_rect, // Soon rect.
+ intersecting_rect); // Eventually rect.
+ scoped_ptr<TilingSetRasterQueueAll> queue(
+ new TilingSetRasterQueueAll(tiling_set.get(), false));
+ EXPECT_FALSE(queue->IsEmpty());
+ }
+ {
+ tiling->SetTilePriorityRectsForTesting(
+ non_intersecting_rect, // Visible rect.
+ non_intersecting_rect, // Skewport rect.
+ non_intersecting_rect, // Soon rect.
+ intersecting_rect); // Eventually rect.
+ scoped_ptr<TilingSetRasterQueueAll> queue(
+ new TilingSetRasterQueueAll(tiling_set.get(), false));
+ EXPECT_FALSE(queue->IsEmpty());
+ }
+}
+
+class TileManagerTest : public testing::Test {
+ public:
+ TileManagerTest()
+ : host_impl_(&proxy_, &shared_bitmap_manager_, &task_graph_runner_) {}
+
+ protected:
+ // MockLayerTreeHostImpl allows us to intercept tile manager callbacks.
+ class MockLayerTreeHostImpl : public FakeLayerTreeHostImpl {
+ public:
+ MockLayerTreeHostImpl(Proxy* proxy,
+ SharedBitmapManager* manager,
+ TaskGraphRunner* task_graph_runner)
+ : FakeLayerTreeHostImpl(proxy, manager, task_graph_runner) {
+ InitializeRenderer(FakeOutputSurface::Create3d());
+ }
+
+ MOCK_METHOD0(NotifyAllTileTasksCompleted, void());
+ };
+
+ TestSharedBitmapManager shared_bitmap_manager_;
+ TestTaskGraphRunner task_graph_runner_;
+ FakeImplProxy proxy_;
+ MockLayerTreeHostImpl host_impl_;
+};
+
+// Test to ensure that we call NotifyAllTileTasksCompleted when PrepareTiles is
+// called.
+TEST_F(TileManagerTest, AllWorkFinishedTest) {
+ // Check with no tile work enqueued.
+ {
+ base::RunLoop run_loop;
+ EXPECT_FALSE(host_impl_.tile_manager()->HasScheduledTileTasksForTesting());
+ EXPECT_CALL(host_impl_, NotifyAllTileTasksCompleted())
+ .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); }));
+ host_impl_.tile_manager()->PrepareTiles(host_impl_.global_tile_state());
+ EXPECT_TRUE(host_impl_.tile_manager()->HasScheduledTileTasksForTesting());
+ run_loop.Run();
+ }
+
+ // Check that the "schedule more work" path also triggers the expected
+ // callback.
+ {
+ base::RunLoop run_loop;
+ EXPECT_FALSE(host_impl_.tile_manager()->HasScheduledTileTasksForTesting());
+ EXPECT_CALL(host_impl_, NotifyAllTileTasksCompleted())
+ .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); }));
+ host_impl_.tile_manager()->PrepareTiles(host_impl_.global_tile_state());
+ host_impl_.tile_manager()->SetMoreTilesNeedToBeRasterizedForTesting();
+ EXPECT_TRUE(host_impl_.tile_manager()->HasScheduledTileTasksForTesting());
+ run_loop.Run();
+ }
}
} // namespace
diff --git a/chromium/cc/tiles/tile_priority.cc b/chromium/cc/tiles/tile_priority.cc
index cf9872e6dcd..0efe51e5972 100644
--- a/chromium/cc/tiles/tile_priority.cc
+++ b/chromium/cc/tiles/tile_priority.cc
@@ -4,6 +4,7 @@
#include "cc/tiles/tile_priority.h"
+#include "base/numerics/safe_conversions.h"
#include "base/trace_event/trace_event_argument.h"
#include "base/values.h"
#include "cc/base/math_util.h"
@@ -89,9 +90,12 @@ void GlobalStateThatImpactsTilePriority::AsValueInto(
base::trace_event::TracedValue* state) const {
state->SetString("memory_limit_policy",
TileMemoryLimitPolicyToString(memory_limit_policy));
- state->SetInteger("soft_memory_limit_in_bytes", soft_memory_limit_in_bytes);
- state->SetInteger("hard_memory_limit_in_bytes", hard_memory_limit_in_bytes);
- state->SetInteger("num_resources_limit", num_resources_limit);
+ state->SetInteger("soft_memory_limit_in_bytes",
+ base::saturated_cast<int>(soft_memory_limit_in_bytes));
+ state->SetInteger("hard_memory_limit_in_bytes",
+ base::saturated_cast<int>(hard_memory_limit_in_bytes));
+ state->SetInteger("num_resources_limit",
+ base::saturated_cast<int>(num_resources_limit));
state->SetString("tree_priority", TreePriorityToString(tree_priority));
}
diff --git a/chromium/cc/tiles/tiling_set_eviction_queue.cc b/chromium/cc/tiles/tiling_set_eviction_queue.cc
index 9329d0db29a..4b314d721b8 100644
--- a/chromium/cc/tiles/tiling_set_eviction_queue.cc
+++ b/chromium/cc/tiles/tiling_set_eviction_queue.cc
@@ -33,37 +33,39 @@ void TilingSetEvictionQueue::GenerateTilingOrder(
// for this class.
PictureLayerTilingSet::TilingRange range =
tiling_set->GetTilingRange(PictureLayerTilingSet::HIGHER_THAN_HIGH_RES);
- for (int i = range.start; i < range.end; ++i) {
- PictureLayerTiling* tiling = tiling_set->tiling_at(i);
+ for (size_t index = range.start; index < range.end; ++index) {
+ PictureLayerTiling* tiling = tiling_set->tiling_at(index);
if (tiling->has_tiles())
tilings_.push_back(tiling);
}
range = tiling_set->GetTilingRange(PictureLayerTilingSet::LOWER_THAN_LOW_RES);
- for (int i = range.end - 1; i >= range.start; --i) {
- PictureLayerTiling* tiling = tiling_set->tiling_at(i);
+ for (size_t i = range.start; i < range.end; ++i) {
+ size_t index = range.start + (range.end - 1 - i);
+ PictureLayerTiling* tiling = tiling_set->tiling_at(index);
if (tiling->has_tiles())
tilings_.push_back(tiling);
}
range = tiling_set->GetTilingRange(
PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES);
- for (int i = range.end - 1; i >= range.start; --i) {
- PictureLayerTiling* tiling = tiling_set->tiling_at(i);
+ for (size_t i = range.start; i < range.end; ++i) {
+ size_t index = range.start + (range.end - 1 - i);
+ PictureLayerTiling* tiling = tiling_set->tiling_at(index);
if (tiling->has_tiles())
tilings_.push_back(tiling);
}
range = tiling_set->GetTilingRange(PictureLayerTilingSet::LOW_RES);
- for (int i = range.start; i < range.end; ++i) {
- PictureLayerTiling* tiling = tiling_set->tiling_at(i);
+ for (size_t index = range.start; index < range.end; ++index) {
+ PictureLayerTiling* tiling = tiling_set->tiling_at(index);
if (tiling->has_tiles())
tilings_.push_back(tiling);
}
range = tiling_set->GetTilingRange(PictureLayerTilingSet::HIGH_RES);
- for (int i = range.start; i < range.end; ++i) {
- PictureLayerTiling* tiling = tiling_set->tiling_at(i);
+ for (size_t index = range.start; index < range.end; ++index) {
+ PictureLayerTiling* tiling = tiling_set->tiling_at(index);
if (tiling->has_tiles())
tilings_.push_back(tiling);
}
@@ -222,9 +224,11 @@ bool TilingSetEvictionQueue::EvictionRectIterator::GetFirstTileAndCheckIfValid(
// After the pending visible rect has been processed, we must return false
// for pending visible rect tiles as tiling iterators do not ignore those
// tiles.
- if (priority_rect_type_ > PictureLayerTiling::PENDING_VISIBLE_RECT &&
- tiling->pending_visible_rect().Intersects(tile->content_rect())) {
- return false;
+ if (priority_rect_type_ > PictureLayerTiling::PENDING_VISIBLE_RECT) {
+ gfx::Rect tile_rect = tiling->tiling_data()->TileBounds(
+ tile->tiling_i_index(), tile->tiling_j_index());
+ if (tiling->pending_visible_rect().Intersects(tile_rect))
+ return false;
}
(*tilings_)[tiling_index_]->UpdateRequiredStatesOnTile(tile);
prioritized_tile_ = (*tilings_)[tiling_index_]->MakePrioritizedTile(
diff --git a/chromium/cc/tiles/tiling_set_raster_queue_all.cc b/chromium/cc/tiles/tiling_set_raster_queue_all.cc
index ae91f271fc2..1cac85d2ad0 100644
--- a/chromium/cc/tiles/tiling_set_raster_queue_all.cc
+++ b/chromium/cc/tiles/tiling_set_raster_queue_all.cc
@@ -52,32 +52,36 @@ TilingSetRasterQueueAll::TilingSetRasterQueueAll(
}
}
- bool use_low_res_tiling = low_res_tiling && low_res_tiling->has_tiles();
- if (use_low_res_tiling && prioritize_low_res) {
- iterators_[LOW_RES] =
- TilingIterator(low_res_tiling, &low_res_tiling->tiling_data_);
- stages_->push_back(IterationStage(LOW_RES, TilePriority::NOW));
+ bool use_low_res_tiling = low_res_tiling && low_res_tiling->has_tiles() &&
+ !low_res_tiling->all_tiles_done();
+ bool use_high_res_tiling = high_res_tiling && high_res_tiling->has_tiles() &&
+ !high_res_tiling->all_tiles_done();
+ bool use_active_non_ideal_pending_high_res_tiling =
+ active_non_ideal_pending_high_res_tiling &&
+ active_non_ideal_pending_high_res_tiling->has_tiles() &&
+ !active_non_ideal_pending_high_res_tiling->all_tiles_done();
+
+ // Make the tiling iterators.
+ if (use_low_res_tiling)
+ MakeTilingIterator(LOW_RES, low_res_tiling);
+ if (use_high_res_tiling)
+ MakeTilingIterator(HIGH_RES, high_res_tiling);
+ if (use_active_non_ideal_pending_high_res_tiling) {
+ MakeTilingIterator(ACTIVE_NON_IDEAL_PENDING_HIGH_RES,
+ active_non_ideal_pending_high_res_tiling);
}
- bool use_high_res_tiling = high_res_tiling && high_res_tiling->has_tiles();
- if (use_high_res_tiling) {
- iterators_[HIGH_RES] =
- TilingIterator(high_res_tiling, &high_res_tiling->tiling_data_);
+ // Set up the stages.
+ if (use_low_res_tiling && prioritize_low_res)
+ stages_->push_back(IterationStage(LOW_RES, TilePriority::NOW));
+
+ if (use_high_res_tiling)
stages_->push_back(IterationStage(HIGH_RES, TilePriority::NOW));
- }
- if (low_res_tiling && !prioritize_low_res) {
- iterators_[LOW_RES] =
- TilingIterator(low_res_tiling, &low_res_tiling->tiling_data_);
+ if (low_res_tiling && !prioritize_low_res)
stages_->push_back(IterationStage(LOW_RES, TilePriority::NOW));
- }
-
- if (active_non_ideal_pending_high_res_tiling &&
- active_non_ideal_pending_high_res_tiling->has_tiles()) {
- iterators_[ACTIVE_NON_IDEAL_PENDING_HIGH_RES] =
- TilingIterator(active_non_ideal_pending_high_res_tiling,
- &active_non_ideal_pending_high_res_tiling->tiling_data_);
+ if (use_active_non_ideal_pending_high_res_tiling) {
stages_->push_back(
IterationStage(ACTIVE_NON_IDEAL_PENDING_HIGH_RES, TilePriority::NOW));
stages_->push_back(
@@ -101,6 +105,16 @@ TilingSetRasterQueueAll::TilingSetRasterQueueAll(
TilingSetRasterQueueAll::~TilingSetRasterQueueAll() {
}
+void TilingSetRasterQueueAll::MakeTilingIterator(IteratorType type,
+ PictureLayerTiling* tiling) {
+ iterators_[type] = TilingIterator(tiling, &tiling->tiling_data_);
+ if (iterators_[type].done()) {
+ tiling->set_all_tiles_done(true);
+ // If we've marked the tiling as done, make sure we're actually done.
+ tiling->VerifyNoTileNeedsRaster();
+ }
+}
+
bool TilingSetRasterQueueAll::IsEmpty() const {
return current_stage_ >= stages_->size();
}
@@ -152,20 +166,25 @@ TilingSetRasterQueueAll::OnePriorityRectIterator::OnePriorityRectIterator(
PictureLayerTiling::PriorityRectType priority_rect_type)
: tiling_(tiling),
tiling_data_(tiling_data),
- priority_rect_type_(priority_rect_type) {
+ priority_rect_type_(priority_rect_type),
+ pending_visible_rect_(tiling->pending_visible_rect()) {
}
template <typename TilingIteratorType>
void TilingSetRasterQueueAll::OnePriorityRectIterator::AdvanceToNextTile(
TilingIteratorType* iterator) {
- bool found_tile = false;
- while (!found_tile) {
+ for (;;) {
++(*iterator);
if (!(*iterator)) {
current_tile_ = PrioritizedTile();
break;
}
- found_tile = GetFirstTileAndCheckIfValid(iterator);
+ Tile* tile = tiling_->TileAt(iterator->index_x(), iterator->index_y());
+ if (IsTileValid(tile)) {
+ tiling_->UpdateRequiredStatesOnTile(tile);
+ current_tile_ = tiling_->MakePrioritizedTile(tile, priority_rect_type_);
+ break;
+ }
}
}
@@ -173,20 +192,28 @@ template <typename TilingIteratorType>
bool TilingSetRasterQueueAll::OnePriorityRectIterator::
GetFirstTileAndCheckIfValid(TilingIteratorType* iterator) {
Tile* tile = tiling_->TileAt(iterator->index_x(), iterator->index_y());
- if (!tile || !TileNeedsRaster(tile)) {
+ if (!IsTileValid(tile)) {
current_tile_ = PrioritizedTile();
return false;
}
+ tiling_->UpdateRequiredStatesOnTile(tile);
+ current_tile_ = tiling_->MakePrioritizedTile(tile, priority_rect_type_);
+ return true;
+}
+
+bool TilingSetRasterQueueAll::OnePriorityRectIterator::IsTileValid(
+ const Tile* tile) const {
+ if (!tile || !TileNeedsRaster(tile))
+ return false;
// After the pending visible rect has been processed, we must return false
// for pending visible rect tiles as tiling iterators do not ignore those
// tiles.
- if (priority_rect_type_ > PictureLayerTiling::PENDING_VISIBLE_RECT &&
- tiling_->pending_visible_rect().Intersects(tile->content_rect())) {
- current_tile_ = PrioritizedTile();
- return false;
+ if (priority_rect_type_ > PictureLayerTiling::PENDING_VISIBLE_RECT) {
+ gfx::Rect tile_rect = tiling_->tiling_data()->TileBounds(
+ tile->tiling_i_index(), tile->tiling_j_index());
+ if (pending_visible_rect_.Intersects(tile_rect))
+ return false;
}
- tiling_->UpdateRequiredStatesOnTile(tile);
- current_tile_ = tiling_->MakePrioritizedTile(tile, priority_rect_type_);
return true;
}
@@ -222,9 +249,8 @@ TilingSetRasterQueueAll::PendingVisibleTilingIterator::
: OnePriorityRectIterator(tiling,
tiling_data,
PictureLayerTiling::PENDING_VISIBLE_RECT) {
- iterator_ = TilingData::DifferenceIterator(tiling_data_,
- tiling_->pending_visible_rect(),
- tiling_->current_visible_rect());
+ iterator_ = TilingData::DifferenceIterator(
+ tiling_data_, pending_visible_rect_, tiling_->current_visible_rect());
if (!iterator_)
return;
if (!GetFirstTileAndCheckIfValid(&iterator_))
@@ -244,8 +270,7 @@ TilingSetRasterQueueAll::SkewportTilingIterator::SkewportTilingIterator(
TilingData* tiling_data)
: OnePriorityRectIterator(tiling,
tiling_data,
- PictureLayerTiling::SKEWPORT_RECT),
- pending_visible_rect_(tiling->pending_visible_rect()) {
+ PictureLayerTiling::SKEWPORT_RECT) {
if (!tiling_->has_skewport_rect_tiles())
return;
iterator_ = TilingData::SpiralDifferenceIterator(
@@ -257,23 +282,12 @@ TilingSetRasterQueueAll::SkewportTilingIterator::SkewportTilingIterator(
++(*this);
return;
}
- // TODO(e_hakkinen): This is not needed as GetFirstTileAndCheckIfValid
- // does the same checking.
- if (current_tile_.tile()->content_rect().Intersects(pending_visible_rect_))
- ++(*this);
}
TilingSetRasterQueueAll::SkewportTilingIterator&
TilingSetRasterQueueAll::SkewportTilingIterator::
operator++() {
AdvanceToNextTile(&iterator_);
- // TODO(e_hakkinen): This is not needed as GetFirstTileAndCheckIfValid called
- // by AdvanceToNextTile does the same checking.
- while (!done()) {
- if (!current_tile_.tile()->content_rect().Intersects(pending_visible_rect_))
- break;
- AdvanceToNextTile(&iterator_);
- }
return *this;
}
@@ -283,8 +297,7 @@ TilingSetRasterQueueAll::SoonBorderTilingIterator::SoonBorderTilingIterator(
TilingData* tiling_data)
: OnePriorityRectIterator(tiling,
tiling_data,
- PictureLayerTiling::SOON_BORDER_RECT),
- pending_visible_rect_(tiling->pending_visible_rect()) {
+ PictureLayerTiling::SOON_BORDER_RECT) {
if (!tiling_->has_soon_border_rect_tiles())
return;
iterator_ = TilingData::SpiralDifferenceIterator(
@@ -296,23 +309,12 @@ TilingSetRasterQueueAll::SoonBorderTilingIterator::SoonBorderTilingIterator(
++(*this);
return;
}
- // TODO(e_hakkinen): This is not needed as GetFirstTileAndCheckIfValid
- // does the same checking.
- if (current_tile_.tile()->content_rect().Intersects(pending_visible_rect_))
- ++(*this);
}
TilingSetRasterQueueAll::SoonBorderTilingIterator&
TilingSetRasterQueueAll::SoonBorderTilingIterator::
operator++() {
AdvanceToNextTile(&iterator_);
- // TODO(e_hakkinen): This is not needed as GetFirstTileAndCheckIfValid called
- // by AdvanceToNextTile does the same checking.
- while (!done()) {
- if (!current_tile_.tile()->content_rect().Intersects(pending_visible_rect_))
- break;
- AdvanceToNextTile(&iterator_);
- }
return *this;
}
@@ -322,8 +324,7 @@ TilingSetRasterQueueAll::EventuallyTilingIterator::EventuallyTilingIterator(
TilingData* tiling_data)
: OnePriorityRectIterator(tiling,
tiling_data,
- PictureLayerTiling::EVENTUALLY_RECT),
- pending_visible_rect_(tiling->pending_visible_rect()) {
+ PictureLayerTiling::EVENTUALLY_RECT) {
if (!tiling_->has_eventually_rect_tiles())
return;
iterator_ = TilingData::SpiralDifferenceIterator(
@@ -335,23 +336,12 @@ TilingSetRasterQueueAll::EventuallyTilingIterator::EventuallyTilingIterator(
++(*this);
return;
}
- // TODO(e_hakkinen): This is not needed as GetFirstTileAndCheckIfValid
- // does the same checking.
- if (current_tile_.tile()->content_rect().Intersects(pending_visible_rect_))
- ++(*this);
}
TilingSetRasterQueueAll::EventuallyTilingIterator&
TilingSetRasterQueueAll::EventuallyTilingIterator::
operator++() {
AdvanceToNextTile(&iterator_);
- // TODO(e_hakkinen): This is not needed as GetFirstTileAndCheckIfValid called
- // by AdvanceToNextTile does the same checking.
- while (!done()) {
- if (!current_tile_.tile()->content_rect().Intersects(pending_visible_rect_))
- break;
- AdvanceToNextTile(&iterator_);
- }
return *this;
}
diff --git a/chromium/cc/tiles/tiling_set_raster_queue_all.h b/chromium/cc/tiles/tiling_set_raster_queue_all.h
index 62d22493730..d6f79463fed 100644
--- a/chromium/cc/tiles/tiling_set_raster_queue_all.h
+++ b/chromium/cc/tiles/tiling_set_raster_queue_all.h
@@ -41,7 +41,7 @@ class CC_EXPORT TilingSetRasterQueueAll {
protected:
~OnePriorityRectIterator() = default;
- bool TileNeedsRaster(Tile* tile) const {
+ bool TileNeedsRaster(const Tile* tile) const {
return tile->draw_info().NeedsRaster() && !tiling_->IsTileOccluded(tile);
}
@@ -49,11 +49,13 @@ class CC_EXPORT TilingSetRasterQueueAll {
void AdvanceToNextTile(TilingIteratorType* iterator);
template <typename TilingIteratorType>
bool GetFirstTileAndCheckIfValid(TilingIteratorType* iterator);
+ bool IsTileValid(const Tile* tile) const;
PrioritizedTile current_tile_;
PictureLayerTiling* tiling_;
TilingData* tiling_data_;
PictureLayerTiling::PriorityRectType priority_rect_type_;
+ gfx::Rect pending_visible_rect_;
};
// Iterates over visible rect only, left to right top to bottom order.
@@ -90,7 +92,6 @@ class CC_EXPORT TilingSetRasterQueueAll {
private:
TilingData::SpiralDifferenceIterator iterator_;
- gfx::Rect pending_visible_rect_;
};
// Iterates over soon border only, spiral around the visible rect.
@@ -104,7 +105,6 @@ class CC_EXPORT TilingSetRasterQueueAll {
private:
TilingData::SpiralDifferenceIterator iterator_;
- gfx::Rect pending_visible_rect_;
};
// Iterates over eventually rect only, spiral around the soon rect.
@@ -118,7 +118,6 @@ class CC_EXPORT TilingSetRasterQueueAll {
private:
TilingData::SpiralDifferenceIterator iterator_;
- gfx::Rect pending_visible_rect_;
};
// Iterates over all of the above phases in the following order: visible,
@@ -174,6 +173,7 @@ class CC_EXPORT TilingSetRasterQueueAll {
NUM_ITERATORS
};
+ void MakeTilingIterator(IteratorType type, PictureLayerTiling* tiling);
void AdvanceToNextStage();
PictureLayerTilingSet* tiling_set_;
diff --git a/chromium/cc/tiles/tiling_set_raster_queue_required.cc b/chromium/cc/tiles/tiling_set_raster_queue_required.cc
index 07b123484c5..59696e40d22 100644
--- a/chromium/cc/tiles/tiling_set_raster_queue_required.cc
+++ b/chromium/cc/tiles/tiling_set_raster_queue_required.cc
@@ -41,7 +41,7 @@ TilingSetRasterQueueRequired::TilingSetRasterQueueRequired(
// If we don't have a tiling, then this queue will yield no tiles. See
// PictureLayerImpl::CanHaveTilings for examples of when a HIGH_RESOLUTION
// tiling would not be generated.
- if (!tiling)
+ if (!tiling || tiling->all_tiles_done())
return;
if (type == RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION) {
diff --git a/chromium/cc/trees/blocking_task_runner.cc b/chromium/cc/trees/blocking_task_runner.cc
index 1111e9bf4b7..b0a935e2529 100644
--- a/chromium/cc/trees/blocking_task_runner.cc
+++ b/chromium/cc/trees/blocking_task_runner.cc
@@ -8,7 +8,6 @@
#include "base/callback.h"
#include "base/logging.h"
-#include "base/message_loop/message_loop_proxy.h"
namespace cc {
diff --git a/chromium/cc/trees/damage_tracker.cc b/chromium/cc/trees/damage_tracker.cc
index 235dfcfd7ef..de11b47c1a9 100644
--- a/chromium/cc/trees/damage_tracker.cc
+++ b/chromium/cc/trees/damage_tracker.cc
@@ -288,6 +288,7 @@ void DamageTracker::ExtendDamageForLayer(LayerImpl* layer,
gfx::RectF damage_rect =
gfx::UnionRects(layer->update_rect(), layer->damage_rect());
+ damage_rect.Intersect(gfx::RectF(layer->bounds()));
if (layer_is_new || layer->LayerPropertyChanged()) {
// If a layer is new or has changed, then its entire layer rect affects the
@@ -300,9 +301,8 @@ void DamageTracker::ExtendDamageForLayer(LayerImpl* layer,
} else if (!damage_rect.IsEmpty()) {
// If the layer properties haven't changed, then the the target surface is
// only affected by the layer's damaged area, which could be empty.
- gfx::Rect damage_content_rect = layer->LayerRectToContentRect(damage_rect);
- gfx::Rect damage_rect_in_target_space = MathUtil::MapEnclosingClippedRect(
- layer->draw_transform(), damage_content_rect);
+ gfx::Rect damage_rect_in_target_space = gfx::ToEnclosingRect(
+ MathUtil::MapClippedRect(layer->draw_transform(), damage_rect));
target_damage_rect->Union(damage_rect_in_target_space);
}
}
diff --git a/chromium/cc/trees/damage_tracker_unittest.cc b/chromium/cc/trees/damage_tracker_unittest.cc
index 2df71ddf2a7..831b1f718ec 100644
--- a/chromium/cc/trees/damage_tracker_unittest.cc
+++ b/chromium/cc/trees/damage_tracker_unittest.cc
@@ -14,6 +14,7 @@
#include "cc/test/test_shared_bitmap_manager.h"
#include "cc/test/test_task_graph_runner.h"
#include "cc/trees/layer_tree_host_common.h"
+#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/single_thread_proxy.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/effects/SkBlurImageFilter.h"
@@ -47,6 +48,7 @@ void ClearDamageForAllSurfaces(LayerImpl* layer) {
}
void EmulateDrawingOneFrame(LayerImpl* root) {
+ root->layer_tree_impl()->property_trees()->needs_rebuild = true;
// This emulates only steps that are relevant to testing the damage tracker:
// 1. computing the render passes and layerlists
// 2. updating all damage trackers in the correct order
@@ -58,16 +60,17 @@ void EmulateDrawingOneFrame(LayerImpl* root) {
// Iterate back-to-front, so that damage correctly propagates from descendant
// surfaces to ancestors.
- for (int i = render_surface_layer_list.size() - 1; i >= 0; --i) {
+ size_t render_surface_layer_list_size = render_surface_layer_list.size();
+ for (size_t i = 0; i < render_surface_layer_list_size; ++i) {
+ size_t index = render_surface_layer_list_size - 1 - i;
RenderSurfaceImpl* target_surface =
- render_surface_layer_list[i]->render_surface();
+ render_surface_layer_list[index]->render_surface();
target_surface->damage_tracker()->UpdateDamageTrackingState(
- target_surface->layer_list(),
- target_surface->OwningLayerId(),
+ target_surface->layer_list(), target_surface->OwningLayerId(),
target_surface->SurfacePropertyChangedOnlyFromDescendant(),
target_surface->content_rect(),
- render_surface_layer_list[i]->mask_layer(),
- render_surface_layer_list[i]->filters());
+ render_surface_layer_list[index]->mask_layer(),
+ render_surface_layer_list[index]->filters());
}
root->ResetAllChangeTrackingForSubtree();
@@ -86,14 +89,12 @@ class DamageTrackerTest : public testing::Test {
root->SetPosition(gfx::PointF());
root->SetBounds(gfx::Size(500, 500));
- root->SetContentBounds(gfx::Size(500, 500));
root->SetDrawsContent(true);
root->SetHasRenderSurface(true);
root->render_surface()->SetContentRect(gfx::Rect(0, 0, 500, 500));
child->SetPosition(gfx::PointF(100.f, 100.f));
child->SetBounds(gfx::Size(30, 30));
- child->SetContentBounds(gfx::Size(30, 30));
child->SetDrawsContent(true);
root->AddChild(child.Pass());
@@ -118,14 +119,12 @@ class DamageTrackerTest : public testing::Test {
root->SetPosition(gfx::PointF());
root->SetBounds(gfx::Size(500, 500));
- root->SetContentBounds(gfx::Size(500, 500));
root->SetDrawsContent(true);
root->SetHasRenderSurface(true);
root->render_surface()->SetContentRect(gfx::Rect(0, 0, 500, 500));
child1->SetPosition(gfx::PointF(100.f, 100.f));
child1->SetBounds(gfx::Size(30, 30));
- child1->SetContentBounds(gfx::Size(30, 30));
// With a child that draws_content, opacity will cause the layer to create
// its own RenderSurface. This layer does not draw, but is intended to
// create its own RenderSurface.
@@ -134,17 +133,14 @@ class DamageTrackerTest : public testing::Test {
child2->SetPosition(gfx::PointF(11.f, 11.f));
child2->SetBounds(gfx::Size(18, 18));
- child2->SetContentBounds(gfx::Size(18, 18));
child2->SetDrawsContent(true);
grand_child1->SetPosition(gfx::PointF(200.f, 200.f));
grand_child1->SetBounds(gfx::Size(6, 8));
- grand_child1->SetContentBounds(gfx::Size(6, 8));
grand_child1->SetDrawsContent(true);
grand_child2->SetPosition(gfx::PointF(190.f, 190.f));
grand_child2->SetBounds(gfx::Size(6, 8));
- grand_child2->SetContentBounds(gfx::Size(6, 8));
grand_child2->SetDrawsContent(true);
child1->AddChild(grand_child1.Pass());
@@ -469,7 +465,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForPerspectiveClippedLayer) {
// Set up the child
child->SetPosition(gfx::PointF(0.f, 0.f));
child->SetBounds(gfx::Size(100, 100));
- child->SetContentBounds(gfx::Size(100, 100));
child->SetTransform(transform);
EmulateDrawingOneFrame(root.get());
@@ -707,7 +702,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingLayer) {
LayerImpl::Create(host_impl_.active_tree(), 3);
child2->SetPosition(gfx::PointF(400.f, 380.f));
child2->SetBounds(gfx::Size(6, 8));
- child2->SetContentBounds(gfx::Size(6, 8));
child2->SetDrawsContent(true);
root->AddChild(child2.Pass());
}
@@ -756,7 +750,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForNewUnchangedLayer) {
LayerImpl::Create(host_impl_.active_tree(), 3);
child2->SetPosition(gfx::PointF(400.f, 380.f));
child2->SetBounds(gfx::Size(6, 8));
- child2->SetContentBounds(gfx::Size(6, 8));
child2->SetDrawsContent(true);
child2->ResetAllChangeTrackingForSubtree();
// Sanity check the initial conditions of the test, if these asserts
@@ -789,7 +782,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForMultipleLayers) {
LayerImpl::Create(host_impl_.active_tree(), 3);
child2->SetPosition(gfx::PointF(400.f, 380.f));
child2->SetBounds(gfx::Size(6, 8));
- child2->SetContentBounds(gfx::Size(6, 8));
child2->SetDrawsContent(true);
root->AddChild(child2.Pass());
}
@@ -1039,7 +1031,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForReplica) {
LayerImpl::Create(host_impl_.active_tree(), 6);
grand_child3->SetPosition(gfx::PointF(240.f, 240.f));
grand_child3->SetBounds(gfx::Size(10, 10));
- grand_child3->SetContentBounds(gfx::Size(10, 10));
grand_child3->SetDrawsContent(true);
child1->AddChild(grand_child3.Pass());
}
@@ -1141,7 +1132,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) {
LayerImpl::Create(host_impl_.active_tree(), 3);
mask_layer->SetPosition(child->position());
mask_layer->SetBounds(child->bounds());
- mask_layer->SetContentBounds(child->bounds());
child->SetMaskLayer(mask_layer.Pass());
child->SetHasRenderSurface(true);
}
@@ -1154,7 +1144,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) {
LayerImpl::Create(host_impl_.active_tree(), 4);
grand_child->SetPosition(gfx::PointF(2.f, 2.f));
grand_child->SetBounds(gfx::Size(2, 2));
- grand_child->SetContentBounds(gfx::Size(2, 2));
grand_child->SetDrawsContent(true);
child->AddChild(grand_child.Pass());
}
@@ -1243,7 +1232,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForReplicaMask) {
LayerImpl::Create(host_impl_.active_tree(), 7);
replica_mask_layer->SetPosition(gfx::PointF());
replica_mask_layer->SetBounds(grand_child1->bounds());
- replica_mask_layer->SetContentBounds(grand_child1->bounds());
grand_child1_replica->SetMaskLayer(replica_mask_layer.Pass());
}
LayerImpl* replica_mask_layer = grand_child1_replica->mask_layer();
@@ -1322,7 +1310,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForReplicaMaskWithTransformOrigin) {
replica_mask_layer->SetPosition(gfx::PointF());
// Note: this is not the transform origin being tested.
replica_mask_layer->SetBounds(grand_child1->bounds());
- replica_mask_layer->SetContentBounds(grand_child1->bounds());
grand_child1_replica->SetMaskLayer(replica_mask_layer.Pass());
}
LayerImpl* replica_mask_layer = grand_child1_replica->mask_layer();
@@ -1456,7 +1443,6 @@ TEST_F(DamageTrackerTest, HugeDamageRect) {
// but has a huge negative position.
child->SetPosition(gfx::PointF());
child->SetBounds(gfx::Size(kBigNumber + i, kBigNumber + i));
- child->SetContentBounds(gfx::Size(kBigNumber + i, kBigNumber + i));
child->SetTransform(transform);
EmulateDrawingOneFrame(root.get());
diff --git a/chromium/cc/trees/draw_property_utils.cc b/chromium/cc/trees/draw_property_utils.cc
index b1b4de1dd74..9f63421ed94 100644
--- a/chromium/cc/trees/draw_property_utils.cc
+++ b/chromium/cc/trees/draw_property_utils.cc
@@ -270,7 +270,7 @@ static bool LayerShouldBeSkipped(LayerType* layer,
// Some additional conditions need to be computed at a later point after the
// recursion is finished.
// - the intersection of render_surface content and layer clip_rect is empty
- // - the visible_content_rect is empty
+ // - the visible_layer_rect is empty
//
// Note, if the layer should not have been drawn due to being fully
// transparent, we would have skipped the entire subtree and never made it
@@ -430,6 +430,14 @@ void ComputeTransforms(TransformTree* transform_tree) {
transform_tree->set_needs_update(false);
}
+void ComputeOpacities(OpacityTree* opacity_tree) {
+ if (!opacity_tree->needs_update())
+ return;
+ for (int i = 1; i < static_cast<int>(opacity_tree->size()); ++i)
+ opacity_tree->UpdateOpacities(i);
+ opacity_tree->set_needs_update(false);
+}
+
template <typename LayerType>
void ComputeVisibleRectsUsingPropertyTreesInternal(
LayerType* root_layer,
@@ -439,6 +447,7 @@ void ComputeVisibleRectsUsingPropertyTreesInternal(
property_trees->clip_tree.set_needs_update(true);
ComputeTransforms(&property_trees->transform_tree);
ComputeClips(&property_trees->clip_tree, property_trees->transform_tree);
+ ComputeOpacities(&property_trees->opacity_tree);
const bool subtree_is_visible_from_ancestor = true;
std::vector<LayerType*> visible_layer_list;
@@ -453,6 +462,8 @@ void ComputeVisibleRectsUsingPropertyTreesInternal(
void BuildPropertyTreesAndComputeVisibleRects(
Layer* root_layer,
const Layer* page_scale_layer,
+ const Layer* inner_viewport_scroll_layer,
+ const Layer* outer_viewport_scroll_layer,
float page_scale_factor,
float device_scale_factor,
const gfx::Rect& viewport,
@@ -460,7 +471,8 @@ void BuildPropertyTreesAndComputeVisibleRects(
PropertyTrees* property_trees,
LayerList* update_layer_list) {
PropertyTreeBuilder::BuildPropertyTrees(
- root_layer, page_scale_layer, page_scale_factor, device_scale_factor,
+ root_layer, page_scale_layer, inner_viewport_scroll_layer,
+ outer_viewport_scroll_layer, page_scale_factor, device_scale_factor,
viewport, device_transform, property_trees);
ComputeVisibleRectsUsingPropertyTrees(root_layer, property_trees,
update_layer_list);
@@ -469,6 +481,8 @@ void BuildPropertyTreesAndComputeVisibleRects(
void BuildPropertyTreesAndComputeVisibleRects(
LayerImpl* root_layer,
const LayerImpl* page_scale_layer,
+ const LayerImpl* inner_viewport_scroll_layer,
+ const LayerImpl* outer_viewport_scroll_layer,
float page_scale_factor,
float device_scale_factor,
const gfx::Rect& viewport,
@@ -476,7 +490,8 @@ void BuildPropertyTreesAndComputeVisibleRects(
PropertyTrees* property_trees,
LayerImplList* update_layer_list) {
PropertyTreeBuilder::BuildPropertyTrees(
- root_layer, page_scale_layer, page_scale_factor, device_scale_factor,
+ root_layer, page_scale_layer, inner_viewport_scroll_layer,
+ outer_viewport_scroll_layer, page_scale_factor, device_scale_factor,
viewport, device_transform, property_trees);
ComputeVisibleRectsUsingPropertyTrees(root_layer, property_trees,
update_layer_list);
@@ -501,10 +516,6 @@ gfx::Transform DrawTransformFromPropertyTreesInternal(
const LayerType* layer,
const TransformTree& tree) {
const TransformNode* node = tree.Node(layer->transform_tree_index());
- // TODO(vollick): ultimately we'll need to find this information (whether or
- // not we establish a render surface) somewhere other than the layer.
- const TransformNode* target_node =
- layer->render_surface() ? node : tree.Node(node->data.content_target_id);
gfx::Transform xform;
const bool owns_non_root_surface = layer->parent() && layer->render_surface();
@@ -518,8 +529,7 @@ gfx::Transform DrawTransformFromPropertyTreesInternal(
layer->offset_to_transform_parent().y());
} else {
// Surfaces need to apply their sublayer scale.
- xform.Scale(target_node->data.sublayer_scale.x(),
- target_node->data.sublayer_scale.y());
+ xform.Scale(node->data.sublayer_scale.x(), node->data.sublayer_scale.y());
}
return xform;
}
@@ -576,7 +586,7 @@ float DrawOpacityFromPropertyTreesInternal(LayerType layer,
float draw_opacity = 1.f;
while (node != target_node) {
- draw_opacity *= node->data;
+ draw_opacity *= node->data.opacity;
node = tree.parent(node);
}
return draw_opacity;
@@ -592,4 +602,34 @@ float DrawOpacityFromPropertyTrees(const LayerImpl* layer,
return DrawOpacityFromPropertyTreesInternal(layer, tree);
}
+bool CanUseLcdTextFromPropertyTrees(const LayerImpl* layer,
+ bool layers_always_allowed_lcd_text,
+ bool can_use_lcd_text,
+ PropertyTrees* property_trees) {
+ if (layers_always_allowed_lcd_text)
+ return true;
+ if (!can_use_lcd_text)
+ return false;
+ if (!layer->contents_opaque())
+ return false;
+ DCHECK(!property_trees->transform_tree.needs_update());
+ DCHECK(!property_trees->opacity_tree.needs_update());
+
+ const OpacityNode* opacity_node =
+ property_trees->opacity_tree.Node(layer->opacity_tree_index());
+ if (opacity_node->data.screen_space_opacity != 1.f)
+ return false;
+ const TransformNode* transform_node =
+ property_trees->transform_tree.Node(layer->transform_tree_index());
+ if (!transform_node->data.node_and_ancestors_have_only_integer_translation)
+ return false;
+ if (static_cast<int>(layer->offset_to_transform_parent().x()) !=
+ layer->offset_to_transform_parent().x())
+ return false;
+ if (static_cast<int>(layer->offset_to_transform_parent().y()) !=
+ layer->offset_to_transform_parent().y())
+ return false;
+ return true;
+}
+
} // namespace cc
diff --git a/chromium/cc/trees/draw_property_utils.h b/chromium/cc/trees/draw_property_utils.h
index 893645d7dd9..952bef1a691 100644
--- a/chromium/cc/trees/draw_property_utils.h
+++ b/chromium/cc/trees/draw_property_utils.h
@@ -33,28 +33,35 @@ ComputeClips(ClipTree* clip_tree, const TransformTree& transform_tree);
// tree. This must be done prior to calling |ComputeClips|.
void CC_EXPORT ComputeTransforms(TransformTree* transform_tree);
+// Computes screen space opacity for every node in the opacity tree.
+void CC_EXPORT ComputeOpacities(OpacityTree* opacity_tree);
+
// Computes the visible content rect for every layer under |root_layer|. The
// visible content rect is the clipped content space rect that will be used for
// recording.
-void CC_EXPORT
-BuildPropertyTreesAndComputeVisibleRects(Layer* root_layer,
- const Layer* page_scale_layer,
- float page_scale_factor,
- float device_scale_factor,
- const gfx::Rect& viewport,
- const gfx::Transform& device_transform,
- PropertyTrees* property_trees,
- LayerList* update_layer_list);
-
-void CC_EXPORT
-BuildPropertyTreesAndComputeVisibleRects(LayerImpl* root_layer,
- const LayerImpl* page_scale_layer,
- float page_scale_factor,
- float device_scale_factor,
- const gfx::Rect& viewport,
- const gfx::Transform& device_transform,
- PropertyTrees* property_trees,
- LayerImplList* update_layer_list);
+void CC_EXPORT BuildPropertyTreesAndComputeVisibleRects(
+ Layer* root_layer,
+ const Layer* page_scale_layer,
+ const Layer* inner_viewport_scroll_layer,
+ const Layer* outer_viewport_scroll_layer,
+ float page_scale_factor,
+ float device_scale_factor,
+ const gfx::Rect& viewport,
+ const gfx::Transform& device_transform,
+ PropertyTrees* property_trees,
+ LayerList* update_layer_list);
+
+void CC_EXPORT BuildPropertyTreesAndComputeVisibleRects(
+ LayerImpl* root_layer,
+ const LayerImpl* page_scale_layer,
+ const LayerImpl* inner_viewport_scroll_layer,
+ const LayerImpl* outer_viewport_scroll_layer,
+ float page_scale_factor,
+ float device_scale_factor,
+ const gfx::Rect& viewport,
+ const gfx::Transform& device_transform,
+ PropertyTrees* property_trees,
+ LayerImplList* update_layer_list);
void CC_EXPORT
ComputeVisibleRectsUsingPropertyTrees(Layer* root_layer,
@@ -87,6 +94,12 @@ DrawOpacityFromPropertyTrees(const Layer* layer, const OpacityTree& tree);
float CC_EXPORT
DrawOpacityFromPropertyTrees(const LayerImpl* layer, const OpacityTree& tree);
+bool CC_EXPORT
+CanUseLcdTextFromPropertyTrees(const LayerImpl* layer,
+ bool layers_always_allowed_lcd_text,
+ bool can_use_lcd_text,
+ PropertyTrees* property_trees);
+
} // namespace cc
#endif // CC_TREES_DRAW_PROPERTY_UTILS_H_
diff --git a/chromium/cc/trees/layer_tree_host.cc b/chromium/cc/trees/layer_tree_host.cc
index 6c4696ee10b..a348301ba49 100644
--- a/chromium/cc/trees/layer_tree_host.cc
+++ b/chromium/cc/trees/layer_tree_host.cc
@@ -20,6 +20,7 @@
#include "base/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"
+#include "cc/animation/animation_host.h"
#include "cc/animation/animation_registrar.h"
#include "cc/animation/layer_animation_controller.h"
#include "cc/base/math_util.h"
@@ -35,7 +36,6 @@
#include "cc/layers/layer_iterator.h"
#include "cc/layers/painted_scrollbar_layer.h"
#include "cc/layers/render_surface.h"
-#include "cc/resources/prioritized_resource_manager.h"
#include "cc/resources/ui_resource_request.h"
#include "cc/scheduler/begin_frame_source.h"
#include "cc/trees/draw_property_utils.h"
@@ -43,7 +43,6 @@
#include "cc/trees/layer_tree_host_common.h"
#include "cc/trees/layer_tree_host_impl.h"
#include "cc/trees/layer_tree_impl.h"
-#include "cc/trees/occlusion_tracker.h"
#include "cc/trees/single_thread_proxy.h"
#include "cc/trees/thread_proxy.h"
#include "cc/trees/tree_synchronizer.h"
@@ -94,6 +93,7 @@ LayerTreeHost::LayerTreeHost(InitParams* params)
needs_meta_info_recomputation_(true),
client_(params->client),
source_frame_number_(0),
+ meta_information_sequence_number_(1),
rendering_stats_instrumentation_(RenderingStatsInstrumentation::Create()),
output_surface_lost_(true),
settings_(*params->settings),
@@ -111,7 +111,6 @@ LayerTreeHost::LayerTreeHost(InitParams* params)
gpu_rasterization_histogram_recorded_(false),
background_color_(SK_ColorWHITE),
has_transparent_background_(false),
- partial_texture_update_requests_(0),
did_complete_scale_animation_(false),
in_paint_layer_contents_(false),
id_(s_layer_tree_host_sequence_number.GetNext() + 1),
@@ -121,8 +120,17 @@ LayerTreeHost::LayerTreeHost(InitParams* params)
task_graph_runner_(params->task_graph_runner),
surface_id_namespace_(0u),
next_surface_sequence_(1u) {
- if (settings_.accelerated_animation_enabled)
- animation_registrar_ = AnimationRegistrar::Create();
+ DCHECK(task_graph_runner_);
+
+ if (settings_.accelerated_animation_enabled) {
+ if (settings_.use_compositor_animation_timelines) {
+ animation_host_ = AnimationHost::Create(ThreadInstance::MAIN);
+ animation_host_->SetMutatorHostClient(this);
+ } else {
+ animation_registrar_ = AnimationRegistrar::Create();
+ }
+ }
+
rendering_stats_instrumentation_->set_record_rendering_stats(
debug_state_.RecordRenderingStats());
}
@@ -158,14 +166,21 @@ void LayerTreeHost::InitializeProxy(scoped_ptr<Proxy> proxy) {
proxy_ = proxy.Pass();
proxy_->Start();
if (settings_.accelerated_animation_enabled) {
- animation_registrar_->set_supports_scroll_animations(
- proxy_->SupportsImplScrolling());
+ if (animation_host_)
+ animation_host_->SetSupportsScrollAnimations(
+ proxy_->SupportsImplScrolling());
+ else
+ animation_registrar_->set_supports_scroll_animations(
+ proxy_->SupportsImplScrolling());
}
}
LayerTreeHost::~LayerTreeHost() {
TRACE_EVENT0("cc", "LayerTreeHost::~LayerTreeHost");
+ if (animation_host_)
+ animation_host_->SetMutatorHostClient(nullptr);
+
if (root_layer_.get())
root_layer_->SetLayerTreeHost(NULL);
@@ -193,13 +208,6 @@ void LayerTreeHost::SetLayerTreeHostClientReady() {
proxy_->SetLayerTreeHostClientReady();
}
-void LayerTreeHost::DeleteContentsTexturesOnImplThread(
- ResourceProvider* resource_provider) {
- DCHECK(proxy_->IsImplThread());
- if (contents_texture_manager_)
- contents_texture_manager_->ClearAllMemory(resource_provider);
-}
-
void LayerTreeHost::WillBeginMainFrame() {
devtools_instrumentation::WillBeginMainThreadFrame(id(),
source_frame_number());
@@ -241,32 +249,6 @@ void LayerTreeHost::BeginCommitOnImplThread(LayerTreeHostImpl* host_impl) {
void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl* host_impl) {
DCHECK(proxy_->IsImplThread());
- // If there are linked evicted backings, these backings' resources may be put
- // into the impl tree, so we can't draw yet. Determine this before clearing
- // all evicted backings.
- bool new_impl_tree_has_no_evicted_resources = false;
- if (contents_texture_manager_) {
- new_impl_tree_has_no_evicted_resources =
- !contents_texture_manager_->LinkedEvictedBackingsExist();
-
- // If the memory limit has been increased since this now-finishing
- // commit began, and the extra now-available memory would have been used,
- // then request another commit.
- if (contents_texture_manager_->MaxMemoryLimitBytes() <
- host_impl->memory_allocation_limit_bytes() &&
- contents_texture_manager_->MaxMemoryLimitBytes() <
- contents_texture_manager_->MaxMemoryNeededBytes()) {
- host_impl->SetNeedsCommit();
- }
-
- host_impl->set_max_memory_needed_bytes(
- contents_texture_manager_->MaxMemoryNeededBytes());
-
- contents_texture_manager_->UpdateBackingsState(
- host_impl->resource_provider());
- contents_texture_manager_->ReduceMemory(host_impl->resource_provider());
- }
-
bool is_new_trace;
TRACE_EVENT_IS_NEW_TRACE(&is_new_trace);
if (is_new_trace &&
@@ -317,6 +299,8 @@ void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl* host_impl) {
sync_tree->RegisterSelection(selection_);
+ // Setting property trees must happen before pushing the page scale.
+ sync_tree->SetPropertyTrees(property_trees_);
sync_tree->PushPageScaleFromMainThread(
page_scale_factor_, min_page_scale_factor_, max_page_scale_factor_);
sync_tree->elastic_overscroll()->PushFromMainThread(elastic_overscroll_);
@@ -350,30 +334,38 @@ void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl* host_impl) {
DCHECK(!sync_tree->ViewportSizeInvalid());
- if (new_impl_tree_has_no_evicted_resources) {
- if (sync_tree->ContentsTexturesPurged())
- sync_tree->ResetContentsTexturesPurged();
- }
-
sync_tree->set_has_ever_been_drawn(false);
- sync_tree->SetPropertyTrees(property_trees_);
{
TRACE_EVENT0("cc", "LayerTreeHost::PushProperties");
TreeSynchronizer::PushProperties(root_layer(), sync_tree->root_layer());
+
+ if (animation_host_) {
+ DCHECK(host_impl->animation_host());
+ animation_host_->PushPropertiesTo(host_impl->animation_host());
+ }
}
+ // This must happen after synchronizing property trees and after push
+ // properties, which updates property tree indices.
+ sync_tree->UpdatePropertyTreeScrollingAndAnimationFromMainThread();
+
micro_benchmark_controller_.ScheduleImplBenchmarks(host_impl);
}
void LayerTreeHost::WillCommit() {
+ OnCommitForSwapPromises();
client_->WillCommit();
}
void LayerTreeHost::UpdateHudLayer() {
if (debug_state_.ShowHudInfo()) {
- if (!hud_layer_.get())
- hud_layer_ = HeadsUpDisplayLayer::Create();
+ if (!hud_layer_.get()) {
+ LayerSettings hud_layer_settings;
+ hud_layer_settings.use_compositor_animation_timelines =
+ settings_.use_compositor_animation_timelines;
+ hud_layer_ = HeadsUpDisplayLayer::Create(hud_layer_settings);
+ }
if (root_layer_.get() && !hud_layer_->parent())
root_layer_->AddChild(hud_layer_);
@@ -406,19 +398,10 @@ void LayerTreeHost::RequestNewOutputSurface() {
void LayerTreeHost::DidInitializeOutputSurface() {
output_surface_lost_ = false;
-
- if (!contents_texture_manager_ && !settings_.impl_side_painting) {
- contents_texture_manager_ =
- PrioritizedResourceManager::Create(proxy_.get());
- surface_memory_placeholder_ =
- contents_texture_manager_->CreateTexture(gfx::Size(), RGBA_8888);
- }
-
if (root_layer()) {
LayerTreeHostCommon::CallFunctionForSubtree(
root_layer(), [](Layer* layer) { layer->OnOutputSurfaceCreated(); });
}
-
client_->DidInitializeOutputSurface();
}
@@ -493,12 +476,6 @@ void LayerTreeHost::SetNeedsUpdateLayers() {
}
void LayerTreeHost::SetNeedsCommit() {
- if (!prepaint_callback_.IsCancelled()) {
- TRACE_EVENT_INSTANT0("cc",
- "LayerTreeHost::SetNeedsCommit::cancel prepaint",
- TRACE_EVENT_SCOPE_THREAD);
- prepaint_callback_.Cancel();
- }
proxy_->SetNeedsCommit();
NotifySwapPromiseMonitorsOfSetNeedsCommit();
}
@@ -543,7 +520,10 @@ void LayerTreeHost::SetNextCommitForcesRedraw() {
void LayerTreeHost::SetAnimationEvents(
scoped_ptr<AnimationEventsVector> events) {
DCHECK(proxy_->IsMainThread());
- animation_registrar_->SetAnimationEvents(events.Pass());
+ if (animation_host_)
+ animation_host_->SetAnimationEvents(events.Pass());
+ else
+ animation_registrar_->SetAnimationEvents(events.Pass());
}
void LayerTreeHost::SetRootLayer(scoped_refptr<Layer> root_layer) {
@@ -679,6 +659,16 @@ void LayerTreeHost::NotifyInputThrottledUntilCommit() {
proxy_->NotifyInputThrottledUntilCommit();
}
+void LayerTreeHost::LayoutAndUpdateLayers() {
+ DCHECK(!proxy_->HasImplThread());
+ // This function is only valid when not using the scheduler.
+ DCHECK(!settings_.single_thread_proxy_scheduler);
+ SingleThreadProxy* proxy = static_cast<SingleThreadProxy*>(proxy_.get());
+
+ SetLayerTreeHostClientReady();
+ proxy->LayoutAndUpdateLayers();
+}
+
void LayerTreeHost::Composite(base::TimeTicks frame_begin_time) {
DCHECK(!proxy_->HasImplThread());
// This function is only valid when not using the scheduler.
@@ -689,18 +679,13 @@ void LayerTreeHost::Composite(base::TimeTicks frame_begin_time) {
proxy->CompositeImmediately(frame_begin_time);
}
-bool LayerTreeHost::UpdateLayers(ResourceUpdateQueue* queue) {
+bool LayerTreeHost::UpdateLayers() {
DCHECK(!output_surface_lost_);
-
if (!root_layer())
return false;
-
DCHECK(!root_layer()->parent());
-
- bool result = UpdateLayers(root_layer(), queue);
-
+ bool result = DoUpdateLayers(root_layer());
micro_benchmark_controller_.DidUpdateLayers();
-
return result || next_commit_forces_redraw_;
}
@@ -725,8 +710,7 @@ static Layer* FindFirstScrollableLayer(Layer* layer) {
}
void LayerTreeHost::RecordGpuRasterizationHistogram() {
- // Gpu rasterization is only supported when impl-side painting is enabled.
- if (gpu_rasterization_histogram_recorded_ || !settings_.impl_side_painting)
+ if (gpu_rasterization_histogram_recorded_)
return;
// Record how widely gpu rasterization is enabled.
@@ -753,10 +737,9 @@ bool LayerTreeHost::UsingSharedMemoryResources() {
return GetRendererCapabilities().using_shared_memory_resources;
}
-bool LayerTreeHost::UpdateLayers(Layer* root_layer,
- ResourceUpdateQueue* queue) {
- TRACE_EVENT1("cc", "LayerTreeHost::UpdateLayers",
- "source_frame_number", source_frame_number());
+bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) {
+ TRACE_EVENT1("cc", "LayerTreeHost::DoUpdateLayers", "source_frame_number",
+ source_frame_number());
RenderSurfaceLayerList render_surface_layer_list;
@@ -781,6 +764,7 @@ bool LayerTreeHost::UpdateLayers(Layer* root_layer,
LayerTreeHostCommon::CalcDrawPropsMainInputs inputs(
root_layer, device_viewport_size(), gfx::Transform(),
device_scale_factor_, page_scale_factor_, page_scale_layer,
+ inner_viewport_scroll_layer_.get(), outer_viewport_scroll_layer_.get(),
elastic_overscroll_, overscroll_elasticity_layer_.get(),
GetRendererCapabilities().max_texture_size, settings_.can_use_lcd_text,
settings_.layers_always_allowed_lcd_text, can_render_to_separate_surface,
@@ -788,79 +772,43 @@ bool LayerTreeHost::UpdateLayers(Layer* root_layer,
settings_.verify_property_trees, &render_surface_layer_list,
render_surface_layer_list_id, &property_trees_);
- // This is a temporary state of affairs until impl-side painting is shipped
- // everywhere and main thread property trees can be used in all cases.
- // This code here implies that even if verify property trees is on,
- // no verification will occur and only property trees will be used on the
- // main thread.
- if (using_only_property_trees()) {
- TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::CalcDrawProps");
-
- LayerTreeHostCommon::PreCalculateMetaInformation(root_layer);
-
- bool preserves_2d_axis_alignment = false;
- gfx::Transform identity_transform;
- LayerList update_layer_list;
-
- LayerTreeHostCommon::UpdateRenderSurfaces(
- root_layer, can_render_to_separate_surface, identity_transform,
- preserves_2d_axis_alignment);
- {
- TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
- "LayerTreeHostCommon::ComputeVisibleRectsWithPropertyTrees");
- BuildPropertyTreesAndComputeVisibleRects(
- root_layer, page_scale_layer, page_scale_factor_,
- device_scale_factor_, gfx::Rect(device_viewport_size_),
- identity_transform, &property_trees_, &update_layer_list);
- }
+ TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::CalcDrawProps");
- for (const auto& layer : update_layer_list)
- layer->SavePaintProperties();
-
- base::AutoReset<bool> painting(&in_paint_layer_contents_, true);
- bool did_paint_content = false;
- for (const auto& layer : update_layer_list) {
- // TODO(enne): temporarily clobber draw properties visible rect.
- layer->draw_properties().visible_content_rect =
- layer->visible_rect_from_property_trees();
- did_paint_content |= layer->Update(queue, nullptr);
- content_is_suitable_for_gpu_rasterization_ &=
- layer->IsSuitableForGpuRasterization();
- }
- return did_paint_content;
- }
+ LayerTreeHostCommon::PreCalculateMetaInformation(root_layer);
+
+ bool preserves_2d_axis_alignment = false;
+ gfx::Transform identity_transform;
+ LayerList update_layer_list;
+ LayerTreeHostCommon::UpdateRenderSurfaces(
+ root_layer, can_render_to_separate_surface, identity_transform,
+ preserves_2d_axis_alignment);
{
- TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::CalcDrawProps");
- LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
+ "LayerTreeHostCommon::ComputeVisibleRectsWithPropertyTrees");
+ BuildPropertyTreesAndComputeVisibleRects(
+ root_layer, page_scale_layer, inner_viewport_scroll_layer_.get(),
+ outer_viewport_scroll_layer_.get(), page_scale_factor_,
+ device_scale_factor_, gfx::Rect(device_viewport_size_),
+ identity_transform, &property_trees_, &update_layer_list);
}
- // Reset partial texture update requests.
- partial_texture_update_requests_ = 0;
+ for (const auto& layer : update_layer_list)
+ layer->SavePaintProperties();
+ base::AutoReset<bool> painting(&in_paint_layer_contents_, true);
bool did_paint_content = false;
- bool need_more_updates = false;
- PaintLayerContents(render_surface_layer_list, queue, &did_paint_content,
- &need_more_updates);
- if (need_more_updates) {
- TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::posting prepaint task");
- prepaint_callback_.Reset(base::Bind(&LayerTreeHost::TriggerPrepaint,
- base::Unretained(this)));
- static base::TimeDelta prepaint_delay =
- base::TimeDelta::FromMilliseconds(100);
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, prepaint_callback_.callback(), prepaint_delay);
+ for (const auto& layer : update_layer_list) {
+ // TODO(enne): temporarily clobber draw properties visible rect.
+ layer->draw_properties().visible_layer_rect =
+ layer->visible_rect_from_property_trees();
+ did_paint_content |= layer->Update();
+ content_is_suitable_for_gpu_rasterization_ &=
+ layer->IsSuitableForGpuRasterization();
}
-
return did_paint_content;
}
-void LayerTreeHost::TriggerPrepaint() {
- prepaint_callback_.Cancel();
- TRACE_EVENT0("cc", "LayerTreeHost::TriggerPrepaint");
- SetNeedsCommit();
-}
-
void LayerTreeHost::ReduceMemoryUsage() {
if (!root_layer())
return;
@@ -869,154 +817,6 @@ void LayerTreeHost::ReduceMemoryUsage() {
root_layer(), [](Layer* layer) { layer->ReduceMemoryUsage(); });
}
-void LayerTreeHost::SetPrioritiesForSurfaces(size_t surface_memory_bytes) {
- DCHECK(surface_memory_placeholder_);
-
- // Surfaces have a place holder for their memory since they are managed
- // independantly but should still be tracked and reduce other memory usage.
- surface_memory_placeholder_->SetTextureManager(
- contents_texture_manager_.get());
- surface_memory_placeholder_->set_request_priority(
- PriorityCalculator::RenderSurfacePriority());
- surface_memory_placeholder_->SetToSelfManagedMemoryPlaceholder(
- surface_memory_bytes);
-}
-
-void LayerTreeHost::SetPrioritiesForLayers(
- const RenderSurfaceLayerList& update_list) {
- PriorityCalculator calculator;
- typedef LayerIterator<Layer> LayerIteratorType;
- LayerIteratorType end = LayerIteratorType::End(&update_list);
- for (LayerIteratorType it = LayerIteratorType::Begin(&update_list);
- it != end;
- ++it) {
- if (it.represents_itself()) {
- it->SetTexturePriorities(calculator);
- } else if (it.represents_target_render_surface()) {
- if (it->mask_layer())
- it->mask_layer()->SetTexturePriorities(calculator);
- if (it->replica_layer() && it->replica_layer()->mask_layer())
- it->replica_layer()->mask_layer()->SetTexturePriorities(calculator);
- }
- }
-}
-
-void LayerTreeHost::PrioritizeTextures(
- const RenderSurfaceLayerList& render_surface_layer_list) {
- if (!contents_texture_manager_)
- return;
-
- contents_texture_manager_->ClearPriorities();
-
- size_t memory_for_render_surfaces_metric =
- CalculateMemoryForRenderSurfaces(render_surface_layer_list);
-
- SetPrioritiesForLayers(render_surface_layer_list);
- SetPrioritiesForSurfaces(memory_for_render_surfaces_metric);
-
- contents_texture_manager_->PrioritizeTextures();
-}
-
-size_t LayerTreeHost::CalculateMemoryForRenderSurfaces(
- const RenderSurfaceLayerList& update_list) {
- size_t readback_bytes = 0;
- size_t contents_texture_bytes = 0;
-
- // Start iteration at 1 to skip the root surface as it does not have a texture
- // cost.
- for (size_t i = 1; i < update_list.size(); ++i) {
- Layer* render_surface_layer = update_list.at(i);
- RenderSurface* render_surface = render_surface_layer->render_surface();
-
- size_t bytes =
- Resource::MemorySizeBytes(render_surface->content_rect().size(),
- RGBA_8888);
- contents_texture_bytes += bytes;
-
- if (render_surface_layer->background_filters().IsEmpty() &&
- render_surface_layer->uses_default_blend_mode())
- continue;
-
- if (!readback_bytes) {
- readback_bytes = Resource::MemorySizeBytes(device_viewport_size_,
- RGBA_8888);
- }
- }
- return readback_bytes + contents_texture_bytes;
-}
-
-void LayerTreeHost::PaintMasksForRenderSurface(Layer* render_surface_layer,
- ResourceUpdateQueue* queue,
- bool* did_paint_content,
- bool* need_more_updates) {
- // Note: Masks and replicas only exist for layers that own render surfaces. If
- // we reach this point in code, we already know that at least something will
- // be drawn into this render surface, so the mask and replica should be
- // painted.
-
- Layer* mask_layer = render_surface_layer->mask_layer();
- if (mask_layer) {
- *did_paint_content |= mask_layer->Update(queue, NULL);
- *need_more_updates |= mask_layer->NeedMoreUpdates();
- }
-
- Layer* replica_mask_layer =
- render_surface_layer->replica_layer() ?
- render_surface_layer->replica_layer()->mask_layer() : NULL;
- if (replica_mask_layer) {
- *did_paint_content |= replica_mask_layer->Update(queue, NULL);
- *need_more_updates |= replica_mask_layer->NeedMoreUpdates();
- }
-}
-
-void LayerTreeHost::PaintLayerContents(
- const RenderSurfaceLayerList& render_surface_layer_list,
- ResourceUpdateQueue* queue,
- bool* did_paint_content,
- bool* need_more_updates) {
- OcclusionTracker<Layer> occlusion_tracker(
- root_layer_->render_surface()->content_rect());
- occlusion_tracker.set_minimum_tracking_size(
- settings_.minimum_occlusion_tracking_size);
-
- PrioritizeTextures(render_surface_layer_list);
-
- in_paint_layer_contents_ = true;
-
- // Iterates front-to-back to allow for testing occlusion and performing
- // culling during the tree walk.
- typedef LayerIterator<Layer> LayerIteratorType;
- LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list);
- for (LayerIteratorType it =
- LayerIteratorType::Begin(&render_surface_layer_list);
- it != end;
- ++it) {
- occlusion_tracker.EnterLayer(it);
-
- if (it.represents_target_render_surface()) {
- PaintMasksForRenderSurface(
- *it, queue, did_paint_content, need_more_updates);
- } else if (it.represents_itself()) {
- DCHECK(!it->paint_properties().bounds.IsEmpty());
- *did_paint_content |= it->Update(queue, &occlusion_tracker);
- *need_more_updates |= it->NeedMoreUpdates();
- // Note the '&&' with previous is-suitable state.
- // This means that once the layer-tree becomes unsuitable for gpu
- // rasterization due to some content, it will continue to be unsuitable
- // even if that content is replaced by gpu-friendly content.
- // This is to avoid switching back-and-forth between gpu and sw
- // rasterization which may be both bad for performance and visually
- // jarring.
- content_is_suitable_for_gpu_rasterization_ &=
- it->IsSuitableForGpuRasterization();
- }
-
- occlusion_tracker.LeaveLayer(it);
- }
-
- in_paint_layer_contents_ = false;
-}
-
void LayerTreeHost::ApplyScrollAndScale(ScrollAndScaleSet* info) {
ScopedPtrVector<SwapPromise>::iterator it = info->swap_promises.begin();
for (; it != info->swap_promises.end(); ++it) {
@@ -1071,22 +871,12 @@ void LayerTreeHost::ApplyScrollAndScale(ScrollAndScaleSet* info) {
ApplyPageScaleDeltaFromImplSide(info->page_scale_delta);
elastic_overscroll_ += info->elastic_overscroll_delta;
- if (!settings_.use_pinch_virtual_viewport) {
- // TODO(miletus): Make sure either this code path is totally gone,
- // or revisit the flooring here if the old pinch viewport code path
- // is causing problems with fractional scroll offset.
- client_->ApplyViewportDeltas(
- gfx::ToFlooredVector2d(inner_viewport_scroll_delta +
- outer_viewport_scroll_delta),
- info->page_scale_delta, info->top_controls_delta);
- } else {
- // TODO(ccameron): pass the elastic overscroll here so that input events
- // may be translated appropriately.
- client_->ApplyViewportDeltas(
- inner_viewport_scroll_delta, outer_viewport_scroll_delta,
- info->elastic_overscroll_delta, info->page_scale_delta,
- info->top_controls_delta);
- }
+ // TODO(ccameron): pass the elastic overscroll here so that input events
+ // may be translated appropriately.
+ client_->ApplyViewportDeltas(
+ inner_viewport_scroll_delta, outer_viewport_scroll_delta,
+ info->elastic_overscroll_delta, info->page_scale_delta,
+ info->top_controls_delta);
}
}
@@ -1114,31 +904,6 @@ void LayerTreeHost::RateLimit() {
client_->RateLimitSharedMainThreadContext();
}
-bool LayerTreeHost::AlwaysUsePartialTextureUpdates() {
- if (!proxy_->GetRendererCapabilities().allow_partial_texture_updates)
- return false;
- return !proxy_->HasImplThread();
-}
-
-size_t LayerTreeHost::MaxPartialTextureUpdates() const {
- size_t max_partial_texture_updates = 0;
- if (proxy_->GetRendererCapabilities().allow_partial_texture_updates &&
- !settings_.impl_side_painting) {
- max_partial_texture_updates =
- std::min(settings_.max_partial_texture_updates,
- proxy_->MaxPartialTextureUpdates());
- }
- return max_partial_texture_updates;
-}
-
-bool LayerTreeHost::RequestPartialTextureUpdate() {
- if (partial_texture_update_requests_ >= MaxPartialTextureUpdates())
- return false;
-
- partial_texture_update_requests_++;
- return true;
-}
-
void LayerTreeHost::SetDeviceScaleFactor(float device_scale_factor) {
if (device_scale_factor == device_scale_factor_)
return;
@@ -1166,11 +931,16 @@ void LayerTreeHost::AnimateLayers(base::TimeTicks monotonic_time) {
return;
AnimationEventsVector events;
- if (animation_registrar_->AnimateLayers(monotonic_time)) {
- animation_registrar_->UpdateAnimationState(true, &events);
- if (!events.empty())
- property_trees_.needs_rebuild = true;
+ if (animation_host_) {
+ if (animation_host_->AnimateLayers(monotonic_time))
+ animation_host_->UpdateAnimationState(true, &events);
+ } else {
+ if (animation_registrar_->AnimateLayers(monotonic_time))
+ animation_registrar_->UpdateAnimationState(true, &events);
}
+
+ if (!events.empty())
+ property_trees_.needs_rebuild = true;
}
UIResourceId LayerTreeHost::CreateUIResource(UIResourceClient* client) {
@@ -1284,6 +1054,11 @@ void LayerTreeHost::BreakSwapPromises(SwapPromise::DidNotSwapReason reason) {
swap_promise_list_.clear();
}
+void LayerTreeHost::OnCommitForSwapPromises() {
+ for (auto* swap_promise : swap_promise_list_)
+ swap_promise->OnCommit();
+}
+
void LayerTreeHost::set_surface_id_namespace(uint32_t id_namespace) {
surface_id_namespace_ = id_namespace;
}
@@ -1307,4 +1082,137 @@ void LayerTreeHost::SetAuthoritativeVSyncInterval(
proxy_->SetAuthoritativeVSyncInterval(interval);
}
+void LayerTreeHost::RecordFrameTimingEvents(
+ scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events,
+ scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) {
+ client_->RecordFrameTimingEvents(composite_events.Pass(),
+ main_frame_events.Pass());
+}
+
+Layer* LayerTreeHost::LayerById(int id) const {
+ LayerIdMap::const_iterator iter = layer_id_map_.find(id);
+ return iter != layer_id_map_.end() ? iter->second : NULL;
+}
+
+void LayerTreeHost::RegisterLayer(Layer* layer) {
+ DCHECK(!LayerById(layer->id()));
+ DCHECK(!in_paint_layer_contents_);
+ layer_id_map_[layer->id()] = layer;
+ if (animation_host_)
+ animation_host_->RegisterLayer(layer->id(), LayerTreeType::ACTIVE);
+}
+
+void LayerTreeHost::UnregisterLayer(Layer* layer) {
+ DCHECK(LayerById(layer->id()));
+ DCHECK(!in_paint_layer_contents_);
+ if (animation_host_)
+ animation_host_->UnregisterLayer(layer->id(), LayerTreeType::ACTIVE);
+ layer_id_map_.erase(layer->id());
+}
+
+bool LayerTreeHost::IsLayerInTree(int layer_id, LayerTreeType tree_type) const {
+ return tree_type == LayerTreeType::ACTIVE;
+}
+
+void LayerTreeHost::SetMutatorsNeedCommit() {
+ SetNeedsCommit();
+}
+
+void LayerTreeHost::SetLayerFilterMutated(int layer_id,
+ LayerTreeType tree_type,
+ const FilterOperations& filters) {
+ LayerAnimationValueObserver* layer = LayerById(layer_id);
+ DCHECK(layer);
+ layer->OnFilterAnimated(filters);
+}
+
+void LayerTreeHost::SetLayerOpacityMutated(int layer_id,
+ LayerTreeType tree_type,
+ float opacity) {
+ LayerAnimationValueObserver* layer = LayerById(layer_id);
+ DCHECK(layer);
+ layer->OnOpacityAnimated(opacity);
+}
+
+void LayerTreeHost::SetLayerTransformMutated(int layer_id,
+ LayerTreeType tree_type,
+ const gfx::Transform& transform) {
+ LayerAnimationValueObserver* layer = LayerById(layer_id);
+ DCHECK(layer);
+ layer->OnTransformAnimated(transform);
+}
+
+void LayerTreeHost::SetLayerScrollOffsetMutated(
+ int layer_id,
+ LayerTreeType tree_type,
+ const gfx::ScrollOffset& scroll_offset) {
+ LayerAnimationValueObserver* layer = LayerById(layer_id);
+ DCHECK(layer);
+ layer->OnScrollOffsetAnimated(scroll_offset);
+}
+
+gfx::ScrollOffset LayerTreeHost::GetScrollOffsetForAnimation(
+ int layer_id) const {
+ LayerAnimationValueProvider* layer = LayerById(layer_id);
+ DCHECK(layer);
+ return layer->ScrollOffsetForAnimation();
+}
+
+bool LayerTreeHost::ScrollOffsetAnimationWasInterrupted(
+ const Layer* layer) const {
+ return animation_host_
+ ? animation_host_->ScrollOffsetAnimationWasInterrupted(layer->id())
+ : false;
+}
+
+bool LayerTreeHost::IsAnimatingFilterProperty(const Layer* layer) const {
+ return animation_host_
+ ? animation_host_->IsAnimatingFilterProperty(layer->id())
+ : false;
+}
+
+bool LayerTreeHost::IsAnimatingOpacityProperty(const Layer* layer) const {
+ return animation_host_
+ ? animation_host_->IsAnimatingOpacityProperty(layer->id())
+ : false;
+}
+
+bool LayerTreeHost::IsAnimatingTransformProperty(const Layer* layer) const {
+ return animation_host_
+ ? animation_host_->IsAnimatingTransformProperty(layer->id())
+ : false;
+}
+
+bool LayerTreeHost::HasPotentiallyRunningOpacityAnimation(
+ const Layer* layer) const {
+ return animation_host_
+ ? animation_host_->HasPotentiallyRunningOpacityAnimation(
+ layer->id())
+ : false;
+}
+
+bool LayerTreeHost::HasPotentiallyRunningTransformAnimation(
+ const Layer* layer) const {
+ return animation_host_
+ ? animation_host_->HasPotentiallyRunningTransformAnimation(
+ layer->id())
+ : false;
+}
+
+bool LayerTreeHost::AnimationsPreserveAxisAlignment(const Layer* layer) const {
+ return animation_host_
+ ? animation_host_->AnimationsPreserveAxisAlignment(layer->id())
+ : true;
+}
+
+bool LayerTreeHost::HasAnyAnimation(const Layer* layer) const {
+ return animation_host_ ? animation_host_->HasAnyAnimation(layer->id())
+ : false;
+}
+
+bool LayerTreeHost::HasActiveAnimation(const Layer* layer) const {
+ return animation_host_ ? animation_host_->HasActiveAnimation(layer->id())
+ : false;
+}
+
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host.h b/chromium/cc/trees/layer_tree_host.h
index cf47facddd4..4f38352f9c6 100644
--- a/chromium/cc/trees/layer_tree_host.h
+++ b/chromium/cc/trees/layer_tree_host.h
@@ -21,6 +21,7 @@
#include "cc/animation/animation_events.h"
#include "cc/base/cc_export.h"
#include "cc/base/scoped_ptr_vector.h"
+#include "cc/debug/frame_timing_tracker.h"
#include "cc/debug/micro_benchmark.h"
#include "cc/debug/micro_benchmark_controller.h"
#include "cc/input/input_handler.h"
@@ -37,6 +38,7 @@
#include "cc/trees/layer_tree_host_client.h"
#include "cc/trees/layer_tree_host_common.h"
#include "cc/trees/layer_tree_settings.h"
+#include "cc/trees/mutator_host_client.h"
#include "cc/trees/proxy.h"
#include "cc/trees/swap_promise_monitor.h"
#include "third_party/skia/include/core/SkColor.h"
@@ -48,14 +50,13 @@ class GpuMemoryBufferManager;
namespace cc {
class AnimationRegistrar;
+class AnimationHost;
class BeginFrameSource;
class HeadsUpDisplayLayer;
class Layer;
class LayerTreeHostImpl;
class LayerTreeHostImplClient;
class LayerTreeHostSingleThreadClient;
-class PrioritizedResource;
-class PrioritizedResourceManager;
class PropertyTrees;
class Region;
class RenderingStatsInstrumentation;
@@ -69,7 +70,7 @@ struct PendingPageScaleAnimation;
struct RenderingStats;
struct ScrollAndScaleSet;
-class CC_EXPORT LayerTreeHost {
+class CC_EXPORT LayerTreeHost : public MutatorHostClient {
public:
// TODO(sad): InitParams should be a movable type so that it can be
// std::move()d to the Create* functions.
@@ -120,8 +121,7 @@ class CC_EXPORT LayerTreeHost {
bool output_surface_lost() const { return output_surface_lost_; }
void DidCommitAndDrawFrame() { client_->DidCommitAndDrawFrame(); }
void DidCompleteSwapBuffers() { client_->DidCompleteSwapBuffers(); }
- void DeleteContentsTexturesOnImplThread(ResourceProvider* resource_provider);
- bool UpdateLayers(ResourceUpdateQueue* queue);
+ bool UpdateLayers();
// Called when the compositor completed page scale animation.
void DidCompletePageScaleAnimation();
@@ -133,6 +133,7 @@ class CC_EXPORT LayerTreeHost {
void NotifyInputThrottledUntilCommit();
+ void LayoutAndUpdateLayers();
void Composite(base::TimeTicks frame_begin_time);
void FinishAllRendering();
@@ -141,6 +142,14 @@ class CC_EXPORT LayerTreeHost {
int source_frame_number() const { return source_frame_number_; }
+ int meta_information_sequence_number() {
+ return meta_information_sequence_number_;
+ }
+
+ void IncrementMetaInformationSequenceNumber() {
+ meta_information_sequence_number_++;
+ }
+
void SetNeedsDisplayOnAllLayers();
void CollectRenderingStats(RenderingStats* stats) const;
@@ -218,10 +227,6 @@ class CC_EXPORT LayerTreeHost {
has_transparent_background_ = transparent;
}
- PrioritizedResourceManager* contents_texture_manager() const {
- return contents_texture_manager_.get();
- }
-
void SetVisible(bool visible);
bool visible() const { return visible_; }
@@ -241,10 +246,6 @@ class CC_EXPORT LayerTreeHost {
void RateLimit();
- bool AlwaysUsePartialTextureUpdates();
- size_t MaxPartialTextureUpdates() const;
- bool RequestPartialTextureUpdate();
-
void SetDeviceScaleFactor(float device_scale_factor);
float device_scale_factor() const { return device_scale_factor_; }
@@ -255,10 +256,10 @@ class CC_EXPORT LayerTreeHost {
HeadsUpDisplayLayer* hud_layer() const { return hud_layer_.get(); }
Proxy* proxy() const { return proxy_.get(); }
-
AnimationRegistrar* animation_registrar() const {
return animation_registrar_.get();
}
+ AnimationHost* animation_host() const { return animation_host_.get(); }
bool in_paint_layer_contents() const { return in_paint_layer_contents_; }
@@ -315,11 +316,41 @@ class CC_EXPORT LayerTreeHost {
return needs_meta_info_recomputation_;
}
- // If this is true, only property trees will be used for main thread CDP.
- // CDP will not be run, and verify_property_trees will be ignored.
- bool using_only_property_trees() const {
- return settings().impl_side_painting;
- }
+ void RecordFrameTimingEvents(
+ scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events,
+ scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events);
+
+ Layer* LayerById(int id) const;
+ void RegisterLayer(Layer* layer);
+ void UnregisterLayer(Layer* layer);
+ // LayerTreeMutatorsClient implementation.
+ bool IsLayerInTree(int layer_id, LayerTreeType tree_type) const override;
+ void SetMutatorsNeedCommit() override;
+ void SetLayerFilterMutated(int layer_id,
+ LayerTreeType tree_type,
+ const FilterOperations& filters) override;
+ void SetLayerOpacityMutated(int layer_id,
+ LayerTreeType tree_type,
+ float opacity) override;
+ void SetLayerTransformMutated(int layer_id,
+ LayerTreeType tree_type,
+ const gfx::Transform& transform) override;
+ void SetLayerScrollOffsetMutated(
+ int layer_id,
+ LayerTreeType tree_type,
+ const gfx::ScrollOffset& scroll_offset) override;
+ void ScrollOffsetAnimationFinished() override {}
+ gfx::ScrollOffset GetScrollOffsetForAnimation(int layer_id) const override;
+
+ bool ScrollOffsetAnimationWasInterrupted(const Layer* layer) const;
+ bool IsAnimatingFilterProperty(const Layer* layer) const;
+ bool IsAnimatingOpacityProperty(const Layer* layer) const;
+ bool IsAnimatingTransformProperty(const Layer* layer) const;
+ bool HasPotentiallyRunningOpacityAnimation(const Layer* layer) const;
+ bool HasPotentiallyRunningTransformAnimation(const Layer* layer) const;
+ bool AnimationsPreserveAxisAlignment(const Layer* layer) const;
+ bool HasAnyAnimation(const Layer* layer) const;
+ bool HasActiveAnimation(const Layer* layer) const;
protected:
explicit LayerTreeHost(InitParams* params);
@@ -349,31 +380,16 @@ class CC_EXPORT LayerTreeHost {
MicroBenchmarkController micro_benchmark_controller_;
+ void OnCommitForSwapPromises();
+
private:
void InitializeProxy(scoped_ptr<Proxy> proxy);
- void PaintLayerContents(
- const RenderSurfaceLayerList& render_surface_layer_list,
- ResourceUpdateQueue* queue,
- bool* did_paint_content,
- bool* need_more_updates);
- void PaintMasksForRenderSurface(Layer* render_surface_layer,
- ResourceUpdateQueue* queue,
- bool* did_paint_content,
- bool* need_more_updates);
- bool UpdateLayers(Layer* root_layer, ResourceUpdateQueue* queue);
+ bool DoUpdateLayers(Layer* root_layer);
void UpdateHudLayer();
- void TriggerPrepaint();
void ReduceMemoryUsage();
- void PrioritizeTextures(
- const RenderSurfaceLayerList& render_surface_layer_list);
- void SetPrioritiesForSurfaces(size_t surface_memory_bytes);
- void SetPrioritiesForLayers(const RenderSurfaceLayerList& update_list);
- size_t CalculateMemoryForRenderSurfaces(
- const RenderSurfaceLayerList& update_list);
-
bool AnimateLayersRecursive(Layer* current, base::TimeTicks time);
struct UIResourceClientData {
@@ -398,12 +414,11 @@ class CC_EXPORT LayerTreeHost {
bool needs_full_tree_sync_;
bool needs_meta_info_recomputation_;
- base::CancelableClosure prepaint_callback_;
-
LayerTreeHostClient* client_;
scoped_ptr<Proxy> proxy_;
int source_frame_number_;
+ int meta_information_sequence_number_;
scoped_ptr<RenderingStatsInstrumentation> rendering_stats_instrumentation_;
bool output_surface_lost_;
@@ -411,9 +426,6 @@ class CC_EXPORT LayerTreeHost {
scoped_refptr<Layer> root_layer_;
scoped_refptr<HeadsUpDisplayLayer> hud_layer_;
- scoped_ptr<PrioritizedResourceManager> contents_texture_manager_;
- scoped_ptr<PrioritizedResource> surface_memory_placeholder_;
-
base::WeakPtr<InputHandler> input_handler_weak_ptr_;
base::WeakPtr<TopControlsManager> top_controls_manager_weak_ptr_;
@@ -441,10 +453,8 @@ class CC_EXPORT LayerTreeHost {
SkColor background_color_;
bool has_transparent_background_;
- typedef ScopedPtrVector<PrioritizedResource> TextureList;
- size_t partial_texture_update_requests_;
-
scoped_ptr<AnimationRegistrar> animation_registrar_;
+ scoped_ptr<AnimationHost> animation_host_;
scoped_ptr<PendingPageScaleAnimation> pending_page_scale_animation_;
@@ -473,6 +483,9 @@ class CC_EXPORT LayerTreeHost {
PropertyTrees property_trees_;
+ typedef base::hash_map<int, Layer*> LayerIdMap;
+ LayerIdMap layer_id_map_;
+
uint32_t surface_id_namespace_;
uint32_t next_surface_sequence_;
diff --git a/chromium/cc/trees/layer_tree_host_client.h b/chromium/cc/trees/layer_tree_host_client.h
index 6b305326ff9..56a128f4bad 100644
--- a/chromium/cc/trees/layer_tree_host_client.h
+++ b/chromium/cc/trees/layer_tree_host_client.h
@@ -8,6 +8,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
+#include "cc/debug/frame_timing_tracker.h"
namespace gfx {
class Vector2d;
@@ -35,9 +36,6 @@ class LayerTreeHostClient {
const gfx::Vector2dF& elastic_overscroll_delta,
float page_scale,
float top_controls_delta) = 0;
- virtual void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
- float page_scale,
- float top_controls_delta) = 0;
// Request an OutputSurface from the client. When the client has one it should
// call LayerTreeHost::SetOutputSurface. This will result in either
// DidFailToInitializeOutputSurface or DidInitializeOutputSurface being
@@ -49,6 +47,9 @@ class LayerTreeHostClient {
virtual void DidCommit() = 0;
virtual void DidCommitAndDrawFrame() = 0;
virtual void DidCompleteSwapBuffers() = 0;
+ virtual void RecordFrameTimingEvents(
+ scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events,
+ scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) = 0;
// Called when page scale animation has completed.
virtual void DidCompletePageScaleAnimation() = 0;
diff --git a/chromium/cc/trees/layer_tree_host_common.cc b/chromium/cc/trees/layer_tree_host_common.cc
index 09882856e55..427a3c825e1 100644
--- a/chromium/cc/trees/layer_tree_host_common.cc
+++ b/chromium/cc/trees/layer_tree_host_common.cc
@@ -302,8 +302,8 @@ void UpdateAccumulatedSurfaceState(
current_target->render_surface()->draw_transform();
// If we have unclipped descendants, the draw transform is a translation.
- DCHECK(current_target->num_unclipped_descendants() == 0 ||
- current_draw_transform.IsIdentityOrTranslation());
+ DCHECK_IMPLIES(current_target->num_unclipped_descendants(),
+ current_draw_transform.IsIdentityOrTranslation());
target_rect = gfx::ToEnclosingRect(
MathUtil::MapClippedRect(current_draw_transform, target_rect));
@@ -370,14 +370,14 @@ static inline bool LayerClipsSubtree(LayerType* layer) {
}
template <typename LayerType>
-static gfx::Rect CalculateVisibleContentRect(
+static gfx::Rect CalculateVisibleLayerRect(
LayerType* layer,
const gfx::Rect& clip_rect_of_target_surface_in_target_space,
const gfx::Rect& layer_rect_in_target_space) {
DCHECK(layer->render_target());
// Nothing is visible if the layer bounds are empty.
- if (!layer->DrawsContent() || layer->content_bounds().IsEmpty() ||
+ if (!layer->DrawsContent() || layer->bounds().IsEmpty() ||
layer->drawable_content_rect().IsEmpty())
return gfx::Rect();
@@ -403,10 +403,8 @@ static gfx::Rect CalculateVisibleContentRect(
return gfx::Rect();
return CalculateVisibleRectWithCachedLayerRect(
- visible_rect_in_target_surface_space,
- gfx::Rect(layer->content_bounds()),
- layer_rect_in_target_space,
- layer->draw_transform());
+ visible_rect_in_target_surface_space, gfx::Rect(layer->bounds()),
+ layer_rect_in_target_space, layer->draw_transform());
}
static inline bool TransformToParentIsKnown(LayerImpl* layer) { return true; }
@@ -434,7 +432,7 @@ static bool LayerShouldBeSkipped(LayerType* layer, bool layer_is_drawn) {
// Some additional conditions need to be computed at a later point after the
// recursion is finished.
// - the intersection of render_surface content and layer clip_rect is empty
- // - the visible_content_rect is empty
+ // - the visible_layer_rect is empty
//
// Note, if the layer should not have been drawn due to being fully
// transparent, we would have skipped the entire subtree and never made it
@@ -712,9 +710,6 @@ gfx::Transform ComputeSizeDeltaCompensation(
// Calculate step 1b
gfx::Transform container_layer_space_to_container_target_surface_space =
container->draw_transform();
- container_layer_space_to_container_target_surface_space.Scale(
- container->contents_scale_x(), container->contents_scale_y());
-
gfx::Transform container_target_surface_space_to_container_layer_space;
if (container_layer_space_to_container_target_surface_space.GetInverse(
&container_target_surface_space_to_container_layer_space)) {
@@ -911,106 +906,12 @@ gfx::Transform ComputeScrollCompensationMatrixForChildren(
template <typename LayerType>
static inline void UpdateLayerScaleDrawProperties(
LayerType* layer,
- float ideal_contents_scale,
float maximum_animation_contents_scale,
- float starting_animation_contents_scale,
- float page_scale_factor,
- float device_scale_factor) {
- layer->draw_properties().ideal_contents_scale = ideal_contents_scale;
+ float starting_animation_contents_scale) {
layer->draw_properties().maximum_animation_contents_scale =
maximum_animation_contents_scale;
layer->draw_properties().starting_animation_contents_scale =
starting_animation_contents_scale;
- layer->draw_properties().page_scale_factor = page_scale_factor;
- layer->draw_properties().device_scale_factor = device_scale_factor;
-}
-
-static inline void CalculateContentsScale(LayerImpl* layer,
- float contents_scale) {
- // LayerImpl has all of its content scales and bounds pushed from the Main
- // thread during commit and just uses those values as-is.
-}
-
-static inline void CalculateContentsScale(Layer* layer, float contents_scale) {
- layer->CalculateContentsScale(contents_scale,
- &layer->draw_properties().contents_scale_x,
- &layer->draw_properties().contents_scale_y,
- &layer->draw_properties().content_bounds);
-
- Layer* mask_layer = layer->mask_layer();
- if (mask_layer) {
- mask_layer->CalculateContentsScale(
- contents_scale,
- &mask_layer->draw_properties().contents_scale_x,
- &mask_layer->draw_properties().contents_scale_y,
- &mask_layer->draw_properties().content_bounds);
- }
-
- Layer* replica_mask_layer =
- layer->replica_layer() ? layer->replica_layer()->mask_layer() : NULL;
- if (replica_mask_layer) {
- replica_mask_layer->CalculateContentsScale(
- contents_scale,
- &replica_mask_layer->draw_properties().contents_scale_x,
- &replica_mask_layer->draw_properties().contents_scale_y,
- &replica_mask_layer->draw_properties().content_bounds);
- }
-}
-
-static inline void UpdateLayerContentsScale(
- LayerImpl* layer,
- bool can_adjust_raster_scale,
- float ideal_contents_scale,
- float device_scale_factor,
- float page_scale_factor,
- bool animating_transform_to_screen) {
- CalculateContentsScale(layer, ideal_contents_scale);
-}
-
-static inline void UpdateLayerContentsScale(
- Layer* layer,
- bool can_adjust_raster_scale,
- float ideal_contents_scale,
- float device_scale_factor,
- float page_scale_factor,
- bool animating_transform_to_screen) {
- if (can_adjust_raster_scale) {
- float ideal_raster_scale =
- ideal_contents_scale / (device_scale_factor * page_scale_factor);
-
- bool need_to_set_raster_scale = layer->raster_scale_is_unknown();
-
- // If we've previously saved a raster_scale but the ideal changes, things
- // are unpredictable and we should just use 1.
- if (!need_to_set_raster_scale && layer->raster_scale() != 1.f &&
- ideal_raster_scale != layer->raster_scale()) {
- ideal_raster_scale = 1.f;
- need_to_set_raster_scale = true;
- }
-
- if (need_to_set_raster_scale) {
- bool use_and_save_ideal_scale =
- ideal_raster_scale >= 1.f && !animating_transform_to_screen;
- if (use_and_save_ideal_scale)
- layer->set_raster_scale(ideal_raster_scale);
- }
- }
-
- float raster_scale = 1.f;
- if (!layer->raster_scale_is_unknown())
- raster_scale = layer->raster_scale();
-
- gfx::Size old_content_bounds = layer->content_bounds();
- float old_contents_scale_x = layer->contents_scale_x();
- float old_contents_scale_y = layer->contents_scale_y();
-
- float contents_scale = raster_scale * device_scale_factor * page_scale_factor;
- CalculateContentsScale(layer, contents_scale);
-
- if (layer->content_bounds() != old_content_bounds ||
- layer->contents_scale_x() != old_contents_scale_x ||
- layer->contents_scale_y() != old_contents_scale_y)
- layer->SetNeedsPushProperties();
}
static inline void CalculateAnimationContentsScale(
@@ -1059,8 +960,7 @@ static inline void CalculateAnimationContentsScale(
// scales and translations. We treat all non-translations as potentially
// affecting scale. Animations that include non-translation/scale components
// will cause the computation of MaximumScale below to fail.
- bool layer_is_animating_scale =
- !layer->layer_animation_controller()->HasOnlyTranslationTransforms();
+ bool layer_is_animating_scale = !layer->HasOnlyTranslationTransforms();
if (!layer_is_animating_scale && !ancestor_is_animating_scale) {
*combined_maximum_animation_contents_scale = 0.f;
@@ -1097,13 +997,11 @@ static inline void CalculateAnimationContentsScale(
float layer_maximum_animated_scale = 0.f;
float layer_start_animated_scale = 0.f;
- if (!layer->layer_animation_controller()->MaximumTargetScale(
- &layer_maximum_animated_scale)) {
+ if (!layer->MaximumTargetScale(&layer_maximum_animated_scale)) {
*combined_maximum_animation_contents_scale = 0.f;
return;
}
- if (!layer->layer_animation_controller()->AnimationStartScale(
- &layer_start_animated_scale)) {
+ if (!layer->AnimationStartScale(&layer_start_animated_scale)) {
*combined_starting_animation_contents_scale = 0.f;
return;
}
@@ -1124,8 +1022,8 @@ static inline void MarkLayerWithRenderSurfaceLayerListId(
int current_render_surface_layer_list_id) {
layer->draw_properties().last_drawn_render_surface_layer_list_id =
current_render_surface_layer_list_id;
- layer->draw_properties().layer_or_descendant_is_drawn =
- !!current_render_surface_layer_list_id;
+ layer->set_layer_or_descendant_is_drawn(
+ !!current_render_surface_layer_list_id);
}
template <typename LayerTypePtr>
@@ -1184,7 +1082,7 @@ static inline void RemoveSurfaceForEarlyExit(
}
struct PreCalculateMetaInformationRecursiveData {
- int num_unclipped_descendants;
+ size_t num_unclipped_descendants;
int num_layer_or_descendants_with_copy_request;
int num_layer_or_descendants_with_input_handler;
@@ -1220,30 +1118,15 @@ static void ValidateRenderSurface(LayerImpl* layer) {
static void ValidateRenderSurface(Layer* layer) {
}
-static void ResetDrawProperties(Layer* layer) {
- layer->draw_properties().sorted_for_recursion = false;
- layer->draw_properties().has_child_with_a_scroll_parent = false;
- layer->draw_properties().layer_or_descendant_is_drawn = false;
- layer->draw_properties().visited = false;
- if (!HasInvertibleOrAnimatedTransform(layer)) {
- // Layers with singular transforms should not be drawn, the whole subtree
- // can be skipped.
- return;
- }
-
- for (size_t i = 0; i < layer->children().size(); ++i) {
- Layer* child_layer = layer->child_at(i);
- if (child_layer->scroll_parent())
- layer->draw_properties().has_child_with_a_scroll_parent = true;
- ResetDrawProperties(child_layer);
- }
+static bool IsMetaInformationRecomputationNeeded(Layer* layer) {
+ return layer->layer_tree_host()->needs_meta_info_recomputation();
}
-static void ResetDrawProperties(LayerImpl* layer) {
+static void UpdateMetaInformationSequenceNumber(Layer* root_layer) {
+ root_layer->layer_tree_host()->IncrementMetaInformationSequenceNumber();
}
-static bool IsMetaInformationRecomputationNeeded(Layer* layer) {
- return layer->layer_tree_host()->needs_meta_info_recomputation();
+static void UpdateMetaInformationSequenceNumber(LayerImpl* root_layer) {
}
// Recursively walks the layer tree(if needed) to compute any information
@@ -1252,6 +1135,12 @@ static void PreCalculateMetaInformationInternal(
Layer* layer,
PreCalculateMetaInformationRecursiveData* recursive_data) {
ValidateRenderSurface(layer);
+
+ layer->set_sorted_for_recursion(false);
+ layer->draw_properties().has_child_with_a_scroll_parent = false;
+ layer->set_layer_or_descendant_is_drawn(false);
+ layer->set_visited(false);
+
if (!HasInvertibleOrAnimatedTransform(layer)) {
// Layers with singular transforms should not be drawn, the whole subtree
// can be skipped.
@@ -1266,17 +1155,23 @@ static void PreCalculateMetaInformationInternal(
if (layer->clip_parent())
recursive_data->num_unclipped_descendants++;
+ layer->set_num_children_with_scroll_parent(0);
for (size_t i = 0; i < layer->children().size(); ++i) {
Layer* child_layer = layer->child_at(i);
PreCalculateMetaInformationRecursiveData data_for_child;
PreCalculateMetaInformationInternal(child_layer, &data_for_child);
+ if (child_layer->scroll_parent()) {
+ layer->draw_properties().has_child_with_a_scroll_parent = true;
+ layer->set_num_children_with_scroll_parent(
+ layer->num_children_with_scroll_parent() + 1);
+ }
recursive_data->Merge(data_for_child);
}
if (layer->clip_children()) {
- int num_clip_children = layer->clip_children()->size();
+ size_t num_clip_children = layer->clip_children()->size();
DCHECK_GE(recursive_data->num_unclipped_descendants, num_clip_children);
recursive_data->num_unclipped_descendants -= num_clip_children;
}
@@ -1308,10 +1203,10 @@ static void PreCalculateMetaInformationInternal(
PreCalculateMetaInformationRecursiveData* recursive_data) {
ValidateRenderSurface(layer);
- layer->draw_properties().sorted_for_recursion = false;
+ layer->set_sorted_for_recursion(false);
layer->draw_properties().has_child_with_a_scroll_parent = false;
- layer->draw_properties().layer_or_descendant_is_drawn = false;
- layer->draw_properties().visited = false;
+ layer->set_layer_or_descendant_is_drawn(false);
+ layer->set_visited(false);
if (!HasInvertibleOrAnimatedTransform(layer)) {
// Layers with singular transforms should not be drawn, the whole subtree
@@ -1334,7 +1229,7 @@ static void PreCalculateMetaInformationInternal(
}
if (layer->clip_children()) {
- int num_clip_children = layer->clip_children()->size();
+ size_t num_clip_children = layer->clip_children()->size();
DCHECK_GE(recursive_data->num_unclipped_descendants, num_clip_children);
recursive_data->num_unclipped_descendants -= num_clip_children;
}
@@ -1359,12 +1254,25 @@ void LayerTreeHostCommon::PreCalculateMetaInformation(Layer* root_layer) {
PreCalculateMetaInformationInternal(root_layer, &recursive_data);
}
+void LayerTreeHostCommon::PreCalculateMetaInformationForTesting(
+ LayerImpl* root_layer) {
+ PreCalculateMetaInformationRecursiveData recursive_data;
+ PreCalculateMetaInformationInternal(root_layer, &recursive_data);
+}
+
+void LayerTreeHostCommon::PreCalculateMetaInformationForTesting(
+ Layer* root_layer) {
+ UpdateMetaInformationSequenceNumber(root_layer);
+ PreCalculateMetaInformationRecursiveData recursive_data;
+ PreCalculateMetaInformationInternal(root_layer, &recursive_data);
+}
+
template <typename LayerType>
struct SubtreeGlobals {
int max_texture_size;
float device_scale_factor;
float page_scale_factor;
- const LayerType* page_scale_application_layer;
+ const LayerType* page_scale_layer;
gfx::Vector2dF elastic_overscroll;
const LayerType* elastic_overscroll_application_layer;
bool can_adjust_raster_scales;
@@ -1412,7 +1320,7 @@ struct DataForRecursion {
bool ancestor_clips_subtree;
typename LayerType::RenderSurfaceType*
nearest_occlusion_immune_ancestor_surface;
- bool in_subtree_of_page_scale_application_layer;
+ bool in_subtree_of_page_scale_layer;
bool subtree_can_use_lcd_text;
bool subtree_is_visible_from_ancestor;
};
@@ -1460,14 +1368,15 @@ static void AddScrollParentChain(std::vector<LayerType*>* out,
// that we will potentionally add to the list. That is, the child of parent
// containing |layer|.
LayerType* child = GetChildContainingLayer(parent, layer);
- if (child->draw_properties().sorted_for_recursion)
+ if (child->sorted_for_recursion())
return;
if (LayerType* scroll_parent = child->scroll_parent())
AddScrollParentChain(out, parent, scroll_parent);
out->push_back(child);
- child->draw_properties().sorted_for_recursion = true;
+ bool sorted_for_recursion = true;
+ child->set_sorted_for_recursion(sorted_for_recursion);
}
template <typename LayerType>
@@ -1479,7 +1388,7 @@ static bool SortChildrenForRecursion(std::vector<LayerType*>* out,
LayerType* current =
LayerTreeHostCommon::get_layer_as_raw_ptr(parent.children(), i);
- if (current->draw_properties().sorted_for_recursion) {
+ if (current->sorted_for_recursion()) {
order_changed = true;
continue;
}
@@ -1518,14 +1427,6 @@ static LayerImplList* GetLayerListForSorting(LayerImplList* layer_list) {
return layer_list;
}
-static inline gfx::Vector2d BoundsDelta(Layer* layer) {
- return gfx::Vector2d();
-}
-
-static inline gfx::Vector2d BoundsDelta(LayerImpl* layer) {
- return gfx::ToCeiledVector2d(layer->bounds_delta());
-}
-
template <typename LayerType, typename GetIndexAndCountType>
static void SortLayerListContributions(
const LayerType& parent,
@@ -1679,18 +1580,18 @@ static void CalculateDrawPropertiesInternal(
// It makes no sense to have a non-unit page_scale_factor without specifying
// which layer roots the subtree the scale is applied to.
- DCHECK(globals.page_scale_application_layer ||
- (globals.page_scale_factor == 1.f));
+ DCHECK(globals.page_scale_layer || (globals.page_scale_factor == 1.f));
- CHECK(!layer->draw_properties().visited);
- layer->draw_properties().visited = true;
+ CHECK(!layer->visited());
+ bool visited = true;
+ layer->set_visited(visited);
DataForRecursion<LayerType> data_for_children;
typename LayerType::RenderSurfaceType*
nearest_occlusion_immune_ancestor_surface =
data_from_ancestor.nearest_occlusion_immune_ancestor_surface;
- data_for_children.in_subtree_of_page_scale_application_layer =
- data_from_ancestor.in_subtree_of_page_scale_application_layer;
+ data_for_children.in_subtree_of_page_scale_layer =
+ data_from_ancestor.in_subtree_of_page_scale_layer;
data_for_children.subtree_can_use_lcd_text =
data_from_ancestor.subtree_can_use_lcd_text;
@@ -1826,69 +1727,42 @@ static void CalculateDrawPropertiesInternal(
// Compute the 2d scale components of the transform hierarchy up to the target
// surface. From there, we can decide on a contents scale for the layer.
float layer_scale_factors = globals.device_scale_factor;
- if (data_from_ancestor.in_subtree_of_page_scale_application_layer)
+ if (data_from_ancestor.in_subtree_of_page_scale_layer)
layer_scale_factors *= globals.page_scale_factor;
gfx::Vector2dF combined_transform_scales =
MathUtil::ComputeTransform2dScaleComponents(
combined_transform,
layer_scale_factors);
- float ideal_contents_scale =
- globals.can_adjust_raster_scales
- ? std::max(combined_transform_scales.x(),
- combined_transform_scales.y())
- : layer_scale_factors;
- UpdateLayerContentsScale(
- layer,
- globals.can_adjust_raster_scales,
- ideal_contents_scale,
- globals.device_scale_factor,
- data_from_ancestor.in_subtree_of_page_scale_application_layer
- ? globals.page_scale_factor
- : 1.f,
- animating_transform_to_screen);
-
- UpdateLayerScaleDrawProperties(
- layer, ideal_contents_scale, combined_maximum_animation_contents_scale,
- combined_starting_animation_contents_scale,
- data_from_ancestor.in_subtree_of_page_scale_application_layer
- ? globals.page_scale_factor
- : 1.f,
- globals.device_scale_factor);
+ UpdateLayerScaleDrawProperties(layer,
+ combined_maximum_animation_contents_scale,
+ combined_starting_animation_contents_scale);
LayerType* mask_layer = layer->mask_layer();
if (mask_layer) {
- UpdateLayerScaleDrawProperties(
- mask_layer, ideal_contents_scale,
- combined_maximum_animation_contents_scale,
- combined_starting_animation_contents_scale,
- data_from_ancestor.in_subtree_of_page_scale_application_layer
- ? globals.page_scale_factor
- : 1.f,
- globals.device_scale_factor);
+ UpdateLayerScaleDrawProperties(mask_layer,
+ combined_maximum_animation_contents_scale,
+ combined_starting_animation_contents_scale);
}
LayerType* replica_mask_layer =
layer->replica_layer() ? layer->replica_layer()->mask_layer() : NULL;
if (replica_mask_layer) {
- UpdateLayerScaleDrawProperties(
- replica_mask_layer, ideal_contents_scale,
- combined_maximum_animation_contents_scale,
- combined_starting_animation_contents_scale,
- data_from_ancestor.in_subtree_of_page_scale_application_layer
- ? globals.page_scale_factor
- : 1.f,
- globals.device_scale_factor);
+ UpdateLayerScaleDrawProperties(replica_mask_layer,
+ combined_maximum_animation_contents_scale,
+ combined_starting_animation_contents_scale);
+ }
+
+ if (layer == globals.page_scale_layer) {
+ combined_transform.Scale(globals.page_scale_factor,
+ globals.page_scale_factor);
+ data_for_children.in_subtree_of_page_scale_layer = true;
}
// The draw_transform that gets computed below is effectively the layer's
// draw_transform, unless the layer itself creates a render_surface. In that
// case, the render_surface re-parents the transforms.
layer_draw_properties.target_space_transform = combined_transform;
- // M[draw] = M[parent] * LT * S[layer2content]
- layer_draw_properties.target_space_transform.Scale(
- SK_MScalar1 / layer->contents_scale_x(),
- SK_MScalar1 / layer->contents_scale_y());
// The layer's screen_space_transform represents the transform between root
// layer's "screen space" and local content space.
@@ -1963,8 +1837,7 @@ static void CalculateDrawPropertiesInternal(
// space.
layer_draw_properties.target_space_transform.MakeIdentity();
layer_draw_properties.target_space_transform.Scale(
- combined_transform_scales.x() / layer->contents_scale_x(),
- combined_transform_scales.y() / layer->contents_scale_y());
+ combined_transform_scales.x(), combined_transform_scales.y());
// Inside the surface's subtree, we scale everything to the owning layer's
// scale. The sublayer matrix transforms layer rects into target surface
@@ -2016,16 +1889,25 @@ static void CalculateDrawPropertiesInternal(
DrawProperties<LayerType>& mask_layer_draw_properties =
layer->mask_layer()->draw_properties();
mask_layer_draw_properties.render_target = layer;
- mask_layer_draw_properties.visible_content_rect =
- gfx::Rect(layer->content_bounds());
+ mask_layer_draw_properties.visible_layer_rect =
+ gfx::Rect(layer->bounds());
+ // Temporarily copy the draw transform of the mask's owning layer into the
+ // mask layer draw properties. This won't actually get used for drawing
+ // (the render surface uses the mask texture directly), but will get used
+ // to get the correct contents scale.
+ // TODO(enne): do something similar for property trees.
+ mask_layer_draw_properties.target_space_transform =
+ layer_draw_properties.target_space_transform;
}
if (layer->replica_layer() && layer->replica_layer()->mask_layer()) {
DrawProperties<LayerType>& replica_mask_draw_properties =
layer->replica_layer()->mask_layer()->draw_properties();
replica_mask_draw_properties.render_target = layer;
- replica_mask_draw_properties.visible_content_rect =
- gfx::Rect(layer->content_bounds());
+ replica_mask_draw_properties.visible_layer_rect =
+ gfx::Rect(layer->bounds());
+ replica_mask_draw_properties.target_space_transform =
+ layer_draw_properties.target_space_transform;
}
// Ignore occlusion from outside the surface when surface contents need to
@@ -2064,7 +1946,7 @@ static void CalculateDrawPropertiesInternal(
gfx::Rect projected_surface_rect = MathUtil::ProjectEnclosingClippedRect(
inverse_surface_draw_transform, surface_clip_rect_in_target_space);
- if (layer_draw_properties.num_unclipped_descendants > 0) {
+ if (layer_draw_properties.num_unclipped_descendants > 0u) {
// If we have unclipped descendants, we cannot count on the render
// surface's bounds clipping our subtree: the unclipped descendants
// could cause us to expand our bounds. In this case, we must rely on
@@ -2143,22 +2025,10 @@ static void CalculateDrawPropertiesInternal(
layer_draw_properties.can_use_lcd_text = layer_can_use_lcd_text;
- gfx::Size content_size_affected_by_delta(layer->content_bounds());
-
- // Non-zero BoundsDelta imply the contents_scale of 1.0
- // because BoundsDela is only set on Android where
- // ContentScalingLayer is never used.
- DCHECK_IMPLIES(!BoundsDelta(layer).IsZero(),
- (layer->contents_scale_x() == 1.0 &&
- layer->contents_scale_y() == 1.0));
-
- // Thus we can omit contents scale in the following calculation.
- gfx::Vector2d bounds_delta = BoundsDelta(layer);
- content_size_affected_by_delta.Enlarge(bounds_delta.x(), bounds_delta.y());
-
+ // The layer bounds() includes the layer's bounds_delta() which we want
+ // for the clip rect.
gfx::Rect rect_in_target_space = MathUtil::MapEnclosingClippedRect(
- layer->draw_transform(),
- gfx::Rect(content_size_affected_by_delta));
+ layer->draw_transform(), gfx::Rect(layer->bounds()));
if (LayerClipsSubtree(layer)) {
layer_or_ancestor_clips_descendants = true;
@@ -2207,12 +2077,6 @@ static void CalculateDrawPropertiesInternal(
size_t layer_list_child_sorting_start_index = descendants.size();
if (!layer->children().empty()) {
- if (layer == globals.page_scale_application_layer) {
- data_for_children.parent_matrix.Scale(
- globals.page_scale_factor,
- globals.page_scale_factor);
- data_for_children.in_subtree_of_page_scale_application_layer = true;
- }
if (layer == globals.elastic_overscroll_application_layer) {
data_for_children.parent_matrix.Translate(
-globals.elastic_overscroll.x(), -globals.elastic_overscroll.y());
@@ -2289,8 +2153,11 @@ static void CalculateDrawPropertiesInternal(
render_surface_layer_list->size() -
child->draw_properties()
.index_of_first_render_surface_layer_list_addition;
- layer_draw_properties.layer_or_descendant_is_drawn |=
- child->draw_properties().layer_or_descendant_is_drawn;
+
+ if (child->layer_or_descendant_is_drawn()) {
+ bool layer_or_descendant_is_drawn = true;
+ layer->set_layer_or_descendant_is_drawn(layer_or_descendant_is_drawn);
+ }
}
// Add the unsorted layer list contributions, if necessary.
@@ -2336,7 +2203,7 @@ static void CalculateDrawPropertiesInternal(
}
// Compute the layer's visible content rect (the rect is in content space).
- layer_draw_properties.visible_content_rect = CalculateVisibleContentRect(
+ layer_draw_properties.visible_layer_rect = CalculateVisibleLayerRect(
layer, clip_rect_of_target_surface_in_target_space, rect_in_target_space);
// Compute the remaining properties for the render surface, if the layer has
@@ -2396,9 +2263,8 @@ static void CalculateDrawPropertiesInternal(
// layer space which we need to undo and replace with a scale from the
// surface's subtree into layer space.
gfx::Transform screen_space_transform = layer->screen_space_transform();
- screen_space_transform.Scale(
- layer->contents_scale_x() / combined_transform_scales.x(),
- layer->contents_scale_y() / combined_transform_scales.y());
+ screen_space_transform.Scale(1.0 / combined_transform_scales.x(),
+ 1.0 / combined_transform_scales.y());
render_surface->SetScreenSpaceTransform(screen_space_transform);
if (layer->replica_layer()) {
@@ -2485,7 +2351,7 @@ static void ProcessCalcDrawPropsInputs(
globals->device_scale_factor =
inputs.device_scale_factor * device_transform_scale;
globals->page_scale_factor = inputs.page_scale_factor;
- globals->page_scale_application_layer = inputs.page_scale_application_layer;
+ globals->page_scale_layer = inputs.page_scale_layer;
globals->elastic_overscroll = inputs.elastic_overscroll;
globals->elastic_overscroll_application_layer =
inputs.elastic_overscroll_application_layer;
@@ -2506,7 +2372,7 @@ static void ProcessCalcDrawPropsInputs(
data_for_recursion->ancestor_is_animating_scale = false;
data_for_recursion->ancestor_clips_subtree = true;
data_for_recursion->nearest_occlusion_immune_ancestor_surface = NULL;
- data_for_recursion->in_subtree_of_page_scale_application_layer = false;
+ data_for_recursion->in_subtree_of_page_scale_layer = false;
data_for_recursion->subtree_can_use_lcd_text = inputs.can_use_lcd_text;
data_for_recursion->subtree_is_visible_from_ancestor = true;
}
@@ -2592,51 +2458,59 @@ static bool ApproximatelyEqual(const gfx::Transform& a,
return true;
}
+void VerifyPropertyTreeValuesForLayer(LayerImpl* current_layer,
+ PropertyTrees* property_trees,
+ bool layers_always_allowed_lcd_text,
+ bool can_use_lcd_text) {
+ const bool visible_rects_match =
+ ApproximatelyEqual(current_layer->visible_layer_rect(),
+ current_layer->visible_rect_from_property_trees());
+ CHECK(visible_rects_match)
+ << "expected: " << current_layer->visible_layer_rect().ToString()
+ << " actual: "
+ << current_layer->visible_rect_from_property_trees().ToString();
+
+ const bool draw_transforms_match =
+ ApproximatelyEqual(current_layer->draw_transform(),
+ DrawTransformFromPropertyTrees(
+ current_layer, property_trees->transform_tree));
+ CHECK(draw_transforms_match)
+ << "expected: " << current_layer->draw_transform().ToString()
+ << " actual: "
+ << DrawTransformFromPropertyTrees(
+ current_layer, property_trees->transform_tree).ToString();
+
+ const bool draw_opacities_match =
+ current_layer->draw_opacity() ==
+ DrawOpacityFromPropertyTrees(current_layer, property_trees->opacity_tree);
+ CHECK(draw_opacities_match)
+ << "expected: " << current_layer->draw_opacity()
+ << " actual: " << DrawOpacityFromPropertyTrees(
+ current_layer, property_trees->opacity_tree);
+ const bool can_use_lcd_text_match =
+ CanUseLcdTextFromPropertyTrees(
+ current_layer, layers_always_allowed_lcd_text, can_use_lcd_text,
+ property_trees) == current_layer->can_use_lcd_text();
+ CHECK(can_use_lcd_text_match);
+}
+
void VerifyPropertyTreeValues(
LayerTreeHostCommon::CalcDrawPropsMainInputs* inputs) {
- LayerIterator<Layer> it, end;
- for (it = LayerIterator<Layer>::Begin(inputs->render_surface_layer_list),
- end = LayerIterator<Layer>::End(inputs->render_surface_layer_list);
- it != end; ++it) {
- Layer* current_layer = *it;
- if (!it.represents_itself() || !current_layer->DrawsContent())
- continue;
-
- const bool visible_rects_match =
- ApproximatelyEqual(current_layer->visible_content_rect(),
- current_layer->visible_rect_from_property_trees());
- CHECK(visible_rects_match)
- << "expected: " << current_layer->visible_content_rect().ToString()
- << " actual: "
- << current_layer->visible_rect_from_property_trees().ToString();
-
- const bool draw_transforms_match = ApproximatelyEqual(
- current_layer->draw_transform(),
- DrawTransformFromPropertyTrees(current_layer,
- inputs->property_trees->transform_tree));
- CHECK(draw_transforms_match)
- << "expected: " << current_layer->draw_transform().ToString()
- << " actual: "
- << DrawTransformFromPropertyTrees(
- current_layer, inputs->property_trees->transform_tree)
- .ToString();
-
- const bool draw_opacities_match =
- current_layer->draw_opacity() ==
- DrawOpacityFromPropertyTrees(current_layer,
- inputs->property_trees->opacity_tree);
- CHECK(draw_opacities_match)
- << "expected: " << current_layer->draw_opacity() << " actual: "
- << DrawOpacityFromPropertyTrees(current_layer,
- inputs->property_trees->opacity_tree);
- }
}
void VerifyPropertyTreeValues(
LayerTreeHostCommon::CalcDrawPropsImplInputs* inputs) {
- // TODO(enne): need to synchronize compositor thread changes
- // for animation and scrolling to the property trees before these
- // can be correct.
+ LayerIterator it, end;
+ for (it = LayerIterator::Begin(inputs->render_surface_layer_list),
+ end = LayerIterator::End(inputs->render_surface_layer_list);
+ it != end; ++it) {
+ LayerImpl* current_layer = *it;
+ if (!it.represents_itself() || !current_layer->DrawsContent())
+ continue;
+ VerifyPropertyTreeValuesForLayer(current_layer, inputs->property_trees,
+ inputs->layers_always_allowed_lcd_text,
+ inputs->can_use_lcd_text);
+ }
}
enum PropertyTreeOption {
@@ -2654,6 +2528,7 @@ void CalculateDrawPropertiesAndVerify(LayerTreeHostCommon::CalcDrawPropsInputs<
DataForRecursion<LayerType> data_for_recursion;
ProcessCalcDrawPropsInputs(*inputs, &globals, &data_for_recursion);
+ UpdateMetaInformationSequenceNumber(inputs->root_layer);
PreCalculateMetaInformationRecursiveData recursive_data;
PreCalculateMetaInformationInternal(inputs->root_layer, &recursive_data);
@@ -2665,7 +2540,6 @@ void CalculateDrawPropertiesAndVerify(LayerTreeHostCommon::CalcDrawPropsInputs<
TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
"LayerTreeHostCommon::CalculateDrawProperties");
}
- ResetDrawProperties(inputs->root_layer);
std::vector<AccumulatedSurfaceState<LayerType>> accumulated_surface_state;
CalculateDrawPropertiesInternal<LayerType>(
@@ -2696,8 +2570,10 @@ void CalculateDrawPropertiesAndVerify(LayerTreeHostCommon::CalcDrawPropsInputs<
}
BuildPropertyTreesAndComputeVisibleRects(
- inputs->root_layer, inputs->page_scale_application_layer,
- inputs->page_scale_factor, inputs->device_scale_factor,
+ inputs->root_layer, inputs->page_scale_layer,
+ inputs->inner_viewport_scroll_layer,
+ inputs->outer_viewport_scroll_layer, inputs->page_scale_factor,
+ inputs->device_scale_factor,
gfx::Rect(inputs->device_viewport_size), inputs->device_transform,
inputs->property_trees, &update_layer_list);
@@ -2747,14 +2623,12 @@ void LayerTreeHostCommon::CalculateDrawProperties(
CalculateDrawPropertiesAndVerify(inputs, BUILD_PROPERTY_TREES_IF_NEEDED);
}
-PropertyTrees* GetPropertyTrees(Layer* layer,
- PropertyTrees* trees_from_inputs) {
+PropertyTrees* GetPropertyTrees(Layer* layer) {
return layer->layer_tree_host()->property_trees();
}
-PropertyTrees* GetPropertyTrees(LayerImpl* layer,
- PropertyTrees* trees_from_inputs) {
- return trees_from_inputs;
+PropertyTrees* GetPropertyTrees(LayerImpl* layer) {
+ return layer->layer_tree_impl()->property_trees();
}
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_common.h b/chromium/cc/trees/layer_tree_host_common.h
index 7d90445023f..bf62111acbe 100644
--- a/chromium/cc/trees/layer_tree_host_common.h
+++ b/chromium/cc/trees/layer_tree_host_common.h
@@ -39,7 +39,9 @@ class CC_EXPORT LayerTreeHostCommon {
const gfx::Transform& device_transform,
float device_scale_factor,
float page_scale_factor,
- const LayerType* page_scale_application_layer,
+ const LayerType* page_scale_layer,
+ const LayerType* inner_viewport_scroll_layer,
+ const LayerType* outer_viewport_scroll_layer,
const gfx::Vector2dF& elastic_overscroll,
const LayerType* elastic_overscroll_application_layer,
int max_texture_size,
@@ -56,7 +58,9 @@ class CC_EXPORT LayerTreeHostCommon {
device_transform(device_transform),
device_scale_factor(device_scale_factor),
page_scale_factor(page_scale_factor),
- page_scale_application_layer(page_scale_application_layer),
+ page_scale_layer(page_scale_layer),
+ inner_viewport_scroll_layer(inner_viewport_scroll_layer),
+ outer_viewport_scroll_layer(outer_viewport_scroll_layer),
elastic_overscroll(elastic_overscroll),
elastic_overscroll_application_layer(
elastic_overscroll_application_layer),
@@ -76,7 +80,9 @@ class CC_EXPORT LayerTreeHostCommon {
gfx::Transform device_transform;
float device_scale_factor;
float page_scale_factor;
- const LayerType* page_scale_application_layer;
+ const LayerType* page_scale_layer;
+ const LayerType* inner_viewport_scroll_layer;
+ const LayerType* outer_viewport_scroll_layer;
gfx::Vector2dF elastic_overscroll;
const LayerType* elastic_overscroll_application_layer;
int max_texture_size;
@@ -102,9 +108,6 @@ class CC_EXPORT LayerTreeHostCommon {
LayerType* root_layer,
const gfx::Size& device_viewport_size,
RenderSurfaceLayerListType* render_surface_layer_list);
-
- private:
- PropertyTrees temporary_property_trees;
};
typedef CalcDrawPropsInputs<Layer, RenderSurfaceLayerList>
@@ -121,6 +124,8 @@ class CC_EXPORT LayerTreeHostCommon {
bool* animation_preserves_axis_alignment);
static void CalculateDrawProperties(CalcDrawPropsMainInputs* inputs);
static void PreCalculateMetaInformation(Layer* root_layer);
+ static void PreCalculateMetaInformationForTesting(LayerImpl* root_layer);
+ static void PreCalculateMetaInformationForTesting(Layer* root_layer);
typedef CalcDrawPropsInputs<LayerImpl, LayerImplList> CalcDrawPropsImplInputs;
typedef CalcDrawPropsInputsForTesting<LayerImpl, LayerImplList>
@@ -235,10 +240,8 @@ void LayerTreeHostCommon::CallFunctionForSubtree(LayerType* layer,
}
}
-CC_EXPORT PropertyTrees* GetPropertyTrees(Layer* layer,
- PropertyTrees* trees_from_inputs);
-CC_EXPORT PropertyTrees* GetPropertyTrees(LayerImpl* layer,
- PropertyTrees* trees_from_inputs);
+CC_EXPORT PropertyTrees* GetPropertyTrees(Layer* layer);
+CC_EXPORT PropertyTrees* GetPropertyTrees(LayerImpl* layer);
template <typename LayerType, typename RenderSurfaceLayerListType>
LayerTreeHostCommon::CalcDrawPropsInputsForTesting<LayerType,
@@ -255,6 +258,8 @@ LayerTreeHostCommon::CalcDrawPropsInputsForTesting<LayerType,
1.f,
1.f,
NULL,
+ NULL,
+ NULL,
gfx::Vector2dF(),
NULL,
std::numeric_limits<int>::max() / 2,
@@ -265,7 +270,7 @@ LayerTreeHostCommon::CalcDrawPropsInputsForTesting<LayerType,
true,
render_surface_layer_list,
0,
- GetPropertyTrees(root_layer, &temporary_property_trees)) {
+ GetPropertyTrees(root_layer)) {
DCHECK(root_layer);
DCHECK(render_surface_layer_list);
}
@@ -284,6 +289,8 @@ LayerTreeHostCommon::CalcDrawPropsInputsForTesting<LayerType,
1.f,
1.f,
NULL,
+ NULL,
+ NULL,
gfx::Vector2dF(),
NULL,
std::numeric_limits<int>::max() / 2,
@@ -294,7 +301,7 @@ LayerTreeHostCommon::CalcDrawPropsInputsForTesting<LayerType,
true,
render_surface_layer_list,
0,
- GetPropertyTrees(root_layer, &temporary_property_trees)) {
+ GetPropertyTrees(root_layer)) {
DCHECK(root_layer);
DCHECK(render_surface_layer_list);
}
diff --git a/chromium/cc/trees/layer_tree_host_common_perftest.cc b/chromium/cc/trees/layer_tree_host_common_perftest.cc
index 9a5de06bb0f..49831328d1e 100644
--- a/chromium/cc/trees/layer_tree_host_common_perftest.cc
+++ b/chromium/cc/trees/layer_tree_host_common_perftest.cc
@@ -77,48 +77,9 @@ class LayerTreeHostCommonPerfTest : public LayerTreeTest {
std::string json_;
};
-class CalcDrawPropsMainTest : public LayerTreeHostCommonPerfTest {
+class CalcDrawPropsTest : public LayerTreeHostCommonPerfTest {
public:
- void RunCalcDrawProps() { RunTest(false, false, false); }
-
- void BeginTest() override {
- timer_.Reset();
-
- do {
- bool can_render_to_separate_surface = true;
- bool verify_property_trees = false;
- int max_texture_size = 8096;
- RenderSurfaceLayerList update_list;
- PropertyTrees property_trees;
- LayerTreeHostCommon::CalcDrawPropsMainInputs inputs(
- layer_tree_host()->root_layer(),
- layer_tree_host()->device_viewport_size(), gfx::Transform(),
- layer_tree_host()->device_scale_factor(),
- layer_tree_host()->page_scale_factor(),
- layer_tree_host()->overscroll_elasticity_layer(),
- layer_tree_host()->elastic_overscroll(),
- layer_tree_host()->page_scale_layer(), max_texture_size,
- layer_tree_host()->settings().can_use_lcd_text,
- layer_tree_host()->settings().layers_always_allowed_lcd_text,
- can_render_to_separate_surface,
- layer_tree_host()
- ->settings()
- .layer_transforms_should_scale_layer_contents,
- verify_property_trees, &update_list, 0, &property_trees);
- LayerTreeHostCommon::CalculateDrawProperties(&inputs);
-
- timer_.NextLap();
- } while (!timer_.HasTimeLimitExpired());
-
- EndTest();
- }
-};
-
-class CalcDrawPropsImplTest : public LayerTreeHostCommonPerfTest {
- public:
- void RunCalcDrawProps() {
- RunTestWithImplSidePainting();
- }
+ void RunCalcDrawProps() { RunTest(false, false); }
void BeginTest() override { PostSetNeedsCommitToMainThread(); }
@@ -152,6 +113,8 @@ class CalcDrawPropsImplTest : public LayerTreeHostCommonPerfTest {
host_impl->DrawTransform(), active_tree->device_scale_factor(),
active_tree->current_page_scale_factor(),
active_tree->InnerViewportContainerLayer(),
+ active_tree->InnerViewportScrollLayer(),
+ active_tree->OuterViewportScrollLayer(),
active_tree->elastic_overscroll()->Current(active_tree->IsActiveTree()),
active_tree->overscroll_elasticity_layer(), max_texture_size,
host_impl->settings().can_use_lcd_text,
@@ -163,10 +126,10 @@ class CalcDrawPropsImplTest : public LayerTreeHostCommonPerfTest {
}
};
-class BspTreePerfTest : public CalcDrawPropsImplTest {
+class BspTreePerfTest : public CalcDrawPropsTest {
public:
BspTreePerfTest() : num_duplicates_(1) {}
- void RunSortLayers() { RunTest(false, false, false); }
+ void RunSortLayers() { RunTest(false, false); }
void SetNumberOfDuplicates(int num_duplicates) {
num_duplicates_ = num_duplicates;
@@ -193,10 +156,8 @@ class BspTreePerfTest : public CalcDrawPropsImplTest {
for (LayerImplList::iterator it = base_list.begin(); it != base_list.end();
++it) {
DrawPolygon* draw_polygon =
- new DrawPolygon(NULL,
- gfx::RectF((*it)->content_bounds()),
- (*it)->draw_transform(),
- polygon_counter++);
+ new DrawPolygon(NULL, gfx::RectF((*it)->bounds()),
+ (*it)->draw_transform(), polygon_counter++);
polygon_list.push_back(scoped_ptr<DrawPolygon>(draw_polygon));
}
@@ -230,49 +191,25 @@ class BspTreePerfTest : public CalcDrawPropsImplTest {
int num_duplicates_;
};
-TEST_F(CalcDrawPropsMainTest, TenTen) {
- SetTestName("10_10_main_thread");
- ReadTestFile("10_10_layer_tree");
- RunCalcDrawProps();
-}
-
-TEST_F(CalcDrawPropsMainTest, HeavyPage) {
- SetTestName("heavy_page_main_thread");
- ReadTestFile("heavy_layer_tree");
- RunCalcDrawProps();
-}
-
-TEST_F(CalcDrawPropsMainTest, TouchRegionLight) {
- SetTestName("touch_region_light_main_thread");
- ReadTestFile("touch_region_light");
- RunCalcDrawProps();
-}
-
-TEST_F(CalcDrawPropsMainTest, TouchRegionHeavy) {
- SetTestName("touch_region_heavy_main_thread");
- ReadTestFile("touch_region_heavy");
- RunCalcDrawProps();
-}
-
-TEST_F(CalcDrawPropsImplTest, TenTen) {
+TEST_F(CalcDrawPropsTest, TenTen) {
SetTestName("10_10");
ReadTestFile("10_10_layer_tree");
RunCalcDrawProps();
}
-TEST_F(CalcDrawPropsImplTest, HeavyPage) {
+TEST_F(CalcDrawPropsTest, HeavyPage) {
SetTestName("heavy_page");
ReadTestFile("heavy_layer_tree");
RunCalcDrawProps();
}
-TEST_F(CalcDrawPropsImplTest, TouchRegionLight) {
+TEST_F(CalcDrawPropsTest, TouchRegionLight) {
SetTestName("touch_region_light");
ReadTestFile("touch_region_light");
RunCalcDrawProps();
}
-TEST_F(CalcDrawPropsImplTest, TouchRegionHeavy) {
+TEST_F(CalcDrawPropsTest, TouchRegionHeavy) {
SetTestName("touch_region_heavy");
ReadTestFile("touch_region_heavy");
RunCalcDrawProps();
diff --git a/chromium/cc/trees/layer_tree_host_common_unittest.cc b/chromium/cc/trees/layer_tree_host_common_unittest.cc
index 591f48c4329..43e2bb02123 100644
--- a/chromium/cc/trees/layer_tree_host_common_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_common_unittest.cc
@@ -10,7 +10,6 @@
#include "cc/animation/layer_animation_controller.h"
#include "cc/animation/transform_operations.h"
#include "cc/base/math_util.h"
-#include "cc/layers/content_layer.h"
#include "cc/layers/content_layer_client.h"
#include "cc/layers/layer.h"
#include "cc/layers/layer_client.h"
@@ -21,9 +20,7 @@
#include "cc/output/copy_output_request.h"
#include "cc/output/copy_output_result.h"
#include "cc/test/animation_test_common.h"
-#include "cc/test/fake_content_layer.h"
#include "cc/test/fake_content_layer_client.h"
-#include "cc/test/fake_content_layer_impl.h"
#include "cc/test/fake_impl_proxy.h"
#include "cc/test/fake_layer_tree_host.h"
#include "cc/test/fake_layer_tree_host_impl.h"
@@ -46,7 +43,8 @@ namespace {
class LayerWithForcedDrawsContent : public Layer {
public:
- LayerWithForcedDrawsContent() {}
+ explicit LayerWithForcedDrawsContent(const LayerSettings& settings)
+ : Layer(settings) {}
bool DrawsContent() const override;
@@ -63,26 +61,20 @@ class MockContentLayerClient : public ContentLayerClient {
void PaintContents(SkCanvas* canvas,
const gfx::Rect& clip,
PaintingControlSetting picture_control) override {}
- void PaintContentsToDisplayList(
- DisplayItemList* display_list,
+ scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
const gfx::Rect& clip,
PaintingControlSetting picture_control) override {
NOTIMPLEMENTED();
+ return nullptr;
}
bool FillsBoundsCompletely() const override { return false; }
};
scoped_refptr<FakePictureLayer> CreateDrawablePictureLayer(
+ const LayerSettings& settings,
ContentLayerClient* delegate) {
scoped_refptr<FakePictureLayer> to_return =
- FakePictureLayer::Create(delegate);
- to_return->SetIsDrawable(true);
- return to_return;
-}
-
-scoped_refptr<ContentLayer> CreateDrawableContentLayer(
- ContentLayerClient* delegate) {
- scoped_refptr<ContentLayer> to_return = ContentLayer::Create(delegate);
+ FakePictureLayer::Create(settings, delegate);
to_return->SetIsDrawable(true);
return to_return;
}
@@ -93,25 +85,37 @@ scoped_refptr<ContentLayer> CreateDrawableContentLayer(
EXPECT_FLOAT_EQ(expected, layer->contents_scale_y()); \
} while (false)
-#define EXPECT_IDEAL_SCALE_EQ(expected, layer) \
- do { \
- EXPECT_FLOAT_EQ(expected, layer->draw_properties().ideal_contents_scale); \
+#define EXPECT_IDEAL_SCALE_EQ(expected, layer) \
+ do { \
+ EXPECT_FLOAT_EQ(expected, layer->GetIdealContentsScale()); \
} while (false)
+class LayerTreeSettingsScaleContent : public LayerTreeSettings {
+ public:
+ LayerTreeSettingsScaleContent() {
+ layer_transforms_should_scale_layer_contents = true;
+ }
+};
+
+class LayerTreeHostCommonScalingTest : public LayerTreeHostCommonTest {
+ public:
+ LayerTreeHostCommonScalingTest()
+ : LayerTreeHostCommonTest(LayerTreeSettingsScaleContent()) {}
+};
+
TEST_F(LayerTreeHostCommonTest, TransformsForNoOpLayer) {
// Sanity check: For layers positioned at zero, with zero size,
// and with identity transforms, then the draw transform,
// screen space transform, and the hierarchy passed on to children
// layers should also be identity transforms.
- scoped_refptr<Layer> parent = Layer::Create();
- scoped_refptr<Layer> child = Layer::Create();
- scoped_refptr<Layer> grand_child = Layer::Create();
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings());
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
+ scoped_refptr<Layer> grand_child = Layer::Create(layer_settings());
parent->AddChild(child);
child->AddChild(grand_child);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(parent);
+ host()->SetRootLayer(parent);
gfx::Transform identity_matrix;
SetLayerPropertiesForTesting(parent.get(),
@@ -148,14 +152,13 @@ TEST_F(LayerTreeHostCommonTest, TransformsForNoOpLayer) {
}
TEST_F(LayerTreeHostCommonTest, DoNotSkipLayersWithHandlers) {
- scoped_refptr<Layer> parent = Layer::Create();
- scoped_refptr<Layer> child = Layer::Create();
- scoped_refptr<Layer> grand_child = Layer::Create();
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings());
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
+ scoped_refptr<Layer> grand_child = Layer::Create(layer_settings());
parent->AddChild(child);
child->AddChild(grand_child);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(parent);
+ host()->SetRootLayer(parent);
gfx::Transform identity_matrix;
SetLayerPropertiesForTesting(parent.get(),
@@ -195,9 +198,9 @@ TEST_F(LayerTreeHostCommonTest, DoNotSkipLayersWithHandlers) {
TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) {
gfx::Transform identity_matrix;
- scoped_refptr<Layer> layer = Layer::Create();
+ scoped_refptr<Layer> layer = Layer::Create(layer_settings());
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(root.get(),
identity_matrix,
gfx::Point3F(),
@@ -207,8 +210,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) {
false);
root->AddChild(layer);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
// Case 2: Setting the bounds of the layer should not affect either the draw
// transform or the screenspace transform.
@@ -319,14 +321,14 @@ TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
gfx::Transform identity_matrix;
scoped_ptr<LayerImpl> sublayer_scoped_ptr(
LayerImpl::Create(host_impl.active_tree(), 1));
LayerImpl* sublayer = sublayer_scoped_ptr.get();
- sublayer->SetContentsScale(kPageScale * kDeviceScale,
- kPageScale * kDeviceScale);
SetLayerPropertiesForTesting(sublayer, identity_matrix, gfx::Point3F(),
gfx::PointF(), gfx::Size(500, 500), true, false,
false);
@@ -364,9 +366,12 @@ TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) {
root.get(), kDeviceScale, kPageScale, scroll_layer->parent());
gfx::Transform expected_transform = identity_matrix;
gfx::PointF sub_layer_screen_position = kScrollLayerPosition - kScrollDelta;
- sub_layer_screen_position.Scale(kPageScale * kDeviceScale);
- expected_transform.Translate(MathUtil::Round(sub_layer_screen_position.x()),
- MathUtil::Round(sub_layer_screen_position.y()));
+ expected_transform.Translate(MathUtil::Round(sub_layer_screen_position.x() *
+ kPageScale * kDeviceScale),
+ MathUtil::Round(sub_layer_screen_position.y() *
+ kPageScale * kDeviceScale));
+ expected_transform.Scale(kPageScale * kDeviceScale,
+ kPageScale * kDeviceScale);
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform,
sublayer->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform,
@@ -384,25 +389,28 @@ TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) {
expected_transform.MakeIdentity();
expected_transform.Translate(
MathUtil::Round(kTranslateX * kPageScale * kDeviceScale +
- sub_layer_screen_position.x()),
+ sub_layer_screen_position.x() * kPageScale *
+ kDeviceScale),
MathUtil::Round(kTranslateY * kPageScale * kDeviceScale +
- sub_layer_screen_position.y()));
+ sub_layer_screen_position.y() * kPageScale *
+ kDeviceScale));
+ expected_transform.Scale(kPageScale * kDeviceScale,
+ kPageScale * kDeviceScale);
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform,
sublayer->draw_transform());
}
TEST_F(LayerTreeHostCommonTest, TransformsForSimpleHierarchy) {
gfx::Transform identity_matrix;
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> parent = Layer::Create();
- scoped_refptr<Layer> child = Layer::Create();
- scoped_refptr<Layer> grand_child = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings());
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
+ scoped_refptr<Layer> grand_child = Layer::Create(layer_settings());
root->AddChild(parent);
parent->AddChild(child);
child->AddChild(grand_child);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
// One-time setup of root layer
SetLayerPropertiesForTesting(root.get(),
@@ -519,17 +527,16 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSimpleHierarchy) {
}
TEST_F(LayerTreeHostCommonTest, TransformsForSingleRenderSurface) {
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> parent = Layer::Create();
- scoped_refptr<Layer> child = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings());
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> grand_child =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(parent);
parent->AddChild(child);
child->AddChild(grand_child);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
// One-time setup of root layer
gfx::Transform identity_matrix;
@@ -614,19 +621,18 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleRenderSurface) {
}
TEST_F(LayerTreeHostCommonTest, TransformsForReplica) {
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> parent = Layer::Create();
- scoped_refptr<Layer> child = Layer::Create();
- scoped_refptr<Layer> child_replica = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings());
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
+ scoped_refptr<Layer> child_replica = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> grand_child =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(parent);
parent->AddChild(child);
child->AddChild(grand_child);
child->SetReplicaLayer(child_replica.get());
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
// One-time setup of root layer
gfx::Transform identity_matrix;
@@ -720,20 +726,20 @@ TEST_F(LayerTreeHostCommonTest, TransformsForRenderSurfaceHierarchy) {
// - verifying that each layer has a reference to the correct render surface
// and render target values.
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> parent = Layer::Create();
- scoped_refptr<Layer> render_surface1 = Layer::Create();
- scoped_refptr<Layer> render_surface2 = Layer::Create();
- scoped_refptr<Layer> child_of_root = Layer::Create();
- scoped_refptr<Layer> child_of_rs1 = Layer::Create();
- scoped_refptr<Layer> child_of_rs2 = Layer::Create();
- scoped_refptr<Layer> replica_of_rs1 = Layer::Create();
- scoped_refptr<Layer> replica_of_rs2 = Layer::Create();
- scoped_refptr<Layer> grand_child_of_root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings());
+ scoped_refptr<Layer> render_surface1 = Layer::Create(layer_settings());
+ scoped_refptr<Layer> render_surface2 = Layer::Create(layer_settings());
+ scoped_refptr<Layer> child_of_root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> child_of_rs1 = Layer::Create(layer_settings());
+ scoped_refptr<Layer> child_of_rs2 = Layer::Create(layer_settings());
+ scoped_refptr<Layer> replica_of_rs1 = Layer::Create(layer_settings());
+ scoped_refptr<Layer> replica_of_rs2 = Layer::Create(layer_settings());
+ scoped_refptr<Layer> grand_child_of_root = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> grand_child_of_rs1 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> grand_child_of_rs2 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(parent);
parent->AddChild(render_surface1);
parent->AddChild(child_of_root);
@@ -746,8 +752,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForRenderSurfaceHierarchy) {
render_surface1->SetReplicaLayer(replica_of_rs1.get());
render_surface2->SetReplicaLayer(replica_of_rs2.get());
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
// In combination with descendant draws content, opacity != 1 forces the layer
// to have a new render surface.
@@ -1006,12 +1011,12 @@ TEST_F(LayerTreeHostCommonTest, TransformsForFlatteningLayer) {
// Note that the way the code is currently implemented, it is not expected to
// use a canonical orthographic projection.
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> child = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> grand_child =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> great_grand_child =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
gfx::Transform rotation_about_y_axis;
rotation_about_y_axis.RotateAboutYAxis(30.0);
@@ -1047,8 +1052,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForFlatteningLayer) {
grand_child->AddChild(great_grand_child);
child->SetForceRenderSurface(true);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
// No layers in this test should preserve 3d.
ASSERT_TRUE(root->should_flatten_transform());
@@ -1102,10 +1106,10 @@ TEST_F(LayerTreeHostCommonTest, TransformsForDegenerateIntermediateLayer) {
// implicitly inherited by the rest of the subtree, which then is positioned
// incorrectly as a result.
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> child = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> grand_child =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
// The child height is zero, but has non-zero width that should be accounted
// for while computing draw transforms.
@@ -1136,8 +1140,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForDegenerateIntermediateLayer) {
child->AddChild(grand_child);
child->SetForceRenderSurface(true);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
ExecuteCalculateDrawProperties(root.get());
@@ -1155,14 +1158,13 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) {
// to child layers instead of applied to the root RenderSurface.
const gfx::Transform identity_matrix;
scoped_refptr<LayerWithForcedDrawsContent> root =
- new LayerWithForcedDrawsContent;
+ new LayerWithForcedDrawsContent(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> child =
- new LayerWithForcedDrawsContent;
+ new LayerWithForcedDrawsContent(layer_settings());
child->SetScrollClipLayerId(root->id());
root->AddChild(child);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
SetLayerPropertiesForTesting(root.get(),
identity_matrix,
@@ -1191,8 +1193,6 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) {
EXPECT_EQ(translate, root->draw_properties().target_space_transform);
EXPECT_EQ(translate, child->draw_properties().target_space_transform);
EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
- EXPECT_EQ(1.f, root->draw_properties().device_scale_factor);
- EXPECT_EQ(1.f, child->draw_properties().device_scale_factor);
}
gfx::Transform scale;
@@ -1207,8 +1207,6 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) {
EXPECT_EQ(scale, root->draw_properties().target_space_transform);
EXPECT_EQ(scale, child->draw_properties().target_space_transform);
EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
- EXPECT_EQ(2.f, root->draw_properties().device_scale_factor);
- EXPECT_EQ(2.f, child->draw_properties().device_scale_factor);
}
gfx::Transform rotate;
@@ -1223,8 +1221,6 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) {
EXPECT_EQ(rotate, root->draw_properties().target_space_transform);
EXPECT_EQ(rotate, child->draw_properties().target_space_transform);
EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
- EXPECT_EQ(1.f, root->draw_properties().device_scale_factor);
- EXPECT_EQ(1.f, child->draw_properties().device_scale_factor);
}
gfx::Transform composite;
@@ -1261,9 +1257,6 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) {
EXPECT_EQ(device_scaled_translate,
child->draw_properties().target_space_transform);
EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
- EXPECT_EQ(device_scale_factor, root->draw_properties().device_scale_factor);
- EXPECT_EQ(device_scale_factor,
- child->draw_properties().device_scale_factor);
}
// Verify it composes correctly with page scale.
@@ -1274,18 +1267,17 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) {
LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
root.get(), root->bounds(), translate, &render_surface_layer_list);
inputs.page_scale_factor = page_scale_factor;
- inputs.page_scale_application_layer = root.get();
+ inputs.page_scale_layer = root.get();
inputs.can_adjust_raster_scales = true;
inputs.property_trees->needs_rebuild = true;
LayerTreeHostCommon::CalculateDrawProperties(&inputs);
gfx::Transform page_scaled_translate = translate;
page_scaled_translate.Scale(page_scale_factor, page_scale_factor);
- EXPECT_EQ(translate, root->draw_properties().target_space_transform);
+ EXPECT_EQ(page_scaled_translate,
+ root->draw_properties().target_space_transform);
EXPECT_EQ(page_scaled_translate,
child->draw_properties().target_space_transform);
EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
- EXPECT_EQ(1.f, root->draw_properties().device_scale_factor);
- EXPECT_EQ(1.f, child->draw_properties().device_scale_factor);
}
// Verify that it composes correctly with transforms directly on root layer.
@@ -1309,13 +1301,12 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) {
TEST_F(LayerTreeHostCommonTest,
RenderSurfaceListForRenderSurfaceWithClippedLayer) {
- scoped_refptr<Layer> parent = Layer::Create();
- scoped_refptr<Layer> render_surface1 = Layer::Create();
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings());
+ scoped_refptr<Layer> render_surface1 = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> child =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(parent);
+ host()->SetRootLayer(parent);
const gfx::Transform identity_matrix;
SetLayerPropertiesForTesting(parent.get(),
@@ -1363,38 +1354,23 @@ TEST_F(LayerTreeHostCommonTest,
}
TEST_F(LayerTreeHostCommonTest, RenderSurfaceListForTransparentChild) {
- scoped_refptr<Layer> parent = Layer::Create();
- scoped_refptr<Layer> render_surface1 = Layer::Create();
- scoped_refptr<LayerWithForcedDrawsContent> child =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
-
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(parent);
+ LayerImpl* parent = root_layer();
+ LayerImpl* render_surface1 = AddChild<LayerImpl>(parent);
+ LayerImpl* child = AddChild<LayerImpl>(render_surface1);
+ child->SetDrawsContent(true);
const gfx::Transform identity_matrix;
- SetLayerPropertiesForTesting(render_surface1.get(),
- identity_matrix,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(10, 10),
- true,
- false);
- SetLayerPropertiesForTesting(child.get(),
- identity_matrix,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(10, 10),
- true,
+ SetLayerPropertiesForTesting(render_surface1, identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(10, 10), true, false,
+ true);
+ SetLayerPropertiesForTesting(child, identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(10, 10), true, false,
false);
-
- parent->AddChild(render_surface1);
- render_surface1->AddChild(child);
- render_surface1->SetForceRenderSurface(true);
render_surface1->SetOpacity(0.f);
- RenderSurfaceLayerList render_surface_layer_list;
- LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
- parent.get(), parent->bounds(), &render_surface_layer_list);
+ LayerImplList render_surface_layer_list;
+ LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
+ parent, parent->bounds(), &render_surface_layer_list);
inputs.can_adjust_raster_scales = true;
LayerTreeHostCommon::CalculateDrawProperties(&inputs);
@@ -1409,12 +1385,11 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceListForTransparentChild) {
}
TEST_F(LayerTreeHostCommonTest, RenderSurfaceForBlendMode) {
- scoped_refptr<Layer> parent = Layer::Create();
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> child =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(parent);
+ host()->SetRootLayer(parent);
const gfx::Transform identity_matrix;
const SkXfermode::Mode blend_mode = SkXfermode::kMultiply_Mode;
@@ -1439,14 +1414,13 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceForBlendMode) {
}
TEST_F(LayerTreeHostCommonTest, ForceRenderSurface) {
- scoped_refptr<Layer> parent = Layer::Create();
- scoped_refptr<Layer> render_surface1 = Layer::Create();
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings());
+ scoped_refptr<Layer> render_surface1 = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> child =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
render_surface1->SetForceRenderSurface(true);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(parent);
+ host()->SetRootLayer(parent);
const gfx::Transform identity_matrix;
SetLayerPropertiesForTesting(parent.get(),
@@ -1508,12 +1482,12 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfacesFlattenScreenSpaceTransform) {
// Render surfaces act as a flattening point for their subtree, so should
// always flatten the target-to-screen space transform seen by descendants.
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> parent = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> child =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> grand_child =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
gfx::Transform rotation_about_y_axis;
rotation_about_y_axis.RotateAboutYAxis(30.0);
@@ -1538,8 +1512,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfacesFlattenScreenSpaceTransform) {
grand_child->SetShouldFlattenTransform(false);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
// Only grand_child should preserve 3d.
EXPECT_TRUE(root->should_flatten_transform());
@@ -1590,20 +1563,19 @@ TEST_F(LayerTreeHostCommonTest, ClipRectCullsRenderSurfaces) {
//
const gfx::Transform identity_matrix;
- scoped_refptr<Layer> parent = Layer::Create();
- scoped_refptr<Layer> child = Layer::Create();
- scoped_refptr<Layer> grand_child = Layer::Create();
- scoped_refptr<Layer> great_grand_child = Layer::Create();
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings());
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
+ scoped_refptr<Layer> grand_child = Layer::Create(layer_settings());
+ scoped_refptr<Layer> great_grand_child = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> leaf_node1 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> leaf_node2 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
parent->AddChild(child);
child->AddChild(grand_child);
grand_child->AddChild(great_grand_child);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(parent);
+ host()->SetRootLayer(parent);
// leaf_node1 ensures that parent and child are kept on the
// render_surface_layer_list, even though grand_child and great_grand_child
@@ -1691,17 +1663,16 @@ TEST_F(LayerTreeHostCommonTest, ClipRectCullsSurfaceWithoutVisibleContent) {
// in the render_surface_layer_list.
const gfx::Transform identity_matrix;
- scoped_refptr<Layer> parent = Layer::Create();
- scoped_refptr<Layer> child = Layer::Create();
- scoped_refptr<Layer> grand_child = Layer::Create();
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings());
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
+ scoped_refptr<Layer> grand_child = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> leaf_node =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
parent->AddChild(child);
child->AddChild(grand_child);
grand_child->AddChild(leaf_node);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(parent);
+ host()->SetRootLayer(parent);
SetLayerPropertiesForTesting(parent.get(),
identity_matrix,
@@ -1786,15 +1757,15 @@ TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectly) {
// and propagates the clip to the subtree.
const gfx::Transform identity_matrix;
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> parent = Layer::Create();
- scoped_refptr<Layer> child1 = Layer::Create();
- scoped_refptr<Layer> child2 = Layer::Create();
- scoped_refptr<Layer> grand_child = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings());
+ scoped_refptr<Layer> child1 = Layer::Create(layer_settings());
+ scoped_refptr<Layer> child2 = Layer::Create(layer_settings());
+ scoped_refptr<Layer> grand_child = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> leaf_node1 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> leaf_node2 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(parent);
parent->AddChild(child1);
parent->AddChild(child2);
@@ -1802,8 +1773,7 @@ TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectly) {
child2->AddChild(leaf_node2);
grand_child->AddChild(leaf_node1);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
child2->SetForceRenderSurface(true);
@@ -1947,12 +1917,12 @@ TEST_F(LayerTreeHostCommonTest, DrawableContentRectForLayers) {
//
const gfx::Transform identity_matrix;
- scoped_refptr<Layer> parent = Layer::Create();
- scoped_refptr<Layer> child = Layer::Create();
- scoped_refptr<Layer> grand_child1 = Layer::Create();
- scoped_refptr<Layer> grand_child2 = Layer::Create();
- scoped_refptr<Layer> grand_child3 = Layer::Create();
- scoped_refptr<Layer> grand_child4 = Layer::Create();
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings());
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
+ scoped_refptr<Layer> grand_child1 = Layer::Create(layer_settings());
+ scoped_refptr<Layer> grand_child2 = Layer::Create(layer_settings());
+ scoped_refptr<Layer> grand_child3 = Layer::Create(layer_settings());
+ scoped_refptr<Layer> grand_child4 = Layer::Create(layer_settings());
parent->AddChild(child);
child->AddChild(grand_child1);
@@ -1960,8 +1930,7 @@ TEST_F(LayerTreeHostCommonTest, DrawableContentRectForLayers) {
child->AddChild(grand_child3);
child->AddChild(grand_child4);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(parent);
+ host()->SetRootLayer(parent);
SetLayerPropertiesForTesting(parent.get(),
identity_matrix,
@@ -2037,20 +2006,20 @@ TEST_F(LayerTreeHostCommonTest, ClipRectIsPropagatedCorrectlyToSurfaces) {
// They may still have a clip rect of their own layer bounds, however, if
// masksToBounds was true.
const gfx::Transform identity_matrix;
- scoped_refptr<Layer> parent = Layer::Create();
- scoped_refptr<Layer> child = Layer::Create();
- scoped_refptr<Layer> grand_child1 = Layer::Create();
- scoped_refptr<Layer> grand_child2 = Layer::Create();
- scoped_refptr<Layer> grand_child3 = Layer::Create();
- scoped_refptr<Layer> grand_child4 = Layer::Create();
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings());
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
+ scoped_refptr<Layer> grand_child1 = Layer::Create(layer_settings());
+ scoped_refptr<Layer> grand_child2 = Layer::Create(layer_settings());
+ scoped_refptr<Layer> grand_child3 = Layer::Create(layer_settings());
+ scoped_refptr<Layer> grand_child4 = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> leaf_node1 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> leaf_node2 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> leaf_node3 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> leaf_node4 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
parent->AddChild(child);
child->AddChild(grand_child1);
@@ -2058,8 +2027,7 @@ TEST_F(LayerTreeHostCommonTest, ClipRectIsPropagatedCorrectlyToSurfaces) {
child->AddChild(grand_child3);
child->AddChild(grand_child4);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(parent);
+ host()->SetRootLayer(parent);
// the leaf nodes ensure that these grand_children become render surfaces for
// this test.
@@ -2175,99 +2143,49 @@ TEST_F(LayerTreeHostCommonTest, ClipRectIsPropagatedCorrectlyToSurfaces) {
}
TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) {
- scoped_refptr<Layer> parent = Layer::Create();
- scoped_refptr<Layer> render_surface1 = Layer::Create();
- scoped_refptr<Layer> render_surface2 = Layer::Create();
- scoped_refptr<Layer> child_of_root = Layer::Create();
- scoped_refptr<Layer> child_of_rs1 = Layer::Create();
- scoped_refptr<Layer> child_of_rs2 = Layer::Create();
- scoped_refptr<Layer> grand_child_of_root = Layer::Create();
- scoped_refptr<LayerWithForcedDrawsContent> grand_child_of_rs1 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
- scoped_refptr<LayerWithForcedDrawsContent> grand_child_of_rs2 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
- parent->AddChild(render_surface1);
- parent->AddChild(child_of_root);
- render_surface1->AddChild(child_of_rs1);
- render_surface1->AddChild(render_surface2);
- render_surface2->AddChild(child_of_rs2);
- child_of_root->AddChild(grand_child_of_root);
- child_of_rs1->AddChild(grand_child_of_rs1);
- child_of_rs2->AddChild(grand_child_of_rs2);
-
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(parent);
-
- // Make our render surfaces.
- render_surface1->SetForceRenderSurface(true);
- render_surface2->SetForceRenderSurface(true);
+ LayerImpl* parent = root_layer();
+ LayerImpl* render_surface1 = AddChildToRoot<LayerImpl>();
+ LayerImpl* child_of_rs1 = AddChild<LayerImpl>(render_surface1);
+ LayerImpl* grand_child_of_rs1 = AddChild<LayerImpl>(child_of_rs1);
+ LayerImpl* render_surface2 = AddChild<LayerImpl>(render_surface1);
+ LayerImpl* child_of_rs2 = AddChild<LayerImpl>(render_surface2);
+ LayerImpl* grand_child_of_rs2 = AddChild<LayerImpl>(child_of_rs2);
+ LayerImpl* child_of_root = AddChildToRoot<LayerImpl>();
+ LayerImpl* grand_child_of_root = AddChild<LayerImpl>(child_of_root);
+
+ grand_child_of_rs1->SetDrawsContent(true);
+ grand_child_of_rs2->SetDrawsContent(true);
gfx::Transform layer_transform;
layer_transform.Translate(1.0, 1.0);
- SetLayerPropertiesForTesting(parent.get(),
- layer_transform,
- gfx::Point3F(0.25f, 0.f, 0.f),
- gfx::PointF(2.5f, 0.f),
- gfx::Size(10, 10),
- true,
- false);
- SetLayerPropertiesForTesting(render_surface1.get(),
- layer_transform,
- gfx::Point3F(0.25f, 0.f, 0.f),
- gfx::PointF(2.5f, 0.f),
- gfx::Size(10, 10),
- true,
- false);
- SetLayerPropertiesForTesting(render_surface2.get(),
- layer_transform,
- gfx::Point3F(0.25f, 0.f, 0.f),
- gfx::PointF(2.5f, 0.f),
- gfx::Size(10, 10),
- true,
- false);
- SetLayerPropertiesForTesting(child_of_root.get(),
- layer_transform,
- gfx::Point3F(0.25f, 0.f, 0.f),
- gfx::PointF(2.5f, 0.f),
- gfx::Size(10, 10),
- true,
- false);
- SetLayerPropertiesForTesting(child_of_rs1.get(),
- layer_transform,
- gfx::Point3F(0.25f, 0.f, 0.f),
- gfx::PointF(2.5f, 0.f),
- gfx::Size(10, 10),
- true,
- false);
- SetLayerPropertiesForTesting(child_of_rs2.get(),
- layer_transform,
- gfx::Point3F(0.25f, 0.f, 0.f),
- gfx::PointF(2.5f, 0.f),
- gfx::Size(10, 10),
- true,
- false);
- SetLayerPropertiesForTesting(grand_child_of_root.get(),
- layer_transform,
- gfx::Point3F(0.25f, 0.f, 0.f),
- gfx::PointF(2.5f, 0.f),
- gfx::Size(10, 10),
- true,
- false);
- SetLayerPropertiesForTesting(grand_child_of_rs1.get(),
- layer_transform,
- gfx::Point3F(0.25f, 0.f, 0.f),
- gfx::PointF(2.5f, 0.f),
- gfx::Size(10, 10),
- true,
- false);
- SetLayerPropertiesForTesting(grand_child_of_rs2.get(),
- layer_transform,
- gfx::Point3F(0.25f, 0.f, 0.f),
- gfx::PointF(2.5f, 0.f),
- gfx::Size(10, 10),
- true,
- false);
+ SetLayerPropertiesForTesting(
+ parent, layer_transform, gfx::Point3F(0.25f, 0.f, 0.f),
+ gfx::PointF(2.5f, 0.f), gfx::Size(10, 10), true, false, true);
+ SetLayerPropertiesForTesting(
+ render_surface1, layer_transform, gfx::Point3F(0.25f, 0.f, 0.f),
+ gfx::PointF(2.5f, 0.f), gfx::Size(10, 10), true, false, true);
+ SetLayerPropertiesForTesting(
+ render_surface2, layer_transform, gfx::Point3F(0.25f, 0.f, 0.f),
+ gfx::PointF(2.5f, 0.f), gfx::Size(10, 10), true, false, true);
+ SetLayerPropertiesForTesting(
+ child_of_root, layer_transform, gfx::Point3F(0.25f, 0.f, 0.f),
+ gfx::PointF(2.5f, 0.f), gfx::Size(10, 10), true, false, false);
+ SetLayerPropertiesForTesting(
+ child_of_rs1, layer_transform, gfx::Point3F(0.25f, 0.f, 0.f),
+ gfx::PointF(2.5f, 0.f), gfx::Size(10, 10), true, false, false);
+ SetLayerPropertiesForTesting(
+ child_of_rs2, layer_transform, gfx::Point3F(0.25f, 0.f, 0.f),
+ gfx::PointF(2.5f, 0.f), gfx::Size(10, 10), true, false, false);
+ SetLayerPropertiesForTesting(
+ grand_child_of_root, layer_transform, gfx::Point3F(0.25f, 0.f, 0.f),
+ gfx::PointF(2.5f, 0.f), gfx::Size(10, 10), true, false, false);
+ SetLayerPropertiesForTesting(
+ grand_child_of_rs1, layer_transform, gfx::Point3F(0.25f, 0.f, 0.f),
+ gfx::PointF(2.5f, 0.f), gfx::Size(10, 10), true, false, false);
+ SetLayerPropertiesForTesting(
+ grand_child_of_rs2, layer_transform, gfx::Point3F(0.25f, 0.f, 0.f),
+ gfx::PointF(2.5f, 0.f), gfx::Size(10, 10), true, false, false);
// Put an animated opacity on the render surface.
AddOpacityTransitionToController(
@@ -2288,7 +2206,7 @@ TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) {
AddAnimatedTransformToController(
grand_child_of_rs2->layer_animation_controller(), 10.0, 30, 0);
- ExecuteCalculateDrawProperties(parent.get());
+ ExecuteCalculateDrawProperties(parent);
// Only layers that are associated with render surfaces should have an actual
// RenderSurface() value.
@@ -2305,17 +2223,17 @@ TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) {
ASSERT_FALSE(grand_child_of_rs2->render_surface());
// Verify all render target accessors
- EXPECT_EQ(parent.get(), parent->render_target());
- EXPECT_EQ(parent.get(), child_of_root->render_target());
- EXPECT_EQ(parent.get(), grand_child_of_root->render_target());
+ EXPECT_EQ(parent, parent->render_target());
+ EXPECT_EQ(parent, child_of_root->render_target());
+ EXPECT_EQ(parent, grand_child_of_root->render_target());
- EXPECT_EQ(render_surface1.get(), render_surface1->render_target());
- EXPECT_EQ(render_surface1.get(), child_of_rs1->render_target());
- EXPECT_EQ(render_surface1.get(), grand_child_of_rs1->render_target());
+ EXPECT_EQ(render_surface1, render_surface1->render_target());
+ EXPECT_EQ(render_surface1, child_of_rs1->render_target());
+ EXPECT_EQ(render_surface1, grand_child_of_rs1->render_target());
- EXPECT_EQ(render_surface2.get(), render_surface2->render_target());
- EXPECT_EQ(render_surface2.get(), child_of_rs2->render_target());
- EXPECT_EQ(render_surface2.get(), grand_child_of_rs2->render_target());
+ EXPECT_EQ(render_surface2, render_surface2->render_target());
+ EXPECT_EQ(render_surface2, child_of_rs2->render_target());
+ EXPECT_EQ(render_surface2, grand_child_of_rs2->render_target());
// Verify draw_opacity_is_animating values
EXPECT_FALSE(parent->draw_opacity_is_animating());
@@ -2671,20 +2589,42 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectForPerspectiveUnprojection) {
EXPECT_EQ(expected, actual);
}
+TEST_F(LayerTreeHostCommonTest,
+ VisibleRectsForPositionedRootLayerClippedByViewport) {
+ scoped_refptr<Layer> root =
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
+ host()->SetRootLayer(root);
+
+ gfx::Transform identity_matrix;
+ // Root layer is positioned at (60, 70). The default device viewport size
+ // is (0, 0, 100x100) in target space. So the root layer's visible rect
+ // will be clipped by the viewport to be (0, 0, 40x30) in layer's space.
+ SetLayerPropertiesForTesting(root.get(), identity_matrix, gfx::Point3F(),
+ gfx::PointF(60, 70), gfx::Size(100, 100), true,
+ false);
+ ExecuteCalculateDrawProperties(root.get());
+
+ EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
+ root->render_surface()->DrawableContentRect());
+ // In target space, not clipped.
+ EXPECT_EQ(gfx::Rect(60, 70, 100, 100), root->drawable_content_rect());
+ // In layer space, clipped.
+ EXPECT_EQ(gfx::Rect(0, 0, 40, 30), root->visible_layer_rect());
+}
+
TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsForSimpleLayers) {
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> child1 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> child2 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> child3 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(child1);
root->AddChild(child2);
root->AddChild(child3);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
gfx::Transform identity_matrix;
SetLayerPropertiesForTesting(root.get(),
@@ -2722,13 +2662,13 @@ TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsForSimpleLayers) {
root->render_surface()->DrawableContentRect());
EXPECT_EQ(gfx::Rect(0, 0, 100, 100), root->drawable_content_rect());
- // Layers that do not draw content should have empty visible_content_rects.
- EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_content_rect());
+ // Layers that do not draw content should have empty visible_layer_rects.
+ EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_layer_rect());
- // layer visible_content_rects are clipped by their target surface.
- EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_content_rect());
- EXPECT_EQ(gfx::Rect(0, 0, 25, 25), child2->visible_content_rect());
- EXPECT_TRUE(child3->visible_content_rect().IsEmpty());
+ // layer visible_layer_rects are clipped by their target surface.
+ EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 25, 25), child2->visible_layer_rect());
+ EXPECT_TRUE(child3->visible_layer_rect().IsEmpty());
// layer drawable_content_rects are not clipped.
EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->drawable_content_rect());
@@ -2738,21 +2678,20 @@ TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsForSimpleLayers) {
TEST_F(LayerTreeHostCommonTest,
DrawableAndVisibleContentRectsForLayersClippedByLayer) {
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> child = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> grand_child1 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> grand_child2 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> grand_child3 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(child);
child->AddChild(grand_child1);
child->AddChild(grand_child2);
child->AddChild(grand_child3);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
gfx::Transform identity_matrix;
SetLayerPropertiesForTesting(root.get(),
@@ -2801,13 +2740,13 @@ TEST_F(LayerTreeHostCommonTest,
EXPECT_EQ(gfx::Rect(0, 0, 100, 100), root->drawable_content_rect());
// Layers that do not draw content should have empty visible content rects.
- EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_content_rect());
- EXPECT_EQ(gfx::Rect(0, 0, 0, 0), child->visible_content_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 0, 0), child->visible_layer_rect());
// All grandchild visible content rects should be clipped by child.
- EXPECT_EQ(gfx::Rect(0, 0, 50, 50), grand_child1->visible_content_rect());
- EXPECT_EQ(gfx::Rect(0, 0, 25, 25), grand_child2->visible_content_rect());
- EXPECT_TRUE(grand_child3->visible_content_rect().IsEmpty());
+ EXPECT_EQ(gfx::Rect(0, 0, 50, 50), grand_child1->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 25, 25), grand_child2->visible_layer_rect());
+ EXPECT_TRUE(grand_child3->visible_layer_rect().IsEmpty());
// All grandchild DrawableContentRects should also be clipped by child.
EXPECT_EQ(gfx::Rect(5, 5, 50, 50), grand_child1->drawable_content_rect());
@@ -2816,15 +2755,14 @@ TEST_F(LayerTreeHostCommonTest,
}
TEST_F(LayerTreeHostCommonTest, VisibleContentRectWithClippingAndScaling) {
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> child = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> grand_child =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(child);
child->AddChild(grand_child);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
gfx::Transform identity_matrix;
gfx::Transform child_scale_matrix;
@@ -2840,7 +2778,7 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectWithClippingAndScaling) {
gfx::Size(100, 100), true, false);
child->SetMasksToBounds(true);
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
// The visible rect is expanded to integer coordinates in target space before
// being projected back to layer space, where it is once again expanded to
@@ -2850,21 +2788,20 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectWithClippingAndScaling) {
TEST_F(LayerTreeHostCommonTest,
DrawableAndVisibleContentRectsForLayersInUnclippedRenderSurface) {
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> render_surface1 = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> render_surface1 = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> child1 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> child2 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> child3 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(render_surface1);
render_surface1->AddChild(child1);
render_surface1->AddChild(child2);
render_surface1->AddChild(child3);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
gfx::Transform identity_matrix;
SetLayerPropertiesForTesting(root.get(),
@@ -2913,8 +2850,8 @@ TEST_F(LayerTreeHostCommonTest,
EXPECT_EQ(gfx::Rect(0, 0, 100, 100), root->drawable_content_rect());
// Layers that do not draw content should have empty visible content rects.
- EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_content_rect());
- EXPECT_EQ(gfx::Rect(0, 0, 0, 0), render_surface1->visible_content_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 0, 0), render_surface1->visible_layer_rect());
// An unclipped surface grows its DrawableContentRect to include all drawable
// regions of the subtree.
@@ -2922,9 +2859,9 @@ TEST_F(LayerTreeHostCommonTest,
render_surface1->render_surface()->DrawableContentRect());
// All layers that draw content into the unclipped surface are also unclipped.
- EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_content_rect());
- EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child2->visible_content_rect());
- EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child3->visible_content_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child2->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child3->visible_layer_rect());
EXPECT_EQ(gfx::Rect(5, 5, 50, 50), child1->drawable_content_rect());
EXPECT_EQ(gfx::Rect(75, 75, 50, 50), child2->drawable_content_rect());
@@ -2933,19 +2870,18 @@ TEST_F(LayerTreeHostCommonTest,
TEST_F(LayerTreeHostCommonTest,
VisibleContentRectsForClippedSurfaceWithEmptyClip) {
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> child1 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> child2 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> child3 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(child1);
root->AddChild(child2);
root->AddChild(child3);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
gfx::Transform identity_matrix;
SetLayerPropertiesForTesting(root.get(), identity_matrix, gfx::Point3F(),
@@ -2976,20 +2912,19 @@ TEST_F(LayerTreeHostCommonTest,
// Visible content rect calculation will check if the target surface is
// clipped or not. An empty clip rect does not indicate the render surface
// is unclipped.
- EXPECT_EQ(empty, child1->visible_content_rect());
- EXPECT_EQ(empty, child2->visible_content_rect());
- EXPECT_EQ(empty, child3->visible_content_rect());
+ EXPECT_EQ(empty, child1->visible_layer_rect());
+ EXPECT_EQ(empty, child2->visible_layer_rect());
+ EXPECT_EQ(empty, child3->visible_layer_rect());
}
TEST_F(LayerTreeHostCommonTest,
DrawableAndVisibleContentRectsForLayersWithUninvertibleTransform) {
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> child =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(child);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
// Case 1: a truly degenerate matrix
gfx::Transform identity_matrix;
@@ -3013,7 +2948,7 @@ TEST_F(LayerTreeHostCommonTest,
ExecuteCalculateDrawProperties(root.get());
- EXPECT_TRUE(child->visible_content_rect().IsEmpty());
+ EXPECT_TRUE(child->visible_layer_rect().IsEmpty());
EXPECT_TRUE(child->drawable_content_rect().IsEmpty());
// Case 2: a matrix with flattened z, uninvertible and not visible according
@@ -3032,7 +2967,7 @@ TEST_F(LayerTreeHostCommonTest,
ExecuteCalculateDrawProperties(root.get());
- EXPECT_TRUE(child->visible_content_rect().IsEmpty());
+ EXPECT_TRUE(child->visible_layer_rect().IsEmpty());
EXPECT_TRUE(child->drawable_content_rect().IsEmpty());
// Case 3: a matrix with flattened z, also uninvertible and not visible.
@@ -3051,19 +2986,18 @@ TEST_F(LayerTreeHostCommonTest,
ExecuteCalculateDrawProperties(root.get());
- EXPECT_TRUE(child->visible_content_rect().IsEmpty());
+ EXPECT_TRUE(child->visible_layer_rect().IsEmpty());
EXPECT_TRUE(child->drawable_content_rect().IsEmpty());
}
TEST_F(LayerTreeHostCommonTest,
SingularTransformDoesNotPreventClearingDrawProperties) {
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> child =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(child);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
gfx::Transform identity_matrix;
gfx::Transform uninvertible_matrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
@@ -3084,7 +3018,7 @@ TEST_F(LayerTreeHostCommonTest,
true,
false);
- child->draw_properties().sorted_for_recursion = true;
+ child->set_sorted_for_recursion(true);
TransformOperations start_transform_operations;
start_transform_operations.AppendScale(1.f, 0.f, 0.f);
@@ -3099,15 +3033,14 @@ TEST_F(LayerTreeHostCommonTest,
ExecuteCalculateDrawProperties(root.get());
- EXPECT_FALSE(child->draw_properties().sorted_for_recursion);
+ EXPECT_FALSE(child->sorted_for_recursion());
}
TEST_F(LayerTreeHostCommonTest,
SingularNonAnimatingTransformDoesNotPreventClearingDrawProperties) {
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
gfx::Transform identity_matrix;
gfx::Transform uninvertible_matrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
@@ -3121,32 +3054,31 @@ TEST_F(LayerTreeHostCommonTest,
true,
false);
- root->draw_properties().sorted_for_recursion = true;
+ root->set_sorted_for_recursion(true);
EXPECT_FALSE(root->TransformIsAnimating());
ExecuteCalculateDrawProperties(root.get());
- EXPECT_FALSE(root->draw_properties().sorted_for_recursion);
+ EXPECT_FALSE(root->sorted_for_recursion());
}
TEST_F(LayerTreeHostCommonTest,
DrawableAndVisibleContentRectsForLayersInClippedRenderSurface) {
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> render_surface1 = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> render_surface1 = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> child1 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> child2 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> child3 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(render_surface1);
render_surface1->AddChild(child1);
render_surface1->AddChild(child2);
render_surface1->AddChild(child3);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
gfx::Transform identity_matrix;
SetLayerPropertiesForTesting(root.get(),
@@ -3196,8 +3128,8 @@ TEST_F(LayerTreeHostCommonTest,
EXPECT_EQ(gfx::Rect(0, 0, 100, 100), root->drawable_content_rect());
// Layers that do not draw content should have empty visible content rects.
- EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_content_rect());
- EXPECT_EQ(gfx::Rect(0, 0, 0, 0), render_surface1->visible_content_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 0, 0), render_surface1->visible_layer_rect());
// A clipped surface grows its DrawableContentRect to include all drawable
// regions of the subtree, but also gets clamped by the ancestor's clip.
@@ -3206,9 +3138,9 @@ TEST_F(LayerTreeHostCommonTest,
// All layers that draw content into the surface have their visible content
// rect clipped by the surface clip rect.
- EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_content_rect());
- EXPECT_EQ(gfx::Rect(0, 0, 25, 25), child2->visible_content_rect());
- EXPECT_TRUE(child3->visible_content_rect().IsEmpty());
+ EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 25, 25), child2->visible_layer_rect());
+ EXPECT_TRUE(child3->visible_layer_rect().IsEmpty());
// But the DrawableContentRects are unclipped.
EXPECT_EQ(gfx::Rect(5, 5, 50, 50), child1->drawable_content_rect());
@@ -3219,23 +3151,22 @@ TEST_F(LayerTreeHostCommonTest,
TEST_F(LayerTreeHostCommonTest,
DrawableAndVisibleContentRectsForSurfaceHierarchy) {
// Check that clipping does not propagate down surfaces.
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> render_surface1 = Layer::Create();
- scoped_refptr<Layer> render_surface2 = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> render_surface1 = Layer::Create(layer_settings());
+ scoped_refptr<Layer> render_surface2 = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> child1 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> child2 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> child3 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(render_surface1);
render_surface1->AddChild(render_surface2);
render_surface2->AddChild(child1);
render_surface2->AddChild(child2);
render_surface2->AddChild(child3);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
gfx::Transform identity_matrix;
SetLayerPropertiesForTesting(root.get(),
@@ -3294,9 +3225,9 @@ TEST_F(LayerTreeHostCommonTest,
EXPECT_EQ(gfx::Rect(0, 0, 100, 100), root->drawable_content_rect());
// Layers that do not draw content should have empty visible content rects.
- EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_content_rect());
- EXPECT_EQ(gfx::Rect(0, 0, 0, 0), render_surface1->visible_content_rect());
- EXPECT_EQ(gfx::Rect(0, 0, 0, 0), render_surface2->visible_content_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 0, 0), render_surface1->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 0, 0), render_surface2->visible_layer_rect());
// A clipped surface grows its DrawableContentRect to include all drawable
// regions of the subtree, but also gets clamped by the ancestor's clip.
@@ -3310,9 +3241,9 @@ TEST_F(LayerTreeHostCommonTest,
render_surface2->render_surface()->DrawableContentRect());
// All layers that draw content into render_surface2 think they are unclipped.
- EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_content_rect());
- EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child2->visible_content_rect());
- EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child3->visible_content_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child2->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child3->visible_layer_rect());
// DrawableContentRects are also unclipped.
EXPECT_EQ(gfx::Rect(5, 5, 50, 50), child1->drawable_content_rect());
@@ -3325,15 +3256,14 @@ TEST_F(LayerTreeHostCommonTest,
// Layers that have non-axis aligned bounds (due to transforms) have an
// expanded, axis-aligned DrawableContentRect and visible content rect.
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> render_surface1 = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> render_surface1 = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> child1 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(render_surface1);
render_surface1->AddChild(child1);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
gfx::Transform identity_matrix;
gfx::Transform child_rotation;
@@ -3370,8 +3300,8 @@ TEST_F(LayerTreeHostCommonTest,
EXPECT_EQ(gfx::Rect(0, 0, 100, 100), root->drawable_content_rect());
// Layers that do not draw content should have empty visible content rects.
- EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_content_rect());
- EXPECT_EQ(gfx::Rect(0, 0, 0, 0), render_surface1->visible_content_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 0, 0), render_surface1->visible_layer_rect());
// The unclipped surface grows its DrawableContentRect to include all drawable
// regions of the subtree.
@@ -3385,7 +3315,7 @@ TEST_F(LayerTreeHostCommonTest,
render_surface1->render_surface()->DrawableContentRect());
// All layers that draw content into the unclipped surface are also unclipped.
- EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_content_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_layer_rect());
EXPECT_EQ(expected_surface_drawable_content, child1->drawable_content_rect());
}
@@ -3394,15 +3324,14 @@ TEST_F(LayerTreeHostCommonTest,
// Layers that have non-axis aligned bounds (due to transforms) have an
// expanded, axis-aligned DrawableContentRect and visible content rect.
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> render_surface1 = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> render_surface1 = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> child1 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(render_surface1);
render_surface1->AddChild(child1);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
gfx::Transform identity_matrix;
gfx::Transform child_rotation;
@@ -3453,7 +3382,7 @@ TEST_F(LayerTreeHostCommonTest,
// up covering the full left half of child1.
//
// Given the floating point math, this number is a little bit fuzzy.
- EXPECT_EQ(gfx::Rect(0, 0, 26, 50), child1->visible_content_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 26, 50), child1->visible_layer_rect());
// The child's DrawableContentRect is unclipped.
EXPECT_EQ(unclipped_surface_content, child1->drawable_content_rect());
@@ -3462,22 +3391,24 @@ TEST_F(LayerTreeHostCommonTest,
TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsInHighDPI) {
MockContentLayerClient client;
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
scoped_refptr<FakePictureLayer> render_surface1 =
- CreateDrawablePictureLayer(&client);
+ CreateDrawablePictureLayer(layer_settings(), &client);
scoped_refptr<FakePictureLayer> render_surface2 =
- CreateDrawablePictureLayer(&client);
- scoped_refptr<FakePictureLayer> child1 = CreateDrawablePictureLayer(&client);
- scoped_refptr<FakePictureLayer> child2 = CreateDrawablePictureLayer(&client);
- scoped_refptr<FakePictureLayer> child3 = CreateDrawablePictureLayer(&client);
+ CreateDrawablePictureLayer(layer_settings(), &client);
+ scoped_refptr<FakePictureLayer> child1 =
+ CreateDrawablePictureLayer(layer_settings(), &client);
+ scoped_refptr<FakePictureLayer> child2 =
+ CreateDrawablePictureLayer(layer_settings(), &client);
+ scoped_refptr<FakePictureLayer> child3 =
+ CreateDrawablePictureLayer(layer_settings(), &client);
root->AddChild(render_surface1);
render_surface1->AddChild(render_surface2);
render_surface2->AddChild(child1);
render_surface2->AddChild(child2);
render_surface2->AddChild(child3);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
gfx::Transform identity_matrix;
SetLayerPropertiesForTesting(root.get(),
@@ -3551,15 +3482,15 @@ TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsInHighDPI) {
EXPECT_EQ(gfx::Rect(250, 250, 100, 100), child3->drawable_content_rect());
// The root layer does not actually draw content of its own.
- EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_content_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_layer_rect());
// All layer visible content rects are not expressed in content space of each
// layer, so they are not scaled by the device_scale_factor.
- EXPECT_EQ(gfx::Rect(0, 0, 3, 4), render_surface1->visible_content_rect());
- EXPECT_EQ(gfx::Rect(0, 0, 7, 13), render_surface2->visible_content_rect());
- EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_content_rect());
- EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child2->visible_content_rect());
- EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child3->visible_content_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 3, 4), render_surface1->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 7, 13), render_surface2->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child2->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child3->visible_layer_rect());
}
TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithoutPreserves3d) {
@@ -3568,27 +3499,27 @@ TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithoutPreserves3d) {
// "flattened" to each parent layer according to current W3C spec.
const gfx::Transform identity_matrix;
- scoped_refptr<Layer> parent = Layer::Create();
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> front_facing_child =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> back_facing_child =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> front_facing_surface =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> back_facing_surface =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent>
front_facing_child_of_front_facing_surface =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent>
back_facing_child_of_front_facing_surface =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent>
front_facing_child_of_back_facing_surface =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent>
back_facing_child_of_back_facing_surface =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
parent->AddChild(front_facing_child);
parent->AddChild(back_facing_child);
@@ -3599,8 +3530,7 @@ TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithoutPreserves3d) {
back_facing_surface->AddChild(front_facing_child_of_back_facing_surface);
back_facing_surface->AddChild(back_facing_child_of_back_facing_surface);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(parent);
+ host()->SetRootLayer(parent);
// Nothing is double-sided
front_facing_child->SetDoubleSided(false);
@@ -3770,31 +3700,31 @@ TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithPreserves3d) {
// is used.
const gfx::Transform identity_matrix;
- scoped_refptr<Layer> parent = Layer::Create();
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> front_facing_child =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> back_facing_child =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> front_facing_surface =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> back_facing_surface =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent>
- front_facing_child_of_front_facing_surface =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ front_facing_child_of_front_facing_surface =
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent>
- back_facing_child_of_front_facing_surface =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ back_facing_child_of_front_facing_surface =
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent>
- front_facing_child_of_back_facing_surface =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ front_facing_child_of_back_facing_surface =
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent>
- back_facing_child_of_back_facing_surface =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ back_facing_child_of_back_facing_surface =
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> dummy_replica_layer1 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> dummy_replica_layer2 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
parent->AddChild(front_facing_child);
parent->AddChild(back_facing_child);
@@ -3805,8 +3735,7 @@ TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithPreserves3d) {
back_facing_surface->AddChild(front_facing_child_of_back_facing_surface);
back_facing_surface->AddChild(back_facing_child_of_back_facing_surface);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(parent);
+ host()->SetRootLayer(parent);
// Nothing is double-sided
front_facing_child->SetDoubleSided(false);
@@ -3955,17 +3884,17 @@ TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithAnimatingTransforms) {
// transforms should be treated as "unknown" so we can not be sure that their
// back face is really showing.
const gfx::Transform identity_matrix;
- scoped_refptr<Layer> parent = Layer::Create();
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> child =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> animating_surface =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> child_of_animating_surface =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> animating_child =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> child2 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
parent->AddChild(child);
parent->AddChild(animating_surface);
@@ -3973,8 +3902,7 @@ TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithAnimatingTransforms) {
parent->AddChild(animating_child);
parent->AddChild(child2);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(parent);
+ host()->SetRootLayer(parent);
// Nothing is double-sided
child->SetDoubleSided(false);
@@ -4084,18 +4012,18 @@ TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithAnimatingTransforms) {
render_surface_layer_list.at(1)
->render_surface()->layer_list().at(1)->id());
- EXPECT_FALSE(child2->visible_content_rect().IsEmpty());
+ EXPECT_FALSE(child2->visible_layer_rect().IsEmpty());
// The animating layers should have a visible content rect that represents the
// area of the front face that is within the viewport.
- EXPECT_EQ(animating_child->visible_content_rect(),
- gfx::Rect(animating_child->content_bounds()));
- EXPECT_EQ(animating_surface->visible_content_rect(),
- gfx::Rect(animating_surface->content_bounds()));
+ EXPECT_EQ(animating_child->visible_layer_rect(),
+ gfx::Rect(animating_child->bounds()));
+ EXPECT_EQ(animating_surface->visible_layer_rect(),
+ gfx::Rect(animating_surface->bounds()));
// And layers in the subtree of the animating layer should have valid visible
// content rects also.
- EXPECT_EQ(child_of_animating_surface->visible_content_rect(),
- gfx::Rect(child_of_animating_surface->content_bounds()));
+ EXPECT_EQ(child_of_animating_surface->visible_layer_rect(),
+ gfx::Rect(child_of_animating_surface->bounds()));
}
TEST_F(LayerTreeHostCommonTest,
@@ -4104,23 +4032,22 @@ TEST_F(LayerTreeHostCommonTest,
// created when it flattens its subtree, and its parent has preserves-3d.
const gfx::Transform identity_matrix;
- scoped_refptr<Layer> parent = Layer::Create();
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> front_facing_surface =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> back_facing_surface =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> child1 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> child2 =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
parent->AddChild(front_facing_surface);
parent->AddChild(back_facing_surface);
front_facing_surface->AddChild(child1);
back_facing_surface->AddChild(child2);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(parent);
+ host()->SetRootLayer(parent);
// RenderSurfaces are not double-sided
front_facing_surface->SetDoubleSided(false);
@@ -4212,110 +4139,50 @@ TEST_F(LayerTreeHostCommonTest,
->render_surface()->layer_list().at(1)->id());
}
-class NoScaleContentLayer : public ContentLayer {
- public:
- static scoped_refptr<NoScaleContentLayer> Create(ContentLayerClient* client) {
- return make_scoped_refptr(new NoScaleContentLayer(client));
- }
-
- void CalculateContentsScale(float ideal_contents_scale,
- float* contents_scale_x,
- float* contents_scale_y,
- gfx::Size* content_bounds) override {
- // Skip over the ContentLayer to the base Layer class.
- Layer::CalculateContentsScale(ideal_contents_scale,
- contents_scale_x,
- contents_scale_y,
- content_bounds);
- }
-
- protected:
- explicit NoScaleContentLayer(ContentLayerClient* client)
- : ContentLayer(client) {}
- ~NoScaleContentLayer() override {}
-};
-
-scoped_refptr<NoScaleContentLayer> CreateNoScaleDrawableContentLayer(
- ContentLayerClient* delegate) {
- scoped_refptr<NoScaleContentLayer> to_return =
- NoScaleContentLayer::Create(delegate);
- to_return->SetIsDrawable(true);
- return to_return;
-}
-
-TEST_F(LayerTreeHostCommonTest, LayerTransformsInHighDPI) {
+TEST_F(LayerTreeHostCommonScalingTest, LayerTransformsInHighDPI) {
// Verify draw and screen space transforms of layers not in a surface.
- MockContentLayerClient delegate;
gfx::Transform identity_matrix;
- scoped_refptr<FakePictureLayer> parent =
- CreateDrawablePictureLayer(&delegate);
- SetLayerPropertiesForTesting(parent.get(),
- identity_matrix,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(100, 100),
- false,
- true);
-
- scoped_refptr<FakePictureLayer> child = CreateDrawablePictureLayer(&delegate);
- SetLayerPropertiesForTesting(child.get(),
- identity_matrix,
- gfx::Point3F(),
- gfx::PointF(2.f, 2.f),
- gfx::Size(10, 10),
- false,
+ LayerImpl* parent = root_layer();
+ SetLayerPropertiesForTesting(parent, identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), false, true,
true);
- scoped_refptr<FakePictureLayer> child_empty =
- CreateDrawablePictureLayer(&delegate);
- SetLayerPropertiesForTesting(child_empty.get(),
- identity_matrix,
- gfx::Point3F(),
- gfx::PointF(2.f, 2.f),
- gfx::Size(),
- false,
- true);
-
- parent->AddChild(child);
- parent->AddChild(child_empty);
+ LayerImpl* child = AddChildToRoot<LayerImpl>();
+ SetLayerPropertiesForTesting(child, identity_matrix, gfx::Point3F(),
+ gfx::PointF(2.f, 2.f), gfx::Size(10, 10), false,
+ true, false);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(parent);
+ LayerImpl* child_empty = AddChildToRoot<LayerImpl>();
+ SetLayerPropertiesForTesting(child_empty, identity_matrix, gfx::Point3F(),
+ gfx::PointF(2.f, 2.f), gfx::Size(), false, true,
+ false);
float device_scale_factor = 2.5f;
- float page_scale_factor = 1.f;
+ gfx::Size viewport_size(100, 100);
+ ExecuteCalculateDrawProperties(parent, device_scale_factor);
- RenderSurfaceLayerList render_surface_layer_list;
- LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
- parent.get(), parent->bounds(), &render_surface_layer_list);
- inputs.device_scale_factor = device_scale_factor;
- inputs.page_scale_factor = page_scale_factor;
- inputs.can_adjust_raster_scales = true;
- LayerTreeHostCommon::CalculateDrawProperties(&inputs);
-
- EXPECT_IDEAL_SCALE_EQ(device_scale_factor * page_scale_factor, parent);
- EXPECT_IDEAL_SCALE_EQ(device_scale_factor * page_scale_factor, child);
- EXPECT_IDEAL_SCALE_EQ(device_scale_factor * page_scale_factor, child_empty);
+ EXPECT_IDEAL_SCALE_EQ(device_scale_factor, parent);
+ EXPECT_IDEAL_SCALE_EQ(device_scale_factor, child);
+ EXPECT_IDEAL_SCALE_EQ(device_scale_factor, child_empty);
- EXPECT_EQ(1u, render_surface_layer_list.size());
+ EXPECT_EQ(1u, render_surface_layer_list_impl()->size());
// Verify parent transforms
gfx::Transform expected_parent_transform;
- expected_parent_transform.Scale(device_scale_factor * page_scale_factor,
- device_scale_factor * page_scale_factor);
+ expected_parent_transform.Scale(device_scale_factor, device_scale_factor);
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform,
parent->screen_space_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform,
parent->draw_transform());
// Verify results of transformed parent rects
- gfx::RectF parent_content_bounds(parent->content_bounds());
+ gfx::RectF parent_bounds(parent->bounds());
gfx::RectF parent_draw_rect =
- MathUtil::MapClippedRect(parent->draw_transform(), parent_content_bounds);
- gfx::RectF parent_screen_space_rect = MathUtil::MapClippedRect(
- parent->screen_space_transform(), parent_content_bounds);
+ MathUtil::MapClippedRect(parent->draw_transform(), parent_bounds);
+ gfx::RectF parent_screen_space_rect =
+ MathUtil::MapClippedRect(parent->screen_space_transform(), parent_bounds);
gfx::RectF expected_parent_draw_rect(parent->bounds());
expected_parent_draw_rect.Scale(device_scale_factor);
@@ -4338,17 +4205,17 @@ TEST_F(LayerTreeHostCommonTest, LayerTransformsInHighDPI) {
// Verify results of transformed child and child_empty rects. They should
// match.
- gfx::RectF child_content_bounds(child->content_bounds());
+ gfx::RectF child_bounds(child->bounds());
gfx::RectF child_draw_rect =
- MathUtil::MapClippedRect(child->draw_transform(), child_content_bounds);
- gfx::RectF child_screen_space_rect = MathUtil::MapClippedRect(
- child->screen_space_transform(), child_content_bounds);
+ MathUtil::MapClippedRect(child->draw_transform(), child_bounds);
+ gfx::RectF child_screen_space_rect =
+ MathUtil::MapClippedRect(child->screen_space_transform(), child_bounds);
- gfx::RectF child_empty_draw_rect = MathUtil::MapClippedRect(
- child_empty->draw_transform(), child_content_bounds);
+ gfx::RectF child_empty_draw_rect =
+ MathUtil::MapClippedRect(child_empty->draw_transform(), child_bounds);
gfx::RectF child_empty_screen_space_rect = MathUtil::MapClippedRect(
- child_empty->screen_space_transform(), child_content_bounds);
+ child_empty->screen_space_transform(), child_bounds);
gfx::RectF expected_child_draw_rect(child->position(), child->bounds());
expected_child_draw_rect.Scale(device_scale_factor);
@@ -4358,70 +4225,41 @@ TEST_F(LayerTreeHostCommonTest, LayerTransformsInHighDPI) {
EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_empty_screen_space_rect);
}
-TEST_F(LayerTreeHostCommonTest, SurfaceLayerTransformsInHighDPI) {
+TEST_F(LayerTreeHostCommonScalingTest, SurfaceLayerTransformsInHighDPI) {
// Verify draw and screen space transforms of layers in a surface.
- MockContentLayerClient delegate;
gfx::Transform identity_matrix;
-
gfx::Transform perspective_matrix;
perspective_matrix.ApplyPerspectiveDepth(2.0);
gfx::Transform scale_small_matrix;
scale_small_matrix.Scale(SK_MScalar1 / 10.f, SK_MScalar1 / 12.f);
- scoped_refptr<Layer> root = Layer::Create();
-
- scoped_refptr<FakePictureLayer> parent =
- CreateDrawablePictureLayer(&delegate);
- SetLayerPropertiesForTesting(parent.get(),
- identity_matrix,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(100, 100),
- false,
- true);
+ LayerImpl* root = root_layer();
+ SetLayerPropertiesForTesting(root, identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), false, true,
+ false);
+ LayerImpl* parent = AddChildToRoot<LayerImpl>();
+ SetLayerPropertiesForTesting(parent, identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), false, true,
+ false);
- scoped_refptr<FakePictureLayer> perspective_surface =
- CreateDrawablePictureLayer(&delegate);
- SetLayerPropertiesForTesting(perspective_surface.get(),
+ LayerImpl* perspective_surface = AddChild<LayerImpl>(parent);
+ SetLayerPropertiesForTesting(perspective_surface,
perspective_matrix * scale_small_matrix,
- gfx::Point3F(),
- gfx::PointF(2.f, 2.f),
- gfx::Size(10, 10),
- false,
- true);
+ gfx::Point3F(), gfx::PointF(2.f, 2.f),
+ gfx::Size(10, 10), false, true, true);
+ perspective_surface->SetDrawsContent(true);
- scoped_refptr<FakePictureLayer> scale_surface =
- CreateDrawablePictureLayer(&delegate);
- SetLayerPropertiesForTesting(scale_surface.get(),
- scale_small_matrix,
- gfx::Point3F(),
- gfx::PointF(2.f, 2.f),
- gfx::Size(10, 10),
- false,
- true);
-
- perspective_surface->SetForceRenderSurface(true);
- scale_surface->SetForceRenderSurface(true);
-
- parent->AddChild(perspective_surface);
- parent->AddChild(scale_surface);
- root->AddChild(parent);
-
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ LayerImpl* scale_surface = AddChild<LayerImpl>(parent);
+ SetLayerPropertiesForTesting(scale_surface, scale_small_matrix,
+ gfx::Point3F(), gfx::PointF(2.f, 2.f),
+ gfx::Size(10, 10), false, true, true);
+ scale_surface->SetDrawsContent(true);
float device_scale_factor = 2.5f;
float page_scale_factor = 3.f;
-
- RenderSurfaceLayerList render_surface_layer_list;
- LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
- root.get(), parent->bounds(), &render_surface_layer_list);
- inputs.device_scale_factor = device_scale_factor;
- inputs.page_scale_factor = page_scale_factor;
- inputs.page_scale_application_layer = root.get();
- inputs.can_adjust_raster_scales = true;
- LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+ ExecuteCalculateDrawProperties(root, device_scale_factor, page_scale_factor,
+ root);
EXPECT_IDEAL_SCALE_EQ(device_scale_factor * page_scale_factor, parent);
EXPECT_IDEAL_SCALE_EQ(device_scale_factor * page_scale_factor,
@@ -4446,7 +4284,7 @@ TEST_F(LayerTreeHostCommonTest, SurfaceLayerTransformsInHighDPI) {
std::max(target_space_transform_scales.x(),
target_space_transform_scales.y()));
- EXPECT_EQ(3u, render_surface_layer_list.size());
+ EXPECT_EQ(3u, render_surface_layer_list_impl()->size());
gfx::Transform expected_parent_draw_transform;
expected_parent_draw_transform.Scale(device_scale_factor * page_scale_factor,
@@ -4478,422 +4316,7 @@ TEST_F(LayerTreeHostCommonTest, SurfaceLayerTransformsInHighDPI) {
perspective_surface->draw_transform());
}
-// TODO(sohanjg): Remove this test when ContentLayer is removed.
-TEST_F(LayerTreeHostCommonTest,
- LayerTransformsInHighDPIAccurateScaleZeroChildPosition) {
- // Verify draw and screen space transforms of layers not in a surface.
- MockContentLayerClient delegate;
- gfx::Transform identity_matrix;
-
- scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate);
- SetLayerPropertiesForTesting(parent.get(),
- identity_matrix,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(133, 133),
- false,
- true);
-
- scoped_refptr<ContentLayer> child = CreateDrawableContentLayer(&delegate);
- SetLayerPropertiesForTesting(child.get(),
- identity_matrix,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(13, 13),
- false,
- true);
-
- scoped_refptr<NoScaleContentLayer> child_no_scale =
- CreateNoScaleDrawableContentLayer(&delegate);
- SetLayerPropertiesForTesting(child_no_scale.get(),
- identity_matrix,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(13, 13),
- false,
- true);
-
- parent->AddChild(child);
- parent->AddChild(child_no_scale);
-
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(parent);
-
- float device_scale_factor = 1.7f;
- float page_scale_factor = 1.f;
-
- RenderSurfaceLayerList render_surface_layer_list;
- LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
- parent.get(), parent->bounds(), &render_surface_layer_list);
- inputs.device_scale_factor = device_scale_factor;
- inputs.page_scale_factor = page_scale_factor;
- inputs.page_scale_application_layer = parent.get();
- inputs.can_adjust_raster_scales = true;
- inputs.verify_property_trees = false;
- LayerTreeHostCommon::CalculateDrawProperties(&inputs);
-
- EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, parent);
- EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, child);
- EXPECT_CONTENTS_SCALE_EQ(1, child_no_scale);
-
- EXPECT_EQ(1u, render_surface_layer_list.size());
-
- // Verify parent transforms
- gfx::Transform expected_parent_transform;
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform,
- parent->screen_space_transform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform,
- parent->draw_transform());
-
- // Verify results of transformed parent rects
- gfx::RectF parent_content_bounds(parent->content_bounds());
-
- gfx::RectF parent_draw_rect =
- MathUtil::MapClippedRect(parent->draw_transform(), parent_content_bounds);
- gfx::RectF parent_screen_space_rect = MathUtil::MapClippedRect(
- parent->screen_space_transform(), parent_content_bounds);
-
- gfx::RectF expected_parent_draw_rect(parent->bounds());
- expected_parent_draw_rect.Scale(device_scale_factor);
- expected_parent_draw_rect.set_width(ceil(expected_parent_draw_rect.width()));
- expected_parent_draw_rect.set_height(
- ceil(expected_parent_draw_rect.height()));
- EXPECT_FLOAT_RECT_EQ(expected_parent_draw_rect, parent_draw_rect);
- EXPECT_FLOAT_RECT_EQ(expected_parent_draw_rect, parent_screen_space_rect);
-
- // Verify child transforms
- gfx::Transform expected_child_transform;
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->draw_transform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
- child->screen_space_transform());
-
- // Verify results of transformed child rects
- gfx::RectF child_content_bounds(child->content_bounds());
-
- gfx::RectF child_draw_rect =
- MathUtil::MapClippedRect(child->draw_transform(), child_content_bounds);
- gfx::RectF child_screen_space_rect = MathUtil::MapClippedRect(
- child->screen_space_transform(), child_content_bounds);
-
- gfx::RectF expected_child_draw_rect(child->bounds());
- expected_child_draw_rect.Scale(device_scale_factor);
- expected_child_draw_rect.set_width(ceil(expected_child_draw_rect.width()));
- expected_child_draw_rect.set_height(ceil(expected_child_draw_rect.height()));
- EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_draw_rect);
- EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_screen_space_rect);
-
- // Verify child_no_scale transforms
- gfx::Transform expected_child_no_scale_transform = child->draw_transform();
- // All transforms operate on content rects. The child's content rect
- // incorporates device scale, but the child_no_scale does not; add it here.
- expected_child_no_scale_transform.Scale(device_scale_factor,
- device_scale_factor);
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_no_scale_transform,
- child_no_scale->draw_transform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_no_scale_transform,
- child_no_scale->screen_space_transform());
-}
-
-// TODO(sohanjg): Remove this test when ContentLayer is removed.
-TEST_F(LayerTreeHostCommonTest, ContentsScale) {
- MockContentLayerClient delegate;
- gfx::Transform identity_matrix;
-
- gfx::Transform parent_scale_matrix;
- SkMScalar initial_parent_scale = 1.75;
- parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale);
-
- gfx::Transform child_scale_matrix;
- SkMScalar initial_child_scale = 1.25;
- child_scale_matrix.Scale(initial_child_scale, initial_child_scale);
-
- scoped_refptr<Layer> root = Layer::Create();
- root->SetBounds(gfx::Size(100, 100));
-
- scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate);
- SetLayerPropertiesForTesting(parent.get(),
- parent_scale_matrix,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(100, 100),
- false,
- true);
-
- scoped_refptr<ContentLayer> child_scale =
- CreateDrawableContentLayer(&delegate);
- SetLayerPropertiesForTesting(child_scale.get(),
- child_scale_matrix,
- gfx::Point3F(),
- gfx::PointF(2.f, 2.f),
- gfx::Size(10, 10),
- false,
- true);
-
- scoped_refptr<ContentLayer> child_empty =
- CreateDrawableContentLayer(&delegate);
- SetLayerPropertiesForTesting(child_empty.get(),
- child_scale_matrix,
- gfx::Point3F(),
- gfx::PointF(2.f, 2.f),
- gfx::Size(),
- false,
- true);
-
- scoped_refptr<NoScaleContentLayer> child_no_scale =
- CreateNoScaleDrawableContentLayer(&delegate);
- SetLayerPropertiesForTesting(child_no_scale.get(),
- child_scale_matrix,
- gfx::Point3F(),
- gfx::PointF(12.f, 12.f),
- gfx::Size(10, 10),
- false,
- true);
-
- root->AddChild(parent);
-
- parent->AddChild(child_scale);
- parent->AddChild(child_empty);
- parent->AddChild(child_no_scale);
-
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
-
- float device_scale_factor = 2.5f;
- float page_scale_factor = 1.f;
-
- {
- RenderSurfaceLayerList render_surface_layer_list;
- LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
- root.get(), root->bounds(), &render_surface_layer_list);
- inputs.device_scale_factor = device_scale_factor;
- inputs.page_scale_factor = page_scale_factor;
- inputs.page_scale_application_layer = root.get();
- inputs.can_adjust_raster_scales = true;
- inputs.verify_property_trees = false;
- LayerTreeHostCommon::CalculateDrawProperties(&inputs);
-
- EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor *
- initial_parent_scale, parent);
- EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor *
- initial_parent_scale * initial_child_scale,
- child_scale);
- EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor *
- initial_parent_scale * initial_child_scale,
- child_empty);
- EXPECT_CONTENTS_SCALE_EQ(1, child_no_scale);
-
- // The parent is scaled up and shouldn't need to scale during draw. The
- // child that can scale its contents should also not need to scale during
- // draw. This shouldn't change if the child has empty bounds. The other
- // children should.
- EXPECT_FLOAT_EQ(1.0, parent->draw_transform().matrix().get(0, 0));
- EXPECT_FLOAT_EQ(1.0, parent->draw_transform().matrix().get(1, 1));
- EXPECT_FLOAT_EQ(1.0, child_scale->draw_transform().matrix().get(0, 0));
- EXPECT_FLOAT_EQ(1.0, child_scale->draw_transform().matrix().get(1, 1));
- EXPECT_FLOAT_EQ(1.0, child_empty->draw_transform().matrix().get(0, 0));
- EXPECT_FLOAT_EQ(1.0, child_empty->draw_transform().matrix().get(1, 1));
- EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor *
- initial_parent_scale * initial_child_scale,
- child_no_scale->draw_transform().matrix().get(0, 0));
- EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor *
- initial_parent_scale * initial_child_scale,
- child_no_scale->draw_transform().matrix().get(1, 1));
- }
-
- // If the device_scale_factor or page_scale_factor changes, then it should be
- // updated using the initial transform as the raster scale.
- device_scale_factor = 2.25f;
- page_scale_factor = 1.25f;
-
- {
- RenderSurfaceLayerList render_surface_layer_list;
- LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
- root.get(), root->bounds(), &render_surface_layer_list);
- inputs.device_scale_factor = device_scale_factor;
- inputs.page_scale_factor = page_scale_factor;
- inputs.page_scale_application_layer = root.get();
- inputs.can_adjust_raster_scales = true;
- inputs.verify_property_trees = false;
- LayerTreeHostCommon::CalculateDrawProperties(&inputs);
-
- EXPECT_CONTENTS_SCALE_EQ(
- device_scale_factor * page_scale_factor * initial_parent_scale, parent);
- EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor *
- initial_parent_scale * initial_child_scale,
- child_scale);
- EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor *
- initial_parent_scale * initial_child_scale,
- child_empty);
- EXPECT_CONTENTS_SCALE_EQ(1, child_no_scale);
- }
-
- // If the transform changes, we expect the raster scale to be reset to 1.0.
- SkMScalar second_child_scale = 1.75;
- child_scale_matrix.Scale(second_child_scale / initial_child_scale,
- second_child_scale / initial_child_scale);
- child_scale->SetTransform(child_scale_matrix);
- child_empty->SetTransform(child_scale_matrix);
-
- {
- RenderSurfaceLayerList render_surface_layer_list;
- LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
- root.get(), root->bounds(), &render_surface_layer_list);
- inputs.device_scale_factor = device_scale_factor;
- inputs.page_scale_factor = page_scale_factor;
- inputs.page_scale_application_layer = root.get();
- inputs.can_adjust_raster_scales = true;
- inputs.verify_property_trees = false;
- LayerTreeHostCommon::CalculateDrawProperties(&inputs);
-
- EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor *
- initial_parent_scale,
- parent);
- EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
- child_scale);
- EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
- child_empty);
- EXPECT_CONTENTS_SCALE_EQ(1, child_no_scale);
- }
-
- // If the device_scale_factor or page_scale_factor changes, then it should be
- // updated, but still using 1.0 as the raster scale.
- device_scale_factor = 2.75f;
- page_scale_factor = 1.75f;
-
- {
- RenderSurfaceLayerList render_surface_layer_list;
- LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
- root.get(), root->bounds(), &render_surface_layer_list);
- inputs.device_scale_factor = device_scale_factor;
- inputs.page_scale_factor = page_scale_factor;
- inputs.page_scale_application_layer = root.get();
- inputs.can_adjust_raster_scales = true;
- inputs.verify_property_trees = false;
- LayerTreeHostCommon::CalculateDrawProperties(&inputs);
-
- EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor *
- initial_parent_scale,
- parent);
- EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
- child_scale);
- EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
- child_empty);
- EXPECT_CONTENTS_SCALE_EQ(1, child_no_scale);
- }
-}
-
-// TODO(sohanjg): Remove this test when ContentLayer is removed.
-TEST_F(LayerTreeHostCommonTest,
- ContentsScale_LayerTransformsDontAffectContentsScale) {
- MockContentLayerClient delegate;
- gfx::Transform identity_matrix;
-
- gfx::Transform parent_scale_matrix;
- SkMScalar initial_parent_scale = 1.75;
- parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale);
-
- gfx::Transform child_scale_matrix;
- SkMScalar initial_child_scale = 1.25;
- child_scale_matrix.Scale(initial_child_scale, initial_child_scale);
-
- scoped_refptr<Layer> root = Layer::Create();
- root->SetBounds(gfx::Size(100, 100));
-
- scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate);
- SetLayerPropertiesForTesting(parent.get(),
- parent_scale_matrix,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(100, 100),
- false,
- true);
-
- scoped_refptr<ContentLayer> child_scale =
- CreateDrawableContentLayer(&delegate);
- SetLayerPropertiesForTesting(child_scale.get(),
- child_scale_matrix,
- gfx::Point3F(),
- gfx::PointF(2.f, 2.f),
- gfx::Size(10, 10),
- false,
- true);
-
- scoped_refptr<ContentLayer> child_empty =
- CreateDrawableContentLayer(&delegate);
- SetLayerPropertiesForTesting(child_empty.get(),
- child_scale_matrix,
- gfx::Point3F(),
- gfx::PointF(2.f, 2.f),
- gfx::Size(),
- false,
- true);
-
- scoped_refptr<NoScaleContentLayer> child_no_scale =
- CreateNoScaleDrawableContentLayer(&delegate);
- SetLayerPropertiesForTesting(child_no_scale.get(),
- child_scale_matrix,
- gfx::Point3F(),
- gfx::PointF(12.f, 12.f),
- gfx::Size(10, 10),
- false,
- true);
-
- root->AddChild(parent);
-
- parent->AddChild(child_scale);
- parent->AddChild(child_empty);
- parent->AddChild(child_no_scale);
-
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
-
- RenderSurfaceLayerList render_surface_layer_list;
-
- float device_scale_factor = 2.5f;
- float page_scale_factor = 1.f;
-
- LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
- root.get(), root->bounds(), &render_surface_layer_list);
- inputs.device_scale_factor = device_scale_factor;
- inputs.page_scale_factor = page_scale_factor;
- inputs.page_scale_application_layer = root.get();
- inputs.verify_property_trees = false;
- LayerTreeHostCommon::CalculateDrawProperties(&inputs);
-
- EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, parent);
- EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
- child_scale);
- EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
- child_empty);
- EXPECT_CONTENTS_SCALE_EQ(1, child_no_scale);
-
- // Since the transform scale does not affect contents scale, it should affect
- // the draw transform instead.
- EXPECT_FLOAT_EQ(initial_parent_scale,
- parent->draw_transform().matrix().get(0, 0));
- EXPECT_FLOAT_EQ(initial_parent_scale,
- parent->draw_transform().matrix().get(1, 1));
- EXPECT_FLOAT_EQ(initial_parent_scale * initial_child_scale,
- child_scale->draw_transform().matrix().get(0, 0));
- EXPECT_FLOAT_EQ(initial_parent_scale * initial_child_scale,
- child_scale->draw_transform().matrix().get(1, 1));
- EXPECT_FLOAT_EQ(initial_parent_scale * initial_child_scale,
- child_empty->draw_transform().matrix().get(0, 0));
- EXPECT_FLOAT_EQ(initial_parent_scale * initial_child_scale,
- child_empty->draw_transform().matrix().get(1, 1));
- EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor *
- initial_parent_scale * initial_child_scale,
- child_no_scale->draw_transform().matrix().get(0, 0));
- EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor *
- initial_parent_scale * initial_child_scale,
- child_no_scale->draw_transform().matrix().get(1, 1));
-}
-
-TEST_F(LayerTreeHostCommonTest, SmallIdealScale) {
- MockContentLayerClient delegate;
- gfx::Transform identity_matrix;
-
+TEST_F(LayerTreeHostCommonScalingTest, SmallIdealScale) {
gfx::Transform parent_scale_matrix;
SkMScalar initial_parent_scale = 1.75;
parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale);
@@ -4902,48 +4325,25 @@ TEST_F(LayerTreeHostCommonTest, SmallIdealScale) {
SkMScalar initial_child_scale = 0.25;
child_scale_matrix.Scale(initial_child_scale, initial_child_scale);
- scoped_refptr<Layer> root = Layer::Create();
+ LayerImpl* root = root_layer();
root->SetBounds(gfx::Size(100, 100));
- scoped_refptr<FakePictureLayer> parent =
- CreateDrawablePictureLayer(&delegate);
- SetLayerPropertiesForTesting(parent.get(),
- parent_scale_matrix,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(100, 100),
- false,
- true);
-
- scoped_refptr<FakePictureLayer> child_scale =
- CreateDrawablePictureLayer(&delegate);
- SetLayerPropertiesForTesting(child_scale.get(),
- child_scale_matrix,
- gfx::Point3F(),
- gfx::PointF(2.f, 2.f),
- gfx::Size(10, 10),
- false,
- true);
-
- root->AddChild(parent);
-
- parent->AddChild(child_scale);
+ LayerImpl* parent = AddChildToRoot<LayerImpl>();
+ SetLayerPropertiesForTesting(parent, parent_scale_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), false, true,
+ false);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ LayerImpl* child_scale = AddChild<LayerImpl>(parent);
+ SetLayerPropertiesForTesting(child_scale, child_scale_matrix, gfx::Point3F(),
+ gfx::PointF(2.f, 2.f), gfx::Size(10, 10), false,
+ true, false);
float device_scale_factor = 2.5f;
float page_scale_factor = 0.01f;
{
- RenderSurfaceLayerList render_surface_layer_list;
- LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
- root.get(), root->bounds(), &render_surface_layer_list);
- inputs.device_scale_factor = device_scale_factor;
- inputs.page_scale_factor = page_scale_factor;
- inputs.page_scale_application_layer = root.get();
- inputs.can_adjust_raster_scales = true;
- LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+ ExecuteCalculateDrawProperties(root, device_scale_factor, page_scale_factor,
+ root);
// The ideal scale is able to go below 1.
float expected_ideal_scale =
@@ -4958,422 +4358,7 @@ TEST_F(LayerTreeHostCommonTest, SmallIdealScale) {
}
}
-TEST_F(LayerTreeHostCommonTest, ContentsScaleForSurfaces) {
- MockContentLayerClient delegate;
- gfx::Transform identity_matrix;
-
- gfx::Transform parent_scale_matrix;
- SkMScalar initial_parent_scale = 2.0;
- parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale);
-
- gfx::Transform child_scale_matrix;
- SkMScalar initial_child_scale = 3.0;
- child_scale_matrix.Scale(initial_child_scale, initial_child_scale);
-
- scoped_refptr<Layer> root = Layer::Create();
- root->SetBounds(gfx::Size(100, 100));
-
- scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate);
- SetLayerPropertiesForTesting(parent.get(),
- parent_scale_matrix,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(100, 100),
- false,
- true);
-
- scoped_refptr<ContentLayer> surface_scale =
- CreateDrawableContentLayer(&delegate);
- SetLayerPropertiesForTesting(surface_scale.get(),
- child_scale_matrix,
- gfx::Point3F(),
- gfx::PointF(2.f, 2.f),
- gfx::Size(10, 10),
- false,
- true);
-
- scoped_refptr<ContentLayer> surface_scale_child_scale =
- CreateDrawableContentLayer(&delegate);
- SetLayerPropertiesForTesting(surface_scale_child_scale.get(),
- child_scale_matrix,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(10, 10),
- false,
- true);
-
- scoped_refptr<NoScaleContentLayer> surface_scale_child_no_scale =
- CreateNoScaleDrawableContentLayer(&delegate);
- SetLayerPropertiesForTesting(surface_scale_child_no_scale.get(),
- child_scale_matrix,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(10, 10),
- false,
- true);
-
- scoped_refptr<NoScaleContentLayer> surface_no_scale =
- CreateNoScaleDrawableContentLayer(&delegate);
- SetLayerPropertiesForTesting(surface_no_scale.get(),
- child_scale_matrix,
- gfx::Point3F(),
- gfx::PointF(12.f, 12.f),
- gfx::Size(10, 10),
- false,
- true);
-
- scoped_refptr<ContentLayer> surface_no_scale_child_scale =
- CreateDrawableContentLayer(&delegate);
- SetLayerPropertiesForTesting(surface_no_scale_child_scale.get(),
- child_scale_matrix,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(10, 10),
- false,
- true);
-
- scoped_refptr<NoScaleContentLayer> surface_no_scale_child_no_scale =
- CreateNoScaleDrawableContentLayer(&delegate);
- SetLayerPropertiesForTesting(surface_no_scale_child_no_scale.get(),
- child_scale_matrix,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(10, 10),
- false,
- true);
-
- root->AddChild(parent);
-
- parent->AddChild(surface_scale);
- parent->AddChild(surface_no_scale);
-
- surface_scale->SetForceRenderSurface(true);
- surface_scale->AddChild(surface_scale_child_scale);
- surface_scale->AddChild(surface_scale_child_no_scale);
-
- surface_no_scale->SetForceRenderSurface(true);
- surface_no_scale->AddChild(surface_no_scale_child_scale);
- surface_no_scale->AddChild(surface_no_scale_child_no_scale);
-
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
-
- SkMScalar device_scale_factor = 5;
- SkMScalar page_scale_factor = 7;
-
- RenderSurfaceLayerList render_surface_layer_list;
- LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
- root.get(), root->bounds(), &render_surface_layer_list);
- inputs.device_scale_factor = device_scale_factor;
- inputs.page_scale_factor = page_scale_factor;
- inputs.page_scale_application_layer = root.get();
- inputs.can_adjust_raster_scales = true;
- inputs.verify_property_trees = false;
- LayerTreeHostCommon::CalculateDrawProperties(&inputs);
-
- EXPECT_CONTENTS_SCALE_EQ(
- device_scale_factor * page_scale_factor * initial_parent_scale, parent);
- EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor *
- initial_parent_scale * initial_child_scale,
- surface_scale);
- EXPECT_CONTENTS_SCALE_EQ(1, surface_no_scale);
- EXPECT_CONTENTS_SCALE_EQ(
- device_scale_factor * page_scale_factor * initial_parent_scale *
- initial_child_scale * initial_child_scale,
- surface_scale_child_scale);
- EXPECT_CONTENTS_SCALE_EQ(1, surface_scale_child_no_scale);
- EXPECT_CONTENTS_SCALE_EQ(
- device_scale_factor * page_scale_factor * initial_parent_scale *
- initial_child_scale * initial_child_scale,
- surface_no_scale_child_scale);
- EXPECT_CONTENTS_SCALE_EQ(1, surface_no_scale_child_no_scale);
-
- // The parent is scaled up and shouldn't need to scale during draw.
- EXPECT_FLOAT_EQ(1.0, parent->draw_transform().matrix().get(0, 0));
- EXPECT_FLOAT_EQ(1.0, parent->draw_transform().matrix().get(1, 1));
-
- // RenderSurfaces should always be 1:1 with their target.
- EXPECT_FLOAT_EQ(
- 1.0,
- surface_scale->render_surface()->draw_transform().matrix().get(0, 0));
- EXPECT_FLOAT_EQ(
- 1.0,
- surface_scale->render_surface()->draw_transform().matrix().get(1, 1));
-
- // The surface_scale can apply contents scale so the layer shouldn't need to
- // scale during draw.
- EXPECT_FLOAT_EQ(1.0, surface_scale->draw_transform().matrix().get(0, 0));
- EXPECT_FLOAT_EQ(1.0, surface_scale->draw_transform().matrix().get(1, 1));
-
- // The surface_scale_child_scale can apply contents scale so it shouldn't need
- // to scale during draw.
- EXPECT_FLOAT_EQ(
- 1.0, surface_scale_child_scale->draw_transform().matrix().get(0, 0));
- EXPECT_FLOAT_EQ(
- 1.0, surface_scale_child_scale->draw_transform().matrix().get(1, 1));
-
- // The surface_scale_child_no_scale can not apply contents scale, so it needs
- // to be scaled during draw.
- EXPECT_FLOAT_EQ(
- device_scale_factor * page_scale_factor * initial_parent_scale *
- initial_child_scale * initial_child_scale,
- surface_scale_child_no_scale->draw_transform().matrix().get(0, 0));
- EXPECT_FLOAT_EQ(
- device_scale_factor * page_scale_factor * initial_parent_scale *
- initial_child_scale * initial_child_scale,
- surface_scale_child_no_scale->draw_transform().matrix().get(1, 1));
-
- // RenderSurfaces should always be 1:1 with their target.
- EXPECT_FLOAT_EQ(
- 1.0,
- surface_no_scale->render_surface()->draw_transform().matrix().get(0, 0));
- EXPECT_FLOAT_EQ(
- 1.0,
- surface_no_scale->render_surface()->draw_transform().matrix().get(1, 1));
-
- // The surface_no_scale layer can not apply contents scale, so it needs to be
- // scaled during draw.
- EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor *
- initial_parent_scale * initial_child_scale,
- surface_no_scale->draw_transform().matrix().get(0, 0));
- EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor *
- initial_parent_scale * initial_child_scale,
- surface_no_scale->draw_transform().matrix().get(1, 1));
-
- // The surface_scale_child_scale can apply contents scale so it shouldn't need
- // to scale during draw.
- EXPECT_FLOAT_EQ(
- 1.0, surface_no_scale_child_scale->draw_transform().matrix().get(0, 0));
- EXPECT_FLOAT_EQ(
- 1.0, surface_no_scale_child_scale->draw_transform().matrix().get(1, 1));
-
- // The surface_scale_child_no_scale can not apply contents scale, so it needs
- // to be scaled during draw.
- EXPECT_FLOAT_EQ(
- device_scale_factor * page_scale_factor * initial_parent_scale *
- initial_child_scale * initial_child_scale,
- surface_no_scale_child_no_scale->draw_transform().matrix().get(0, 0));
- EXPECT_FLOAT_EQ(
- device_scale_factor * page_scale_factor * initial_parent_scale *
- initial_child_scale * initial_child_scale,
- surface_no_scale_child_no_scale->draw_transform().matrix().get(1, 1));
-}
-
-// TODO(sohanjg): Remove this test when ContentLayer is removed.
-TEST_F(LayerTreeHostCommonTest,
- ContentsScaleForSurfaces_LayerTransformsDontAffectContentsScale) {
- MockContentLayerClient delegate;
- gfx::Transform identity_matrix;
-
- gfx::Transform parent_scale_matrix;
- SkMScalar initial_parent_scale = 2.0;
- parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale);
-
- gfx::Transform child_scale_matrix;
- SkMScalar initial_child_scale = 3.0;
- child_scale_matrix.Scale(initial_child_scale, initial_child_scale);
-
- scoped_refptr<Layer> root = Layer::Create();
- root->SetBounds(gfx::Size(100, 100));
-
- scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate);
- SetLayerPropertiesForTesting(parent.get(),
- parent_scale_matrix,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(100, 100),
- false,
- true);
-
- scoped_refptr<ContentLayer> surface_scale =
- CreateDrawableContentLayer(&delegate);
- SetLayerPropertiesForTesting(surface_scale.get(),
- child_scale_matrix,
- gfx::Point3F(),
- gfx::PointF(2.f, 2.f),
- gfx::Size(10, 10),
- false,
- true);
-
- scoped_refptr<ContentLayer> surface_scale_child_scale =
- CreateDrawableContentLayer(&delegate);
- SetLayerPropertiesForTesting(surface_scale_child_scale.get(),
- child_scale_matrix,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(10, 10),
- false,
- true);
-
- scoped_refptr<NoScaleContentLayer> surface_scale_child_no_scale =
- CreateNoScaleDrawableContentLayer(&delegate);
- SetLayerPropertiesForTesting(surface_scale_child_no_scale.get(),
- child_scale_matrix,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(10, 10),
- false,
- true);
-
- scoped_refptr<NoScaleContentLayer> surface_no_scale =
- CreateNoScaleDrawableContentLayer(&delegate);
- SetLayerPropertiesForTesting(surface_no_scale.get(),
- child_scale_matrix,
- gfx::Point3F(),
- gfx::PointF(12.f, 12.f),
- gfx::Size(10, 10),
- false,
- true);
-
- scoped_refptr<ContentLayer> surface_no_scale_child_scale =
- CreateDrawableContentLayer(&delegate);
- SetLayerPropertiesForTesting(surface_no_scale_child_scale.get(),
- child_scale_matrix,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(10, 10),
- false,
- true);
-
- scoped_refptr<NoScaleContentLayer> surface_no_scale_child_no_scale =
- CreateNoScaleDrawableContentLayer(&delegate);
- SetLayerPropertiesForTesting(surface_no_scale_child_no_scale.get(),
- child_scale_matrix,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(10, 10),
- false,
- true);
-
- root->AddChild(parent);
-
- parent->AddChild(surface_scale);
- parent->AddChild(surface_no_scale);
-
- surface_scale->SetForceRenderSurface(true);
- surface_scale->AddChild(surface_scale_child_scale);
- surface_scale->AddChild(surface_scale_child_no_scale);
-
- surface_no_scale->SetForceRenderSurface(true);
- surface_no_scale->AddChild(surface_no_scale_child_scale);
- surface_no_scale->AddChild(surface_no_scale_child_no_scale);
-
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
-
- RenderSurfaceLayerList render_surface_layer_list;
-
- SkMScalar device_scale_factor = 5.0;
- SkMScalar page_scale_factor = 7.0;
- LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
- root.get(), root->bounds(), &render_surface_layer_list);
- inputs.device_scale_factor = device_scale_factor;
- inputs.page_scale_factor = page_scale_factor;
- inputs.page_scale_application_layer = root.get();
- inputs.verify_property_trees = false;
- LayerTreeHostCommon::CalculateDrawProperties(&inputs);
-
- EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
- parent);
- EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
- surface_scale);
- EXPECT_CONTENTS_SCALE_EQ(1.f, surface_no_scale);
- EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
- surface_scale_child_scale);
- EXPECT_CONTENTS_SCALE_EQ(1.f, surface_scale_child_no_scale);
- EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
- surface_no_scale_child_scale);
- EXPECT_CONTENTS_SCALE_EQ(1.f, surface_no_scale_child_no_scale);
-
- // The parent is scaled up during draw, since its contents are not scaled by
- // the transform hierarchy.
- EXPECT_FLOAT_EQ(initial_parent_scale,
- parent->draw_transform().matrix().get(0, 0));
- EXPECT_FLOAT_EQ(initial_parent_scale,
- parent->draw_transform().matrix().get(1, 1));
-
- // The child surface is not scaled up during draw since its subtree is scaled
- // by the transform hierarchy.
- EXPECT_FLOAT_EQ(
- 1.f,
- surface_scale->render_surface()->draw_transform().matrix().get(0, 0));
- EXPECT_FLOAT_EQ(
- 1.f,
- surface_scale->render_surface()->draw_transform().matrix().get(1, 1));
-
- // The surface_scale's RenderSurface is not scaled during draw, so the layer
- // needs to be scaled when drawing into its surface.
- EXPECT_FLOAT_EQ(initial_parent_scale * initial_child_scale,
- surface_scale->draw_transform().matrix().get(0, 0));
- EXPECT_FLOAT_EQ(initial_parent_scale * initial_child_scale,
- surface_scale->draw_transform().matrix().get(1, 1));
-
- // The surface_scale_child_scale is not scaled when drawing into its surface,
- // since its content bounds are scaled by the transform hierarchy.
- EXPECT_FLOAT_EQ(
- initial_child_scale * initial_child_scale * initial_parent_scale,
- surface_scale_child_scale->draw_transform().matrix().get(0, 0));
- EXPECT_FLOAT_EQ(
- initial_child_scale * initial_child_scale * initial_parent_scale,
- surface_scale_child_scale->draw_transform().matrix().get(1, 1));
-
- // The surface_scale_child_no_scale is scaled by the device scale, page scale
- // and transform hierarchy.
- EXPECT_FLOAT_EQ(
- device_scale_factor * page_scale_factor * initial_parent_scale *
- initial_child_scale * initial_child_scale,
- surface_scale_child_no_scale->draw_transform().matrix().get(0, 0));
- EXPECT_FLOAT_EQ(
- device_scale_factor * page_scale_factor * initial_parent_scale *
- initial_child_scale * initial_child_scale,
- surface_scale_child_no_scale->draw_transform().matrix().get(1, 1));
-
- // The child surface is not scaled up during draw since its subtree is scaled
- // by the transform hierarchy.
- EXPECT_FLOAT_EQ(
- 1.f,
- surface_no_scale->render_surface()->draw_transform().matrix().get(0, 0));
- EXPECT_FLOAT_EQ(
- 1.f,
- surface_no_scale->render_surface()->draw_transform().matrix().get(1, 1));
-
- // The surface_no_scale layer has a fixed contents scale of 1, so it needs to
- // be scaled by the device and page scale factors. Its surface is already
- // scaled by the transform hierarchy so those don't need to scale the layer's
- // drawing.
- EXPECT_FLOAT_EQ(initial_parent_scale * initial_child_scale *
- device_scale_factor * page_scale_factor,
- surface_no_scale->draw_transform().matrix().get(0, 0));
- EXPECT_FLOAT_EQ(initial_parent_scale * initial_child_scale *
- device_scale_factor * page_scale_factor,
- surface_no_scale->draw_transform().matrix().get(1, 1));
-
- // The surface_no_scale_child_scale has its contents scaled by the page and
- // device scale factors, but needs to be scaled by the transform hierarchy
- // when drawing.
- EXPECT_FLOAT_EQ(
- initial_parent_scale * initial_child_scale * initial_child_scale,
- surface_no_scale_child_scale->draw_transform().matrix().get(0, 0));
- EXPECT_FLOAT_EQ(
- initial_parent_scale * initial_child_scale * initial_child_scale,
- surface_no_scale_child_scale->draw_transform().matrix().get(1, 1));
-
- // The surface_no_scale_child_no_scale needs to be scaled by the device and
- // page scale factors and by any transform heirarchy below its target surface.
- EXPECT_FLOAT_EQ(
- device_scale_factor * page_scale_factor * initial_parent_scale *
- initial_child_scale * initial_child_scale,
- surface_no_scale_child_no_scale->draw_transform().matrix().get(0, 0));
- EXPECT_FLOAT_EQ(
- device_scale_factor * page_scale_factor * initial_parent_scale *
- initial_child_scale * initial_child_scale,
- surface_no_scale_child_no_scale->draw_transform().matrix().get(1, 1));
-}
-
-TEST_F(LayerTreeHostCommonTest, IdealScaleForAnimatingLayer) {
- MockContentLayerClient delegate;
- gfx::Transform identity_matrix;
-
+TEST_F(LayerTreeHostCommonScalingTest, IdealScaleForAnimatingLayer) {
gfx::Transform parent_scale_matrix;
SkMScalar initial_parent_scale = 1.75;
parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale);
@@ -5382,42 +4367,21 @@ TEST_F(LayerTreeHostCommonTest, IdealScaleForAnimatingLayer) {
SkMScalar initial_child_scale = 1.25;
child_scale_matrix.Scale(initial_child_scale, initial_child_scale);
- scoped_refptr<Layer> root = Layer::Create();
+ LayerImpl* root = root_layer();
root->SetBounds(gfx::Size(100, 100));
- scoped_refptr<FakePictureLayer> parent =
- CreateDrawablePictureLayer(&delegate);
- SetLayerPropertiesForTesting(parent.get(),
- parent_scale_matrix,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(100, 100),
- false,
- true);
-
- scoped_refptr<FakePictureLayer> child_scale =
- CreateDrawablePictureLayer(&delegate);
- SetLayerPropertiesForTesting(child_scale.get(),
- child_scale_matrix,
- gfx::Point3F(),
- gfx::PointF(2.f, 2.f),
- gfx::Size(10, 10),
- false,
- true);
-
- root->AddChild(parent);
-
- parent->AddChild(child_scale);
+ LayerImpl* parent = AddChildToRoot<LayerImpl>();
+ SetLayerPropertiesForTesting(parent, parent_scale_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), false, true,
+ false);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ LayerImpl* child_scale = AddChild<LayerImpl>(parent);
+ SetLayerPropertiesForTesting(child_scale, child_scale_matrix, gfx::Point3F(),
+ gfx::PointF(2.f, 2.f), gfx::Size(10, 10), false,
+ true, false);
{
- RenderSurfaceLayerList render_surface_layer_list;
- LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
- root.get(), root->bounds(), &render_surface_layer_list);
- inputs.can_adjust_raster_scales = true;
- LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+ ExecuteCalculateDrawProperties(root);
EXPECT_IDEAL_SCALE_EQ(initial_parent_scale, parent);
// Animating layers compute ideal scale in the same way as when
@@ -5427,74 +4391,12 @@ TEST_F(LayerTreeHostCommonTest, IdealScaleForAnimatingLayer) {
}
}
-// TODO(sohanjg): Remove this test when ContentLayer is removed.
-TEST_F(LayerTreeHostCommonTest,
- ChangeInContentBoundsOrScaleTriggersPushProperties) {
- MockContentLayerClient delegate;
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> child = CreateDrawableContentLayer(&delegate);
- root->AddChild(child);
-
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
-
- gfx::Transform identity_matrix;
- SetLayerPropertiesForTesting(root.get(),
- identity_matrix,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(100, 100),
- true,
- false);
- SetLayerPropertiesForTesting(child.get(),
- identity_matrix,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(100, 100),
- true,
- false);
-
- root->reset_needs_push_properties_for_testing();
- child->reset_needs_push_properties_for_testing();
-
- gfx::Size device_viewport_size = gfx::Size(100, 100);
- RenderSurfaceLayerList render_surface_layer_list;
- LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
- root.get(), device_viewport_size, &render_surface_layer_list);
- inputs.device_scale_factor = 1.f;
- inputs.can_adjust_raster_scales = true;
- inputs.verify_property_trees = false;
-
- // This will change both layers' content bounds.
- LayerTreeHostCommon::CalculateDrawProperties(&inputs);
- EXPECT_TRUE(root->needs_push_properties());
- EXPECT_TRUE(child->needs_push_properties());
-
- root->reset_needs_push_properties_for_testing();
- child->reset_needs_push_properties_for_testing();
-
- // This will change only the child layer's contents scale and content bounds,
- // since the root layer is not a ContentsScalingLayer.
- inputs.device_scale_factor = 2.f;
- LayerTreeHostCommon::CalculateDrawProperties(&inputs);
- EXPECT_FALSE(root->needs_push_properties());
- EXPECT_TRUE(child->needs_push_properties());
-
- root->reset_needs_push_properties_for_testing();
- child->reset_needs_push_properties_for_testing();
-
- // This will not change either layer's contents scale or content bounds.
- LayerTreeHostCommon::CalculateDrawProperties(&inputs);
- EXPECT_FALSE(root->needs_push_properties());
- EXPECT_FALSE(child->needs_push_properties());
-}
-
TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) {
MockContentLayerClient delegate;
gfx::Transform identity_matrix;
scoped_refptr<FakePictureLayer> parent =
- CreateDrawablePictureLayer(&delegate);
+ CreateDrawablePictureLayer(layer_settings(), &delegate);
SetLayerPropertiesForTesting(parent.get(),
identity_matrix,
gfx::Point3F(),
@@ -5503,7 +4405,8 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) {
false,
true);
- scoped_refptr<FakePictureLayer> child = CreateDrawablePictureLayer(&delegate);
+ scoped_refptr<FakePictureLayer> child =
+ CreateDrawablePictureLayer(layer_settings(), &delegate);
SetLayerPropertiesForTesting(child.get(),
identity_matrix,
gfx::Point3F(),
@@ -5515,7 +4418,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) {
gfx::Transform replica_transform;
replica_transform.Scale(1.0, -1.0);
scoped_refptr<FakePictureLayer> replica =
- CreateDrawablePictureLayer(&delegate);
+ CreateDrawablePictureLayer(layer_settings(), &delegate);
SetLayerPropertiesForTesting(replica.get(),
replica_transform,
gfx::Point3F(),
@@ -5527,7 +4430,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) {
// This layer should end up in the same surface as child, with the same draw
// and screen space transforms.
scoped_refptr<FakePictureLayer> duplicate_child_non_owner =
- CreateDrawablePictureLayer(&delegate);
+ CreateDrawablePictureLayer(layer_settings(), &delegate);
SetLayerPropertiesForTesting(duplicate_child_non_owner.get(),
identity_matrix,
gfx::Point3F(),
@@ -5540,8 +4443,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) {
child->AddChild(duplicate_child_non_owner);
child->SetReplicaLayer(replica.get());
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(parent);
+ host()->SetRootLayer(parent);
RenderSurfaceLayerList render_surface_layer_list;
@@ -5585,8 +4487,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) {
duplicate_child_non_owner->screen_space_transform());
EXPECT_EQ(child->drawable_content_rect(),
duplicate_child_non_owner->drawable_content_rect());
- EXPECT_EQ(child->content_bounds(),
- duplicate_child_non_owner->content_bounds());
+ EXPECT_EQ(child->bounds(), duplicate_child_non_owner->bounds());
gfx::Transform expected_render_surface_draw_transform;
expected_render_surface_draw_transform.Translate(
@@ -5634,7 +4535,7 @@ TEST_F(LayerTreeHostCommonTest,
gfx::Transform identity_matrix;
scoped_refptr<FakePictureLayer> parent =
- CreateDrawablePictureLayer(&delegate);
+ CreateDrawablePictureLayer(layer_settings(), &delegate);
SetLayerPropertiesForTesting(parent.get(),
identity_matrix,
gfx::Point3F(),
@@ -5643,7 +4544,8 @@ TEST_F(LayerTreeHostCommonTest,
false,
true);
- scoped_refptr<FakePictureLayer> child = CreateDrawablePictureLayer(&delegate);
+ scoped_refptr<FakePictureLayer> child =
+ CreateDrawablePictureLayer(layer_settings(), &delegate);
SetLayerPropertiesForTesting(child.get(),
identity_matrix,
gfx::Point3F(),
@@ -5655,7 +4557,7 @@ TEST_F(LayerTreeHostCommonTest,
gfx::Transform replica_transform;
replica_transform.Scale(1.0, -1.0);
scoped_refptr<FakePictureLayer> replica =
- CreateDrawablePictureLayer(&delegate);
+ CreateDrawablePictureLayer(layer_settings(), &delegate);
SetLayerPropertiesForTesting(replica.get(),
replica_transform,
gfx::Point3F(),
@@ -5667,8 +4569,7 @@ TEST_F(LayerTreeHostCommonTest,
parent->AddChild(child);
child->SetReplicaLayer(replica.get());
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(parent);
+ host()->SetRootLayer(parent);
float device_scale_factor = 1.7f;
@@ -5705,19 +4606,18 @@ TEST_F(LayerTreeHostCommonTest,
}
TEST_F(LayerTreeHostCommonTest, SubtreeSearch) {
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> child = Layer::Create();
- scoped_refptr<Layer> grand_child = Layer::Create();
- scoped_refptr<Layer> mask_layer = Layer::Create();
- scoped_refptr<Layer> replica_layer = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
+ scoped_refptr<Layer> grand_child = Layer::Create(layer_settings());
+ scoped_refptr<Layer> mask_layer = Layer::Create(layer_settings());
+ scoped_refptr<Layer> replica_layer = Layer::Create(layer_settings());
grand_child->SetReplicaLayer(replica_layer.get());
child->AddChild(grand_child.get());
child->SetMaskLayer(mask_layer.get());
root->AddChild(child.get());
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
int nonexistent_id = -1;
EXPECT_EQ(root.get(),
@@ -5738,10 +4638,10 @@ TEST_F(LayerTreeHostCommonTest, SubtreeSearch) {
}
TEST_F(LayerTreeHostCommonTest, TransparentChildRenderSurfaceCreation) {
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> child = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> grand_child =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
const gfx::Transform identity_matrix;
SetLayerPropertiesForTesting(root.get(),
@@ -5770,8 +4670,7 @@ TEST_F(LayerTreeHostCommonTest, TransparentChildRenderSurfaceCreation) {
child->AddChild(grand_child);
child->SetOpacity(0.5f);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
ExecuteCalculateDrawProperties(root.get());
@@ -5781,7 +4680,9 @@ TEST_F(LayerTreeHostCommonTest, TransparentChildRenderSurfaceCreation) {
TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
host_impl.CreatePendingTree();
scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.pending_tree(), 1);
@@ -5818,12 +4719,12 @@ TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) {
}
using LCDTextTestParam = std::tr1::tuple<bool, bool, bool>;
-class LCDTextTest
- : public LayerTreeHostCommonTestBase,
- public testing::TestWithParam<LCDTextTestParam> {
+class LCDTextTest : public LayerTreeHostCommonTestBase,
+ public testing::TestWithParam<LCDTextTestParam> {
public:
LCDTextTest()
- : host_impl_(&proxy_, &shared_bitmap_manager_, &task_graph_runner_),
+ : LayerTreeHostCommonTestBase(LayerTreeSettings()),
+ host_impl_(&proxy_, &shared_bitmap_manager_, &task_graph_runner_),
root_(nullptr),
child_(nullptr),
grand_child_(nullptr) {}
@@ -5853,6 +4754,10 @@ class LCDTextTest
child_->SetContentsOpaque(true);
grand_child_->SetContentsOpaque(true);
+ root_->SetDrawsContent(true);
+ child_->SetDrawsContent(true);
+ grand_child_->SetDrawsContent(true);
+
gfx::Transform identity_matrix;
SetLayerPropertiesForTesting(root_, identity_matrix, gfx::Point3F(),
gfx::PointF(), gfx::Size(1, 1), true, false,
@@ -5894,6 +4799,7 @@ TEST_P(LCDTextTest, CanUseLCDText) {
gfx::Transform integral_translation;
integral_translation.Translate(1.0, 2.0);
child_->SetTransform(integral_translation);
+ child_->layer_tree_impl()->property_trees()->needs_rebuild = true;
ExecuteCalculateDrawProperties(root_, 1.f, 1.f, NULL, can_use_lcd_text_,
layers_always_allowed_lcd_text_);
EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
@@ -5904,6 +4810,7 @@ TEST_P(LCDTextTest, CanUseLCDText) {
gfx::Transform non_integral_translation;
non_integral_translation.Translate(1.5, 2.5);
child_->SetTransform(non_integral_translation);
+ child_->layer_tree_impl()->property_trees()->needs_rebuild = true;
ExecuteCalculateDrawProperties(root_, 1.f, 1.f, NULL, can_use_lcd_text_,
layers_always_allowed_lcd_text_);
EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
@@ -5914,6 +4821,7 @@ TEST_P(LCDTextTest, CanUseLCDText) {
gfx::Transform rotation;
rotation.Rotate(10.0);
child_->SetTransform(rotation);
+ child_->layer_tree_impl()->property_trees()->needs_rebuild = true;
ExecuteCalculateDrawProperties(root_, 1.f, 1.f, NULL, can_use_lcd_text_,
layers_always_allowed_lcd_text_);
EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
@@ -5924,6 +4832,7 @@ TEST_P(LCDTextTest, CanUseLCDText) {
gfx::Transform scale;
scale.Scale(2.0, 2.0);
child_->SetTransform(scale);
+ child_->layer_tree_impl()->property_trees()->needs_rebuild = true;
ExecuteCalculateDrawProperties(root_, 1.f, 1.f, NULL, can_use_lcd_text_,
layers_always_allowed_lcd_text_);
EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
@@ -5934,6 +4843,7 @@ TEST_P(LCDTextTest, CanUseLCDText) {
gfx::Transform skew;
skew.SkewX(10.0);
child_->SetTransform(skew);
+ child_->layer_tree_impl()->property_trees()->needs_rebuild = true;
ExecuteCalculateDrawProperties(root_, 1.f, 1.f, NULL, can_use_lcd_text_,
layers_always_allowed_lcd_text_);
EXPECT_EQ(expect_lcd_text, root_->can_use_lcd_text());
@@ -5942,6 +4852,7 @@ TEST_P(LCDTextTest, CanUseLCDText) {
// Case 7: Translucent.
child_->SetTransform(identity_matrix);
+ child_->layer_tree_impl()->property_trees()->needs_rebuild = true;
child_->SetOpacity(0.5f);
ExecuteCalculateDrawProperties(root_, 1.f, 1.f, NULL, can_use_lcd_text_,
layers_always_allowed_lcd_text_);
@@ -5951,6 +4862,7 @@ TEST_P(LCDTextTest, CanUseLCDText) {
// Case 8: Sanity check: restore transform and opacity.
child_->SetTransform(identity_matrix);
+ child_->layer_tree_impl()->property_trees()->needs_rebuild = true;
child_->SetOpacity(1.f);
ExecuteCalculateDrawProperties(root_, 1.f, 1.f, NULL, can_use_lcd_text_,
layers_always_allowed_lcd_text_);
@@ -5988,6 +4900,7 @@ TEST_P(LCDTextTest, CanUseLCDTextWithAnimation) {
// Add opacity animation.
child_->SetOpacity(0.9f);
+ child_->layer_tree_impl()->property_trees()->needs_rebuild = true;
AddOpacityTransitionToController(
child_->layer_animation_controller(), 10.0, 0.9f, 0.1f, false);
@@ -6032,11 +4945,13 @@ INSTANTIATE_TEST_CASE_P(LayerTreeHostCommonTest,
TEST_F(LayerTreeHostCommonTest, SubtreeHidden_SingleLayer) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
host_impl.CreatePendingTree();
const gfx::Transform identity_matrix;
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(root.get(),
identity_matrix,
gfx::Point3F(),
@@ -6046,7 +4961,7 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHidden_SingleLayer) {
false);
root->SetIsDrawable(true);
- scoped_refptr<Layer> child = Layer::Create();
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(child.get(),
identity_matrix,
gfx::Point3F(),
@@ -6056,7 +4971,7 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHidden_SingleLayer) {
false);
child->SetIsDrawable(true);
- scoped_refptr<Layer> grand_child = Layer::Create();
+ scoped_refptr<Layer> grand_child = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(grand_child.get(),
identity_matrix,
gfx::Point3F(),
@@ -6070,8 +4985,7 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHidden_SingleLayer) {
child->AddChild(grand_child);
root->AddChild(child);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
RenderSurfaceLayerList render_surface_layer_list;
LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
@@ -6090,7 +5004,9 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHidden_SingleLayer) {
TEST_F(LayerTreeHostCommonTest, SubtreeHidden_SingleLayerImpl) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
host_impl.CreatePendingTree();
const gfx::Transform identity_matrix;
@@ -6135,11 +5051,13 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHidden_SingleLayerImpl) {
TEST_F(LayerTreeHostCommonTest, SubtreeHidden_TwoLayers) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
host_impl.CreatePendingTree();
const gfx::Transform identity_matrix;
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(root.get(),
identity_matrix,
gfx::Point3F(),
@@ -6149,7 +5067,7 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHidden_TwoLayers) {
false);
root->SetIsDrawable(true);
- scoped_refptr<Layer> child = Layer::Create();
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(child.get(),
identity_matrix,
gfx::Point3F(),
@@ -6160,7 +5078,7 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHidden_TwoLayers) {
child->SetIsDrawable(true);
child->SetHideLayerAndSubtree(true);
- scoped_refptr<Layer> grand_child = Layer::Create();
+ scoped_refptr<Layer> grand_child = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(grand_child.get(),
identity_matrix,
gfx::Point3F(),
@@ -6173,8 +5091,7 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHidden_TwoLayers) {
child->AddChild(grand_child);
root->AddChild(child);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
RenderSurfaceLayerList render_surface_layer_list;
LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
@@ -6192,7 +5109,9 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHidden_TwoLayers) {
TEST_F(LayerTreeHostCommonTest, SubtreeHidden_TwoLayersImpl) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
host_impl.CreatePendingTree();
const gfx::Transform identity_matrix;
@@ -6237,11 +5156,13 @@ void EmptyCopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}
TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
host_impl.CreatePendingTree();
const gfx::Transform identity_matrix;
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(root.get(),
identity_matrix,
gfx::Point3F(),
@@ -6251,7 +5172,7 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) {
false);
root->SetIsDrawable(true);
- scoped_refptr<Layer> copy_grand_parent = Layer::Create();
+ scoped_refptr<Layer> copy_grand_parent = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(copy_grand_parent.get(),
identity_matrix,
gfx::Point3F(),
@@ -6261,7 +5182,7 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) {
false);
copy_grand_parent->SetIsDrawable(true);
- scoped_refptr<Layer> copy_parent = Layer::Create();
+ scoped_refptr<Layer> copy_parent = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(copy_parent.get(),
identity_matrix,
gfx::Point3F(),
@@ -6272,7 +5193,7 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) {
copy_parent->SetIsDrawable(true);
copy_parent->SetForceRenderSurface(true);
- scoped_refptr<Layer> copy_layer = Layer::Create();
+ scoped_refptr<Layer> copy_layer = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(copy_layer.get(),
identity_matrix,
gfx::Point3F(),
@@ -6282,7 +5203,7 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) {
false);
copy_layer->SetIsDrawable(true);
- scoped_refptr<Layer> copy_child = Layer::Create();
+ scoped_refptr<Layer> copy_child = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(copy_child.get(),
identity_matrix,
gfx::Point3F(),
@@ -6292,7 +5213,8 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) {
false);
copy_child->SetIsDrawable(true);
- scoped_refptr<Layer> copy_grand_parent_sibling_before = Layer::Create();
+ scoped_refptr<Layer> copy_grand_parent_sibling_before =
+ Layer::Create(layer_settings());
SetLayerPropertiesForTesting(copy_grand_parent_sibling_before.get(),
identity_matrix,
gfx::Point3F(),
@@ -6302,7 +5224,8 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) {
false);
copy_grand_parent_sibling_before->SetIsDrawable(true);
- scoped_refptr<Layer> copy_grand_parent_sibling_after = Layer::Create();
+ scoped_refptr<Layer> copy_grand_parent_sibling_after =
+ Layer::Create(layer_settings());
SetLayerPropertiesForTesting(copy_grand_parent_sibling_after.get(),
identity_matrix,
gfx::Point3F(),
@@ -6319,8 +5242,7 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) {
root->AddChild(copy_grand_parent);
root->AddChild(copy_grand_parent_sibling_after);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
// Hide the copy_grand_parent and its subtree. But make a copy request in that
// hidden subtree on copy_layer.
@@ -6384,11 +5306,13 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) {
TEST_F(LayerTreeHostCommonTest, ClippedOutCopyRequest) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
host_impl.CreatePendingTree();
const gfx::Transform identity_matrix;
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(root.get(),
identity_matrix,
gfx::Point3F(),
@@ -6398,7 +5322,7 @@ TEST_F(LayerTreeHostCommonTest, ClippedOutCopyRequest) {
false);
root->SetIsDrawable(true);
- scoped_refptr<Layer> copy_parent = Layer::Create();
+ scoped_refptr<Layer> copy_parent = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(copy_parent.get(),
identity_matrix,
gfx::Point3F(),
@@ -6409,7 +5333,7 @@ TEST_F(LayerTreeHostCommonTest, ClippedOutCopyRequest) {
copy_parent->SetIsDrawable(true);
copy_parent->SetMasksToBounds(true);
- scoped_refptr<Layer> copy_layer = Layer::Create();
+ scoped_refptr<Layer> copy_layer = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(copy_layer.get(),
identity_matrix,
gfx::Point3F(),
@@ -6419,7 +5343,7 @@ TEST_F(LayerTreeHostCommonTest, ClippedOutCopyRequest) {
false);
copy_layer->SetIsDrawable(true);
- scoped_refptr<Layer> copy_child = Layer::Create();
+ scoped_refptr<Layer> copy_child = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(copy_child.get(),
identity_matrix,
gfx::Point3F(),
@@ -6433,8 +5357,7 @@ TEST_F(LayerTreeHostCommonTest, ClippedOutCopyRequest) {
copy_parent->AddChild(copy_layer);
root->AddChild(copy_parent);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
copy_layer->RequestCopyOfOutput(CopyOutputRequest::CreateRequest(
base::Bind(&EmptyCopyOutputCallback)));
@@ -6459,11 +5382,13 @@ TEST_F(LayerTreeHostCommonTest, ClippedOutCopyRequest) {
TEST_F(LayerTreeHostCommonTest, VisibleContentRectInsideSurface) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
host_impl.CreatePendingTree();
const gfx::Transform identity_matrix;
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(root.get(),
identity_matrix,
gfx::Point3F(),
@@ -6474,7 +5399,7 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectInsideSurface) {
root->SetIsDrawable(true);
// The surface is moved slightly outside of the viewport.
- scoped_refptr<Layer> surface = Layer::Create();
+ scoped_refptr<Layer> surface = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(surface.get(),
identity_matrix,
gfx::Point3F(),
@@ -6484,7 +5409,7 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectInsideSurface) {
false);
surface->SetForceRenderSurface(true);
- scoped_refptr<Layer> surface_child = Layer::Create();
+ scoped_refptr<Layer> surface_child = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(surface_child.get(),
identity_matrix,
gfx::Point3F(),
@@ -6497,8 +5422,7 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectInsideSurface) {
surface->AddChild(surface_child);
root->AddChild(surface);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
RenderSurfaceLayerList render_surface_layer_list;
LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
@@ -6506,10 +5430,10 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectInsideSurface) {
inputs.can_adjust_raster_scales = true;
LayerTreeHostCommon::CalculateDrawProperties(&inputs);
- // The visible_content_rect for the |surface_child| should not be clipped by
+ // The visible_layer_rect for the |surface_child| should not be clipped by
// the viewport.
EXPECT_EQ(gfx::Rect(50, 50).ToString(),
- surface_child->visible_content_rect().ToString());
+ surface_child->visible_layer_rect().ToString());
}
TEST_F(LayerTreeHostCommonTest, TransformedClipParent) {
@@ -6524,12 +5448,12 @@ TEST_F(LayerTreeHostCommonTest, TransformedClipParent) {
//
// The render surface should be resized correctly and the clip child should
// inherit the right clip rect.
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> render_surface = Layer::Create();
- scoped_refptr<Layer> clip_parent = Layer::Create();
- scoped_refptr<Layer> intervening = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> render_surface = Layer::Create(layer_settings());
+ scoped_refptr<Layer> clip_parent = Layer::Create(layer_settings());
+ scoped_refptr<Layer> intervening = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> clip_child =
- make_scoped_refptr(new LayerWithForcedDrawsContent);
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(render_surface);
render_surface->AddChild(clip_parent);
@@ -6584,8 +5508,7 @@ TEST_F(LayerTreeHostCommonTest, TransformedClipParent) {
true,
false);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
ExecuteCalculateDrawProperties(root.get());
@@ -6626,13 +5549,13 @@ TEST_F(LayerTreeHostCommonTest, ClipParentWithInterveningRenderSurface) {
// + render_surface2 (also sets opacity)
// + clip_child
//
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> clip_parent = Layer::Create();
- scoped_refptr<Layer> render_surface1 = Layer::Create();
- scoped_refptr<Layer> intervening = Layer::Create();
- scoped_refptr<Layer> render_surface2 = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> clip_parent = Layer::Create(layer_settings());
+ scoped_refptr<Layer> render_surface1 = Layer::Create(layer_settings());
+ scoped_refptr<Layer> intervening = Layer::Create(layer_settings());
+ scoped_refptr<Layer> render_surface2 = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> clip_child =
- make_scoped_refptr(new LayerWithForcedDrawsContent);
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(clip_parent);
clip_parent->AddChild(render_surface1);
@@ -6695,8 +5618,7 @@ TEST_F(LayerTreeHostCommonTest, ClipParentWithInterveningRenderSurface) {
true,
false);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
ExecuteCalculateDrawProperties(root.get());
@@ -6737,7 +5659,7 @@ TEST_F(LayerTreeHostCommonTest, ClipParentWithInterveningRenderSurface) {
EXPECT_EQ(gfx::Rect(-1, -1, 40, 40).ToString(),
clip_child->clip_rect().ToString());
EXPECT_EQ(gfx::Rect(9, 9, 40, 40).ToString(),
- clip_child->visible_content_rect().ToString());
+ clip_child->visible_layer_rect().ToString());
EXPECT_TRUE(clip_child->is_clipped());
}
@@ -6753,13 +5675,13 @@ TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) {
// + render_surface2 (also sets opacity)
// + clip_child
//
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> clip_parent = Layer::Create();
- scoped_refptr<Layer> render_surface1 = Layer::Create();
- scoped_refptr<Layer> intervening = Layer::Create();
- scoped_refptr<Layer> render_surface2 = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> clip_parent = Layer::Create(layer_settings());
+ scoped_refptr<Layer> render_surface1 = Layer::Create(layer_settings());
+ scoped_refptr<Layer> intervening = Layer::Create(layer_settings());
+ scoped_refptr<Layer> render_surface2 = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> clip_child =
- make_scoped_refptr(new LayerWithForcedDrawsContent);
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(clip_parent);
clip_parent->AddChild(render_surface1);
@@ -6824,8 +5746,7 @@ TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) {
true,
false);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
ExecuteCalculateDrawProperties(root.get());
@@ -6866,7 +5787,7 @@ TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) {
EXPECT_EQ(gfx::Rect(2, 2, 40, 40).ToString(),
clip_child->clip_rect().ToString());
EXPECT_EQ(gfx::Rect(12, 12, 40, 40).ToString(),
- clip_child->visible_content_rect().ToString());
+ clip_child->visible_layer_rect().ToString());
EXPECT_TRUE(clip_child->is_clipped());
}
@@ -6879,12 +5800,12 @@ TEST_F(LayerTreeHostCommonTest, DescendantsOfClipChildren) {
// + clip_child
// + child
//
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> clip_parent = Layer::Create();
- scoped_refptr<Layer> intervening = Layer::Create();
- scoped_refptr<Layer> clip_child = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> clip_parent = Layer::Create(layer_settings());
+ scoped_refptr<Layer> intervening = Layer::Create(layer_settings());
+ scoped_refptr<Layer> clip_child = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> child =
- make_scoped_refptr(new LayerWithForcedDrawsContent);
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(clip_parent);
clip_parent->AddChild(intervening);
@@ -6933,8 +5854,7 @@ TEST_F(LayerTreeHostCommonTest, DescendantsOfClipChildren) {
true,
false);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
ExecuteCalculateDrawProperties(root.get());
@@ -6946,7 +5866,7 @@ TEST_F(LayerTreeHostCommonTest, DescendantsOfClipChildren) {
clip_child->clip_rect().ToString());
EXPECT_TRUE(clip_child->is_clipped());
EXPECT_EQ(gfx::Rect(0, 0, 40, 40).ToString(),
- child->visible_content_rect().ToString());
+ child->visible_layer_rect().ToString());
EXPECT_TRUE(child->is_clipped());
}
@@ -6963,14 +5883,14 @@ TEST_F(LayerTreeHostCommonTest,
// + non_clip_child
//
// In this example render_surface2 should be unaffected by clip_child.
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> clip_parent = Layer::Create();
- scoped_refptr<Layer> render_surface1 = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> clip_parent = Layer::Create(layer_settings());
+ scoped_refptr<Layer> render_surface1 = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> clip_child =
- make_scoped_refptr(new LayerWithForcedDrawsContent);
- scoped_refptr<Layer> render_surface2 = Layer::Create();
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
+ scoped_refptr<Layer> render_surface2 = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> non_clip_child =
- make_scoped_refptr(new LayerWithForcedDrawsContent);
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(clip_parent);
clip_parent->AddChild(render_surface1);
@@ -7030,8 +5950,7 @@ TEST_F(LayerTreeHostCommonTest,
render_surface1->SetForceRenderSurface(true);
render_surface2->SetForceRenderSurface(true);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
ExecuteCalculateDrawProperties(root.get());
@@ -7063,14 +5982,16 @@ TEST_F(LayerTreeHostCommonTest,
render_surface2->render_surface()->content_rect().ToString());
// Sanity check our num_unclipped_descendants values.
- EXPECT_EQ(1, render_surface1->num_unclipped_descendants());
- EXPECT_EQ(0, render_surface2->num_unclipped_descendants());
+ EXPECT_EQ(1u, render_surface1->num_unclipped_descendants());
+ EXPECT_EQ(0u, render_surface2->num_unclipped_descendants());
}
TEST_F(LayerTreeHostCommonTest, CanRenderToSeparateSurface) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
scoped_ptr<LayerImpl> root =
LayerImpl::Create(host_impl.active_tree(), 12345);
scoped_ptr<LayerImpl> child1 =
@@ -7120,8 +6041,8 @@ TEST_F(LayerTreeHostCommonTest, CanRenderToSeparateSurface) {
int count_represents_target_render_surface = 0;
int count_represents_contributing_render_surface = 0;
int count_represents_itself = 0;
- auto end = LayerIterator<LayerImpl>::End(&render_surface_layer_list);
- for (auto it = LayerIterator<LayerImpl>::Begin(&render_surface_layer_list);
+ LayerIterator end = LayerIterator::End(&render_surface_layer_list);
+ for (LayerIterator it = LayerIterator::Begin(&render_surface_layer_list);
it != end; ++it) {
if (it.represents_target_render_surface())
count_represents_target_render_surface++;
@@ -7151,8 +6072,8 @@ TEST_F(LayerTreeHostCommonTest, CanRenderToSeparateSurface) {
int count_represents_target_render_surface = 0;
int count_represents_contributing_render_surface = 0;
int count_represents_itself = 0;
- auto end = LayerIterator<LayerImpl>::End(&render_surface_layer_list);
- for (auto it = LayerIterator<LayerImpl>::Begin(&render_surface_layer_list);
+ LayerIterator end = LayerIterator::End(&render_surface_layer_list);
+ for (LayerIterator it = LayerIterator::Begin(&render_surface_layer_list);
it != end; ++it) {
if (it.represents_target_render_surface())
count_represents_target_render_surface++;
@@ -7172,66 +6093,53 @@ TEST_F(LayerTreeHostCommonTest, CanRenderToSeparateSurface) {
}
TEST_F(LayerTreeHostCommonTest, DoNotIncludeBackfaceInvisibleSurfaces) {
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> render_surface = Layer::Create();
- scoped_refptr<LayerWithForcedDrawsContent> child =
- make_scoped_refptr(new LayerWithForcedDrawsContent);
-
- root->AddChild(render_surface);
- render_surface->AddChild(child);
+ LayerImpl* root = root_layer();
+ LayerImpl* render_surface = AddChild<LayerImpl>(root);
+ LayerImpl* child = AddChild<LayerImpl>(render_surface);
+ child->SetDrawsContent(true);
gfx::Transform identity_transform;
- SetLayerPropertiesForTesting(root.get(),
- identity_transform,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(50, 50),
- true,
- false);
- SetLayerPropertiesForTesting(render_surface.get(),
- identity_transform,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(30, 30),
- false,
+ SetLayerPropertiesForTesting(root, identity_transform, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(50, 50), true, false,
true);
- SetLayerPropertiesForTesting(child.get(),
- identity_transform,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(20, 20),
- true,
+ SetLayerPropertiesForTesting(render_surface, identity_transform,
+ gfx::Point3F(), gfx::PointF(), gfx::Size(30, 30),
+ false, true, true);
+ SetLayerPropertiesForTesting(child, identity_transform, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(20, 20), true, false,
false);
root->SetShouldFlattenTransform(false);
root->Set3dSortingContextId(1);
render_surface->SetDoubleSided(false);
- render_surface->SetForceRenderSurface(true);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ ExecuteCalculateDrawProperties(root);
- ExecuteCalculateDrawProperties(root.get());
-
- EXPECT_EQ(2u, render_surface_layer_list()->size());
- EXPECT_EQ(1u,
- render_surface_layer_list()->at(0)
- ->render_surface()->layer_list().size());
- EXPECT_EQ(1u,
- render_surface_layer_list()->at(1)
- ->render_surface()->layer_list().size());
+ EXPECT_EQ(2u, render_surface_layer_list_impl()->size());
+ EXPECT_EQ(1u, render_surface_layer_list_impl()
+ ->at(0)
+ ->render_surface()
+ ->layer_list()
+ .size());
+ EXPECT_EQ(1u, render_surface_layer_list_impl()
+ ->at(1)
+ ->render_surface()
+ ->layer_list()
+ .size());
gfx::Transform rotation_transform = identity_transform;
rotation_transform.RotateAboutXAxis(180.0);
render_surface->SetTransform(rotation_transform);
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawProperties(root);
- EXPECT_EQ(1u, render_surface_layer_list()->size());
- EXPECT_EQ(0u,
- render_surface_layer_list()->at(0)
- ->render_surface()->layer_list().size());
+ EXPECT_EQ(1u, render_surface_layer_list_impl()->size());
+ EXPECT_EQ(0u, render_surface_layer_list_impl()
+ ->at(0)
+ ->render_surface()
+ ->layer_list()
+ .size());
}
TEST_F(LayerTreeHostCommonTest, ClippedByScrollParent) {
@@ -7244,13 +6152,13 @@ TEST_F(LayerTreeHostCommonTest, ClippedByScrollParent) {
// | + scroll_parent
// + scroll_child
//
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> scroll_parent_border = Layer::Create();
- scoped_refptr<Layer> scroll_parent_clip = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> scroll_parent_border = Layer::Create(layer_settings());
+ scoped_refptr<Layer> scroll_parent_clip = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> scroll_parent =
- make_scoped_refptr(new LayerWithForcedDrawsContent);
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> scroll_child =
- make_scoped_refptr(new LayerWithForcedDrawsContent);
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(scroll_child);
@@ -7299,8 +6207,7 @@ TEST_F(LayerTreeHostCommonTest, ClippedByScrollParent) {
true,
false);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
ExecuteCalculateDrawProperties(root.get());
@@ -7313,11 +6220,11 @@ TEST_F(LayerTreeHostCommonTest, ClippedByScrollParent) {
TEST_F(LayerTreeHostCommonTest, SingularTransformSubtreesDoNotDraw) {
scoped_refptr<LayerWithForcedDrawsContent> root =
- make_scoped_refptr(new LayerWithForcedDrawsContent);
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> parent =
- make_scoped_refptr(new LayerWithForcedDrawsContent);
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> child =
- make_scoped_refptr(new LayerWithForcedDrawsContent);
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(parent);
parent->AddChild(child);
@@ -7348,8 +6255,7 @@ TEST_F(LayerTreeHostCommonTest, SingularTransformSubtreesDoNotDraw) {
true);
child->SetForceRenderSurface(true);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
ExecuteCalculateDrawProperties(root.get());
@@ -7380,70 +6286,45 @@ TEST_F(LayerTreeHostCommonTest, ClippedByOutOfOrderScrollParent) {
// still results in correct clipping.
//
// + root
- // + scroll_child
// + scroll_parent_border
// + scroll_parent_clip
// + scroll_parent
+ // + scroll_child
//
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> scroll_parent_border = Layer::Create();
- scoped_refptr<Layer> scroll_parent_clip = Layer::Create();
- scoped_refptr<LayerWithForcedDrawsContent> scroll_parent =
- make_scoped_refptr(new LayerWithForcedDrawsContent);
- scoped_refptr<LayerWithForcedDrawsContent> scroll_child =
- make_scoped_refptr(new LayerWithForcedDrawsContent);
-
- root->AddChild(scroll_parent_border);
- scroll_parent_border->AddChild(scroll_parent_clip);
- scroll_parent_clip->AddChild(scroll_parent);
+ LayerImpl* root = root_layer();
+ LayerImpl* scroll_parent_border = AddChild<LayerImpl>(root);
+ LayerImpl* scroll_parent_clip = AddChild<LayerImpl>(scroll_parent_border);
+ LayerImpl* scroll_parent = AddChild<LayerImpl>(scroll_parent_clip);
+ LayerImpl* scroll_child = AddChild<LayerImpl>(root);
- root->AddChild(scroll_child);
+ scroll_parent->SetDrawsContent(true);
+ scroll_child->SetDrawsContent(true);
scroll_parent_clip->SetMasksToBounds(true);
- scroll_child->SetScrollParent(scroll_parent.get());
+ scroll_child->SetScrollParent(scroll_parent);
+ scoped_ptr<std::set<LayerImpl*>> scroll_children(new std::set<LayerImpl*>);
+ scroll_children->insert(scroll_child);
+ scroll_parent->SetScrollChildren(scroll_children.release());
gfx::Transform identity_transform;
- SetLayerPropertiesForTesting(root.get(),
- identity_transform,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(50, 50),
- true,
- false);
- SetLayerPropertiesForTesting(scroll_parent_border.get(),
- identity_transform,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(40, 40),
- true,
- false);
- SetLayerPropertiesForTesting(scroll_parent_clip.get(),
- identity_transform,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(30, 30),
- true,
- false);
- SetLayerPropertiesForTesting(scroll_parent.get(),
- identity_transform,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(50, 50),
- true,
- false);
- SetLayerPropertiesForTesting(scroll_child.get(),
- identity_transform,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(50, 50),
- true,
+ SetLayerPropertiesForTesting(root, identity_transform, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(50, 50), true, false,
+ true);
+ SetLayerPropertiesForTesting(scroll_parent_border, identity_transform,
+ gfx::Point3F(), gfx::PointF(), gfx::Size(40, 40),
+ true, false, false);
+ SetLayerPropertiesForTesting(scroll_parent_clip, identity_transform,
+ gfx::Point3F(), gfx::PointF(), gfx::Size(30, 30),
+ true, false, false);
+ SetLayerPropertiesForTesting(scroll_parent, identity_transform,
+ gfx::Point3F(), gfx::PointF(), gfx::Size(50, 50),
+ true, false, false);
+ SetLayerPropertiesForTesting(scroll_child, identity_transform, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(50, 50), true, false,
false);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
-
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawProperties(root);
EXPECT_TRUE(root->render_surface());
@@ -7465,98 +6346,60 @@ TEST_F(LayerTreeHostCommonTest, ClippedByOutOfOrderScrollGrandparent) {
// + scroll_grandparent_clip
// + scroll_grandparent
//
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> scroll_parent_border = Layer::Create();
- scoped_refptr<Layer> scroll_parent_clip = Layer::Create();
- scoped_refptr<LayerWithForcedDrawsContent> scroll_parent =
- make_scoped_refptr(new LayerWithForcedDrawsContent);
-
- scoped_refptr<Layer> scroll_grandparent_border = Layer::Create();
- scoped_refptr<Layer> scroll_grandparent_clip = Layer::Create();
- scoped_refptr<LayerWithForcedDrawsContent> scroll_grandparent =
- make_scoped_refptr(new LayerWithForcedDrawsContent);
-
- scoped_refptr<LayerWithForcedDrawsContent> scroll_child =
- make_scoped_refptr(new LayerWithForcedDrawsContent);
-
- root->AddChild(scroll_child);
-
- root->AddChild(scroll_parent_border);
- scroll_parent_border->AddChild(scroll_parent_clip);
- scroll_parent_clip->AddChild(scroll_parent);
-
- root->AddChild(scroll_grandparent_border);
- scroll_grandparent_border->AddChild(scroll_grandparent_clip);
- scroll_grandparent_clip->AddChild(scroll_grandparent);
+ LayerImpl* root = root_layer();
+ LayerImpl* scroll_child = AddChild<LayerImpl>(root);
+ LayerImpl* scroll_parent_border = AddChild<LayerImpl>(root);
+ LayerImpl* scroll_parent_clip = AddChild<LayerImpl>(scroll_parent_border);
+ LayerImpl* scroll_parent = AddChild<LayerImpl>(scroll_parent_clip);
+ LayerImpl* scroll_grandparent_border = AddChild<LayerImpl>(root);
+ LayerImpl* scroll_grandparent_clip =
+ AddChild<LayerImpl>(scroll_grandparent_border);
+ LayerImpl* scroll_grandparent = AddChild<LayerImpl>(scroll_grandparent_clip);
+
+ scroll_parent->SetDrawsContent(true);
+ scroll_grandparent->SetDrawsContent(true);
+ scroll_child->SetDrawsContent(true);
scroll_parent_clip->SetMasksToBounds(true);
scroll_grandparent_clip->SetMasksToBounds(true);
- scroll_child->SetScrollParent(scroll_parent.get());
- scroll_parent_border->SetScrollParent(scroll_grandparent.get());
+ scroll_child->SetScrollParent(scroll_parent);
+ scoped_ptr<std::set<LayerImpl*>> scroll_children(new std::set<LayerImpl*>);
+ scroll_children->insert(scroll_child);
+ scroll_parent->SetScrollChildren(scroll_children.release());
+
+ scroll_parent_border->SetScrollParent(scroll_grandparent);
+ scroll_children.reset(new std::set<LayerImpl*>);
+ scroll_children->insert(scroll_parent_border);
+ scroll_grandparent->SetScrollChildren(scroll_children.release());
gfx::Transform identity_transform;
- SetLayerPropertiesForTesting(root.get(),
- identity_transform,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(50, 50),
- true,
- false);
- SetLayerPropertiesForTesting(scroll_grandparent_border.get(),
- identity_transform,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(40, 40),
- true,
- false);
- SetLayerPropertiesForTesting(scroll_grandparent_clip.get(),
- identity_transform,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(20, 20),
- true,
- false);
- SetLayerPropertiesForTesting(scroll_grandparent.get(),
- identity_transform,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(50, 50),
- true,
- false);
- SetLayerPropertiesForTesting(scroll_parent_border.get(),
- identity_transform,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(40, 40),
- true,
- false);
- SetLayerPropertiesForTesting(scroll_parent_clip.get(),
- identity_transform,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(30, 30),
- true,
- false);
- SetLayerPropertiesForTesting(scroll_parent.get(),
- identity_transform,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(50, 50),
- true,
- false);
- SetLayerPropertiesForTesting(scroll_child.get(),
- identity_transform,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(50, 50),
- true,
+ SetLayerPropertiesForTesting(root, identity_transform, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(50, 50), true, false,
+ true);
+ SetLayerPropertiesForTesting(scroll_grandparent_border, identity_transform,
+ gfx::Point3F(), gfx::PointF(), gfx::Size(40, 40),
+ true, false, false);
+ SetLayerPropertiesForTesting(scroll_grandparent_clip, identity_transform,
+ gfx::Point3F(), gfx::PointF(), gfx::Size(20, 20),
+ true, false, false);
+ SetLayerPropertiesForTesting(scroll_grandparent, identity_transform,
+ gfx::Point3F(), gfx::PointF(), gfx::Size(50, 50),
+ true, false, false);
+ SetLayerPropertiesForTesting(scroll_parent_border, identity_transform,
+ gfx::Point3F(), gfx::PointF(), gfx::Size(40, 40),
+ true, false, false);
+ SetLayerPropertiesForTesting(scroll_parent_clip, identity_transform,
+ gfx::Point3F(), gfx::PointF(), gfx::Size(30, 30),
+ true, false, false);
+ SetLayerPropertiesForTesting(scroll_parent, identity_transform,
+ gfx::Point3F(), gfx::PointF(), gfx::Size(50, 50),
+ true, false, false);
+ SetLayerPropertiesForTesting(scroll_child, identity_transform, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(50, 50), true, false,
false);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
-
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawProperties(root);
EXPECT_TRUE(root->render_surface());
@@ -7567,12 +6410,9 @@ TEST_F(LayerTreeHostCommonTest, ClippedByOutOfOrderScrollGrandparent) {
// Despite the fact that we visited the above layers out of order to get the
// correct clip, the layer lists should be unaffected.
EXPECT_EQ(3u, root->render_surface()->layer_list().size());
- EXPECT_EQ(scroll_child.get(),
- root->render_surface()->layer_list().at(0).get());
- EXPECT_EQ(scroll_parent.get(),
- root->render_surface()->layer_list().at(1).get());
- EXPECT_EQ(scroll_grandparent.get(),
- root->render_surface()->layer_list().at(2).get());
+ EXPECT_EQ(scroll_child, root->render_surface()->layer_list().at(0));
+ EXPECT_EQ(scroll_parent, root->render_surface()->layer_list().at(1));
+ EXPECT_EQ(scroll_grandparent, root->render_surface()->layer_list().at(2));
}
TEST_F(LayerTreeHostCommonTest, OutOfOrderClippingRequiresRSLLSorting) {
@@ -7583,136 +6423,79 @@ TEST_F(LayerTreeHostCommonTest, OutOfOrderClippingRequiresRSLLSorting) {
// + scroll_parent_border
// + scroll_parent_clip
// + scroll_parent
- // + render_surface1
+ // + render_surface2
// + scroll_grandparent_border
// + scroll_grandparent_clip
// + scroll_grandparent
- // + render_surface2
+ // + render_surface1
//
- scoped_refptr<LayerWithForcedDrawsContent> root =
- make_scoped_refptr(new LayerWithForcedDrawsContent);
-
- scoped_refptr<Layer> scroll_parent_border = Layer::Create();
- scoped_refptr<Layer> scroll_parent_clip = Layer::Create();
- scoped_refptr<LayerWithForcedDrawsContent> scroll_parent =
- make_scoped_refptr(new LayerWithForcedDrawsContent);
- scoped_refptr<LayerWithForcedDrawsContent> render_surface1 =
- make_scoped_refptr(new LayerWithForcedDrawsContent);
-
- scoped_refptr<Layer> scroll_grandparent_border = Layer::Create();
- scoped_refptr<Layer> scroll_grandparent_clip = Layer::Create();
- scoped_refptr<LayerWithForcedDrawsContent> scroll_grandparent =
- make_scoped_refptr(new LayerWithForcedDrawsContent);
- scoped_refptr<LayerWithForcedDrawsContent> render_surface2 =
- make_scoped_refptr(new LayerWithForcedDrawsContent);
-
- scoped_refptr<LayerWithForcedDrawsContent> scroll_child =
- make_scoped_refptr(new LayerWithForcedDrawsContent);
+ LayerImpl* root = root_layer();
+ root->SetDrawsContent(true);
- root->AddChild(scroll_child);
+ LayerImpl* scroll_child = AddChild<LayerImpl>(root);
+ scroll_child->SetDrawsContent(true);
- root->AddChild(scroll_parent_border);
- scroll_parent_border->AddChild(scroll_parent_clip);
- scroll_parent_clip->AddChild(scroll_parent);
- scroll_parent->AddChild(render_surface2);
+ LayerImpl* scroll_parent_border = AddChild<LayerImpl>(root);
+ LayerImpl* scroll_parent_clip = AddChild<LayerImpl>(scroll_parent_border);
+ LayerImpl* scroll_parent = AddChild<LayerImpl>(scroll_parent_clip);
+ LayerImpl* render_surface2 = AddChild<LayerImpl>(scroll_parent);
+ LayerImpl* scroll_grandparent_border = AddChild<LayerImpl>(root);
+ LayerImpl* scroll_grandparent_clip =
+ AddChild<LayerImpl>(scroll_grandparent_border);
+ LayerImpl* scroll_grandparent = AddChild<LayerImpl>(scroll_grandparent_clip);
+ LayerImpl* render_surface1 = AddChild<LayerImpl>(scroll_grandparent);
- root->AddChild(scroll_grandparent_border);
- scroll_grandparent_border->AddChild(scroll_grandparent_clip);
- scroll_grandparent_clip->AddChild(scroll_grandparent);
- scroll_grandparent->AddChild(render_surface1);
+ scroll_parent->SetDrawsContent(true);
+ render_surface1->SetDrawsContent(true);
+ scroll_grandparent->SetDrawsContent(true);
+ render_surface2->SetDrawsContent(true);
scroll_parent_clip->SetMasksToBounds(true);
scroll_grandparent_clip->SetMasksToBounds(true);
- scroll_child->SetScrollParent(scroll_parent.get());
- scroll_parent_border->SetScrollParent(scroll_grandparent.get());
+ scroll_child->SetScrollParent(scroll_parent);
+ scoped_ptr<std::set<LayerImpl*>> scroll_children(new std::set<LayerImpl*>);
+ scroll_children->insert(scroll_child);
+ scroll_parent->SetScrollChildren(scroll_children.release());
- render_surface1->SetForceRenderSurface(true);
- render_surface2->SetForceRenderSurface(true);
+ scroll_parent_border->SetScrollParent(scroll_grandparent);
+ scroll_children.reset(new std::set<LayerImpl*>);
+ scroll_children->insert(scroll_parent_border);
+ scroll_grandparent->SetScrollChildren(scroll_children.release());
gfx::Transform identity_transform;
- SetLayerPropertiesForTesting(root.get(),
- identity_transform,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(50, 50),
- true,
- false);
- SetLayerPropertiesForTesting(scroll_grandparent_border.get(),
- identity_transform,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(40, 40),
- true,
- false);
- SetLayerPropertiesForTesting(scroll_grandparent_clip.get(),
- identity_transform,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(20, 20),
- true,
- false);
- SetLayerPropertiesForTesting(scroll_grandparent.get(),
- identity_transform,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(50, 50),
- true,
- false);
- SetLayerPropertiesForTesting(render_surface1.get(),
- identity_transform,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(50, 50),
- true,
- false);
- SetLayerPropertiesForTesting(scroll_parent_border.get(),
- identity_transform,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(40, 40),
- true,
- false);
- SetLayerPropertiesForTesting(scroll_parent_clip.get(),
- identity_transform,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(30, 30),
- true,
- false);
- SetLayerPropertiesForTesting(scroll_parent.get(),
- identity_transform,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(50, 50),
- true,
- false);
- SetLayerPropertiesForTesting(render_surface2.get(),
- identity_transform,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(50, 50),
- true,
- false);
- SetLayerPropertiesForTesting(scroll_child.get(),
- identity_transform,
- gfx::Point3F(),
- gfx::PointF(),
- gfx::Size(50, 50),
- true,
+ SetLayerPropertiesForTesting(root, identity_transform, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(50, 50), true, false,
+ true);
+ SetLayerPropertiesForTesting(scroll_grandparent_border, identity_transform,
+ gfx::Point3F(), gfx::PointF(), gfx::Size(40, 40),
+ true, false, false);
+ SetLayerPropertiesForTesting(scroll_grandparent_clip, identity_transform,
+ gfx::Point3F(), gfx::PointF(), gfx::Size(20, 20),
+ true, false, false);
+ SetLayerPropertiesForTesting(scroll_grandparent, identity_transform,
+ gfx::Point3F(), gfx::PointF(), gfx::Size(50, 50),
+ true, false, false);
+ SetLayerPropertiesForTesting(render_surface1, identity_transform,
+ gfx::Point3F(), gfx::PointF(), gfx::Size(50, 50),
+ true, false, true);
+ SetLayerPropertiesForTesting(scroll_parent_border, identity_transform,
+ gfx::Point3F(), gfx::PointF(), gfx::Size(40, 40),
+ true, false, false);
+ SetLayerPropertiesForTesting(scroll_parent_clip, identity_transform,
+ gfx::Point3F(), gfx::PointF(), gfx::Size(30, 30),
+ true, false, false);
+ SetLayerPropertiesForTesting(scroll_parent, identity_transform,
+ gfx::Point3F(), gfx::PointF(), gfx::Size(50, 50),
+ true, false, false);
+ SetLayerPropertiesForTesting(render_surface2, identity_transform,
+ gfx::Point3F(), gfx::PointF(), gfx::Size(50, 50),
+ true, false, true);
+ SetLayerPropertiesForTesting(scroll_child, identity_transform, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(50, 50), true, false,
false);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
-
- RenderSurfaceLayerList render_surface_layer_list;
- LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
- root.get(),
- root->bounds(),
- identity_transform,
- &render_surface_layer_list);
-
- LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+ ExecuteCalculateDrawProperties(root);
EXPECT_TRUE(root->render_surface());
@@ -7722,13 +6505,13 @@ TEST_F(LayerTreeHostCommonTest, OutOfOrderClippingRequiresRSLLSorting) {
// Despite the fact that we had to process the layers out of order to get the
// right clip, our render_surface_layer_list's order should be unaffected.
- EXPECT_EQ(3u, render_surface_layer_list.size());
- EXPECT_EQ(root.get(), render_surface_layer_list.at(0));
- EXPECT_EQ(render_surface2.get(), render_surface_layer_list.at(1));
- EXPECT_EQ(render_surface1.get(), render_surface_layer_list.at(2));
- EXPECT_TRUE(render_surface_layer_list.at(0)->render_surface());
- EXPECT_TRUE(render_surface_layer_list.at(1)->render_surface());
- EXPECT_TRUE(render_surface_layer_list.at(2)->render_surface());
+ EXPECT_EQ(3u, render_surface_layer_list_impl()->size());
+ EXPECT_EQ(root, render_surface_layer_list_impl()->at(0));
+ EXPECT_EQ(render_surface2, render_surface_layer_list_impl()->at(1));
+ EXPECT_EQ(render_surface1, render_surface_layer_list_impl()->at(2));
+ EXPECT_TRUE(render_surface_layer_list_impl()->at(0)->render_surface());
+ EXPECT_TRUE(render_surface_layer_list_impl()->at(1)->render_surface());
+ EXPECT_TRUE(render_surface_layer_list_impl()->at(2)->render_surface());
}
TEST_F(LayerTreeHostCommonTest, FixedPositionWithInterveningRenderSurface) {
@@ -7742,13 +6525,13 @@ TEST_F(LayerTreeHostCommonTest, FixedPositionWithInterveningRenderSurface) {
// + fixed
// + child
//
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> render_surface =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> fixed =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> child =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(render_surface);
render_surface->AddChild(fixed);
@@ -7773,8 +6556,7 @@ TEST_F(LayerTreeHostCommonTest, FixedPositionWithInterveningRenderSurface) {
gfx::PointF(1.f, 2.f), gfx::Size(50, 50), true,
false);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
ExecuteCalculateDrawProperties(root.get());
@@ -7808,7 +6590,9 @@ TEST_F(LayerTreeHostCommonTest, ScrollCompensationWithRounding) {
//
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
host_impl.CreatePendingTree();
scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
scoped_ptr<LayerImpl> container =
@@ -7952,7 +6736,9 @@ TEST_F(LayerTreeHostCommonTest,
//
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
host_impl.CreatePendingTree();
scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
scoped_ptr<LayerImpl> container =
@@ -8046,7 +6832,9 @@ class AnimationScaleFactorTrackingLayerImpl : public LayerImpl {
TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
gfx::Transform identity_matrix;
scoped_ptr<AnimationScaleFactorTrackingLayerImpl> grand_parent =
AnimationScaleFactorTrackingLayerImpl::Create(host_impl.active_tree(), 1);
@@ -8178,6 +6966,7 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) {
scale_matrix.Scale(1.f, 2.f);
grand_parent->SetTransform(scale_matrix);
parent_raw->SetTransform(scale_matrix);
+ grand_parent->layer_tree_impl()->property_trees()->needs_rebuild = true;
AddAnimatedTransformToLayer(parent_raw, 1.0, TransformOperations(), scale);
ExecuteCalculateDrawProperties(grand_parent.get());
@@ -8196,6 +6985,7 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) {
gfx::Transform perspective_matrix;
perspective_matrix.ApplyPerspectiveDepth(2.f);
child_raw->SetTransform(perspective_matrix);
+ grand_parent->layer_tree_impl()->property_trees()->needs_rebuild = true;
ExecuteCalculateDrawProperties(grand_parent.get());
// |child| has a transform that's neither a translation nor a scale.
@@ -8208,6 +6998,7 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) {
0.f, grand_child_raw->draw_properties().maximum_animation_contents_scale);
parent_raw->SetTransform(perspective_matrix);
+ grand_parent->layer_tree_impl()->property_trees()->needs_rebuild = true;
ExecuteCalculateDrawProperties(grand_parent.get());
// |parent| and |child| have transforms that are neither translations nor
@@ -8223,6 +7014,7 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) {
parent_raw->SetTransform(identity_matrix);
child_raw->SetTransform(identity_matrix);
grand_parent->SetTransform(perspective_matrix);
+ grand_parent->layer_tree_impl()->property_trees()->needs_rebuild = true;
ExecuteCalculateDrawProperties(grand_parent.get());
@@ -8242,10 +7034,9 @@ static int membership_id(LayerImpl* layer) {
static void GatherDrawnLayers(LayerImplList* rsll,
std::set<LayerImpl*>* drawn_layers) {
- for (LayerIterator<LayerImpl> it = LayerIterator<LayerImpl>::Begin(rsll),
- end = LayerIterator<LayerImpl>::End(rsll);
- it != end;
- ++it) {
+ for (LayerIterator it = LayerIterator::Begin(rsll),
+ end = LayerIterator::End(rsll);
+ it != end; ++it) {
LayerImpl* layer = *it;
if (it.represents_itself())
drawn_layers->insert(layer);
@@ -8263,7 +7054,9 @@ static void GatherDrawnLayers(LayerImplList* rsll,
TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
gfx::Transform identity_matrix;
scoped_ptr<LayerImpl> grand_parent =
@@ -8506,7 +7299,11 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) {
TEST_F(LayerTreeHostCommonTest, DrawPropertyScales) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ LayerTreeSettings settings;
+ settings.layer_transforms_should_scale_layer_contents = true;
+ FakeLayerTreeHostImpl host_impl(settings, &proxy, &shared_bitmap_manager,
+ &task_graph_runner);
scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
LayerImpl* root_layer = root.get();
@@ -8553,16 +7350,10 @@ TEST_F(LayerTreeHostCommonTest, DrawPropertyScales) {
ExecuteCalculateDrawProperties(root_layer);
- EXPECT_FLOAT_EQ(1.f, root_layer->draw_properties().ideal_contents_scale);
- EXPECT_FLOAT_EQ(3.f, child1_layer->draw_properties().ideal_contents_scale);
- EXPECT_FLOAT_EQ(
- 3.f, child1_layer->mask_layer()->draw_properties().ideal_contents_scale);
- EXPECT_FLOAT_EQ(3.f,
- child1_layer->replica_layer()
- ->mask_layer()
- ->draw_properties()
- .ideal_contents_scale);
- EXPECT_FLOAT_EQ(5.f, child2_layer->draw_properties().ideal_contents_scale);
+ EXPECT_FLOAT_EQ(1.f, root_layer->GetIdealContentsScale());
+ EXPECT_FLOAT_EQ(3.f, child1_layer->GetIdealContentsScale());
+ EXPECT_FLOAT_EQ(3.f, child1_layer->mask_layer()->GetIdealContentsScale());
+ EXPECT_FLOAT_EQ(5.f, child2_layer->GetIdealContentsScale());
EXPECT_FLOAT_EQ(
0.f, root_layer->draw_properties().maximum_animation_contents_scale);
@@ -8580,28 +7371,6 @@ TEST_F(LayerTreeHostCommonTest, DrawPropertyScales) {
EXPECT_FLOAT_EQ(
8.f, child2_layer->draw_properties().maximum_animation_contents_scale);
- EXPECT_FLOAT_EQ(1.f, root_layer->draw_properties().page_scale_factor);
- EXPECT_FLOAT_EQ(1.f, child1_layer->draw_properties().page_scale_factor);
- EXPECT_FLOAT_EQ(
- 1.f, child1_layer->mask_layer()->draw_properties().page_scale_factor);
- EXPECT_FLOAT_EQ(1.f,
- child1_layer->replica_layer()
- ->mask_layer()
- ->draw_properties()
- .page_scale_factor);
- EXPECT_FLOAT_EQ(1.f, child2_layer->draw_properties().page_scale_factor);
-
- EXPECT_FLOAT_EQ(1.f, root_layer->draw_properties().device_scale_factor);
- EXPECT_FLOAT_EQ(1.f, child1_layer->draw_properties().device_scale_factor);
- EXPECT_FLOAT_EQ(
- 1.f, child1_layer->mask_layer()->draw_properties().device_scale_factor);
- EXPECT_FLOAT_EQ(1.f,
- child1_layer->replica_layer()
- ->mask_layer()
- ->draw_properties()
- .device_scale_factor);
- EXPECT_FLOAT_EQ(1.f, child2_layer->draw_properties().device_scale_factor);
-
// Changing page-scale would affect ideal_contents_scale and
// maximum_animation_contents_scale.
@@ -8616,19 +7385,16 @@ TEST_F(LayerTreeHostCommonTest, DrawPropertyScales) {
inputs.page_scale_factor = page_scale_factor;
inputs.can_adjust_raster_scales = true;
- inputs.page_scale_application_layer = root_layer;
+ inputs.page_scale_layer = root_layer;
LayerTreeHostCommon::CalculateDrawProperties(&inputs);
- EXPECT_FLOAT_EQ(1.f, root_layer->draw_properties().ideal_contents_scale);
- EXPECT_FLOAT_EQ(9.f, child1_layer->draw_properties().ideal_contents_scale);
+ EXPECT_FLOAT_EQ(3.f, root_layer->GetIdealContentsScale());
+ EXPECT_FLOAT_EQ(9.f, child1_layer->GetIdealContentsScale());
+ EXPECT_FLOAT_EQ(9.f, child1_layer->mask_layer()->GetIdealContentsScale());
EXPECT_FLOAT_EQ(
- 9.f, child1_layer->mask_layer()->draw_properties().ideal_contents_scale);
- EXPECT_FLOAT_EQ(9.f,
- child1_layer->replica_layer()
- ->mask_layer()
- ->draw_properties()
- .ideal_contents_scale);
- EXPECT_FLOAT_EQ(15.f, child2_layer->draw_properties().ideal_contents_scale);
+ 9.f,
+ child1_layer->replica_layer()->mask_layer()->GetIdealContentsScale());
+ EXPECT_FLOAT_EQ(15.f, child2_layer->GetIdealContentsScale());
EXPECT_FLOAT_EQ(
0.f, root_layer->draw_properties().maximum_animation_contents_scale);
@@ -8646,28 +7412,6 @@ TEST_F(LayerTreeHostCommonTest, DrawPropertyScales) {
EXPECT_FLOAT_EQ(
24.f, child2_layer->draw_properties().maximum_animation_contents_scale);
- EXPECT_FLOAT_EQ(1.f, root_layer->draw_properties().page_scale_factor);
- EXPECT_FLOAT_EQ(3.f, child1_layer->draw_properties().page_scale_factor);
- EXPECT_FLOAT_EQ(
- 3.f, child1_layer->mask_layer()->draw_properties().page_scale_factor);
- EXPECT_FLOAT_EQ(3.f,
- child1_layer->replica_layer()
- ->mask_layer()
- ->draw_properties()
- .page_scale_factor);
- EXPECT_FLOAT_EQ(3.f, child2_layer->draw_properties().page_scale_factor);
-
- EXPECT_FLOAT_EQ(1.f, root_layer->draw_properties().device_scale_factor);
- EXPECT_FLOAT_EQ(1.f, child1_layer->draw_properties().device_scale_factor);
- EXPECT_FLOAT_EQ(
- 1.f, child1_layer->mask_layer()->draw_properties().device_scale_factor);
- EXPECT_FLOAT_EQ(1.f,
- child1_layer->replica_layer()
- ->mask_layer()
- ->draw_properties()
- .device_scale_factor);
- EXPECT_FLOAT_EQ(1.f, child2_layer->draw_properties().device_scale_factor);
-
// Changing device-scale would affect ideal_contents_scale and
// maximum_animation_contents_scale.
@@ -8676,16 +7420,13 @@ TEST_F(LayerTreeHostCommonTest, DrawPropertyScales) {
inputs.can_adjust_raster_scales = true;
LayerTreeHostCommon::CalculateDrawProperties(&inputs);
- EXPECT_FLOAT_EQ(4.f, root_layer->draw_properties().ideal_contents_scale);
- EXPECT_FLOAT_EQ(36.f, child1_layer->draw_properties().ideal_contents_scale);
+ EXPECT_FLOAT_EQ(12.f, root_layer->GetIdealContentsScale());
+ EXPECT_FLOAT_EQ(36.f, child1_layer->GetIdealContentsScale());
+ EXPECT_FLOAT_EQ(36.f, child1_layer->mask_layer()->GetIdealContentsScale());
EXPECT_FLOAT_EQ(
- 36.f, child1_layer->mask_layer()->draw_properties().ideal_contents_scale);
- EXPECT_FLOAT_EQ(36.f,
- child1_layer->replica_layer()
- ->mask_layer()
- ->draw_properties()
- .ideal_contents_scale);
- EXPECT_FLOAT_EQ(60.f, child2_layer->draw_properties().ideal_contents_scale);
+ 36.f,
+ child1_layer->replica_layer()->mask_layer()->GetIdealContentsScale());
+ EXPECT_FLOAT_EQ(60.f, child2_layer->GetIdealContentsScale());
EXPECT_FLOAT_EQ(
0.f, root_layer->draw_properties().maximum_animation_contents_scale);
@@ -8702,32 +7443,10 @@ TEST_F(LayerTreeHostCommonTest, DrawPropertyScales) {
.maximum_animation_contents_scale);
EXPECT_FLOAT_EQ(
96.f, child2_layer->draw_properties().maximum_animation_contents_scale);
-
- EXPECT_FLOAT_EQ(1.f, root_layer->draw_properties().page_scale_factor);
- EXPECT_FLOAT_EQ(3.f, child1_layer->draw_properties().page_scale_factor);
- EXPECT_FLOAT_EQ(
- 3.f, child1_layer->mask_layer()->draw_properties().page_scale_factor);
- EXPECT_FLOAT_EQ(3.f,
- child1_layer->replica_layer()
- ->mask_layer()
- ->draw_properties()
- .page_scale_factor);
- EXPECT_FLOAT_EQ(3.f, child2_layer->draw_properties().page_scale_factor);
-
- EXPECT_FLOAT_EQ(4.f, root_layer->draw_properties().device_scale_factor);
- EXPECT_FLOAT_EQ(4.f, child1_layer->draw_properties().device_scale_factor);
- EXPECT_FLOAT_EQ(
- 4.f, child1_layer->mask_layer()->draw_properties().device_scale_factor);
- EXPECT_FLOAT_EQ(4.f,
- child1_layer->replica_layer()
- ->mask_layer()
- ->draw_properties()
- .device_scale_factor);
- EXPECT_FLOAT_EQ(4.f, child2_layer->draw_properties().device_scale_factor);
}
TEST_F(LayerTreeHostCommonTest, VisibleContentRectInChildRenderSurface) {
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(root.get(),
gfx::Transform(),
gfx::Point3F(),
@@ -8737,7 +7456,7 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectInChildRenderSurface) {
false);
root->SetIsDrawable(true);
- scoped_refptr<Layer> clip = Layer::Create();
+ scoped_refptr<Layer> clip = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(clip.get(),
gfx::Transform(),
gfx::Point3F(),
@@ -8747,7 +7466,7 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectInChildRenderSurface) {
false);
clip->SetMasksToBounds(true);
- scoped_refptr<Layer> content = Layer::Create();
+ scoped_refptr<Layer> content = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(content.get(),
gfx::Transform(),
gfx::Point3F(),
@@ -8761,32 +7480,32 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectInChildRenderSurface) {
root->AddChild(clip);
clip->AddChild(content);
- FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
- scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(&client);
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
gfx::Size device_viewport_size(768, 582);
RenderSurfaceLayerList render_surface_layer_list;
LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
- host->root_layer(), device_viewport_size, &render_surface_layer_list);
+ host()->root_layer(), device_viewport_size, &render_surface_layer_list);
inputs.device_scale_factor = 2.f;
inputs.page_scale_factor = 1.f;
- inputs.page_scale_application_layer = NULL;
+ inputs.page_scale_layer = NULL;
LayerTreeHostCommon::CalculateDrawProperties(&inputs);
// Layers in the root render surface have their visible content rect clipped
// by the viewport.
- EXPECT_EQ(gfx::Rect(768 / 2, 582 / 2), root->visible_content_rect());
+ EXPECT_EQ(gfx::Rect(768 / 2, 582 / 2), root->visible_layer_rect());
// Layers drawing to a child render surface should still have their visible
// content rect clipped by the viewport.
- EXPECT_EQ(gfx::Rect(768 / 2, 582 / 2), content->visible_content_rect());
+ EXPECT_EQ(gfx::Rect(768 / 2, 582 / 2), content->visible_layer_rect());
}
TEST_F(LayerTreeHostCommonTest, BoundsDeltaAffectVisibleContentRect) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
// Set two layers: the root layer clips it's child,
// the child draws its content.
@@ -8800,6 +7519,7 @@ TEST_F(LayerTreeHostCommonTest, BoundsDeltaAffectVisibleContentRect) {
gfx::Size device_viewport_size = gfx::Size(300, 600);
gfx::Transform identity_matrix;
+ host_impl.SetViewportSize(device_viewport_size);
host_impl.active_tree()->SetRootLayer(
LayerImpl::Create(host_impl.active_tree(), 1));
@@ -8812,8 +7532,6 @@ TEST_F(LayerTreeHostCommonTest, BoundsDeltaAffectVisibleContentRect) {
false,
false,
true);
-
- root->SetContentBounds(root_size);
root->SetMasksToBounds(true);
root->AddChild(LayerImpl::Create(host_impl.active_tree(), 2));
@@ -8827,8 +7545,6 @@ TEST_F(LayerTreeHostCommonTest, BoundsDeltaAffectVisibleContentRect) {
false,
false,
false);
-
- sublayer->SetContentBounds(sublayer_size);
sublayer->SetDrawsContent(true);
LayerImplList layer_impl_list;
@@ -8837,7 +7553,7 @@ TEST_F(LayerTreeHostCommonTest, BoundsDeltaAffectVisibleContentRect) {
LayerTreeHostCommon::CalculateDrawProperties(&inputs);
- EXPECT_EQ(gfx::Rect(root_size), sublayer->visible_content_rect());
+ EXPECT_EQ(gfx::Rect(root_size), sublayer->visible_layer_rect());
root->SetBoundsDelta(gfx::Vector2dF(0.0, 50.0));
@@ -8845,19 +7561,80 @@ TEST_F(LayerTreeHostCommonTest, BoundsDeltaAffectVisibleContentRect) {
gfx::Rect affected_by_delta(0, 0, root_size.width(),
root_size.height() + 50);
- EXPECT_EQ(affected_by_delta, sublayer->visible_content_rect());
+ EXPECT_EQ(affected_by_delta, sublayer->visible_layer_rect());
+}
+
+TEST_F(LayerTreeHostCommonTest, NodesAffectedByBoundsDeltaGetUpdated) {
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> inner_viewport_container_layer =
+ Layer::Create(layer_settings());
+ scoped_refptr<Layer> inner_viewport_scroll_layer =
+ Layer::Create(layer_settings());
+ scoped_refptr<Layer> outer_viewport_container_layer =
+ Layer::Create(layer_settings());
+ scoped_refptr<Layer> outer_viewport_scroll_layer =
+ Layer::Create(layer_settings());
+
+ root->AddChild(inner_viewport_container_layer);
+ inner_viewport_container_layer->AddChild(inner_viewport_scroll_layer);
+ inner_viewport_scroll_layer->AddChild(outer_viewport_container_layer);
+ outer_viewport_container_layer->AddChild(outer_viewport_scroll_layer);
+
+ inner_viewport_scroll_layer->SetScrollClipLayerId(
+ inner_viewport_container_layer->id());
+ outer_viewport_scroll_layer->SetScrollClipLayerId(
+ outer_viewport_container_layer->id());
+
+ inner_viewport_scroll_layer->SetIsContainerForFixedPositionLayers(true);
+ outer_viewport_scroll_layer->SetIsContainerForFixedPositionLayers(true);
+
+ host()->SetRootLayer(root);
+ host()->RegisterViewportLayers(nullptr, root, inner_viewport_scroll_layer,
+ outer_viewport_scroll_layer);
+
+ scoped_refptr<Layer> fixed_to_inner = Layer::Create(layer_settings());
+ scoped_refptr<Layer> fixed_to_outer = Layer::Create(layer_settings());
+
+ inner_viewport_scroll_layer->AddChild(fixed_to_inner);
+ outer_viewport_scroll_layer->AddChild(fixed_to_outer);
+
+ LayerPositionConstraint fixed_to_right;
+ fixed_to_right.set_is_fixed_position(true);
+ fixed_to_right.set_is_fixed_to_right_edge(true);
+
+ fixed_to_inner->SetPositionConstraint(fixed_to_right);
+ fixed_to_outer->SetPositionConstraint(fixed_to_right);
+
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
+
+ TransformTree& transform_tree = host()->property_trees()->transform_tree;
+ EXPECT_TRUE(transform_tree.HasNodesAffectedByInnerViewportBoundsDelta());
+ EXPECT_TRUE(transform_tree.HasNodesAffectedByOuterViewportBoundsDelta());
+
+ LayerPositionConstraint fixed_to_left;
+ fixed_to_left.set_is_fixed_position(true);
+ fixed_to_inner->SetPositionConstraint(fixed_to_left);
+
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
+ EXPECT_FALSE(transform_tree.HasNodesAffectedByInnerViewportBoundsDelta());
+ EXPECT_TRUE(transform_tree.HasNodesAffectedByOuterViewportBoundsDelta());
+
+ fixed_to_outer->SetPositionConstraint(fixed_to_left);
+
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
+ EXPECT_FALSE(transform_tree.HasNodesAffectedByInnerViewportBoundsDelta());
+ EXPECT_FALSE(transform_tree.HasNodesAffectedByOuterViewportBoundsDelta());
}
TEST_F(LayerTreeHostCommonTest, VisibleContentRectForAnimatedLayer) {
const gfx::Transform identity_matrix;
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> animated =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(animated);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
SetLayerPropertiesForTesting(root.get(), identity_matrix, gfx::Point3F(),
gfx::PointF(), gfx::Size(100, 100), true, false);
@@ -8871,7 +7648,7 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectForAnimatedLayer) {
AddOpacityTransitionToController(animated->layer_animation_controller(), 10.0,
0.f, 1.f, false);
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
EXPECT_FALSE(animated->visible_rect_from_property_trees().IsEmpty());
}
@@ -8879,14 +7656,14 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectForAnimatedLayer) {
TEST_F(LayerTreeHostCommonTest,
VisibleContentRectForAnimatedLayerWithSingularTransform) {
const gfx::Transform identity_matrix;
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> clip = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> clip = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> animated =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> surface =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> descendant_of_animation =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(clip);
clip->AddChild(animated);
@@ -8896,8 +7673,7 @@ TEST_F(LayerTreeHostCommonTest,
clip->SetMasksToBounds(true);
surface->SetForceRenderSurface(true);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
gfx::Transform uninvertible_matrix;
uninvertible_matrix.Scale3d(6.f, 6.f, 0.f);
@@ -8922,7 +7698,7 @@ TEST_F(LayerTreeHostCommonTest,
AddAnimatedTransformToLayer(animated.get(), 10.0, start_transform_operations,
end_transform_operations);
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
// The animated layer has a singular transform and maps to a non-empty rect in
// clipped target space, so is treated as fully visible.
@@ -8939,7 +7715,7 @@ TEST_F(LayerTreeHostCommonTest,
SetLayerPropertiesForTesting(animated.get(), zero_matrix, gfx::Point3F(),
gfx::PointF(), gfx::Size(120, 120), true, false);
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
// The animated layer maps to the empty rect in clipped target space, so is
// treated as having an empty visible rect.
@@ -8956,9 +7732,9 @@ TEST_F(LayerTreeHostCommonTest,
// Verify that having an animated filter (but no current filter, as these
// are mutually exclusive) correctly creates a render surface.
TEST_F(LayerTreeHostCommonTest, AnimatedFilterCreatesRenderSurface) {
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> child = Layer::Create();
- scoped_refptr<Layer> grandchild = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
+ scoped_refptr<Layer> grandchild = Layer::Create(layer_settings());
root->AddChild(child);
child->AddChild(grandchild);
@@ -8970,8 +7746,7 @@ TEST_F(LayerTreeHostCommonTest, AnimatedFilterCreatesRenderSurface) {
SetLayerPropertiesForTesting(grandchild.get(), identity_transform,
gfx::Point3F(), gfx::PointF(), gfx::Size(50, 50),
true, false);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
AddAnimatedFilterToLayer(child.get(), 10.0, 0.1f, 0.2f);
@@ -8993,10 +7768,10 @@ TEST_F(LayerTreeHostCommonTest, AnimatedFilterCreatesRenderSurface) {
// Ensures that the property tree code accounts for offsets between fixed
// position layers and their respective containers.
TEST_F(LayerTreeHostCommonTest, PropertyTreesAccountForFixedParentOffset) {
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> child = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> grandchild =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(child);
child->AddChild(grandchild);
@@ -9019,10 +7794,49 @@ TEST_F(LayerTreeHostCommonTest, PropertyTreesAccountForFixedParentOffset) {
root->SetIsContainerForFixedPositionLayers(true);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
+
+ EXPECT_EQ(gfx::Rect(0, 0, 50, 50),
+ grandchild->visible_rect_from_property_trees());
+}
+
+// Ensures that the property tree code accounts for offsets between fixed
+// position containers and their transform tree parents, when a fixed position
+// layer's container is its layer tree parent, but this parent doesn't have its
+// own transform tree node.
+TEST_F(LayerTreeHostCommonTest,
+ PropertyTreesAccountForFixedParentOffsetWhenContainerIsParent) {
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
+ scoped_refptr<LayerWithForcedDrawsContent> grandchild =
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
+
+ root->AddChild(child);
+ child->AddChild(grandchild);
+
+ gfx::Transform identity_transform;
+ SetLayerPropertiesForTesting(root.get(), identity_transform, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(50, 50), true, false);
+ SetLayerPropertiesForTesting(child.get(), identity_transform, gfx::Point3F(),
+ gfx::PointF(1000, 1000), gfx::Size(50, 50), true,
+ false);
+ SetLayerPropertiesForTesting(grandchild.get(), identity_transform,
+ gfx::Point3F(), gfx::PointF(-1000, -1000),
+ gfx::Size(50, 50), true, false);
+
+ root->SetMasksToBounds(true);
+ child->SetIsContainerForFixedPositionLayers(true);
+ LayerPositionConstraint constraint;
+ constraint.set_is_fixed_position(true);
+ grandchild->SetPositionConstraint(constraint);
+
+ root->SetIsContainerForFixedPositionLayers(true);
+
+ host()->SetRootLayer(root);
+
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
EXPECT_EQ(gfx::Rect(0, 0, 50, 50),
grandchild->visible_rect_from_property_trees());
@@ -9038,35 +7852,35 @@ TEST_F(LayerTreeHostCommonTest, CombineClipsUsingContentTarget) {
rotate.Rotate(5);
gfx::Transform identity;
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(root.get(), identity, gfx::Point3F(),
gfx::PointF(), gfx::Size(2500, 1500), true,
false);
- scoped_refptr<Layer> frame_clip = Layer::Create();
+ scoped_refptr<Layer> frame_clip = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(frame_clip.get(), identity, gfx::Point3F(),
gfx::PointF(), gfx::Size(2500, 1500), true,
false);
frame_clip->SetMasksToBounds(true);
- scoped_refptr<Layer> rotated = Layer::Create();
+ scoped_refptr<Layer> rotated = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(rotated.get(), rotate,
gfx::Point3F(1250, 250, 0), gfx::PointF(),
gfx::Size(2500, 500), true, false);
- scoped_refptr<Layer> surface = Layer::Create();
+ scoped_refptr<Layer> surface = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(surface.get(), rotate, gfx::Point3F(),
gfx::PointF(), gfx::Size(2500, 500), true,
false);
surface->SetOpacity(0.5);
scoped_refptr<LayerWithForcedDrawsContent> container =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
SetLayerPropertiesForTesting(container.get(), identity, gfx::Point3F(),
gfx::PointF(), gfx::Size(300, 300), true, false);
scoped_refptr<LayerWithForcedDrawsContent> box =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
SetLayerPropertiesForTesting(box.get(), identity, gfx::Point3F(),
gfx::PointF(), gfx::Size(100, 100), true, false);
@@ -9076,8 +7890,7 @@ TEST_F(LayerTreeHostCommonTest, CombineClipsUsingContentTarget) {
surface->AddChild(container);
surface->AddChild(box);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
ExecuteCalculateDrawProperties(root.get());
}
@@ -9087,19 +7900,19 @@ TEST_F(LayerTreeHostCommonTest, OnlyApplyFixedPositioningOnce) {
gfx::Transform translate_z;
translate_z.Translate3d(0, 0, 10);
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(root.get(), identity, gfx::Point3F(),
gfx::PointF(), gfx::Size(800, 800), true, false);
root->SetIsContainerForFixedPositionLayers(true);
- scoped_refptr<Layer> frame_clip = Layer::Create();
+ scoped_refptr<Layer> frame_clip = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(frame_clip.get(), translate_z, gfx::Point3F(),
gfx::PointF(500, 100), gfx::Size(100, 100), true,
false);
frame_clip->SetMasksToBounds(true);
scoped_refptr<LayerWithForcedDrawsContent> fixed =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
SetLayerPropertiesForTesting(fixed.get(), identity, gfx::Point3F(),
gfx::PointF(), gfx::Size(1000, 1000), true,
false);
@@ -9111,10 +7924,9 @@ TEST_F(LayerTreeHostCommonTest, OnlyApplyFixedPositioningOnce) {
root->AddChild(frame_clip);
frame_clip->AddChild(fixed);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
gfx::Rect expected(0, 0, 100, 100);
EXPECT_EQ(expected, fixed->visible_rect_from_property_trees());
@@ -9126,19 +7938,19 @@ TEST_F(LayerTreeHostCommonTest,
gfx::Transform translate_z;
translate_z.Translate3d(0, 0, 10);
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(root.get(), identity, gfx::Point3F(),
gfx::PointF(), gfx::Size(800, 800), true, false);
root->SetIsContainerForFixedPositionLayers(true);
- scoped_refptr<Layer> frame_clip = Layer::Create();
+ scoped_refptr<Layer> frame_clip = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(frame_clip.get(), translate_z, gfx::Point3F(),
gfx::PointF(500, 100), gfx::Size(100, 100), true,
false);
frame_clip->SetMasksToBounds(true);
scoped_refptr<LayerWithForcedDrawsContent> scroller =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
SetLayerPropertiesForTesting(scroller.get(), identity, gfx::Point3F(),
gfx::PointF(), gfx::Size(1000, 1000), true,
false);
@@ -9148,7 +7960,7 @@ TEST_F(LayerTreeHostCommonTest,
scroller->SetScrollClipLayerId(frame_clip->id());
scoped_refptr<LayerWithForcedDrawsContent> fixed =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
SetLayerPropertiesForTesting(fixed.get(), identity, gfx::Point3F(),
gfx::PointF(), gfx::Size(50, 50), true, false);
@@ -9157,7 +7969,7 @@ TEST_F(LayerTreeHostCommonTest,
fixed->SetPositionConstraint(constraint);
scoped_refptr<LayerWithForcedDrawsContent> fixed_child =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
SetLayerPropertiesForTesting(fixed_child.get(), identity, gfx::Point3F(),
gfx::PointF(), gfx::Size(10, 10), true, false);
@@ -9168,10 +7980,9 @@ TEST_F(LayerTreeHostCommonTest,
scroller->AddChild(fixed);
fixed->AddChild(fixed_child);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
gfx::Rect expected(0, 0, 50, 50);
EXPECT_EQ(expected, fixed->visible_rect_from_property_trees());
@@ -9183,19 +7994,19 @@ TEST_F(LayerTreeHostCommonTest,
TEST_F(LayerTreeHostCommonTest, FixedClipsShouldBeAssociatedWithTheRightNode) {
gfx::Transform identity;
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(root.get(), identity, gfx::Point3F(),
gfx::PointF(), gfx::Size(800, 800), true, false);
root->SetIsContainerForFixedPositionLayers(true);
- scoped_refptr<Layer> frame_clip = Layer::Create();
+ scoped_refptr<Layer> frame_clip = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(frame_clip.get(), identity, gfx::Point3F(),
gfx::PointF(500, 100), gfx::Size(100, 100), true,
false);
frame_clip->SetMasksToBounds(true);
scoped_refptr<LayerWithForcedDrawsContent> scroller =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
SetLayerPropertiesForTesting(scroller.get(), identity, gfx::Point3F(),
gfx::PointF(), gfx::Size(1000, 1000), true,
false);
@@ -9204,7 +8015,7 @@ TEST_F(LayerTreeHostCommonTest, FixedClipsShouldBeAssociatedWithTheRightNode) {
scroller->SetScrollClipLayerId(frame_clip->id());
scoped_refptr<LayerWithForcedDrawsContent> fixed =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
SetLayerPropertiesForTesting(fixed.get(), identity, gfx::Point3F(),
gfx::PointF(100, 100), gfx::Size(50, 50), true,
false);
@@ -9219,10 +8030,9 @@ TEST_F(LayerTreeHostCommonTest, FixedClipsShouldBeAssociatedWithTheRightNode) {
frame_clip->AddChild(scroller);
scroller->AddChild(fixed);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
gfx::Rect expected(0, 0, 50, 50);
EXPECT_EQ(expected, fixed->visible_rect_from_property_trees());
@@ -9236,31 +8046,30 @@ TEST_F(LayerTreeHostCommonTest, ChangingAxisAlignmentTriggersRebuild) {
translate.Translate(10, 10);
rotate.Rotate(45);
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
SetLayerPropertiesForTesting(root.get(), identity, gfx::Point3F(),
gfx::PointF(), gfx::Size(800, 800), true, false);
root->SetIsContainerForFixedPositionLayers(true);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
+ EXPECT_FALSE(host()->property_trees()->needs_rebuild);
root->SetTransform(translate);
- EXPECT_FALSE(host->property_trees()->needs_rebuild);
+ EXPECT_FALSE(host()->property_trees()->needs_rebuild);
root->SetTransform(rotate);
- EXPECT_TRUE(host->property_trees()->needs_rebuild);
+ EXPECT_TRUE(host()->property_trees()->needs_rebuild);
}
TEST_F(LayerTreeHostCommonTest, ChangeTransformOrigin) {
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> child =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(child);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
gfx::Transform identity_matrix;
gfx::Transform scale_matrix;
@@ -9270,29 +8079,28 @@ TEST_F(LayerTreeHostCommonTest, ChangeTransformOrigin) {
SetLayerPropertiesForTesting(child.get(), scale_matrix, gfx::Point3F(),
gfx::PointF(), gfx::Size(10, 10), true, false);
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
EXPECT_EQ(gfx::Rect(10, 10), child->visible_rect_from_property_trees());
child->SetTransformOrigin(gfx::Point3F(10.f, 10.f, 10.f));
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
EXPECT_EQ(gfx::Rect(5, 5, 5, 5), child->visible_rect_from_property_trees());
}
TEST_F(LayerTreeHostCommonTest, UpdateScrollChildPosition) {
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> scroll_parent =
- make_scoped_refptr(new LayerWithForcedDrawsContent);
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> scroll_child =
- make_scoped_refptr(new LayerWithForcedDrawsContent);
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
root->AddChild(scroll_child);
root->AddChild(scroll_parent);
scroll_child->SetScrollParent(scroll_parent.get());
scroll_parent->SetScrollClipLayerId(root->id());
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
gfx::Transform identity_transform;
gfx::Transform scale;
@@ -9305,13 +8113,13 @@ TEST_F(LayerTreeHostCommonTest, UpdateScrollChildPosition) {
gfx::Point3F(), gfx::PointF(), gfx::Size(30, 30),
true, false);
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
EXPECT_EQ(gfx::Rect(25, 25),
scroll_child->visible_rect_from_property_trees());
scroll_child->SetPosition(gfx::PointF(0, -10.f));
scroll_parent->SetScrollOffset(gfx::ScrollOffset(0.f, 10.f));
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
EXPECT_EQ(gfx::Rect(0, 5, 25, 25),
scroll_child->visible_rect_from_property_trees());
}
@@ -9322,13 +8130,13 @@ static void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
TEST_F(LayerTreeHostCommonTest, SkippingSubtreeMain) {
gfx::Transform identity;
FakeContentLayerClient client;
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> child =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
scoped_refptr<LayerWithForcedDrawsContent> grandchild =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
- scoped_refptr<FakeContentLayer> greatgrandchild(
- FakeContentLayer::Create(&client));
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
+ scoped_refptr<FakePictureLayer> greatgrandchild(
+ FakePictureLayer::Create(layer_settings(), &client));
SetLayerPropertiesForTesting(root.get(), identity, gfx::Point3F(),
gfx::PointF(), gfx::Size(100, 100), true, false);
SetLayerPropertiesForTesting(child.get(), identity, gfx::Point3F(),
@@ -9342,11 +8150,10 @@ TEST_F(LayerTreeHostCommonTest, SkippingSubtreeMain) {
child->AddChild(grandchild);
grandchild->AddChild(greatgrandchild);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
// Check the non-skipped case.
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
EXPECT_EQ(gfx::Rect(10, 10), grandchild->visible_rect_from_property_trees());
// Now we will reset the visible rect from property trees for the grandchild,
@@ -9358,41 +8165,43 @@ TEST_F(LayerTreeHostCommonTest, SkippingSubtreeMain) {
singular.matrix().set(0, 0, 0);
child->SetTransform(singular);
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
EXPECT_EQ(gfx::Rect(0, 0), grandchild->visible_rect_from_property_trees());
child->SetTransform(identity);
child->SetHideLayerAndSubtree(true);
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
EXPECT_EQ(gfx::Rect(0, 0), grandchild->visible_rect_from_property_trees());
child->SetHideLayerAndSubtree(false);
child->SetOpacity(0.f);
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
EXPECT_EQ(gfx::Rect(0, 0), grandchild->visible_rect_from_property_trees());
// Now, even though child has zero opacity, we will configure |grandchild| and
// |greatgrandchild| in several ways that should force the subtree to be
// processed anyhow.
grandchild->SetTouchEventHandlerRegion(Region(gfx::Rect(0, 0, 10, 10)));
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
EXPECT_EQ(gfx::Rect(10, 10), grandchild->visible_rect_from_property_trees());
grandchild->set_visible_rect_from_property_trees(gfx::Rect());
grandchild->SetTouchEventHandlerRegion(Region());
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
EXPECT_EQ(gfx::Rect(0, 0), grandchild->visible_rect_from_property_trees());
grandchild->set_visible_rect_from_property_trees(gfx::Rect());
greatgrandchild->RequestCopyOfOutput(
CopyOutputRequest::CreateBitmapRequest(base::Bind(&CopyOutputCallback)));
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
EXPECT_EQ(gfx::Rect(10, 10), grandchild->visible_rect_from_property_trees());
}
TEST_F(LayerTreeHostCommonTest, SkippingSubtreeImpl) {
FakeImplProxy proxy;
TestSharedBitmapManager shared_bitmap_manager;
- FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager, nullptr);
+ TestTaskGraphRunner task_graph_runner;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager,
+ &task_graph_runner);
gfx::Transform identity;
scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
@@ -9400,8 +8209,8 @@ TEST_F(LayerTreeHostCommonTest, SkippingSubtreeImpl) {
scoped_ptr<LayerImpl> grandchild =
LayerImpl::Create(host_impl.active_tree(), 3);
- scoped_ptr<FakeContentLayerImpl> greatgrandchild(
- FakeContentLayerImpl::Create(host_impl.active_tree(), 4));
+ scoped_ptr<FakePictureLayerImpl> greatgrandchild(
+ FakePictureLayerImpl::Create(host_impl.active_tree(), 4));
child->SetDrawsContent(true);
grandchild->SetDrawsContent(true);
@@ -9429,7 +8238,7 @@ TEST_F(LayerTreeHostCommonTest, SkippingSubtreeImpl) {
root->AddChild(child.Pass());
// Check the non-skipped case.
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
EXPECT_EQ(gfx::Rect(10, 10),
grandchild_ptr->visible_rect_from_property_trees());
@@ -9442,19 +8251,19 @@ TEST_F(LayerTreeHostCommonTest, SkippingSubtreeImpl) {
singular.matrix().set(0, 0, 0);
child_ptr->SetTransform(singular);
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
EXPECT_EQ(gfx::Rect(0, 0),
grandchild_ptr->visible_rect_from_property_trees());
child_ptr->SetTransform(identity);
child_ptr->SetHideLayerAndSubtree(true);
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
EXPECT_EQ(gfx::Rect(0, 0),
grandchild_ptr->visible_rect_from_property_trees());
child_ptr->SetHideLayerAndSubtree(false);
child_ptr->SetOpacity(0.f);
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
EXPECT_EQ(gfx::Rect(0, 0),
grandchild_ptr->visible_rect_from_property_trees());
@@ -9462,12 +8271,12 @@ TEST_F(LayerTreeHostCommonTest, SkippingSubtreeImpl) {
// |greatgrandchild| in several ways that should force the subtree to be
// processed anyhow.
grandchild_ptr->SetTouchEventHandlerRegion(Region(gfx::Rect(0, 0, 10, 10)));
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
EXPECT_EQ(gfx::Rect(10, 10),
grandchild_ptr->visible_rect_from_property_trees());
grandchild_ptr->set_visible_rect_from_property_trees(gfx::Rect());
grandchild_ptr->SetTouchEventHandlerRegion(Region());
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
EXPECT_EQ(gfx::Rect(0, 0),
grandchild_ptr->visible_rect_from_property_trees());
grandchild_ptr->set_visible_rect_from_property_trees(gfx::Rect());
@@ -9476,7 +8285,7 @@ TEST_F(LayerTreeHostCommonTest, SkippingSubtreeImpl) {
requests.push_back(CopyOutputRequest::CreateEmptyRequest());
greatgrandchild_ptr->PassCopyRequests(&requests);
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
EXPECT_EQ(gfx::Rect(10, 10),
grandchild_ptr->visible_rect_from_property_trees());
}
@@ -9484,29 +8293,28 @@ TEST_F(LayerTreeHostCommonTest, SkippingSubtreeImpl) {
TEST_F(LayerTreeHostCommonTest, SkippingLayer) {
gfx::Transform identity;
FakeContentLayerClient client;
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
scoped_refptr<LayerWithForcedDrawsContent> child =
- make_scoped_refptr(new LayerWithForcedDrawsContent());
+ make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings()));
SetLayerPropertiesForTesting(root.get(), identity, gfx::Point3F(),
gfx::PointF(), gfx::Size(100, 100), true, false);
SetLayerPropertiesForTesting(child.get(), identity, gfx::Point3F(),
gfx::PointF(), gfx::Size(10, 10), true, false);
root->AddChild(child);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
EXPECT_EQ(gfx::Rect(10, 10), child->visible_rect_from_property_trees());
child->set_visible_rect_from_property_trees(gfx::Rect());
child->SetHideLayerAndSubtree(true);
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
EXPECT_EQ(gfx::Rect(0, 0), child->visible_rect_from_property_trees());
child->SetHideLayerAndSubtree(false);
child->SetBounds(gfx::Size());
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
EXPECT_EQ(gfx::Rect(0, 0), child->visible_rect_from_property_trees());
child->SetBounds(gfx::Size(10, 10));
@@ -9514,22 +8322,22 @@ TEST_F(LayerTreeHostCommonTest, SkippingLayer) {
child->SetDoubleSided(false);
rotate.RotateAboutXAxis(180.f);
child->SetTransform(rotate);
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
EXPECT_EQ(gfx::Rect(0, 0), child->visible_rect_from_property_trees());
child->SetDoubleSided(true);
child->SetTransform(identity);
child->SetOpacity(0.f);
- ExecuteCalculateDrawProperties(root.get());
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
EXPECT_EQ(gfx::Rect(0, 0), child->visible_rect_from_property_trees());
}
TEST_F(LayerTreeHostCommonTest, LayerTreeRebuildTest) {
// Ensure that the treewalk in LayerTreeHostCommom::
// PreCalculateMetaInformation happens when its required.
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> parent = Layer::Create();
- scoped_refptr<Layer> child = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> parent = Layer::Create(layer_settings());
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
root->AddChild(parent);
parent->AddChild(child);
@@ -9545,11 +8353,10 @@ TEST_F(LayerTreeHostCommonTest, LayerTreeRebuildTest) {
SetLayerPropertiesForTesting(child.get(), identity, gfx::Point3F(),
gfx::PointF(), gfx::Size(100, 100), true, false);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
ExecuteCalculateDrawProperties(root.get());
- EXPECT_EQ(parent->draw_properties().num_unclipped_descendants, 1);
+ EXPECT_EQ(parent->draw_properties().num_unclipped_descendants, 1u);
// Ensure the dynamic update to input handlers happens.
child->SetHaveWheelEventHandlers(true);
@@ -9572,8 +8379,8 @@ TEST_F(LayerTreeHostCommonTest, LayerTreeRebuildTest) {
TEST_F(LayerTreeHostCommonTest, InputHandlersRecursiveUpdateTest) {
// Ensure that the treewalk in LayertreeHostCommon::
// PreCalculateMetaInformation updates input handlers correctly.
- scoped_refptr<Layer> root = Layer::Create();
- scoped_refptr<Layer> child = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
root->AddChild(child);
@@ -9586,8 +8393,7 @@ TEST_F(LayerTreeHostCommonTest, InputHandlersRecursiveUpdateTest) {
SetLayerPropertiesForTesting(child.get(), identity, gfx::Point3F(),
gfx::PointF(), gfx::Size(100, 100), true, false);
- scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
- host->SetRootLayer(root);
+ host()->SetRootLayer(root);
EXPECT_EQ(root->num_layer_or_descendants_with_input_handler(), 0);
ExecuteCalculateDrawProperties(root.get());
@@ -9596,5 +8402,69 @@ TEST_F(LayerTreeHostCommonTest, InputHandlersRecursiveUpdateTest) {
EXPECT_EQ(root->num_layer_or_descendants_with_input_handler(), 0);
}
+TEST_F(LayerTreeHostCommonTest, ResetPropertyTreeIndices) {
+ gfx::Transform identity;
+ gfx::Transform translate_z;
+ translate_z.Translate3d(0, 0, 10);
+
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ SetLayerPropertiesForTesting(root.get(), identity, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(800, 800), true, false);
+
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
+ SetLayerPropertiesForTesting(child.get(), translate_z, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), true, false);
+
+ root->AddChild(child);
+
+ host()->SetRootLayer(root);
+
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
+ EXPECT_NE(-1, child->transform_tree_index());
+
+ child->RemoveFromParent();
+
+ ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
+ EXPECT_EQ(-1, child->transform_tree_index());
+}
+
+TEST_F(LayerTreeHostCommonTest, ResetLayerDrawPropertiestest) {
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
+
+ root->AddChild(child);
+ gfx::Transform identity;
+
+ SetLayerPropertiesForTesting(root.get(), identity, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), true, false);
+ SetLayerPropertiesForTesting(child.get(), identity, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), true, false);
+
+ host()->SetRootLayer(root);
+
+ EXPECT_FALSE(root->layer_or_descendant_is_drawn());
+ EXPECT_FALSE(root->visited());
+ EXPECT_FALSE(root->sorted_for_recursion());
+ EXPECT_FALSE(child->layer_or_descendant_is_drawn());
+ EXPECT_FALSE(child->visited());
+ EXPECT_FALSE(child->sorted_for_recursion());
+
+ root->set_layer_or_descendant_is_drawn(true);
+ root->set_visited(true);
+ root->set_sorted_for_recursion(true);
+ child->set_layer_or_descendant_is_drawn(true);
+ child->set_visited(true);
+ child->set_sorted_for_recursion(true);
+
+ LayerTreeHostCommon::PreCalculateMetaInformationForTesting(root.get());
+
+ EXPECT_FALSE(root->layer_or_descendant_is_drawn());
+ EXPECT_FALSE(root->visited());
+ EXPECT_FALSE(root->sorted_for_recursion());
+ EXPECT_FALSE(child->layer_or_descendant_is_drawn());
+ EXPECT_FALSE(child->visited());
+ EXPECT_FALSE(child->sorted_for_recursion());
+}
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_impl.cc b/chromium/cc/trees/layer_tree_host_impl.cc
index 9e1474586cb..f616d517a3f 100644
--- a/chromium/cc/trees/layer_tree_host_impl.cc
+++ b/chromium/cc/trees/layer_tree_host_impl.cc
@@ -14,15 +14,16 @@
#include "base/containers/small_map.h"
#include "base/json/json_writer.h"
#include "base/metrics/histogram.h"
+#include "base/numerics/safe_conversions.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event_argument.h"
+#include "cc/animation/animation_host.h"
#include "cc/animation/animation_id_provider.h"
#include "cc/animation/scroll_offset_animation_curve.h"
#include "cc/animation/scrollbar_animation_controller.h"
#include "cc/animation/timing_function.h"
#include "cc/base/math_util.h"
-#include "cc/base/util.h"
#include "cc/debug/benchmark_instrumentation.h"
#include "cc/debug/debug_rect_history.h"
#include "cc/debug/devtools_instrumentation.h"
@@ -60,7 +61,6 @@
#include "cc/raster/tile_task_worker_pool.h"
#include "cc/raster/zero_copy_tile_task_worker_pool.h"
#include "cc/resources/memory_history.h"
-#include "cc/resources/prioritized_resource_manager.h"
#include "cc/resources/resource_pool.h"
#include "cc/resources/ui_resource_bitmap.h"
#include "cc/scheduler/delay_based_time_source.h"
@@ -76,7 +76,6 @@
#include "cc/trees/tree_synchronizer.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/gles2_interface.h"
-#include "ui/gfx/frame_time.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/geometry/scroll_offset.h"
#include "ui/gfx/geometry/size_conversions.h"
@@ -158,6 +157,16 @@ size_t GetMaxStagingResourceCount() {
return 32;
}
+size_t GetDefaultMemoryAllocationLimit() {
+ // TODO(ccameron): (http://crbug.com/137094) This 64MB default is a straggler
+ // from the old texture manager and is just to give us a default memory
+ // allocation before we get a callback from the GPU memory manager. We
+ // should probaby either:
+ // - wait for the callback before rendering anything instead
+ // - push this into the GPU memory manager somehow.
+ return 64 * 1024 * 1024;
+}
+
} // namespace
LayerTreeHostImpl::FrameData::FrameData() : has_no_damage(false) {
@@ -190,6 +199,7 @@ LayerTreeHostImpl::LayerTreeHostImpl(
int id)
: client_(client),
proxy_(proxy),
+ current_begin_frame_tracker_(BEGINFRAMETRACKER_FROM_HERE),
content_is_suitable_for_gpu_rasterization_(true),
has_gpu_rasterization_trigger_(false),
use_gpu_rasterization_(false),
@@ -207,23 +217,27 @@ LayerTreeHostImpl::LayerTreeHostImpl(
settings_(settings),
visible_(true),
cached_managed_memory_policy_(
- PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
+ GetDefaultMemoryAllocationLimit(),
gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
ManagedMemoryPolicy::kDefaultNumResourcesLimit),
+ // Must be initialized after settings_ and proxy_.
+ tile_manager_(
+ TileManager::Create(this,
+ GetTaskRunner(),
+ IsSynchronousSingleThreaded()
+ ? std::numeric_limits<size_t>::max()
+ : settings.scheduled_raster_task_limit)),
pinch_gesture_active_(false),
pinch_gesture_end_should_clear_scrolling_layer_(false),
fps_counter_(FrameRateCounter::Create(proxy_->HasImplThread())),
paint_time_counter_(PaintTimeCounter::Create()),
memory_history_(MemoryHistory::Create()),
debug_rect_history_(DebugRectHistory::Create()),
- texture_mailbox_deleter_(new TextureMailboxDeleter(
- proxy_->HasImplThread() ? proxy_->ImplThreadTaskRunner()
- : proxy_->MainThreadTaskRunner())),
+ texture_mailbox_deleter_(new TextureMailboxDeleter(GetTaskRunner())),
max_memory_needed_bytes_(0),
device_scale_factor_(1.f),
resourceless_software_draw_(false),
- begin_impl_frame_interval_(BeginFrameArgs::DefaultInterval()),
- animation_registrar_(AnimationRegistrar::Create()),
+ animation_registrar_(),
rendering_stats_instrumentation_(rendering_stats_instrumentation),
micro_benchmark_controller_(this),
shared_bitmap_manager_(shared_bitmap_manager),
@@ -232,11 +246,24 @@ LayerTreeHostImpl::LayerTreeHostImpl(
id_(id),
requires_high_res_to_draw_(false),
is_likely_to_require_a_draw_(false),
- frame_timing_tracker_(FrameTimingTracker::Create()) {
+ frame_timing_tracker_(FrameTimingTracker::Create(this)) {
+ if (settings.use_compositor_animation_timelines) {
+ if (settings.accelerated_animation_enabled) {
+ animation_host_ = AnimationHost::Create(ThreadInstance::IMPL);
+ animation_host_->SetMutatorHostClient(this);
+ animation_host_->SetSupportsScrollAnimations(
+ proxy_->SupportsImplScrolling());
+ }
+ } else {
+ animation_registrar_ = AnimationRegistrar::Create();
+ animation_registrar_->set_supports_scroll_animations(
+ proxy_->SupportsImplScrolling());
+ }
+
DCHECK(proxy_->IsImplThread());
+ DCHECK_IMPLIES(settings.use_one_copy, !settings.use_zero_copy);
+ DCHECK_IMPLIES(settings.use_zero_copy, !settings.use_one_copy);
DidVisibilityChange(this, visible_);
- animation_registrar_->set_supports_scroll_animations(
- proxy_->SupportsImplScrolling());
SetDebugState(settings.initial_debug_state);
@@ -280,29 +307,36 @@ LayerTreeHostImpl::~LayerTreeHostImpl() {
recycle_tree_ = nullptr;
pending_tree_ = nullptr;
active_tree_ = nullptr;
- DestroyTileManager();
+
+ if (animation_host_) {
+ animation_host_->ClearTimelines();
+ animation_host_->SetMutatorHostClient(nullptr);
+ }
+
+ CleanUpTileManager();
}
void LayerTreeHostImpl::BeginMainFrameAborted(CommitEarlyOutReason reason) {
// If the begin frame data was handled, then scroll and scale set was applied
// by the main thread, so the active tree needs to be updated as if these sent
// values were applied and committed.
- if (CommitEarlyOutHandledCommit(reason)) {
+ if (CommitEarlyOutHandledCommit(reason))
active_tree_->ApplySentScrollAndScaleDeltasFromAbortedCommit();
- active_tree_->ResetContentsTexturesPurged();
- }
}
void LayerTreeHostImpl::BeginCommit() {
TRACE_EVENT0("cc", "LayerTreeHostImpl::BeginCommit");
// Ensure all textures are returned so partial texture updates can happen
- // during the commit. Impl-side-painting doesn't upload during commits, so
- // is unaffected.
- if (!settings_.impl_side_painting && output_surface_)
+ // during the commit.
+ // TODO(ericrk): We should not need to ForceReclaimResources when using
+ // Impl-side-painting as it doesn't upload during commits. However,
+ // Display::Draw currently relies on resource being reclaimed to block drawing
+ // between BeginCommit / Swap. See crbug.com/489515.
+ if (output_surface_)
output_surface_->ForceReclaimResources();
- if (settings_.impl_side_painting && !proxy_->CommitToActiveTree())
+ if (!proxy_->CommitToActiveTree())
CreatePendingTree();
}
@@ -314,31 +348,25 @@ void LayerTreeHostImpl::CommitComplete() {
UpdateTreeResourcesForGpuRasterizationIfNeeded();
sync_tree()->set_needs_update_draw_properties();
- if (settings_.impl_side_painting) {
- // Impl-side painting needs an update immediately post-commit to have the
- // opportunity to create tilings. Other paths can call UpdateDrawProperties
- // more lazily when needed prior to drawing. Because invalidations may
- // be coming from the main thread, it's safe to do an update for lcd text
- // at this point and see if lcd text needs to be disabled on any layers.
- bool update_lcd_text = true;
- sync_tree()->UpdateDrawProperties(update_lcd_text);
- // Start working on newly created tiles immediately if needed.
- if (tile_manager_ && tile_priorities_dirty_) {
- PrepareTiles();
- } else {
- NotifyReadyToActivate();
-
- // Ensure we get ReadyToDraw signal even when PrepareTiles not run. This
- // is important for SingleThreadProxy and impl-side painting case. For
- // STP, we commit to active tree and RequiresHighResToDraw, and set
- // Scheduler to wait for ReadyToDraw signal to avoid Checkerboard.
- if (proxy_->CommitToActiveTree())
- NotifyReadyToDraw();
- }
- } else {
- // If we're not in impl-side painting, the tree is immediately considered
- // active.
- ActivateSyncTree();
+ // We need an update immediately post-commit to have the opportunity to create
+ // tilings. Because invalidations may be coming from the main thread, it's
+ // safe to do an update for lcd text at this point and see if lcd text needs
+ // to be disabled on any layers.
+ bool update_lcd_text = true;
+ sync_tree()->UpdateDrawProperties(update_lcd_text);
+ // Start working on newly created tiles immediately if needed.
+ // TODO(vmpstr): Investigate always having PrepareTiles issue
+ // NotifyReadyToActivate, instead of handling it here.
+ bool did_prepare_tiles = PrepareTiles();
+ if (!did_prepare_tiles) {
+ NotifyReadyToActivate();
+
+ // Ensure we get ReadyToDraw signal even when PrepareTiles not run. This
+ // is important for SingleThreadProxy and impl-side painting case. For
+ // STP, we commit to active tree and RequiresHighResToDraw, and set
+ // Scheduler to wait for ReadyToDraw signal to avoid Checkerboard.
+ if (proxy_->CommitToActiveTree())
+ NotifyReadyToDraw();
}
micro_benchmark_controller_.DidCompleteCommit();
@@ -381,12 +409,6 @@ bool LayerTreeHostImpl::CanDraw() const {
TRACE_EVENT_SCOPE_THREAD);
return false;
}
- if (active_tree_->ContentsTexturesPurged()) {
- TRACE_EVENT_INSTANT0(
- "cc", "LayerTreeHostImpl::CanDraw contents textures purged",
- TRACE_EVENT_SCOPE_THREAD);
- return false;
- }
if (EvictedUIResourcesExist()) {
TRACE_EVENT_INSTANT0(
"cc", "LayerTreeHostImpl::CanDraw UI resources evicted not recreated",
@@ -397,24 +419,31 @@ bool LayerTreeHostImpl::CanDraw() const {
}
void LayerTreeHostImpl::Animate(base::TimeTicks monotonic_time) {
- if (input_handler_client_)
- input_handler_client_->Animate(monotonic_time);
+ // mithro(TODO): Enable these checks.
+ // DCHECK(!current_begin_frame_tracker_.HasFinished());
+ // DCHECK(monotonic_time == current_begin_frame_tracker_.Current().frame_time)
+ // << "Called animate with unknown frame time!?";
+ if (!root_layer_scroll_offset_delegate_ ||
+ (CurrentlyScrollingLayer() != InnerViewportScrollLayer() &&
+ CurrentlyScrollingLayer() != OuterViewportScrollLayer())) {
+ AnimateInput(monotonic_time);
+ }
AnimatePageScale(monotonic_time);
AnimateLayers(monotonic_time);
AnimateScrollbars(monotonic_time);
AnimateTopControls(monotonic_time);
}
-void LayerTreeHostImpl::PrepareTiles() {
- if (!tile_manager_)
- return;
+bool LayerTreeHostImpl::PrepareTiles() {
if (!tile_priorities_dirty_)
- return;
-
- tile_priorities_dirty_ = false;
- tile_manager_->PrepareTiles(global_tile_state_);
+ return false;
+ client_->WillPrepareTiles();
+ bool did_prepare_tiles = tile_manager_->PrepareTiles(global_tile_state_);
+ if (did_prepare_tiles)
+ tile_priorities_dirty_ = false;
client_->DidPrepareTiles();
+ return did_prepare_tiles;
}
void LayerTreeHostImpl::StartPageScaleAnimation(
@@ -457,6 +486,22 @@ void LayerTreeHostImpl::StartPageScaleAnimation(
client_->RenewTreePriority();
}
+void LayerTreeHostImpl::SetNeedsAnimateInput() {
+ if (root_layer_scroll_offset_delegate_ &&
+ (CurrentlyScrollingLayer() == InnerViewportScrollLayer() ||
+ CurrentlyScrollingLayer() == OuterViewportScrollLayer())) {
+ if (root_layer_animation_callback_.is_null()) {
+ root_layer_animation_callback_ =
+ base::Bind(&LayerTreeHostImpl::AnimateInput, AsWeakPtr());
+ }
+ root_layer_scroll_offset_delegate_->SetNeedsAnimate(
+ root_layer_animation_callback_);
+ return;
+ }
+
+ SetNeedsAnimate();
+}
+
bool LayerTreeHostImpl::IsCurrentlyScrollingLayerAt(
const gfx::Point& viewport_point,
InputHandler::ScrollInputType type) {
@@ -566,10 +611,9 @@ void LayerTreeHostImpl::TrackDamageForAllSurfaces(
// must compute all damage tracking before drawing anything, so that we know
// the root damage rect. The root damage rect is then used to scissor each
// surface.
-
- for (int surface_index = render_surface_layer_list.size() - 1;
- surface_index >= 0;
- --surface_index) {
+ size_t render_surface_layer_list_size = render_surface_layer_list.size();
+ for (size_t i = 0; i < render_surface_layer_list_size; ++i) {
+ size_t surface_index = render_surface_layer_list_size - 1 - i;
LayerImpl* render_surface_layer = render_surface_layer_list[surface_index];
RenderSurfaceImpl* render_surface = render_surface_layer->render_surface();
DCHECK(render_surface);
@@ -745,9 +789,10 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(
"RequiresHighResToDraw", RequiresHighResToDraw());
// Create the render passes in dependency order.
- for (int surface_index = frame->render_surface_layer_list->size() - 1;
- surface_index >= 0;
- --surface_index) {
+ size_t render_surface_layer_list_size =
+ frame->render_surface_layer_list->size();
+ for (size_t i = 0; i < render_surface_layer_list_size; ++i) {
+ size_t surface_index = render_surface_layer_list_size - 1 - i;
LayerImpl* render_surface_layer =
(*frame->render_surface_layer_list)[surface_index];
RenderSurfaceImpl* render_surface = render_surface_layer->render_surface();
@@ -795,9 +840,9 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(
bool have_copy_request = false;
bool have_missing_animated_tiles = false;
- auto end = LayerIterator<LayerImpl>::End(frame->render_surface_layer_list);
- for (auto it =
- LayerIterator<LayerImpl>::Begin(frame->render_surface_layer_list);
+ LayerIterator end = LayerIterator::End(frame->render_surface_layer_list);
+ for (LayerIterator it =
+ LayerIterator::Begin(frame->render_surface_layer_list);
it != end; ++it) {
RenderPassId target_render_pass_id =
it.target_render_surface_layer()->render_surface()->GetRenderPassId();
@@ -822,11 +867,10 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(
*it,
contributing_render_pass,
&append_quads_data);
- } else if (it.represents_itself() &&
- !it->visible_content_rect().IsEmpty()) {
+ } else if (it.represents_itself() && !it->visible_layer_rect().IsEmpty()) {
bool occluded =
it->draw_properties().occlusion_in_content_space.IsOccluded(
- it->visible_content_rect());
+ it->visible_layer_rect());
if (!occluded && it->WillDraw(draw_mode, resource_provider_.get())) {
DCHECK_EQ(active_tree_, it->layer_tree_impl());
@@ -852,9 +896,7 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(
// For layers that represent themselves, add composite frame timing
// requests if the visible rect intersects the requested rect.
for (const auto& request : it->frame_timing_requests()) {
- const gfx::Rect& request_content_rect =
- it->LayerRectToContentRect(request.rect());
- if (request_content_rect.Intersects(it->visible_content_rect())) {
+ if (request.rect().Intersects(it->visible_layer_rect())) {
frame->composite_events.push_back(
FrameTimingTracker::FrameAndRectIds(
active_tree_->source_frame_number(), request.id()));
@@ -866,7 +908,7 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(
}
rendering_stats_instrumentation_->AddVisibleContentArea(
- append_quads_data.visible_content_area);
+ append_quads_data.visible_layer_area);
rendering_stats_instrumentation_->AddApproximatedVisibleContentArea(
append_quads_data.approximated_visible_content_area);
rendering_stats_instrumentation_->AddCheckerboardedVisibleContentArea(
@@ -991,25 +1033,26 @@ DrawResult LayerTreeHostImpl::PrepareToDraw(FrameData* frame) {
input_handler_client_->ReconcileElasticOverscrollAndRootScroll();
UMA_HISTOGRAM_CUSTOM_COUNTS(
- "Compositing.NumActiveLayers", active_tree_->NumLayers(), 1, 400, 20);
+ "Compositing.NumActiveLayers",
+ base::saturated_cast<int>(active_tree_->NumLayers()), 1, 400, 20);
size_t total_picture_memory = 0;
for (const PictureLayerImpl* layer : active_tree()->picture_layers())
total_picture_memory += layer->GetRasterSource()->GetPictureMemoryUsage();
if (total_picture_memory != 0) {
- UMA_HISTOGRAM_COUNTS("Compositing.PictureMemoryUsageKb",
- total_picture_memory / 1024);
+ UMA_HISTOGRAM_COUNTS(
+ "Compositing.PictureMemoryUsageKb",
+ base::saturated_cast<int>(total_picture_memory / 1024));
}
bool update_lcd_text = false;
bool ok = active_tree_->UpdateDrawProperties(update_lcd_text);
DCHECK(ok) << "UpdateDrawProperties failed during draw";
- // This will cause NotifyTileStateChanged() to be called for any visible tiles
- // that completed, which will add damage to the frame for them so they appear
- // as part of the current frame being drawn.
- if (tile_manager_)
- tile_manager_->UpdateVisibleTiles(global_tile_state_);
+ // This will cause NotifyTileStateChanged() to be called for any tiles that
+ // completed, which will add damage for visible tiles to the frame for them so
+ // they appear as part of the current frame being drawn.
+ tile_manager_->Flush();
frame->render_surface_layer_list = &active_tree_->RenderSurfaceLayerList();
frame->render_passes.clear();
@@ -1122,7 +1165,7 @@ void LayerTreeHostImpl::RemoveRenderPasses(FrameData* frame) {
}
void LayerTreeHostImpl::EvictTexturesForTesting() {
- EnforceManagedMemoryPolicy(ManagedMemoryPolicy(0));
+ UpdateTileManagerMemoryPolicy(ManagedMemoryPolicy(0));
}
void LayerTreeHostImpl::BlockNotifyReadyToActivateForTesting(bool block) {
@@ -1144,29 +1187,13 @@ void LayerTreeHostImpl::ResetTreesForTesting() {
recycle_tree_ = nullptr;
}
-void LayerTreeHostImpl::EnforceManagedMemoryPolicy(
- const ManagedMemoryPolicy& policy) {
-
- bool evicted_resources = client_->ReduceContentsTextureMemoryOnImplThread(
- visible_ ? policy.bytes_limit_when_visible : 0,
- ManagedMemoryPolicy::PriorityCutoffToValue(
- visible_ ? policy.priority_cutoff_when_visible
- : gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING));
- if (evicted_resources) {
- active_tree_->SetContentsTexturesPurged();
- if (pending_tree_)
- pending_tree_->SetContentsTexturesPurged();
- client_->SetNeedsCommitOnImplThread();
- client_->OnCanDrawStateChanged(CanDraw());
- client_->RenewTreePriority();
- }
-
- UpdateTileManagerMemoryPolicy(policy);
+size_t LayerTreeHostImpl::SourceAnimationFrameNumberForTesting() const {
+ return fps_counter_->current_frame_number();
}
void LayerTreeHostImpl::UpdateTileManagerMemoryPolicy(
const ManagedMemoryPolicy& policy) {
- if (!tile_manager_)
+ if (!resource_pool_)
return;
global_tile_state_.hard_memory_limit_in_bytes = 0;
@@ -1186,6 +1213,16 @@ void LayerTreeHostImpl::UpdateTileManagerMemoryPolicy(
gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING);
global_tile_state_.num_resources_limit = policy.num_resources_limit;
+ if (output_surface_ && global_tile_state_.hard_memory_limit_in_bytes > 0) {
+ // If |global_tile_state_.hard_memory_limit_in_bytes| is greater than 0, we
+ // allow the worker context to retain allocated resources. Notify the worker
+ // context. If the memory policy has become zero, we'll handle the
+ // notification in NotifyAllTileTasksCompleted, after in-progress work
+ // finishes.
+ output_surface_->SetWorkerContextShouldAggressivelyFreeResources(
+ false /* aggressively_free_resources */);
+ }
+
// TODO(reveman): We should avoid keeping around unused resources if
// possible. crbug.com/224475
// Unused limit is calculated from soft-limit, as hard-limit may
@@ -1217,7 +1254,6 @@ void LayerTreeHostImpl::UpdateTileManagerMemoryPolicy(
}
void LayerTreeHostImpl::DidModifyTilePriorities() {
- DCHECK(settings_.impl_side_painting);
// Mark priorities as dirty and schedule a PrepareTiles().
tile_priorities_dirty_ = true;
client_->SetNeedsPrepareTilesOnImplThread();
@@ -1269,6 +1305,15 @@ void LayerTreeHostImpl::NotifyReadyToDraw() {
client_->NotifyReadyToDraw();
}
+void LayerTreeHostImpl::NotifyAllTileTasksCompleted() {
+ // The tile tasks started by the most recent call to PrepareTiles have
+ // completed. Now is a good time to free resources if necessary.
+ if (output_surface_ && global_tile_state_.hard_memory_limit_in_bytes == 0) {
+ output_surface_->SetWorkerContextShouldAggressivelyFreeResources(
+ true /* aggressively_free_resources */);
+ }
+}
+
void LayerTreeHostImpl::NotifyTileStateChanged(const Tile* tile) {
TRACE_EVENT0("cc", "LayerTreeHostImpl::NotifyTileStateChanged");
@@ -1300,14 +1345,17 @@ void LayerTreeHostImpl::SetMemoryPolicy(const ManagedMemoryPolicy& policy) {
// This is short term solution to synchronously drop tile resources when
// using synchronous compositing to avoid memory usage regression.
// TODO(boliu): crbug.com/499004 to track removing this.
- if (!policy.bytes_limit_when_visible && tile_manager_ &&
+ if (!policy.bytes_limit_when_visible && resource_pool_ &&
settings_.using_synchronous_renderer_compositor) {
ReleaseTreeResources();
- // TileManager destruction will synchronoulsy wait for all tile workers to
- // be cancelled or completed. This allows all resources to be freed
- // synchronously.
- DestroyTileManager();
- CreateAndSetTileManager();
+ CleanUpTileManager();
+
+ // Force a call to NotifyAllTileTasks completed - otherwise this logic may
+ // be skipped if no work was enqueued at the time the tile manager was
+ // destroyed.
+ NotifyAllTileTasksCompleted();
+
+ CreateTileManagerResources();
RecreateTreeResources();
}
}
@@ -1315,7 +1363,6 @@ void LayerTreeHostImpl::SetMemoryPolicy(const ManagedMemoryPolicy& policy) {
void LayerTreeHostImpl::SetTreeActivationCallback(
const base::Closure& callback) {
DCHECK(proxy_->IsImplThread());
- DCHECK(settings_.impl_side_painting || callback.is_null());
tree_activation_callback_ = callback;
}
@@ -1336,10 +1383,10 @@ void LayerTreeHostImpl::SetManagedMemoryPolicy(
// In single-thread mode, this can be called on the main thread by
// GLRenderer::OnMemoryAllocationChanged.
DebugScopedSetImplThread impl_thread(proxy_);
- EnforceManagedMemoryPolicy(actual_policy);
+ UpdateTileManagerMemoryPolicy(actual_policy);
} else {
DCHECK(proxy_->IsImplThread());
- EnforceManagedMemoryPolicy(actual_policy);
+ UpdateTileManagerMemoryPolicy(actual_policy);
}
// If there is already enough memory to draw everything imaginable and the
@@ -1415,9 +1462,7 @@ void LayerTreeHostImpl::ReclaimResources(const CompositorFrameAck* ack) {
// In OOM, we now might be able to release more resources that were held
// because they were exported.
- if (tile_manager_) {
- DCHECK(resource_pool_);
-
+ if (resource_pool_) {
resource_pool_->CheckBusyResources(false);
resource_pool_->ReduceResourceUsage();
}
@@ -1496,10 +1541,7 @@ void LayerTreeHostImpl::DrawLayers(FrameData* frame) {
!output_surface_->context_provider());
rendering_stats_instrumentation_->IncrementFrameCount(1);
- if (tile_manager_) {
- memory_history_->SaveEntry(
- tile_manager_->memory_stats_from_last_assign());
- }
+ memory_history_->SaveEntry(tile_manager_->memory_stats_from_last_assign());
if (debug_state_.ShowHudRects()) {
debug_rect_history_->SaveDebugRectsForCurrentFrame(
@@ -1509,13 +1551,6 @@ void LayerTreeHostImpl::DrawLayers(FrameData* frame) {
debug_state_);
}
- if (!settings_.impl_side_painting && debug_state_.continuous_painting) {
- const RenderingStats& stats =
- rendering_stats_instrumentation_->GetRenderingStats();
- paint_time_counter_->SavePaintTime(
- stats.begin_main_frame_to_commit_duration.GetLastTimeDelta());
- }
-
bool is_new_trace;
TRACE_EVENT_IS_NEW_TRACE(&is_new_trace);
if (is_new_trace) {
@@ -1549,7 +1584,9 @@ void LayerTreeHostImpl::DrawLayers(FrameData* frame) {
if (draw_mode == DRAW_MODE_RESOURCELESS_SOFTWARE) {
bool disable_picture_quad_image_filtering =
- IsActivelyScrolling() || animation_registrar_->needs_animate_layers();
+ IsActivelyScrolling() ||
+ (animation_host_ ? animation_host_->NeedsAnimateLayers()
+ : animation_registrar_->needs_animate_layers());
scoped_ptr<SoftwareRenderer> temp_software_renderer =
SoftwareRenderer::Create(this, &settings_.renderer_settings,
@@ -1593,10 +1630,6 @@ void LayerTreeHostImpl::DidDrawAllLayers(const FrameData& frame) {
for (auto& it : video_frame_controllers_)
it->DidDrawFrame();
-
- // Once all layers have been drawn, pending texture uploads should no
- // longer block future uploads.
- resource_provider_->MarkPendingUploadsAsNonBlocking();
}
void LayerTreeHostImpl::FinishAllRendering() {
@@ -1674,11 +1707,13 @@ void LayerTreeHostImpl::UpdateTreeResourcesForGpuRasterizationIfNeeded() {
return;
// Clean up and replace existing tile manager with another one that uses
- // appropriate rasterizer.
+ // appropriate rasterizer. Only do this however if we already have a
+ // resource pool, since otherwise we might not be able to create a new
+ // one.
ReleaseTreeResources();
- if (tile_manager_) {
- DestroyTileManager();
- CreateAndSetTileManager();
+ if (resource_pool_) {
+ CleanUpTileManager();
+ CreateTileManagerResources();
}
RecreateTreeResources();
@@ -1723,16 +1758,7 @@ bool LayerTreeHostImpl::SwapBuffers(const LayerTreeHostImpl::FrameData& frame) {
}
void LayerTreeHostImpl::WillBeginImplFrame(const BeginFrameArgs& args) {
- // Sample the frame time now. This time will be used for updating animations
- // when we draw.
- DCHECK(!current_begin_frame_args_.IsValid());
- current_begin_frame_args_ = args;
- // TODO(mithro): Stop overriding the frame time once the usage of frame
- // timing is unified.
- current_begin_frame_args_.frame_time = gfx::FrameTime::Now();
-
- // Cache the begin impl frame interval
- begin_impl_frame_interval_ = args.interval;
+ current_begin_frame_tracker_.Start(args);
if (is_likely_to_require_a_draw_) {
// Optimistically schedule a draw. This will let us expect the tile manager
@@ -1746,8 +1772,7 @@ void LayerTreeHostImpl::WillBeginImplFrame(const BeginFrameArgs& args) {
}
void LayerTreeHostImpl::DidFinishImplFrame() {
- DCHECK(current_begin_frame_args_.IsValid());
- current_begin_frame_args_ = BeginFrameArgs();
+ current_begin_frame_tracker_.Finish();
}
void LayerTreeHostImpl::UpdateViewportContainerSizes() {
@@ -1806,8 +1831,7 @@ void LayerTreeHostImpl::UpdateViewportContainerSizes() {
void LayerTreeHostImpl::SynchronouslyInitializeAllTiles() {
// Only valid for the single-threaded non-scheduled/synchronous case
// using the zero copy raster worker pool.
- if (tile_manager_)
- single_thread_synchronous_task_graph_runner_->RunUntilIdle();
+ single_thread_synchronous_task_graph_runner_->RunUntilIdle();
}
void LayerTreeHostImpl::DidLoseOutputSurface() {
@@ -1837,11 +1861,15 @@ LayerImpl* LayerTreeHostImpl::CurrentlyScrollingLayer() const {
}
bool LayerTreeHostImpl::IsActivelyScrolling() const {
- return (did_lock_scrolling_layer_ && CurrentlyScrollingLayer()) ||
- (InnerViewportScrollLayer() &&
- InnerViewportScrollLayer()->IsExternalFlingActive()) ||
- (OuterViewportScrollLayer() &&
- OuterViewportScrollLayer()->IsExternalFlingActive());
+ if (!CurrentlyScrollingLayer())
+ return false;
+ if (root_layer_scroll_offset_delegate_ &&
+ (CurrentlyScrollingLayer() == InnerViewportScrollLayer() ||
+ CurrentlyScrollingLayer() == OuterViewportScrollLayer())) {
+ // ScrollDelegate cannot determine current scroll, so assume no.
+ return false;
+ }
+ return did_lock_scrolling_layer_;
}
// Content layers can be either directly scrollable or contained in an outer
@@ -1911,15 +1939,16 @@ void LayerTreeHostImpl::ActivateSyncTree() {
active_tree_->ProcessUIResourceRequestQueue();
}
+ // bounds_delta isn't a pushed property, so the newly-pushed property tree
+ // won't already account for current bounds_delta values.
+ active_tree_->UpdatePropertyTreesForBoundsDelta();
active_tree_->DidBecomeActive();
ActivateAnimations();
- if (settings_.impl_side_painting) {
- client_->RenewTreePriority();
- // If we have any picture layers, then by activating we also modified tile
- // priorities.
- if (!active_tree_->picture_layers().empty())
- DidModifyTilePriorities();
- }
+ client_->RenewTreePriority();
+ // If we have any picture layers, then by activating we also modified tile
+ // priorities.
+ if (!active_tree_->picture_layers().empty())
+ DidModifyTilePriorities();
client_->OnCanDrawStateChanged(CanDraw());
client_->DidActivateSyncTree();
@@ -1954,7 +1983,7 @@ void LayerTreeHostImpl::SetVisible(bool visible) {
return;
visible_ = visible;
DidVisibilityChange(this, visible_);
- EnforceManagedMemoryPolicy(ActualManagedMemoryPolicy());
+ UpdateTileManagerMemoryPolicy(ActualManagedMemoryPolicy());
// If we just became visible, we have to ensure that we draw high res tiles,
// to prevent checkerboard/low res flashes.
@@ -1963,10 +1992,11 @@ void LayerTreeHostImpl::SetVisible(bool visible) {
else
EvictAllUIResources();
- // Evict tiles immediately if invisible since this tab may never get another
- // draw or timer tick.
- if (!visible_)
- PrepareTiles();
+ // Call PrepareTiles unconditionally on visibility change since this tab may
+ // never get another draw or timer tick. When becoming visible we care about
+ // unblocking the scheduler which might be waiting for activation / ready to
+ // draw. When becoming invisible we care about evicting tiles immediately.
+ PrepareTiles();
if (!renderer_)
return;
@@ -2000,11 +2030,6 @@ size_t LayerTreeHostImpl::memory_allocation_limit_bytes() const {
return ActualManagedMemoryPolicy().bytes_limit_when_visible;
}
-int LayerTreeHostImpl::memory_allocation_priority_cutoff() const {
- return ManagedMemoryPolicy::PriorityCutoffToValue(
- ActualManagedMemoryPolicy().priority_cutoff_when_visible);
-}
-
void LayerTreeHostImpl::ReleaseTreeResources() {
active_tree_->ReleaseResources();
if (pending_tree_)
@@ -2056,28 +2081,13 @@ void LayerTreeHostImpl::CreateAndSetRenderer() {
client_->UpdateRendererCapabilitiesOnImplThread();
}
-void LayerTreeHostImpl::CreateAndSetTileManager() {
- DCHECK(!tile_manager_);
- DCHECK(settings_.impl_side_painting);
- DCHECK(output_surface_);
- DCHECK(resource_provider_);
-
+void LayerTreeHostImpl::CreateTileManagerResources() {
CreateResourceAndTileTaskWorkerPool(&tile_task_worker_pool_, &resource_pool_,
&staging_resource_pool_);
- DCHECK(tile_task_worker_pool_);
- DCHECK(resource_pool_);
-
- base::SingleThreadTaskRunner* task_runner =
- proxy_->HasImplThread() ? proxy_->ImplThreadTaskRunner()
- : proxy_->MainThreadTaskRunner();
- DCHECK(task_runner);
- size_t scheduled_raster_task_limit =
+ tile_manager_->SetResources(
+ resource_pool_.get(), tile_task_worker_pool_->AsTileTaskRunner(),
IsSynchronousSingleThreaded() ? std::numeric_limits<size_t>::max()
- : settings_.scheduled_raster_task_limit;
- tile_manager_ = TileManager::Create(
- this, task_runner, resource_pool_.get(),
- tile_task_worker_pool_->AsTileTaskRunner(), scheduled_raster_task_limit);
-
+ : settings_.scheduled_raster_task_limit);
UpdateTileManagerMemoryPolicy(ActualManagedMemoryPolicy());
}
@@ -2085,10 +2095,7 @@ void LayerTreeHostImpl::CreateResourceAndTileTaskWorkerPool(
scoped_ptr<TileTaskWorkerPool>* tile_task_worker_pool,
scoped_ptr<ResourcePool>* resource_pool,
scoped_ptr<ResourcePool>* staging_resource_pool) {
- base::SingleThreadTaskRunner* task_runner =
- proxy_->HasImplThread() ? proxy_->ImplThreadTaskRunner()
- : proxy_->MainThreadTaskRunner();
- DCHECK(task_runner);
+ DCHECK(GetTaskRunner());
// Pass the single-threaded synchronous task graph runner to the worker pool
// if we're in synchronous single-threaded mode.
@@ -2105,7 +2112,7 @@ void LayerTreeHostImpl::CreateResourceAndTileTaskWorkerPool(
ResourcePool::Create(resource_provider_.get(), GL_TEXTURE_2D);
*tile_task_worker_pool = BitmapTileTaskWorkerPool::Create(
- task_runner, task_graph_runner, resource_provider_.get());
+ GetTaskRunner(), task_graph_runner, resource_provider_.get());
return;
}
@@ -2117,42 +2124,51 @@ void LayerTreeHostImpl::CreateResourceAndTileTaskWorkerPool(
use_msaa_ ? settings_.gpu_rasterization_msaa_sample_count : 0;
*tile_task_worker_pool = GpuTileTaskWorkerPool::Create(
- task_runner, task_graph_runner, context_provider,
+ GetTaskRunner(), task_graph_runner, context_provider,
resource_provider_.get(), settings_.use_distance_field_text,
msaa_sample_count);
return;
}
- if (GetRendererCapabilities().using_image) {
- unsigned image_target = settings_.use_image_texture_target;
- DCHECK_IMPLIES(
- image_target == GL_TEXTURE_RECTANGLE_ARB,
- context_provider->ContextCapabilities().gpu.texture_rectangle);
- DCHECK_IMPLIES(
- image_target == GL_TEXTURE_EXTERNAL_OES,
- context_provider->ContextCapabilities().gpu.egl_image_external);
+ DCHECK(GetRendererCapabilities().using_image);
+ unsigned image_target = settings_.use_image_texture_target;
+ DCHECK_IMPLIES(image_target == GL_TEXTURE_RECTANGLE_ARB,
+ context_provider->ContextCapabilities().gpu.texture_rectangle);
+ DCHECK_IMPLIES(
+ image_target == GL_TEXTURE_EXTERNAL_OES,
+ context_provider->ContextCapabilities().gpu.egl_image_external);
- if (settings_.use_zero_copy || IsSynchronousSingleThreaded()) {
- *resource_pool =
- ResourcePool::Create(resource_provider_.get(), image_target);
+ if (settings_.use_zero_copy) {
+ *resource_pool =
+ ResourcePool::Create(resource_provider_.get(), image_target);
- *tile_task_worker_pool = ZeroCopyTileTaskWorkerPool::Create(
- task_runner, task_graph_runner, resource_provider_.get());
- return;
- }
+ *tile_task_worker_pool = ZeroCopyTileTaskWorkerPool::Create(
+ GetTaskRunner(), task_graph_runner, resource_provider_.get());
+ return;
+ }
- if (settings_.use_one_copy) {
- // We need to create a staging resource pool when using copy rasterizer.
- *staging_resource_pool =
- ResourcePool::Create(resource_provider_.get(), image_target);
- *resource_pool =
- ResourcePool::Create(resource_provider_.get(), GL_TEXTURE_2D);
-
- *tile_task_worker_pool = OneCopyTileTaskWorkerPool::Create(
- task_runner, task_graph_runner, context_provider,
- resource_provider_.get(), staging_resource_pool_.get());
- return;
- }
+ if (settings_.use_one_copy) {
+ // Synchronous single-threaded mode depends on tiles being ready to
+ // draw when raster is complete. Therefore, it must use one of zero
+ // copy, software raster, or GPU raster.
+ DCHECK(!IsSynchronousSingleThreaded());
+
+ // We need to create a staging resource pool when using copy rasterizer.
+ *staging_resource_pool =
+ ResourcePool::Create(resource_provider_.get(), image_target);
+ *resource_pool =
+ ResourcePool::Create(resource_provider_.get(), GL_TEXTURE_2D);
+
+ int max_copy_texture_chromium_size =
+ context_provider->ContextCapabilities()
+ .gpu.max_copy_texture_chromium_size;
+
+ *tile_task_worker_pool = OneCopyTileTaskWorkerPool::Create(
+ GetTaskRunner(), task_graph_runner, context_provider,
+ resource_provider_.get(), staging_resource_pool_.get(),
+ max_copy_texture_chromium_size,
+ settings_.use_persistent_map_for_gpu_memory_buffers);
+ return;
}
// Synchronous single-threaded mode depends on tiles being ready to
@@ -2164,7 +2180,7 @@ void LayerTreeHostImpl::CreateResourceAndTileTaskWorkerPool(
resource_provider_.get(), GL_TEXTURE_2D);
*tile_task_worker_pool = PixelBufferTileTaskWorkerPool::Create(
- task_runner, task_graph_runner_, context_provider,
+ GetTaskRunner(), task_graph_runner_, context_provider,
resource_provider_.get(),
GetMaxTransferBufferUsageBytes(context_provider->ContextCapabilities(),
settings_.renderer_settings.refresh_rate));
@@ -2184,8 +2200,15 @@ void LayerTreeHostImpl::RecordMainFrameTiming(
request_ids, start_time, end_time, active_tree_->source_frame_number());
}
-void LayerTreeHostImpl::DestroyTileManager() {
- tile_manager_ = nullptr;
+void LayerTreeHostImpl::PostFrameTimingEvents(
+ scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events,
+ scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) {
+ client_->PostFrameTimingEventsOnImplThread(composite_events.Pass(),
+ main_frame_events.Pass());
+}
+
+void LayerTreeHostImpl::CleanUpTileManager() {
+ tile_manager_->FinishTasksAndCleanUp();
resource_pool_ = nullptr;
staging_resource_pool_ = nullptr;
tile_task_worker_pool_ = nullptr;
@@ -2207,7 +2230,7 @@ bool LayerTreeHostImpl::InitializeRenderer(
// Note: order is important here.
renderer_ = nullptr;
- DestroyTileManager();
+ CleanUpTileManager();
resource_provider_ = nullptr;
output_surface_ = nullptr;
@@ -2224,15 +2247,15 @@ bool LayerTreeHostImpl::InitializeRenderer(
proxy_->blocking_main_thread_task_runner(),
settings_.renderer_settings.highp_threshold_min,
settings_.renderer_settings.use_rgba_4444_textures,
- settings_.renderer_settings.texture_id_allocation_chunk_size);
+ settings_.renderer_settings.texture_id_allocation_chunk_size,
+ settings_.use_persistent_map_for_gpu_memory_buffers);
CreateAndSetRenderer();
// Since the new renderer may be capable of MSAA, update status here.
UpdateGpuRasterizationStatus();
- if (settings_.impl_side_painting && settings_.raster_enabled)
- CreateAndSetTileManager();
+ CreateTileManagerResources();
RecreateTreeResources();
// Initialize vsync parameters to sane values.
@@ -2419,18 +2442,42 @@ static bool HasScrollAncestor(LayerImpl* child, LayerImpl* scroll_ancestor) {
return false;
}
+InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl(
+ LayerImpl* scrolling_layer_impl,
+ InputHandler::ScrollInputType type) {
+ if (!scrolling_layer_impl)
+ return SCROLL_IGNORED;
+
+ top_controls_manager_->ScrollBegin();
+
+ active_tree_->SetCurrentlyScrollingLayer(scrolling_layer_impl);
+ should_bubble_scrolls_ = (type != NON_BUBBLING_GESTURE);
+ wheel_scrolling_ = (type == WHEEL);
+ client_->RenewTreePriority();
+ UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", false);
+ return SCROLL_STARTED;
+}
+
+InputHandler::ScrollStatus LayerTreeHostImpl::RootScrollBegin(
+ InputHandler::ScrollInputType type) {
+ TRACE_EVENT0("cc", "LayerTreeHostImpl::RootScrollBegin");
+
+ DCHECK(!CurrentlyScrollingLayer());
+ ClearCurrentlyScrollingLayer();
+
+ return ScrollBeginImpl(InnerViewportScrollLayer(), type);
+}
+
InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin(
const gfx::Point& viewport_point,
InputHandler::ScrollInputType type) {
TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBegin");
- top_controls_manager_->ScrollBegin();
-
DCHECK(!CurrentlyScrollingLayer());
ClearCurrentlyScrollingLayer();
- gfx::PointF device_viewport_point = gfx::ScalePoint(viewport_point,
- device_scale_factor_);
+ gfx::PointF device_viewport_point =
+ gfx::ScalePoint(viewport_point, device_scale_factor_);
LayerImpl* layer_impl =
active_tree_->FindLayerThatIsHitByPoint(device_viewport_point);
@@ -2443,27 +2490,16 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin(
}
bool scroll_on_main_thread = false;
- LayerImpl* scrolling_layer_impl =
- FindScrollLayerForDeviceViewportPoint(device_viewport_point,
- type,
- layer_impl,
- &scroll_on_main_thread,
- &scroll_affects_scroll_handler_);
+ LayerImpl* scrolling_layer_impl = FindScrollLayerForDeviceViewportPoint(
+ device_viewport_point, type, layer_impl, &scroll_on_main_thread,
+ &scroll_affects_scroll_handler_);
if (scroll_on_main_thread) {
UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true);
return SCROLL_ON_MAIN_THREAD;
}
- if (scrolling_layer_impl) {
- active_tree_->SetCurrentlyScrollingLayer(scrolling_layer_impl);
- should_bubble_scrolls_ = (type != NON_BUBBLING_GESTURE);
- wheel_scrolling_ = (type == WHEEL);
- client_->RenewTreePriority();
- UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", false);
- return SCROLL_STARTED;
- }
- return SCROLL_IGNORED;
+ return ScrollBeginImpl(scrolling_layer_impl, type);
}
InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated(
@@ -2555,13 +2591,6 @@ gfx::Vector2dF LayerTreeHostImpl::ScrollLayerWithViewportSpaceDelta(
if (start_clipped || end_clipped)
return gfx::Vector2dF();
- // local_start_point and local_end_point are in content space but we want to
- // move them to layer space for scrolling.
- float width_scale = 1.f / layer_impl->contents_scale_x();
- float height_scale = 1.f / layer_impl->contents_scale_y();
- local_start_point.Scale(width_scale, height_scale);
- local_end_point.Scale(width_scale, height_scale);
-
// Apply the scroll delta.
gfx::ScrollOffset previous_offset = layer_impl->CurrentScrollOffset();
layer_impl->ScrollBy(local_end_point - local_start_point);
@@ -2572,16 +2601,11 @@ gfx::Vector2dF LayerTreeHostImpl::ScrollLayerWithViewportSpaceDelta(
// ScreenSpaceTransform.
gfx::PointF actual_local_end_point =
local_start_point + gfx::Vector2dF(scrolled.x(), scrolled.y());
- gfx::PointF actual_local_content_end_point =
- gfx::ScalePoint(actual_local_end_point,
- 1.f / width_scale,
- 1.f / height_scale);
// Calculate the applied scroll delta in viewport space coordinates.
gfx::PointF actual_screen_space_end_point =
MathUtil::MapPoint(layer_impl->screen_space_transform(),
- actual_local_content_end_point,
- &end_clipped);
+ actual_local_end_point, &end_clipped);
DCHECK(!end_clipped);
if (end_clipped)
return gfx::Vector2dF();
@@ -2601,7 +2625,10 @@ static gfx::Vector2dF ScrollLayerWithLocalDelta(
layer_impl->ScrollBy(delta);
gfx::ScrollOffset scrolled =
layer_impl->CurrentScrollOffset() - previous_offset;
- return gfx::Vector2dF(scrolled.x(), scrolled.y());
+ gfx::Vector2dF consumed_scroll(scrolled.x(), scrolled.y());
+ consumed_scroll.Scale(page_scale_factor);
+
+ return consumed_scroll;
}
gfx::Vector2dF LayerTreeHostImpl::ScrollLayer(LayerImpl* layer_impl,
@@ -2645,6 +2672,13 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy(
bool did_scroll_y = false;
bool did_scroll_top_controls = false;
+ if (pinch_gesture_active_ && settings().invert_viewport_scroll_order) {
+ // Scrolls during a pinch gesture should pan the visual viewport, rather
+ // than a typical bubbling scroll.
+ viewport()->Pan(pending_delta);
+ return InputHandlerScrollResult();
+ }
+
for (LayerImpl* layer_impl = CurrentlyScrollingLayer();
layer_impl;
layer_impl = nextLayerInScrollOrder(layer_impl)) {
@@ -2656,9 +2690,11 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy(
gfx::Vector2dF applied_delta;
if (layer_impl == InnerViewportScrollLayer()) {
+ bool affect_top_controls = true;
Viewport::ScrollResult result = viewport()->ScrollBy(pending_delta,
viewport_point,
- wheel_scrolling_);
+ wheel_scrolling_,
+ affect_top_controls);
applied_delta = result.applied_delta;
unused_root_delta = result.unused_scroll_delta;
did_scroll_top_controls = result.top_controls_applied_delta.y() != 0;
@@ -2807,19 +2843,15 @@ void LayerTreeHostImpl::ScrollEnd() {
}
InputHandler::ScrollStatus LayerTreeHostImpl::FlingScrollBegin() {
- if (!active_tree_->CurrentlyScrollingLayer())
- return SCROLL_IGNORED;
-
- if (settings_.ignore_root_layer_flings &&
- (active_tree_->CurrentlyScrollingLayer() == InnerViewportScrollLayer() ||
- active_tree_->CurrentlyScrollingLayer() == OuterViewportScrollLayer())) {
- ClearCurrentlyScrollingLayer();
+ if (!CurrentlyScrollingLayer())
return SCROLL_IGNORED;
- }
- if (!wheel_scrolling_) {
+ bool currently_scrolling_viewport =
+ CurrentlyScrollingLayer() == OuterViewportScrollLayer() ||
+ CurrentlyScrollingLayer() == InnerViewportScrollLayer();
+ if (!wheel_scrolling_ && !currently_scrolling_viewport) {
// Allow the fling to lock to the first layer that moves after the initial
- // fling |ScrollBy()| event.
+ // fling |ScrollBy()| event, unless we're already scrolling the viewport.
did_lock_scrolling_layer_ = false;
should_bubble_scrolls_ = false;
}
@@ -2833,8 +2865,7 @@ float LayerTreeHostImpl::DeviceSpaceDistanceToLayer(
if (!layer_impl)
return std::numeric_limits<float>::max();
- gfx::Rect layer_impl_bounds(
- layer_impl->content_bounds());
+ gfx::Rect layer_impl_bounds(layer_impl->bounds());
gfx::RectF device_viewport_layer_impl_bounds = MathUtil::MapClippedRect(
layer_impl->screen_space_transform(),
@@ -2913,7 +2944,6 @@ bool LayerTreeHostImpl::HandleMouseOverScrollbar(LayerImpl* layer_impl,
void LayerTreeHostImpl::PinchGestureBegin() {
pinch_gesture_active_ = true;
- previous_pinch_anchor_ = gfx::Point();
client_->RenewTreePriority();
pinch_gesture_end_should_clear_scrolling_layer_ = !CurrentlyScrollingLayer();
if (active_tree_->OuterViewportScrollLayer()) {
@@ -2938,35 +2968,7 @@ void LayerTreeHostImpl::PinchGestureUpdate(float magnify_delta,
// the pinch update.
active_tree_->SetRootLayerScrollOffsetDelegate(NULL);
- // Keep the center-of-pinch anchor specified by (x, y) in a stable
- // position over the course of the magnify.
- float page_scale = active_tree_->current_page_scale_factor();
- gfx::PointF previous_scale_anchor = gfx::ScalePoint(anchor, 1.f / page_scale);
- active_tree_->SetPageScaleOnActiveTree(page_scale * magnify_delta);
- page_scale = active_tree_->current_page_scale_factor();
- gfx::PointF new_scale_anchor = gfx::ScalePoint(anchor, 1.f / page_scale);
- gfx::Vector2dF move = previous_scale_anchor - new_scale_anchor;
-
- previous_pinch_anchor_ = anchor;
-
- // If clamping the inner viewport scroll offset causes a change, it should
- // be accounted for from the intended move.
- move -= InnerViewportScrollLayer()->ClampScrollToMaxScrollOffset();
-
- // We manually manage the bubbling behaviour here as it is different to that
- // implemented in LayerTreeHostImpl::ScrollBy(). Specifically:
- // 1) we want to explicit limit the bubbling to the outer/inner viewports,
- // 2) we don't want the directional limitations on the unused parts that
- // ScrollBy() implements, and
- // 3) pinching should not engage the top controls manager.
- gfx::Vector2dF unused = OuterViewportScrollLayer()
- ? OuterViewportScrollLayer()->ScrollBy(move)
- : move;
-
- if (!unused.IsZero()) {
- InnerViewportScrollLayer()->ScrollBy(unused);
- InnerViewportScrollLayer()->ClampScrollToMaxScrollOffset();
- }
+ viewport()->PinchUpdate(magnify_delta, anchor);
active_tree_->SetRootLayerScrollOffsetDelegate(
root_layer_scroll_offset_delegate_);
@@ -2982,6 +2984,7 @@ void LayerTreeHostImpl::PinchGestureEnd() {
pinch_gesture_end_should_clear_scrolling_layer_ = false;
ClearCurrentlyScrollingLayer();
}
+ viewport()->PinchEnd();
top_controls_manager_->PinchEnd();
client_->SetNeedsCommitOnImplThread();
// When a pinch ends, we may be displaying content cached at incorrect scales,
@@ -3049,6 +3052,12 @@ void LayerTreeHostImpl::ScrollViewportBy(gfx::Vector2dF scroll_delta) {
InnerViewportScrollLayer()->ScrollBy(unused_delta);
}
+void LayerTreeHostImpl::AnimateInput(base::TimeTicks monotonic_time) {
+ DCHECK(proxy_->IsImplThread());
+ if (input_handler_client_)
+ input_handler_client_->Animate(monotonic_time);
+}
+
void LayerTreeHostImpl::AnimatePageScale(base::TimeTicks monotonic_time) {
if (!page_scale_animation_)
return;
@@ -3115,18 +3124,31 @@ void LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time) {
if (!settings_.accelerated_animation_enabled || !active_tree_->root_layer())
return;
- if (animation_registrar_->AnimateLayers(monotonic_time))
- SetNeedsAnimate();
+ if (animation_host_) {
+ if (animation_host_->AnimateLayers(monotonic_time))
+ SetNeedsAnimate();
+ } else {
+ if (animation_registrar_->AnimateLayers(monotonic_time))
+ SetNeedsAnimate();
+ }
}
void LayerTreeHostImpl::UpdateAnimationState(bool start_ready_animations) {
if (!settings_.accelerated_animation_enabled || !active_tree_->root_layer())
return;
- scoped_ptr<AnimationEventsVector> events =
- animation_registrar_->CreateEvents();
- const bool has_active_animations = animation_registrar_->UpdateAnimationState(
- start_ready_animations, events.get());
+ bool has_active_animations = false;
+ scoped_ptr<AnimationEventsVector> events;
+
+ if (animation_host_) {
+ events = animation_host_->CreateEvents();
+ has_active_animations = animation_host_->UpdateAnimationState(
+ start_ready_animations, events.get());
+ } else {
+ events = animation_registrar_->CreateEvents();
+ has_active_animations = animation_registrar_->UpdateAnimationState(
+ start_ready_animations, events.get());
+ }
if (!events->empty())
client_->PostAnimationEventsToMainThreadOnImplThread(events.Pass());
@@ -3139,8 +3161,13 @@ void LayerTreeHostImpl::ActivateAnimations() {
if (!settings_.accelerated_animation_enabled || !active_tree_->root_layer())
return;
- if (animation_registrar_->ActivateAnimations())
- SetNeedsAnimate();
+ if (animation_host_) {
+ if (animation_host_->ActivateAnimations())
+ SetNeedsAnimate();
+ } else {
+ if (animation_registrar_->ActivateAnimations())
+ SetNeedsAnimate();
+ }
}
std::string LayerTreeHostImpl::LayerTreeAsJson() const {
@@ -3148,15 +3175,11 @@ std::string LayerTreeHostImpl::LayerTreeAsJson() const {
if (active_tree_->root_layer()) {
scoped_ptr<base::Value> json(active_tree_->root_layer()->LayerTreeAsJson());
base::JSONWriter::WriteWithOptions(
- json.get(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &str);
+ *json, base::JSONWriter::OPTIONS_PRETTY_PRINT, &str);
}
return str;
}
-int LayerTreeHostImpl::SourceAnimationFrameNumber() const {
- return fps_counter_->current_frame_number();
-}
-
void LayerTreeHostImpl::StartAnimatingScrollbarAnimationController(
ScrollbarAnimationController* controller) {
scrollbar_animation_controllers_.insert(controller);
@@ -3182,8 +3205,9 @@ void LayerTreeHostImpl::AddVideoFrameController(
VideoFrameController* controller) {
bool was_empty = video_frame_controllers_.empty();
video_frame_controllers_.insert(controller);
- if (current_begin_frame_args_.IsValid())
- controller->OnBeginFrame(current_begin_frame_args_);
+ if (current_begin_frame_tracker_.DangerousMethodHasStarted() &&
+ !current_begin_frame_tracker_.DangerousMethodHasFinished())
+ controller->OnBeginFrame(current_begin_frame_tracker_.Current());
if (was_empty)
client_->SetVideoNeedsBeginFrames(true);
}
@@ -3210,14 +3234,13 @@ TreePriority LayerTreeHostImpl::GetTreePriority() const {
}
BeginFrameArgs LayerTreeHostImpl::CurrentBeginFrameArgs() const {
- // Try to use the current frame time to keep animations non-jittery. But if
- // we're not in a frame (because this is during an input event or a delayed
- // task), fall back to physical time. This should still be monotonic.
- if (current_begin_frame_args_.IsValid())
- return current_begin_frame_args_;
- return BeginFrameArgs::Create(
- BEGINFRAME_FROM_HERE, gfx::FrameTime::Now(), base::TimeTicks(),
- BeginFrameArgs::DefaultInterval(), BeginFrameArgs::NORMAL);
+ // TODO(mithro): Replace call with current_begin_frame_tracker_.Current()
+ // once all calls which happens outside impl frames are fixed.
+ return current_begin_frame_tracker_.DangerousMethodCurrentOrLast();
+}
+
+base::TimeDelta LayerTreeHostImpl::CurrentBeginFrameInterval() const {
+ return current_begin_frame_tracker_.Interval();
}
scoped_refptr<base::trace_event::ConvertableToTraceFormat>
@@ -3310,7 +3333,7 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
// Allow for multiple creation requests with the same UIResourceId. The
// previous resource is simply deleted.
- ResourceProvider::ResourceId id = ResourceIdForUIResource(uid);
+ ResourceId id = ResourceIdForUIResource(uid);
if (id)
DeleteUIResource(uid);
@@ -3343,7 +3366,7 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
}
void LayerTreeHostImpl::DeleteUIResource(UIResourceId uid) {
- ResourceProvider::ResourceId id = ResourceIdForUIResource(uid);
+ ResourceId id = ResourceIdForUIResource(uid);
if (id) {
resource_provider_->DeleteResource(id);
ui_resource_map_.erase(uid);
@@ -3368,8 +3391,7 @@ void LayerTreeHostImpl::EvictAllUIResources() {
client_->RenewTreePriority();
}
-ResourceProvider::ResourceId LayerTreeHostImpl::ResourceIdForUIResource(
- UIResourceId uid) const {
+ResourceId LayerTreeHostImpl::ResourceIdForUIResource(UIResourceId uid) const {
UIResourceMap::const_iterator iter = ui_resource_map_.find(uid);
if (iter != ui_resource_map_.end())
return iter->second.resource_id;
@@ -3425,6 +3447,10 @@ void LayerTreeHostImpl::ScrollAnimationCreate(
LayerImpl* layer_impl,
const gfx::ScrollOffset& target_offset,
const gfx::ScrollOffset& current_offset) {
+ if (animation_host_)
+ return animation_host_->ImplOnlyScrollAnimationCreate(
+ layer_impl->id(), target_offset, current_offset);
+
scoped_ptr<ScrollOffsetAnimationCurve> curve =
ScrollOffsetAnimationCurve::Create(target_offset,
EaseInOutTimingFunction::Create());
@@ -3441,6 +3467,11 @@ void LayerTreeHostImpl::ScrollAnimationCreate(
bool LayerTreeHostImpl::ScrollAnimationUpdateTarget(
LayerImpl* layer_impl,
const gfx::Vector2dF& scroll_delta) {
+ if (animation_host_)
+ return animation_host_->ImplOnlyScrollAnimationUpdateTarget(
+ layer_impl->id(), scroll_delta, layer_impl->MaxScrollOffset(),
+ CurrentBeginFrameArgs().frame_time);
+
Animation* animation =
layer_impl->layer_animation_controller()
? layer_impl->layer_animation_controller()->GetAnimation(
@@ -3464,4 +3495,132 @@ bool LayerTreeHostImpl::ScrollAnimationUpdateTarget(
return true;
}
+
+bool LayerTreeHostImpl::IsLayerInTree(int layer_id,
+ LayerTreeType tree_type) const {
+ if (tree_type == LayerTreeType::ACTIVE) {
+ return active_tree() ? active_tree()->LayerById(layer_id) != nullptr
+ : false;
+ } else {
+ if (pending_tree() && pending_tree()->LayerById(layer_id))
+ return true;
+ if (recycle_tree() && recycle_tree()->LayerById(layer_id))
+ return true;
+
+ return false;
+ }
+}
+
+void LayerTreeHostImpl::SetMutatorsNeedCommit() {
+ SetNeedsCommit();
+}
+
+void LayerTreeHostImpl::SetTreeLayerFilterMutated(
+ int layer_id,
+ LayerTreeImpl* tree,
+ const FilterOperations& filters) {
+ if (!tree)
+ return;
+
+ LayerAnimationValueObserver* layer = tree->LayerById(layer_id);
+ if (layer)
+ layer->OnFilterAnimated(filters);
+}
+
+void LayerTreeHostImpl::SetTreeLayerOpacityMutated(int layer_id,
+ LayerTreeImpl* tree,
+ float opacity) {
+ if (!tree)
+ return;
+
+ LayerAnimationValueObserver* layer = tree->LayerById(layer_id);
+ if (layer)
+ layer->OnOpacityAnimated(opacity);
+}
+
+void LayerTreeHostImpl::SetTreeLayerTransformMutated(
+ int layer_id,
+ LayerTreeImpl* tree,
+ const gfx::Transform& transform) {
+ if (!tree)
+ return;
+
+ LayerAnimationValueObserver* layer = tree->LayerById(layer_id);
+ if (layer)
+ layer->OnTransformAnimated(transform);
+}
+
+void LayerTreeHostImpl::SetTreeLayerScrollOffsetMutated(
+ int layer_id,
+ LayerTreeImpl* tree,
+ const gfx::ScrollOffset& scroll_offset) {
+ if (!tree)
+ return;
+
+ LayerAnimationValueObserver* layer = tree->LayerById(layer_id);
+ if (layer)
+ layer->OnScrollOffsetAnimated(scroll_offset);
+}
+
+void LayerTreeHostImpl::SetLayerFilterMutated(int layer_id,
+ LayerTreeType tree_type,
+ const FilterOperations& filters) {
+ if (tree_type == LayerTreeType::ACTIVE) {
+ SetTreeLayerFilterMutated(layer_id, active_tree(), filters);
+ } else {
+ SetTreeLayerFilterMutated(layer_id, pending_tree(), filters);
+ SetTreeLayerFilterMutated(layer_id, recycle_tree(), filters);
+ }
+}
+
+void LayerTreeHostImpl::SetLayerOpacityMutated(int layer_id,
+ LayerTreeType tree_type,
+ float opacity) {
+ if (tree_type == LayerTreeType::ACTIVE) {
+ SetTreeLayerOpacityMutated(layer_id, active_tree(), opacity);
+ } else {
+ SetTreeLayerOpacityMutated(layer_id, pending_tree(), opacity);
+ SetTreeLayerOpacityMutated(layer_id, recycle_tree(), opacity);
+ }
+}
+
+void LayerTreeHostImpl::SetLayerTransformMutated(
+ int layer_id,
+ LayerTreeType tree_type,
+ const gfx::Transform& transform) {
+ if (tree_type == LayerTreeType::ACTIVE) {
+ SetTreeLayerTransformMutated(layer_id, active_tree(), transform);
+ } else {
+ SetTreeLayerTransformMutated(layer_id, pending_tree(), transform);
+ SetTreeLayerTransformMutated(layer_id, recycle_tree(), transform);
+ }
+}
+
+void LayerTreeHostImpl::SetLayerScrollOffsetMutated(
+ int layer_id,
+ LayerTreeType tree_type,
+ const gfx::ScrollOffset& scroll_offset) {
+ if (tree_type == LayerTreeType::ACTIVE) {
+ SetTreeLayerScrollOffsetMutated(layer_id, active_tree(), scroll_offset);
+ } else {
+ SetTreeLayerScrollOffsetMutated(layer_id, pending_tree(), scroll_offset);
+ SetTreeLayerScrollOffsetMutated(layer_id, recycle_tree(), scroll_offset);
+ }
+}
+
+void LayerTreeHostImpl::ScrollOffsetAnimationFinished() {
+ ScrollEnd();
+}
+
+gfx::ScrollOffset LayerTreeHostImpl::GetScrollOffsetForAnimation(
+ int layer_id) const {
+ if (active_tree()) {
+ LayerAnimationValueProvider* layer = active_tree()->LayerById(layer_id);
+ if (layer)
+ return layer->ScrollOffsetForAnimation();
+ }
+
+ return gfx::ScrollOffset();
+}
+
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_impl.h b/chromium/cc/trees/layer_tree_host_impl.h
index 42454a61c00..f66f5b1de83 100644
--- a/chromium/cc/trees/layer_tree_host_impl.h
+++ b/chromium/cc/trees/layer_tree_host_impl.h
@@ -32,11 +32,13 @@
#include "cc/quads/render_pass.h"
#include "cc/resources/resource_provider.h"
#include "cc/resources/ui_resource_client.h"
+#include "cc/scheduler/begin_frame_tracker.h"
#include "cc/scheduler/commit_earlyout_reason.h"
#include "cc/scheduler/draw_result.h"
#include "cc/scheduler/video_frame_controller.h"
#include "cc/tiles/tile_manager.h"
#include "cc/trees/layer_tree_settings.h"
+#include "cc/trees/mutator_host_client.h"
#include "cc/trees/proxy.h"
#include "skia/ext/refptr.h"
#include "third_party/skia/include/core/SkColor.h"
@@ -48,6 +50,7 @@ class ScrollOffset;
namespace cc {
+class AnimationHost;
class CompletionEvent;
class CompositorFrameMetadata;
class DebugRectHistory;
@@ -109,15 +112,12 @@ class LayerTreeHostImplClient {
virtual void SetVideoNeedsBeginFrames(bool needs_begin_frames) = 0;
virtual void PostAnimationEventsToMainThreadOnImplThread(
scoped_ptr<AnimationEventsVector> events) = 0;
- // Returns true if resources were deleted by this call.
- virtual bool ReduceContentsTextureMemoryOnImplThread(
- size_t limit_bytes,
- int priority_cutoff) = 0;
virtual bool IsInsideDraw() = 0;
virtual void RenewTreePriority() = 0;
virtual void PostDelayedAnimationTaskOnImplThread(const base::Closure& task,
base::TimeDelta delay) = 0;
virtual void DidActivateSyncTree() = 0;
+ virtual void WillPrepareTiles() = 0;
virtual void DidPrepareTiles() = 0;
// Called when page scale animation has completed on the impl thread.
@@ -126,6 +126,10 @@ class LayerTreeHostImplClient {
// Called when output surface asks for a draw.
virtual void OnDrawForOutputSurface() = 0;
+ virtual void PostFrameTimingEventsOnImplThread(
+ scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events,
+ scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) = 0;
+
protected:
virtual ~LayerTreeHostImplClient() {}
};
@@ -140,6 +144,7 @@ class CC_EXPORT LayerTreeHostImpl
public TopControlsManagerClient,
public ScrollbarAnimationControllerClient,
public VideoFrameControllerClient,
+ public MutatorHostClient,
public base::SupportsWeakPtr<LayerTreeHostImpl> {
public:
static scoped_ptr<LayerTreeHostImpl> Create(
@@ -158,6 +163,8 @@ class CC_EXPORT LayerTreeHostImpl
InputHandler::ScrollStatus ScrollBegin(
const gfx::Point& viewport_point,
InputHandler::ScrollInputType type) override;
+ InputHandler::ScrollStatus RootScrollBegin(
+ InputHandler::ScrollInputType type) override;
InputHandler::ScrollStatus ScrollAnimated(
const gfx::Point& viewport_point,
const gfx::Vector2dF& scroll_delta) override;
@@ -180,7 +187,7 @@ class CC_EXPORT LayerTreeHostImpl
bool anchor_point,
float page_scale,
base::TimeDelta duration);
- void SetNeedsAnimate() override;
+ void SetNeedsAnimateInput() override;
bool IsCurrentlyScrollingLayerAt(const gfx::Point& viewport_point,
InputHandler::ScrollInputType type) override;
bool HaveWheelEventHandlersAt(const gfx::Point& viewport_point) override;
@@ -226,7 +233,39 @@ class CC_EXPORT LayerTreeHostImpl
void DidAnimateScrollOffset();
void SetViewportDamage(const gfx::Rect& damage_rect);
- virtual void PrepareTiles();
+ void SetTreeLayerFilterMutated(int layer_id,
+ LayerTreeImpl* tree,
+ const FilterOperations& filters);
+ void SetTreeLayerOpacityMutated(int layer_id,
+ LayerTreeImpl* tree,
+ float opacity);
+ void SetTreeLayerTransformMutated(int layer_id,
+ LayerTreeImpl* tree,
+ const gfx::Transform& transform);
+ void SetTreeLayerScrollOffsetMutated(int layer_id,
+ LayerTreeImpl* tree,
+ const gfx::ScrollOffset& scroll_offset);
+
+ // LayerTreeMutatorsClient implementation.
+ bool IsLayerInTree(int layer_id, LayerTreeType tree_type) const override;
+ void SetMutatorsNeedCommit() override;
+ void SetLayerFilterMutated(int layer_id,
+ LayerTreeType tree_type,
+ const FilterOperations& filters) override;
+ void SetLayerOpacityMutated(int layer_id,
+ LayerTreeType tree_type,
+ float opacity) override;
+ void SetLayerTransformMutated(int layer_id,
+ LayerTreeType tree_type,
+ const gfx::Transform& transform) override;
+ void SetLayerScrollOffsetMutated(
+ int layer_id,
+ LayerTreeType tree_type,
+ const gfx::ScrollOffset& scroll_offset) override;
+ void ScrollOffsetAnimationFinished() override;
+ gfx::ScrollOffset GetScrollOffsetForAnimation(int layer_id) const override;
+
+ virtual bool PrepareTiles();
// Returns DRAW_SUCCESS unless problems occured preparing the frame, and we
// should try to avoid displaying the frame. If PrepareToDraw is called,
@@ -250,6 +289,8 @@ class CC_EXPORT LayerTreeHostImpl
// Resets all of the trees to an empty state.
void ResetTreesForTesting();
+ size_t SourceAnimationFrameNumberForTesting() const;
+
DrawMode GetDrawMode() const;
// Viewport size in draw space: this size is in physical pixels and is used
@@ -265,6 +306,7 @@ class CC_EXPORT LayerTreeHostImpl
// TileManagerClient implementation.
void NotifyReadyToActivate() override;
void NotifyReadyToDraw() override;
+ void NotifyAllTileTasksCompleted() override;
void NotifyTileStateChanged(const Tile* tile) override;
scoped_ptr<RasterTilePriorityQueue> BuildRasterQueue(
TreePriority tree_priority,
@@ -316,7 +358,6 @@ class CC_EXPORT LayerTreeHostImpl
std::string LayerTreeAsJson() const;
void FinishAllRendering();
- int SourceAnimationFrameNumber() const;
virtual bool InitializeRenderer(scoped_ptr<OutputSurface> output_surface);
TileManager* tile_manager() { return tile_manager_.get(); }
@@ -388,12 +429,12 @@ class CC_EXPORT LayerTreeHostImpl
bool AnimationsAreVisible() { return visible() && CanDraw(); }
void SetNeedsCommit() { client_->SetNeedsCommitOnImplThread(); }
+ void SetNeedsAnimate();
void SetNeedsRedraw();
ManagedMemoryPolicy ActualManagedMemoryPolicy() const;
size_t memory_allocation_limit_bytes() const;
- int memory_allocation_priority_cutoff() const;
void SetViewportSize(const gfx::Size& device_viewport_size);
gfx::Size device_viewport_size() const { return device_viewport_size_; }
@@ -438,6 +479,7 @@ class CC_EXPORT LayerTreeHostImpl
AnimationRegistrar* animation_registrar() const {
return animation_registrar_.get();
}
+ AnimationHost* animation_host() const { return animation_host_.get(); }
void SetDebugState(const LayerTreeDebugState& new_debug_state);
const LayerTreeDebugState& debug_state() const { return debug_state_; }
@@ -451,12 +493,12 @@ class CC_EXPORT LayerTreeHostImpl
void SetTreePriority(TreePriority priority);
TreePriority GetTreePriority() const;
+ // TODO(mithro): Remove this methods which exposes the internal
+ // BeginFrameArgs to external callers.
virtual BeginFrameArgs CurrentBeginFrameArgs() const;
// Expected time between two begin impl frame calls.
- base::TimeDelta begin_impl_frame_interval() const {
- return begin_impl_frame_interval_;
- }
+ base::TimeDelta CurrentBeginFrameInterval() const;
void AsValueWithFrameInto(FrameData* frame,
base::trace_event::TracedValue* value) const;
@@ -473,13 +515,12 @@ class CC_EXPORT LayerTreeHostImpl
void EvictAllUIResources();
bool EvictedUIResourcesExist() const;
- virtual ResourceProvider::ResourceId ResourceIdForUIResource(
- UIResourceId uid) const;
+ virtual ResourceId ResourceIdForUIResource(UIResourceId uid) const;
virtual bool IsUIResourceOpaque(UIResourceId uid) const;
struct UIResourceData {
- ResourceProvider::ResourceId resource_id;
+ ResourceId resource_id;
gfx::Size size;
bool opaque;
};
@@ -538,6 +579,11 @@ class CC_EXPORT LayerTreeHostImpl
const BeginFrameArgs& start_of_main_frame_args,
const BeginFrameArgs& expected_next_main_frame_args);
+ // Post the given frame timing events to the requester.
+ void PostFrameTimingEvents(
+ scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events,
+ scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events);
+
protected:
LayerTreeHostImpl(
const LayerTreeSettings& settings,
@@ -562,6 +608,8 @@ class CC_EXPORT LayerTreeHostImpl
LayerTreeHostImplClient* client_;
Proxy* proxy_;
+ BeginFrameTracker current_begin_frame_tracker_;
+
private:
gfx::Vector2dF ScrollLayerWithViewportSpaceDelta(
LayerImpl* layer_impl,
@@ -569,8 +617,8 @@ class CC_EXPORT LayerTreeHostImpl
const gfx::Vector2dF& viewport_delta);
void CreateAndSetRenderer();
- void CreateAndSetTileManager();
- void DestroyTileManager();
+ void CleanUpTileManager();
+ void CreateTileManagerResources();
void ReleaseTreeResources();
void RecreateTreeResources();
@@ -587,6 +635,11 @@ class CC_EXPORT LayerTreeHostImpl
// outer if the inner is at its scroll extents.
void ScrollViewportInnerFirst(gfx::Vector2dF scroll_delta);
+ InputHandler::ScrollStatus ScrollBeginImpl(
+ LayerImpl* scrolling_layer_impl,
+ InputHandler::ScrollInputType type);
+
+ void AnimateInput(base::TimeTicks monotonic_time);
void AnimatePageScale(base::TimeTicks monotonic_time);
void AnimateScrollbars(base::TimeTicks monotonic_time);
void AnimateTopControls(base::TimeTicks monotonic_time);
@@ -617,7 +670,6 @@ class CC_EXPORT LayerTreeHostImpl
LayerImpl* layer_impl);
void StartScrollbarFadeRecursive(LayerImpl* layer);
void SetManagedMemoryPolicy(const ManagedMemoryPolicy& policy);
- void EnforceManagedMemoryPolicy(const ManagedMemoryPolicy& policy);
void MarkUIResourceNotEvicted(UIResourceId uid);
@@ -630,6 +682,12 @@ class CC_EXPORT LayerTreeHostImpl
bool ScrollAnimationUpdateTarget(LayerImpl* layer_impl,
const gfx::Vector2dF& scroll_delta);
+ base::SingleThreadTaskRunner* GetTaskRunner() const {
+ DCHECK(proxy_);
+ return proxy_->HasImplThread() ? proxy_->ImplThreadTaskRunner()
+ : proxy_->MainThreadTaskRunner();
+ }
+
typedef base::hash_map<UIResourceId, UIResourceData>
UIResourceMap;
UIResourceMap ui_resource_map_;
@@ -641,11 +699,7 @@ class CC_EXPORT LayerTreeHostImpl
scoped_ptr<OutputSurface> output_surface_;
- // |resource_provider_| and |tile_manager_| can be NULL, e.g. when using tile-
- // free rendering - see OutputSurface::ForcedDrawToSoftwareDevice().
- // |tile_manager_| can also be NULL when raster_enabled is false.
scoped_ptr<ResourceProvider> resource_provider_;
- scoped_ptr<TileManager> tile_manager_;
bool content_is_suitable_for_gpu_rasterization_;
bool has_gpu_rasterization_trigger_;
bool use_gpu_rasterization_;
@@ -686,16 +740,19 @@ class CC_EXPORT LayerTreeHostImpl
// The optional delegate for the root layer scroll offset.
LayerScrollOffsetDelegate* root_layer_scroll_offset_delegate_;
+ LayerScrollOffsetDelegate::AnimationCallback root_layer_animation_callback_;
+
const LayerTreeSettings settings_;
LayerTreeDebugState debug_state_;
bool visible_;
ManagedMemoryPolicy cached_managed_memory_policy_;
+ scoped_ptr<TileManager> tile_manager_;
+
gfx::Vector2dF accumulated_root_overscroll_;
bool pinch_gesture_active_;
bool pinch_gesture_end_should_clear_scrolling_layer_;
- gfx::Point previous_pinch_anchor_;
scoped_ptr<TopControlsManager> top_controls_manager_;
@@ -737,12 +794,8 @@ class CC_EXPORT LayerTreeHostImpl
gfx::Rect viewport_damage_rect_;
- BeginFrameArgs current_begin_frame_args_;
-
- // Expected time between two begin impl frame calls.
- base::TimeDelta begin_impl_frame_interval_;
-
scoped_ptr<AnimationRegistrar> animation_registrar_;
+ scoped_ptr<AnimationHost> animation_host_;
std::set<ScrollbarAnimationController*> scrollbar_animation_controllers_;
std::set<VideoFrameController*> video_frame_controllers_;
diff --git a/chromium/cc/trees/layer_tree_host_impl_unittest.cc b/chromium/cc/trees/layer_tree_host_impl_unittest.cc
index 8ff2f62a1e3..daa179f62eb 100644
--- a/chromium/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_impl_unittest.cc
@@ -27,8 +27,8 @@
#include "cc/layers/solid_color_layer_impl.h"
#include "cc/layers/solid_color_scrollbar_layer_impl.h"
#include "cc/layers/texture_layer_impl.h"
-#include "cc/layers/tiled_layer_impl.h"
#include "cc/layers/video_layer_impl.h"
+#include "cc/layers/viewport.h"
#include "cc/output/begin_frame_args.h"
#include "cc/output/compositor_frame_ack.h"
#include "cc/output/compositor_frame_metadata.h"
@@ -58,14 +58,12 @@
#include "cc/test/test_shared_bitmap_manager.h"
#include "cc/test/test_task_graph_runner.h"
#include "cc/test/test_web_graphics_context_3d.h"
-#include "cc/tiles/layer_tiling_data.h"
#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/single_thread_proxy.h"
#include "media/base/media.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkMallocPixelRef.h"
-#include "ui/gfx/frame_time.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/geometry/vector2d_conversions.h"
@@ -88,9 +86,6 @@ class LayerTreeHostImplTest : public testing::Test,
base::ThreadTaskRunnerHandle::Get()),
always_impl_thread_(&proxy_),
always_main_thread_blocked_(&proxy_),
- shared_bitmap_manager_(new TestSharedBitmapManager),
- gpu_memory_buffer_manager_(new TestGpuMemoryBufferManager),
- task_graph_runner_(new TestTaskGraphRunner),
on_can_draw_state_changed_called_(false),
did_notify_ready_to_activate_(false),
did_request_commit_(false),
@@ -98,19 +93,15 @@ class LayerTreeHostImplTest : public testing::Test,
did_request_animate_(false),
did_request_prepare_tiles_(false),
did_complete_page_scale_animation_(false),
- reduce_memory_result_(true),
- current_limit_bytes_(0),
- current_priority_cutoff_value_(0) {
+ reduce_memory_result_(true) {
media::InitializeMediaLibrary();
}
LayerTreeSettings DefaultSettings() {
LayerTreeSettings settings;
settings.minimum_occlusion_tracking_size = gfx::Size();
- settings.impl_side_painting = true;
settings.renderer_settings.texture_id_allocation_chunk_size = 1;
settings.report_overscroll_only_for_scrollable_axes = true;
- settings.use_pinch_virtual_viewport = true;
settings.gpu_rasterization_enabled = true;
return settings;
}
@@ -149,12 +140,6 @@ class LayerTreeHostImplTest : public testing::Test,
void SetVideoNeedsBeginFrames(bool needs_begin_frames) override {}
void PostAnimationEventsToMainThreadOnImplThread(
scoped_ptr<AnimationEventsVector> events) override {}
- bool ReduceContentsTextureMemoryOnImplThread(size_t limit_bytes,
- int priority_cutoff) override {
- current_limit_bytes_ = limit_bytes;
- current_priority_cutoff_value_ = priority_cutoff;
- return reduce_memory_result_;
- }
bool IsInsideDraw() override { return false; }
void RenewTreePriority() override {}
void PostDelayedAnimationTaskOnImplThread(const base::Closure& task,
@@ -163,11 +148,16 @@ class LayerTreeHostImplTest : public testing::Test,
requested_animation_delay_ = delay;
}
void DidActivateSyncTree() override {}
+ void WillPrepareTiles() override {}
void DidPrepareTiles() override {}
void DidCompletePageScaleAnimationOnImplThread() override {
did_complete_page_scale_animation_ = true;
}
void OnDrawForOutputSurface() override {}
+ void PostFrameTimingEventsOnImplThread(
+ scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events,
+ scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events)
+ override {}
void set_reduce_memory_result(bool reduce_memory_result) {
reduce_memory_result_ = reduce_memory_result;
@@ -177,19 +167,21 @@ class LayerTreeHostImplTest : public testing::Test,
scoped_ptr<OutputSurface> output_surface) {
host_impl_ = LayerTreeHostImpl::Create(
settings, this, &proxy_, &stats_instrumentation_,
- shared_bitmap_manager_.get(), gpu_memory_buffer_manager_.get(),
- task_graph_runner_.get(), 0);
+ &shared_bitmap_manager_, &gpu_memory_buffer_manager_,
+ &task_graph_runner_, 0);
bool init = host_impl_->InitializeRenderer(output_surface.Pass());
host_impl_->SetViewportSize(gfx::Size(10, 10));
+ // Set the BeginFrameArgs so that methods which use it are able to.
+ host_impl_->WillBeginImplFrame(
+ CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE));
return init;
}
void SetupRootLayerImpl(scoped_ptr<LayerImpl> root) {
root->SetPosition(gfx::PointF());
root->SetBounds(gfx::Size(10, 10));
- root->SetContentBounds(gfx::Size(10, 10));
root->SetDrawsContent(true);
- root->draw_properties().visible_content_rect = gfx::Rect(0, 0, 10, 10);
+ root->draw_properties().visible_layer_rect = gfx::Rect(0, 0, 10, 10);
root->SetHasRenderSurface(true);
host_impl_->active_tree()->SetRootLayer(root.Pass());
}
@@ -200,19 +192,27 @@ class LayerTreeHostImplTest : public testing::Test,
ExpectClearedScrollDeltasRecursive(layer->children()[i]);
}
- static void ExpectContains(const ScrollAndScaleSet& scroll_info,
- int id,
- const gfx::Vector2d& scroll_delta) {
+ static ::testing::AssertionResult ScrollInfoContains(
+ const ScrollAndScaleSet& scroll_info,
+ int id,
+ const gfx::Vector2d& scroll_delta) {
int times_encountered = 0;
for (size_t i = 0; i < scroll_info.scrolls.size(); ++i) {
if (scroll_info.scrolls[i].layer_id != id)
continue;
- EXPECT_VECTOR_EQ(scroll_delta, scroll_info.scrolls[i].scroll_delta);
+
+ if (scroll_delta != scroll_info.scrolls[i].scroll_delta) {
+ return ::testing::AssertionFailure()
+ << "Expected " << scroll_delta.ToString() << ", not "
+ << scroll_info.scrolls[i].scroll_delta.ToString();
+ }
times_encountered++;
}
- ASSERT_EQ(1, times_encountered);
+ if (times_encountered != 1)
+ return ::testing::AssertionFailure() << "No layer found with id " << id;
+ return ::testing::AssertionSuccess();
}
static void ExpectNone(const ScrollAndScaleSet& scroll_info, int id) {
@@ -242,7 +242,6 @@ class LayerTreeHostImplTest : public testing::Test,
scoped_ptr<LayerImpl> root =
LayerImpl::Create(layer_tree_impl, 1);
root->SetBounds(content_size);
- root->SetContentBounds(content_size);
root->SetPosition(gfx::PointF());
root->SetHasRenderSurface(true);
@@ -261,7 +260,6 @@ class LayerTreeHostImplTest : public testing::Test,
inner_scroll->SetScrollClipLayer(inner_clip->id());
inner_scroll->SetBounds(content_size);
- inner_scroll->SetContentBounds(content_size);
inner_scroll->SetPosition(gfx::PointF());
scoped_ptr<LayerImpl> outer_clip =
@@ -274,14 +272,12 @@ class LayerTreeHostImplTest : public testing::Test,
outer_scroll->SetScrollClipLayer(outer_clip->id());
outer_scroll->PushScrollOffsetFromMainThread(gfx::ScrollOffset());
outer_scroll->SetBounds(content_size);
- outer_scroll->SetContentBounds(content_size);
outer_scroll->SetPosition(gfx::PointF());
scoped_ptr<LayerImpl> contents =
LayerImpl::Create(layer_tree_impl, kContentLayerId);
contents->SetDrawsContent(true);
contents->SetBounds(content_size);
- contents->SetContentBounds(content_size);
contents->SetPosition(gfx::PointF());
outer_scroll->AddChild(contents.Pass());
@@ -307,6 +303,34 @@ class LayerTreeHostImplTest : public testing::Test,
return scroll_layer;
}
+ // Sets up a typical virtual viewport setup with one child content layer.
+ // Returns a pointer to the content layer.
+ LayerImpl* CreateBasicVirtualViewportLayers(const gfx::Size& viewport_size,
+ const gfx::Size& content_size) {
+ // CreateScrollAndContentsLayers makes the outer viewport unscrollable and
+ // the inner a different size from the outer. We'll reuse its layer
+ // hierarchy but adjust the sizing to our needs.
+ CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size);
+
+ LayerImpl* content_layer =
+ host_impl_->OuterViewportScrollLayer()->children().back();
+ content_layer->SetBounds(content_size);
+ host_impl_->OuterViewportScrollLayer()->SetBounds(content_size);
+
+ LayerImpl* outer_clip = host_impl_->OuterViewportScrollLayer()->parent();
+ outer_clip->SetBounds(viewport_size);
+
+ LayerImpl* inner_clip_layer =
+ host_impl_->InnerViewportScrollLayer()->parent()->parent();
+ inner_clip_layer->SetBounds(viewport_size);
+ host_impl_->InnerViewportScrollLayer()->SetBounds(viewport_size);
+
+ host_impl_->SetViewportSize(viewport_size);
+ host_impl_->active_tree()->DidBecomeActive();
+
+ return content_layer;
+ }
+
// TODO(wjmaclean) Add clip-layer pointer to parameters.
scoped_ptr<LayerImpl> CreateScrollableLayer(int id,
const gfx::Size& size,
@@ -318,7 +342,6 @@ class LayerTreeHostImplTest : public testing::Test,
layer->SetScrollClipLayer(clip_layer->id());
layer->SetDrawsContent(true);
layer->SetBounds(size);
- layer->SetContentBounds(size);
clip_layer->SetBounds(gfx::Size(size.width() / 2, size.height() / 2));
return layer.Pass();
}
@@ -374,32 +397,6 @@ class LayerTreeHostImplTest : public testing::Test,
EXPECT_TRUE(host_impl_->CanDraw());
EXPECT_TRUE(on_can_draw_state_changed_called_);
on_can_draw_state_changed_called_ = false;
-
- // Toggle contents textures purged without causing any evictions,
- // and make sure that it does not change can_draw.
- set_reduce_memory_result(false);
- host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
- host_impl_->memory_allocation_limit_bytes() - 1));
- EXPECT_TRUE(host_impl_->CanDraw());
- EXPECT_FALSE(on_can_draw_state_changed_called_);
- on_can_draw_state_changed_called_ = false;
-
- // Toggle contents textures purged to make sure it toggles can_draw.
- set_reduce_memory_result(true);
- host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
- host_impl_->memory_allocation_limit_bytes() - 1));
- if (always_draw) {
- EXPECT_TRUE(host_impl_->CanDraw());
- } else {
- EXPECT_FALSE(host_impl_->CanDraw());
- }
- EXPECT_TRUE(on_can_draw_state_changed_called_);
- on_can_draw_state_changed_called_ = false;
-
- host_impl_->active_tree()->ResetContentsTexturesPurged();
- EXPECT_TRUE(host_impl_->CanDraw());
- EXPECT_TRUE(on_can_draw_state_changed_called_);
- on_can_draw_state_changed_called_ = false;
}
void SetupMouseMoveAtWithDeviceScale(float device_scale_factor);
@@ -419,9 +416,9 @@ class LayerTreeHostImplTest : public testing::Test,
DebugScopedSetImplThread always_impl_thread_;
DebugScopedSetMainThreadBlocked always_main_thread_blocked_;
- scoped_ptr<TestSharedBitmapManager> shared_bitmap_manager_;
- scoped_ptr<TestGpuMemoryBufferManager> gpu_memory_buffer_manager_;
- scoped_ptr<TestTaskGraphRunner> task_graph_runner_;
+ TestSharedBitmapManager shared_bitmap_manager_;
+ TestGpuMemoryBufferManager gpu_memory_buffer_manager_;
+ TestTaskGraphRunner task_graph_runner_;
scoped_ptr<LayerTreeHostImpl> host_impl_;
FakeRenderingStatsInstrumentation stats_instrumentation_;
bool on_can_draw_state_changed_called_;
@@ -434,8 +431,16 @@ class LayerTreeHostImplTest : public testing::Test,
bool reduce_memory_result_;
base::Closure animation_task_;
base::TimeDelta requested_animation_delay_;
- size_t current_limit_bytes_;
- int current_priority_cutoff_value_;
+};
+
+// A test fixture for new animation timelines tests.
+class LayerTreeHostImplTimelinesTest : public LayerTreeHostImplTest {
+ public:
+ void SetUp() override {
+ LayerTreeSettings settings = DefaultSettings();
+ settings.use_compositor_animation_timelines = true;
+ CreateHostImpl(settings, CreateOutputSurface());
+ }
};
TEST_F(LayerTreeHostImplTest, NotifyIfCanDrawChanged) {
@@ -510,17 +515,19 @@ TEST_F(LayerTreeHostImplTest, ScrollDeltaRepeatedScrolls) {
scroll_info = host_impl_->ProcessScrollDeltas();
ASSERT_EQ(scroll_info->scrolls.size(), 1u);
- ExpectContains(*scroll_info, root->id(), scroll_delta);
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info, root->id(), scroll_delta));
gfx::Vector2d scroll_delta2(-5, 27);
root->ScrollBy(scroll_delta2);
scroll_info = host_impl_->ProcessScrollDeltas();
ASSERT_EQ(scroll_info->scrolls.size(), 1u);
- ExpectContains(*scroll_info, root->id(), scroll_delta + scroll_delta2);
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info, root->id(),
+ scroll_delta + scroll_delta2));
root->ScrollBy(gfx::Vector2d());
scroll_info = host_impl_->ProcessScrollDeltas();
- ExpectContains(*scroll_info, root->id(), scroll_delta + scroll_delta2);
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info, root->id(),
+ scroll_delta + scroll_delta2));
}
TEST_F(LayerTreeHostImplTest, ScrollRootCallsCommitAndRedraw) {
@@ -597,7 +604,8 @@ TEST_F(LayerTreeHostImplTest, ReplaceTreeWhileScrolling) {
host_impl_->ScrollBy(gfx::Point(), scroll_delta);
host_impl_->ScrollEnd();
scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
- ExpectContains(*scroll_info, scroll_layer->id(), scroll_delta);
+ EXPECT_TRUE(
+ ScrollInfoContains(*scroll_info, scroll_layer->id(), scroll_delta));
}
TEST_F(LayerTreeHostImplTest, ScrollBlocksOnWheelEventHandlers) {
@@ -646,7 +654,6 @@ TEST_F(LayerTreeHostImplTest, ScrollBlocksOnTouchEventHandlers) {
child_layer->SetDrawsContent(true);
child_layer->SetPosition(gfx::PointF(0, 20));
child_layer->SetBounds(gfx::Size(50, 50));
- child_layer->SetContentBounds(gfx::Size(50, 50));
scroll->AddChild(child_layer.Pass());
}
@@ -846,7 +853,6 @@ TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionBasic) {
host_impl_->SetViewportSize(gfx::Size(100, 100));
LayerImpl* root = host_impl_->active_tree()->root_layer();
- root->SetContentsScale(2.f, 2.f);
root->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
DrawFrame();
@@ -887,7 +893,6 @@ TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionWithOffset) {
host_impl_->SetViewportSize(gfx::Size(100, 100));
LayerImpl* root = host_impl_->active_tree()->root_layer();
- root->SetContentsScale(2.f, 2.f);
root->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
root->SetPosition(gfx::PointF(-25.f, 0.f));
@@ -1020,7 +1025,6 @@ TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) {
ASSERT_EQ(1u, scroll_layer->children().size());
LayerImpl* overflow = scroll_layer->children()[0];
overflow->SetBounds(overflow_size);
- overflow->SetContentBounds(overflow_size);
overflow->SetScrollClipLayer(scroll_layer->parent()->id());
overflow->PushScrollOffsetFromMainThread(gfx::ScrollOffset());
overflow->SetPosition(gfx::PointF());
@@ -1126,11 +1130,184 @@ TEST_F(LayerTreeHostImplTest, ImplPinchZoom) {
scoped_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
- ExpectContains(*scroll_info.get(), scroll_layer->id(),
- gfx::Vector2d(0, scroll_delta.y() / page_scale_delta));
+ EXPECT_TRUE(ScrollInfoContains(
+ *scroll_info.get(), scroll_layer->id(),
+ gfx::Vector2d(0, scroll_delta.y() / page_scale_delta)));
}
}
+TEST_F(LayerTreeHostImplTest, ScrollDuringPinchScrollsInnerViewport) {
+ LayerTreeSettings settings = DefaultSettings();
+ settings.invert_viewport_scroll_order = true;
+ CreateHostImpl(settings,
+ CreateOutputSurface());
+
+ const gfx::Size content_size(1000, 1000);
+ const gfx::Size viewport_size(500, 500);
+ CreateBasicVirtualViewportLayers(viewport_size, content_size);
+
+ LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer();
+ LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer();
+
+ EXPECT_VECTOR_EQ(
+ gfx::Vector2dF(500, 500),
+ outer_scroll_layer->MaxScrollOffset());
+
+ host_impl_->ScrollBegin(gfx::Point(250, 250), InputHandler::GESTURE);
+ host_impl_->PinchGestureBegin();
+ host_impl_->PinchGestureUpdate(2, gfx::Point(250, 250));
+ host_impl_->ScrollBy(gfx::Point(250, 250), gfx::Vector2dF(10.f, 10.f));
+ host_impl_->PinchGestureEnd();
+ host_impl_->ScrollEnd();
+
+ EXPECT_VECTOR_EQ(
+ gfx::Vector2dF(0, 0),
+ outer_scroll_layer->CurrentScrollOffset());
+ EXPECT_VECTOR_EQ(
+ gfx::Vector2dF(130, 130),
+ inner_scroll_layer->CurrentScrollOffset());
+}
+
+// Tests the "snapping" of pinch-zoom gestures to the screen edge. That is, when
+// a pinch zoom is anchored within a certain margin of the screen edge, we
+// should assume the user means to scroll into the edge of the screen.
+TEST_F(LayerTreeHostImplTest, PinchZoomSnapsToScreenEdge) {
+ LayerTreeSettings settings = DefaultSettings();
+ settings.invert_viewport_scroll_order = true;
+ CreateHostImpl(settings,
+ CreateOutputSurface());
+
+ const gfx::Size content_size(1000, 1000);
+ const gfx::Size viewport_size(500, 500);
+ CreateBasicVirtualViewportLayers(viewport_size, content_size);
+
+ int offsetFromEdge = Viewport::kPinchZoomSnapMarginDips - 5;
+ gfx::Point anchor(viewport_size.width() - offsetFromEdge,
+ viewport_size.height() - offsetFromEdge);
+
+ // Pinch in within the margins. The scroll should stay exactly locked to the
+ // bottom and right.
+ host_impl_->ScrollBegin(anchor, InputHandler::GESTURE);
+ host_impl_->PinchGestureBegin();
+ host_impl_->PinchGestureUpdate(2, anchor);
+ host_impl_->PinchGestureEnd();
+ host_impl_->ScrollEnd();
+
+ EXPECT_VECTOR_EQ(
+ gfx::Vector2dF(250, 250),
+ host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset());
+
+ // Reset.
+ host_impl_->active_tree()->SetPageScaleOnActiveTree(1.f);
+ host_impl_->InnerViewportScrollLayer()->SetScrollDelta(gfx::Vector2d());
+ host_impl_->OuterViewportScrollLayer()->SetScrollDelta(gfx::Vector2d());
+
+ // Pinch in within the margins. The scroll should stay exactly locked to the
+ // top and left.
+ anchor = gfx::Point(offsetFromEdge, offsetFromEdge);
+ host_impl_->ScrollBegin(anchor, InputHandler::GESTURE);
+ host_impl_->PinchGestureBegin();
+ host_impl_->PinchGestureUpdate(2, anchor);
+ host_impl_->PinchGestureEnd();
+ host_impl_->ScrollEnd();
+
+ EXPECT_VECTOR_EQ(
+ gfx::Vector2dF(0, 0),
+ host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset());
+
+ // Reset.
+ host_impl_->active_tree()->SetPageScaleOnActiveTree(1.f);
+ host_impl_->InnerViewportScrollLayer()->SetScrollDelta(gfx::Vector2d());
+ host_impl_->OuterViewportScrollLayer()->SetScrollDelta(gfx::Vector2d());
+
+ // Pinch in just outside the margin. There should be no snapping.
+ offsetFromEdge = Viewport::kPinchZoomSnapMarginDips;
+ anchor = gfx::Point(offsetFromEdge, offsetFromEdge);
+ host_impl_->ScrollBegin(anchor, InputHandler::GESTURE);
+ host_impl_->PinchGestureBegin();
+ host_impl_->PinchGestureUpdate(2, anchor);
+ host_impl_->PinchGestureEnd();
+ host_impl_->ScrollEnd();
+
+ EXPECT_VECTOR_EQ(
+ gfx::Vector2dF(50, 50),
+ host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset());
+
+ // Reset.
+ host_impl_->active_tree()->SetPageScaleOnActiveTree(1.f);
+ host_impl_->InnerViewportScrollLayer()->SetScrollDelta(gfx::Vector2d());
+ host_impl_->OuterViewportScrollLayer()->SetScrollDelta(gfx::Vector2d());
+
+ // Pinch in just outside the margin. There should be no snapping.
+ offsetFromEdge = Viewport::kPinchZoomSnapMarginDips;
+ anchor = gfx::Point(viewport_size.width() - offsetFromEdge,
+ viewport_size.height() - offsetFromEdge);
+ host_impl_->ScrollBegin(anchor, InputHandler::GESTURE);
+ host_impl_->PinchGestureBegin();
+ host_impl_->PinchGestureUpdate(2, anchor);
+ host_impl_->PinchGestureEnd();
+ host_impl_->ScrollEnd();
+
+ EXPECT_VECTOR_EQ(
+ gfx::Vector2dF(200, 200),
+ host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset());
+}
+
+TEST_F(LayerTreeHostImplTest, ImplPinchZoomWheelBubbleBetweenViewports) {
+ const gfx::Size content_size(200, 200);
+ const gfx::Size viewport_size(100, 100);
+ CreateBasicVirtualViewportLayers(viewport_size, content_size);
+
+ LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer();
+ LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer();
+
+ // Zoom into the page by a 2X factor
+ float min_page_scale = 1.f, max_page_scale = 4.f;
+ float page_scale_factor = 2.f;
+ host_impl_->active_tree()->PushPageScaleFromMainThread(
+ page_scale_factor, min_page_scale, max_page_scale);
+ host_impl_->SetPageScaleOnActiveTree(page_scale_factor);
+
+ // Scroll by a small amount, there should be no bubbling up to the inner
+ // viewport.
+ host_impl_->ScrollBegin(gfx::Point(0, 0), InputHandler::WHEEL);
+ host_impl_->ScrollBy(gfx::Point(0, 0), gfx::Vector2dF(10.f, 20.f));
+ host_impl_->ScrollEnd();
+
+ EXPECT_VECTOR_EQ(
+ gfx::Vector2dF(5, 10),
+ outer_scroll_layer->CurrentScrollOffset());
+ EXPECT_VECTOR_EQ(
+ gfx::Vector2dF(),
+ inner_scroll_layer->CurrentScrollOffset());
+
+ // Scroll by the outer viewport's max scroll extent, there the remainder
+ // should bubble up to the inner viewport.
+ host_impl_->ScrollBegin(gfx::Point(0, 0), InputHandler::WHEEL);
+ host_impl_->ScrollBy(gfx::Point(0, 0), gfx::Vector2dF(200.f, 200.f));
+ host_impl_->ScrollEnd();
+
+ EXPECT_VECTOR_EQ(
+ gfx::Vector2dF(100, 100),
+ outer_scroll_layer->CurrentScrollOffset());
+ EXPECT_VECTOR_EQ(
+ gfx::Vector2dF(5, 10),
+ inner_scroll_layer->CurrentScrollOffset());
+
+ // Scroll by the inner viewport's max scroll extent, it should all go to the
+ // inner viewport.
+ host_impl_->ScrollBegin(gfx::Point(0, 0), InputHandler::WHEEL);
+ host_impl_->ScrollBy(gfx::Point(0, 0), gfx::Vector2dF(90.f, 80.f));
+ host_impl_->ScrollEnd();
+
+ EXPECT_VECTOR_EQ(
+ gfx::Vector2dF(100, 100),
+ outer_scroll_layer->CurrentScrollOffset());
+ EXPECT_VECTOR_EQ(
+ gfx::Vector2dF(50, 50),
+ inner_scroll_layer->CurrentScrollOffset());
+}
+
TEST_F(LayerTreeHostImplTest, ScrollWithSwapPromises) {
ui::LatencyInfo latency_info;
latency_info.trace_id = 1234;
@@ -1342,7 +1519,8 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) {
scoped_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
- ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(-10, -10));
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(),
+ gfx::Vector2d(-10, -10)));
}
// Two-finger panning should work when starting fully zoomed out.
@@ -1364,7 +1542,8 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) {
scoped_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
EXPECT_EQ(scroll_info->page_scale_delta, 2.f);
- ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(20, 20));
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(),
+ gfx::Vector2d(20, 20)));
}
}
@@ -1424,7 +1603,8 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimation) {
scoped_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
EXPECT_EQ(scroll_info->page_scale_delta, 2);
- ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(-50, -50));
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(),
+ gfx::Vector2d(-50, -50)));
}
// Anchor zoom-out
@@ -1463,7 +1643,8 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimation) {
host_impl_->ProcessScrollDeltas();
EXPECT_EQ(scroll_info->page_scale_delta, min_page_scale);
// Pushed to (0,0) via clamping against contents layer size.
- ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(-50, -50));
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(),
+ gfx::Vector2d(-50, -50)));
}
}
@@ -1604,7 +1785,8 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationTransferedOnSyncTreeActivate) {
scoped_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
EXPECT_EQ(scroll_info->page_scale_delta, target_scale);
- ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(-50, -50));
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(),
+ gfx::Vector2d(-50, -50)));
}
TEST_F(LayerTreeHostImplTest, PageScaleAnimationCompletedNotification) {
@@ -1646,14 +1828,15 @@ class LayerTreeHostImplOverridePhysicalTime : public LayerTreeHostImpl {
LayerTreeHostImplClient* client,
Proxy* proxy,
SharedBitmapManager* manager,
+ TaskGraphRunner* task_graph_runner,
RenderingStatsInstrumentation* rendering_stats_instrumentation)
: LayerTreeHostImpl(settings,
client,
proxy,
rendering_stats_instrumentation,
manager,
- NULL,
- NULL,
+ nullptr,
+ task_graph_runner,
0) {}
BeginFrameArgs CurrentBeginFrameArgs() const override {
@@ -1676,9 +1859,9 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
gfx::Size content_size(100, 100);
LayerTreeHostImplOverridePhysicalTime* host_impl_override_time =
- new LayerTreeHostImplOverridePhysicalTime(settings, this, &proxy_,
- shared_bitmap_manager_.get(),
- &stats_instrumentation_);
+ new LayerTreeHostImplOverridePhysicalTime(
+ settings, this, &proxy_, &shared_bitmap_manager_,
+ &task_graph_runner_, &stats_instrumentation_);
host_impl_ = make_scoped_ptr(host_impl_override_time);
host_impl_->InitializeRenderer(CreateOutputSurface());
host_impl_->SetViewportSize(viewport_size);
@@ -1693,14 +1876,12 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
scroll->PushScrollOffsetFromMainThread(gfx::ScrollOffset());
root->SetBounds(viewport_size);
scroll->SetBounds(content_size);
- scroll->SetContentBounds(content_size);
scroll->SetIsContainerForFixedPositionLayers(true);
scoped_ptr<LayerImpl> contents =
LayerImpl::Create(host_impl_->active_tree(), 3);
contents->SetDrawsContent(true);
contents->SetBounds(content_size);
- contents->SetContentBounds(content_size);
scoped_ptr<SolidColorScrollbarLayerImpl> scrollbar =
SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), 4,
@@ -1728,7 +1909,7 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
SetupLayers(settings);
- base::TimeTicks fake_now = gfx::FrameTime::Now();
+ base::TimeTicks fake_now = base::TimeTicks::Now();
EXPECT_FALSE(did_request_animate_);
EXPECT_FALSE(did_request_redraw_);
@@ -1851,21 +2032,18 @@ void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale(
scroll->SetScrollClipLayer(root->id());
scroll->PushScrollOffsetFromMainThread(gfx::ScrollOffset());
scroll->SetBounds(content_size);
- scroll->SetContentBounds(content_size);
scroll->SetIsContainerForFixedPositionLayers(true);
scoped_ptr<LayerImpl> contents =
LayerImpl::Create(host_impl_->active_tree(), 3);
contents->SetDrawsContent(true);
contents->SetBounds(content_size);
- contents->SetContentBounds(content_size);
// The scrollbar is on the right side.
scoped_ptr<PaintedScrollbarLayerImpl> scrollbar =
PaintedScrollbarLayerImpl::Create(host_impl_->active_tree(), 5, VERTICAL);
scrollbar->SetDrawsContent(true);
scrollbar->SetBounds(gfx::Size(15, viewport_size.height()));
- scrollbar->SetContentBounds(gfx::Size(15, viewport_size.height()));
scrollbar->SetPosition(gfx::Point(285, 0));
scroll->AddChild(contents.Pass());
@@ -2058,9 +2236,8 @@ class DidDrawCheckLayer : public LayerImpl {
append_quads_called_(false),
did_draw_called_(false) {
SetBounds(gfx::Size(10, 10));
- SetContentBounds(gfx::Size(10, 10));
SetDrawsContent(true);
- draw_properties().visible_content_rect = gfx::Rect(0, 0, 10, 10);
+ draw_properties().visible_layer_rect = gfx::Rect(0, 0, 10, 10);
}
private:
@@ -2124,10 +2301,9 @@ TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) {
root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2));
DidDrawCheckLayer* layer =
static_cast<DidDrawCheckLayer*>(root->children()[0]);
- // Ensure visible_content_rect for layer is empty.
+ // Ensure visible_layer_rect for layer is empty.
layer->SetPosition(gfx::PointF(100.f, 100.f));
layer->SetBounds(gfx::Size(10, 10));
- layer->SetContentBounds(gfx::Size(10, 10));
LayerTreeHostImpl::FrameData frame;
@@ -2141,9 +2317,9 @@ TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) {
EXPECT_FALSE(layer->will_draw_called());
EXPECT_FALSE(layer->did_draw_called());
- EXPECT_TRUE(layer->visible_content_rect().IsEmpty());
+ EXPECT_TRUE(layer->visible_layer_rect().IsEmpty());
- // Ensure visible_content_rect for layer is not empty
+ // Ensure visible_layer_rect for layer is not empty
layer->SetPosition(gfx::PointF());
EXPECT_FALSE(layer->will_draw_called());
@@ -2156,7 +2332,7 @@ TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) {
EXPECT_TRUE(layer->will_draw_called());
EXPECT_TRUE(layer->did_draw_called());
- EXPECT_FALSE(layer->visible_content_rect().IsEmpty());
+ EXPECT_FALSE(layer->visible_layer_rect().IsEmpty());
}
TEST_F(LayerTreeHostImplTest, WillDrawNotCalledOnOccludedLayer) {
@@ -2179,7 +2355,6 @@ TEST_F(LayerTreeHostImplTest, WillDrawNotCalledOnOccludedLayer) {
// This layer covers the occluded_layer above. Make this layer large so it can
// occlude.
top_layer->SetBounds(big_size);
- top_layer->SetContentBounds(big_size);
top_layer->SetContentsOpaque(true);
LayerTreeHostImpl::FrameData frame;
@@ -2539,8 +2714,6 @@ class LayerTreeHostImplTopControlsTest : public LayerTreeHostImplTest {
: layer_size_(10, 10),
clip_size_(layer_size_),
top_controls_height_(50) {
- settings_.use_pinch_virtual_viewport = true;
-
viewport_size_ = gfx::Size(clip_size_.width(),
clip_size_.height() + top_controls_height_);
}
@@ -2564,7 +2737,6 @@ class LayerTreeHostImplTopControlsTest : public LayerTreeHostImplTest {
root_clip->SetBounds(clip_size_);
root->SetScrollClipLayer(root_clip->id());
root->SetBounds(layer_size_);
- root->SetContentBounds(layer_size_);
root->SetPosition(gfx::PointF());
root->SetDrawsContent(false);
root->SetIsContainerForFixedPositionLayers(true);
@@ -2593,7 +2765,6 @@ class LayerTreeHostImplTopControlsTest : public LayerTreeHostImplTest {
root_clip->SetBounds(clip_size_);
root->SetScrollClipLayer(root_clip->id());
root->SetBounds(layer_size_);
- root->SetContentBounds(layer_size_);
root->SetPosition(gfx::PointF());
root->SetDrawsContent(false);
root->SetIsContainerForFixedPositionLayers(true);
@@ -2635,7 +2806,6 @@ class LayerTreeHostImplTopControlsTest : public LayerTreeHostImplTest {
root_clip->SetBounds(inner_viewport_size);
root->SetScrollClipLayer(root_clip->id());
root->SetBounds(outer_viewport_size);
- root->SetContentBounds(outer_viewport_size);
root->SetPosition(gfx::PointF());
root->SetDrawsContent(false);
root->SetIsContainerForFixedPositionLayers(true);
@@ -2643,7 +2813,6 @@ class LayerTreeHostImplTopControlsTest : public LayerTreeHostImplTest {
outer_clip->SetBounds(outer_viewport_size);
outer_scroll->SetScrollClipLayer(outer_clip->id());
outer_scroll->SetBounds(scroll_layer_size);
- outer_scroll->SetContentBounds(scroll_layer_size);
outer_scroll->SetPosition(gfx::PointF());
outer_scroll->SetDrawsContent(false);
outer_scroll->SetIsContainerForFixedPositionLayers(true);
@@ -2848,7 +3017,6 @@ TEST_F(LayerTreeHostImplTopControlsTest, TopControlsScrollableSublayer) {
child_clip->SetBounds(sub_content_layer_size);
child->SetScrollClipLayer(child_clip->id());
child->SetBounds(sub_content_size);
- child->SetContentBounds(sub_content_size);
child->SetPosition(gfx::PointF());
child->SetDrawsContent(true);
child->SetIsContainerForFixedPositionLayers(true);
@@ -3204,8 +3372,6 @@ TEST_F(LayerTreeHostImplTest, ScrollNonCompositedRoot) {
content_layer->SetDrawsContent(true);
content_layer->SetPosition(gfx::PointF());
content_layer->SetBounds(contents_size);
- content_layer->SetContentBounds(contents_size);
- content_layer->SetContentsScale(2.f, 2.f);
scoped_ptr<LayerImpl> scroll_clip_layer =
LayerImpl::Create(host_impl_->active_tree(), 3);
@@ -3215,7 +3381,6 @@ TEST_F(LayerTreeHostImplTest, ScrollNonCompositedRoot) {
LayerImpl::Create(host_impl_->active_tree(), 2);
scroll_layer->SetScrollClipLayer(3);
scroll_layer->SetBounds(contents_size);
- scroll_layer->SetContentBounds(contents_size);
scroll_layer->SetPosition(gfx::PointF());
scroll_layer->AddChild(content_layer.Pass());
scroll_clip_layer->AddChild(scroll_layer.Pass());
@@ -3238,7 +3403,6 @@ TEST_F(LayerTreeHostImplTest, ScrollChildCallsCommitAndRedraw) {
gfx::Size contents_size(20, 20);
scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
root->SetBounds(surface_size);
- root->SetContentBounds(contents_size);
root->AddChild(CreateScrollableLayer(2, contents_size, root.get()));
root->SetHasRenderSurface(true);
host_impl_->active_tree()->SetRootLayer(root.Pass());
@@ -3362,7 +3526,8 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnMainThread) {
page_scale);
scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
- ExpectContains(*scroll_info.get(), root_scroll->id(), expected_scroll_delta);
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), root_scroll->id(),
+ expected_scroll_delta));
// The scroll range should also have been updated.
EXPECT_EQ(expected_max_scroll, root_scroll->MaxScrollOffset());
@@ -3418,7 +3583,8 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) {
// The scroll delta is not scaled because the main thread did not scale.
scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
- ExpectContains(*scroll_info.get(), root_scroll->id(), expected_scroll_delta);
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), root_scroll->id(),
+ expected_scroll_delta));
// The scroll range should also have been updated.
EXPECT_EQ(expected_max_scroll, root_scroll->MaxScrollOffset());
@@ -3458,15 +3624,6 @@ TEST_F(LayerTreeHostImplTest, PageScaleDeltaAppliedToRootScrollLayerOnly) {
host_impl_->ScrollEnd();
DrawOneFrame();
- EXPECT_EQ(1.f, root->contents_scale_x());
- EXPECT_EQ(1.f, root->contents_scale_y());
- EXPECT_EQ(1.f, scroll->contents_scale_x());
- EXPECT_EQ(1.f, scroll->contents_scale_y());
- EXPECT_EQ(1.f, child->contents_scale_x());
- EXPECT_EQ(1.f, child->contents_scale_y());
- EXPECT_EQ(1.f, grand_child->contents_scale_x());
- EXPECT_EQ(1.f, grand_child->contents_scale_y());
-
// Make sure all the layers are drawn with the page scale delta applied, i.e.,
// the page scale delta on the root layer is applied hierarchically.
LayerTreeHostImpl::FrameData frame;
@@ -3494,7 +3651,6 @@ TEST_F(LayerTreeHostImplTest, ScrollChildAndChangePageScaleOnMainThread) {
scoped_ptr<LayerImpl> root_scrolling =
LayerImpl::Create(host_impl_->active_tree(), 2);
root_scrolling->SetBounds(surface_size);
- root_scrolling->SetContentBounds(surface_size);
root_scrolling->SetScrollClipLayer(root->id());
root_scrolling->SetIsContainerForFixedPositionLayers(true);
LayerImpl* root_scrolling_ptr = root_scrolling.get();
@@ -3526,8 +3682,8 @@ TEST_F(LayerTreeHostImplTest, ScrollChildAndChangePageScaleOnMainThread) {
DrawOneFrame();
scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
- ExpectContains(
- *scroll_info.get(), child_scroll_layer_id, expected_scroll_delta);
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_scroll_layer_id,
+ expected_scroll_delta));
// The scroll range should not have changed.
EXPECT_EQ(child->MaxScrollOffset(), expected_max_scroll);
@@ -3576,10 +3732,12 @@ TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) {
// The grand child should have scrolled up to its limit.
LayerImpl* child = host_impl_->active_tree()->root_layer()->children()[0];
LayerImpl* grand_child = child->children()[0];
- ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, -5));
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child->id(),
+ gfx::Vector2d(0, -5)));
// The child should have only scrolled on the other axis.
- ExpectContains(*scroll_info.get(), child->id(), gfx::Vector2d(-3, 0));
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child->id(),
+ gfx::Vector2d(-3, 0)));
}
}
@@ -3631,7 +3789,8 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) {
LayerImpl* child =
host_impl_->active_tree()->root_layer()->children()[0]->children()[0];
LayerImpl* grand_child = child->children()[0];
- ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, -2));
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child->id(),
+ gfx::Vector2d(0, -2)));
// The child should not have scrolled.
ExpectNone(*scroll_info.get(), child->id());
@@ -3649,10 +3808,12 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) {
scroll_info = host_impl_->ProcessScrollDeltas();
// The child should have scrolled up to its limit.
- ExpectContains(*scroll_info.get(), child->id(), gfx::Vector2d(0, -3));
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child->id(),
+ gfx::Vector2d(0, -3)));
// The grand child should not have scrolled.
- ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, -2));
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child->id(),
+ gfx::Vector2d(0, -2)));
// After scrolling the parent, another scroll on the opposite direction
// should still scroll the child.
@@ -3668,11 +3829,12 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) {
scroll_info = host_impl_->ProcessScrollDeltas();
// The grand child should have scrolled.
- ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, 5));
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child->id(),
+ gfx::Vector2d(0, 5)));
// The child should not have scrolled.
- ExpectContains(*scroll_info.get(), child->id(), gfx::Vector2d(0, -3));
-
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child->id(),
+ gfx::Vector2d(0, -3)));
// Scrolling should be adjusted from viewport space.
host_impl_->active_tree()->PushPageScaleFromMainThread(2.f, 2.f, 2.f);
@@ -3689,7 +3851,8 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) {
scroll_info = host_impl_->ProcessScrollDeltas();
// Should have scrolled by half the amount in layer space (5 - 2/2)
- ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, 4));
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child->id(),
+ gfx::Vector2d(0, 4)));
}
}
TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) {
@@ -3731,7 +3894,8 @@ TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) {
// Only the root scroll should have scrolled.
ASSERT_EQ(scroll_info->scrolls.size(), 1u);
- ExpectContains(*scroll_info.get(), root_scroll_id, scroll_delta);
+ EXPECT_TRUE(
+ ScrollInfoContains(*scroll_info.get(), root_scroll_id, scroll_delta));
}
}
@@ -3792,8 +3956,8 @@ TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) {
// The layer should have scrolled down in its local coordinates.
scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
- ExpectContains(*scroll_info.get(), scroll_layer->id(),
- gfx::Vector2d(0, gesture_scroll_delta.x()));
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->id(),
+ gfx::Vector2d(0, gesture_scroll_delta.x())));
// Reset and scroll down with the wheel.
scroll_layer->SetScrollDelta(gfx::Vector2dF());
@@ -3805,9 +3969,8 @@ TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) {
// The layer should have scrolled down in its local coordinates.
scroll_info = host_impl_->ProcessScrollDeltas();
- ExpectContains(*scroll_info.get(),
- scroll_layer->id(),
- wheel_scroll_delta);
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->id(),
+ wheel_scroll_delta));
}
TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) {
@@ -3820,7 +3983,7 @@ TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) {
scoped_ptr<LayerImpl> clip_layer =
LayerImpl::Create(host_impl_->active_tree(), child_clip_layer_id);
scoped_ptr<LayerImpl> child = CreateScrollableLayer(
- child_layer_id, scroll_layer->content_bounds(), clip_layer.get());
+ child_layer_id, scroll_layer->bounds(), clip_layer.get());
gfx::Transform rotate_transform;
rotate_transform.Translate(-50.0, -50.0);
rotate_transform.Rotate(child_layer_angle);
@@ -3857,7 +4020,8 @@ TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) {
std::cos(MathUtil::Deg2Rad(child_layer_angle)));
scoped_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
- ExpectContains(*scroll_info.get(), child_layer_id, expected_scroll_delta);
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_layer_id,
+ expected_scroll_delta));
// The root scroll layer should not have scrolled, because the input delta
// was close to the layer's axis of movement.
@@ -3879,7 +4043,8 @@ TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) {
std::sin(MathUtil::Deg2Rad(child_layer_angle)));
scoped_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
- ExpectContains(*scroll_info.get(), child_layer_id, expected_scroll_delta);
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_layer_id,
+ expected_scroll_delta));
// The root scroll layer should have scrolled more, since the input scroll
// delta was mostly orthogonal to the child layer's vertical scroll axis.
@@ -3887,9 +4052,83 @@ TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) {
gesture_scroll_delta.x() *
std::pow(std::cos(MathUtil::Deg2Rad(child_layer_angle)), 2),
0);
- ExpectContains(*scroll_info.get(),
- scroll_layer->id(),
- expected_root_scroll_delta);
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->id(),
+ expected_root_scroll_delta));
+ }
+}
+
+TEST_F(LayerTreeHostImplTest, ScrollPerspectiveTransformedLayer) {
+ // When scrolling an element with perspective, the distance scrolled
+ // depends on the point at which the scroll begins.
+ LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
+ int child_clip_layer_id = 6;
+ int child_layer_id = 7;
+
+ // Create a child layer that is rotated on its x axis, with perspective.
+ scoped_ptr<LayerImpl> clip_layer =
+ LayerImpl::Create(host_impl_->active_tree(), child_clip_layer_id);
+ scoped_ptr<LayerImpl> child = CreateScrollableLayer(
+ child_layer_id, scroll_layer->bounds(), clip_layer.get());
+ LayerImpl* child_ptr = child.get();
+ gfx::Transform perspective_transform;
+ perspective_transform.Translate(-50.0, -50.0);
+ perspective_transform.ApplyPerspectiveDepth(20);
+ perspective_transform.RotateAboutXAxis(45);
+ perspective_transform.Translate(50.0, 50.0);
+ clip_layer->SetTransform(perspective_transform);
+
+ clip_layer->SetBounds(gfx::Size(child_ptr->bounds().width() / 2,
+ child_ptr->bounds().height() / 2));
+ // The transform depends on the layer's transform origin, and the child layer
+ // is a different size than the clip, so make sure the clip layer's origin
+ // lines up over the child.
+ clip_layer->SetTransformOrigin(gfx::Point3F(
+ clip_layer->bounds().width(), clip_layer->bounds().height(), 0.f));
+ clip_layer->AddChild(child.Pass());
+ scroll_layer->AddChild(clip_layer.Pass());
+
+ gfx::Size surface_size(50, 50);
+ host_impl_->SetViewportSize(surface_size);
+
+ scoped_ptr<ScrollAndScaleSet> scroll_info;
+
+ gfx::Vector2d gesture_scroll_deltas[4];
+ gesture_scroll_deltas[0] = gfx::Vector2d(4, 10);
+ gesture_scroll_deltas[1] = gfx::Vector2d(4, 10);
+ gesture_scroll_deltas[2] = gfx::Vector2d(10, 0);
+ gesture_scroll_deltas[3] = gfx::Vector2d(10, 0);
+
+ gfx::Vector2d expected_scroll_deltas[4];
+ // Perspective affects the vertical delta by a different
+ // amount depending on the vertical position of the |viewport_point|.
+ expected_scroll_deltas[0] = gfx::Vector2d(2, 8);
+ expected_scroll_deltas[1] = gfx::Vector2d(1, 4);
+ // Deltas which start with the same vertical position of the
+ // |viewport_point| are subject to identical perspective effects.
+ expected_scroll_deltas[2] = gfx::Vector2d(4, 0);
+ expected_scroll_deltas[3] = gfx::Vector2d(4, 0);
+
+ gfx::Point viewport_point(1, 1);
+
+ // Scroll in screen coordinates with a gesture. Each scroll starts
+ // where the previous scroll ended, but the scroll position is reset
+ // for each scroll.
+ for (int i = 0; i < 4; ++i) {
+ child_ptr->SetScrollDelta(gfx::Vector2dF());
+ DrawFrame();
+ EXPECT_EQ(InputHandler::SCROLL_STARTED,
+ host_impl_->ScrollBegin(viewport_point, InputHandler::GESTURE));
+ host_impl_->ScrollBy(viewport_point, gesture_scroll_deltas[i]);
+ viewport_point += gesture_scroll_deltas[i];
+ host_impl_->ScrollEnd();
+
+ scroll_info = host_impl_->ProcessScrollDeltas();
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_layer_id,
+ expected_scroll_deltas[i]));
+
+ // The root scroll layer should not have scrolled, because the input delta
+ // was close to the layer's axis of movement.
+ EXPECT_EQ(scroll_info->scrolls.size(), 1u);
}
}
@@ -3917,9 +4156,8 @@ TEST_F(LayerTreeHostImplTest, ScrollScaledLayer) {
// The layer should have scrolled down in its local coordinates, but half the
// amount.
scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
- ExpectContains(*scroll_info.get(),
- scroll_layer->id(),
- gfx::Vector2d(0, scroll_delta.y() / scale));
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->id(),
+ gfx::Vector2d(0, scroll_delta.y() / scale)));
// Reset and scroll down with the wheel.
scroll_layer->SetScrollDelta(gfx::Vector2dF());
@@ -3931,9 +4169,8 @@ TEST_F(LayerTreeHostImplTest, ScrollScaledLayer) {
// It should apply the scale factor to the scroll delta for the wheel event.
scroll_info = host_impl_->ProcessScrollDeltas();
- ExpectContains(*scroll_info.get(),
- scroll_layer->id(),
- wheel_scroll_delta);
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->id(),
+ wheel_scroll_delta));
}
TEST_F(LayerTreeHostImplTest, ScrollViewportRounding) {
@@ -3957,7 +4194,8 @@ class TestScrollOffsetDelegate : public LayerScrollOffsetDelegate {
TestScrollOffsetDelegate()
: page_scale_factor_(0.f),
min_page_scale_factor_(-1.f),
- max_page_scale_factor_(-1.f) {}
+ max_page_scale_factor_(-1.f),
+ needs_animate_(false) {}
~TestScrollOffsetDelegate() override {}
@@ -3965,7 +4203,11 @@ class TestScrollOffsetDelegate : public LayerScrollOffsetDelegate {
return getter_return_value_;
}
- bool IsExternalFlingActive() const override { return false; }
+ bool IsExternalScrollActive() const override { return false; }
+
+ void SetNeedsAnimate(const AnimationCallback&) override {
+ needs_animate_ = true;
+ }
void UpdateRootLayerState(const gfx::ScrollOffset& total_scroll_offset,
const gfx::ScrollOffset& max_scroll_offset,
@@ -3985,6 +4227,12 @@ class TestScrollOffsetDelegate : public LayerScrollOffsetDelegate {
set_getter_return_value(last_set_scroll_offset_);
}
+ bool GetAndResetNeedsAnimate() {
+ bool needs_animate = needs_animate_;
+ needs_animate_ = false;
+ return needs_animate;
+ }
+
gfx::ScrollOffset last_set_scroll_offset() {
return last_set_scroll_offset_;
}
@@ -4021,8 +4269,10 @@ class TestScrollOffsetDelegate : public LayerScrollOffsetDelegate {
float page_scale_factor_;
float min_page_scale_factor_;
float max_page_scale_factor_;
+ bool needs_animate_;
};
+// TODO(jdduke): Test root fling animation.
TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) {
TestScrollOffsetDelegate scroll_delegate;
host_impl_->SetViewportSize(gfx::Size(10, 20));
@@ -4270,6 +4520,7 @@ TEST_F(LayerTreeHostImplTest, OverscrollRoot) {
TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) {
// Scroll child layers beyond their maximum scroll range and make sure root
// overscroll does not accumulate.
+ InputHandlerScrollResult scroll_result;
gfx::Size surface_size(10, 10);
scoped_ptr<LayerImpl> root_clip =
LayerImpl::Create(host_impl_->active_tree(), 4);
@@ -4300,7 +4551,9 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) {
EXPECT_EQ(InputHandler::SCROLL_STARTED,
host_impl_->ScrollBegin(gfx::Point(),
InputHandler::NON_BUBBLING_GESTURE));
- host_impl_->ScrollBy(gfx::Point(), scroll_delta);
+ scroll_result = host_impl_->ScrollBy(gfx::Point(), scroll_delta);
+ EXPECT_TRUE(scroll_result.did_scroll);
+ EXPECT_FALSE(scroll_result.did_overscroll_root);
EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
host_impl_->ScrollEnd();
@@ -4312,7 +4565,9 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) {
InputHandler::NON_BUBBLING_GESTURE));
EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child_layer);
EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
- host_impl_->ScrollBy(gfx::Point(), scroll_delta);
+ scroll_result = host_impl_->ScrollBy(gfx::Point(), scroll_delta);
+ EXPECT_TRUE(scroll_result.did_scroll);
+ EXPECT_FALSE(scroll_result.did_overscroll_root);
EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child_layer);
EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
host_impl_->ScrollEnd();
@@ -4324,7 +4579,9 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) {
host_impl_->ScrollBegin(gfx::Point(5, 5),
InputHandler::NON_BUBBLING_GESTURE));
EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child_layer);
- host_impl_->ScrollBy(gfx::Point(), scroll_delta);
+ scroll_result = host_impl_->ScrollBy(gfx::Point(), scroll_delta);
+ EXPECT_TRUE(scroll_result.did_scroll);
+ EXPECT_FALSE(scroll_result.did_overscroll_root);
EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child_layer);
EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
host_impl_->ScrollEnd();
@@ -4335,6 +4592,7 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildEventBubbling) {
// When we try to scroll a non-scrollable child layer, the scroll delta
// should be applied to one of its ancestors if possible. Overscroll should
// be reflected only when it has bubbled up to the root scrolling layer.
+ InputHandlerScrollResult scroll_result;
gfx::Size surface_size(10, 10);
gfx::Size content_size(20, 20);
scoped_ptr<LayerImpl> root_clip =
@@ -4361,17 +4619,24 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildEventBubbling) {
gfx::Vector2d scroll_delta(0, 8);
EXPECT_EQ(InputHandler::SCROLL_STARTED,
host_impl_->ScrollBegin(gfx::Point(5, 5), InputHandler::WHEEL));
- host_impl_->ScrollBy(gfx::Point(), scroll_delta);
+ scroll_result = host_impl_->ScrollBy(gfx::Point(), scroll_delta);
+ EXPECT_TRUE(scroll_result.did_scroll);
+ EXPECT_FALSE(scroll_result.did_overscroll_root);
EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
- host_impl_->ScrollBy(gfx::Point(), scroll_delta);
+ scroll_result = host_impl_->ScrollBy(gfx::Point(), scroll_delta);
+ EXPECT_TRUE(scroll_result.did_scroll);
+ EXPECT_TRUE(scroll_result.did_overscroll_root);
EXPECT_EQ(gfx::Vector2dF(0, 6), host_impl_->accumulated_root_overscroll());
- host_impl_->ScrollBy(gfx::Point(), scroll_delta);
+ scroll_result = host_impl_->ScrollBy(gfx::Point(), scroll_delta);
+ EXPECT_FALSE(scroll_result.did_scroll);
+ EXPECT_TRUE(scroll_result.did_overscroll_root);
EXPECT_EQ(gfx::Vector2dF(0, 14), host_impl_->accumulated_root_overscroll());
host_impl_->ScrollEnd();
}
}
TEST_F(LayerTreeHostImplTest, OverscrollAlways) {
+ InputHandlerScrollResult scroll_result;
LayerTreeSettings settings;
CreateHostImpl(settings, CreateOutputSurface());
@@ -4386,11 +4651,14 @@ TEST_F(LayerTreeHostImplTest, OverscrollAlways) {
// Even though the layer can't scroll the overscroll still happens.
EXPECT_EQ(InputHandler::SCROLL_STARTED,
host_impl_->ScrollBegin(gfx::Point(), InputHandler::WHEEL));
- host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
+ scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
+ EXPECT_FALSE(scroll_result.did_scroll);
+ EXPECT_TRUE(scroll_result.did_overscroll_root);
EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_->accumulated_root_overscroll());
}
TEST_F(LayerTreeHostImplTest, NoOverscrollOnFractionalDeviceScale) {
+ InputHandlerScrollResult scroll_result;
gfx::Size surface_size(980, 1439);
gfx::Size content_size(980, 1438);
float device_scale_factor = 1.5f;
@@ -4424,7 +4692,9 @@ TEST_F(LayerTreeHostImplTest, NoOverscrollOnFractionalDeviceScale) {
// vertical GlowEffect should not be applied in about:blank page.
EXPECT_EQ(InputHandler::SCROLL_STARTED,
host_impl_->ScrollBegin(gfx::Point(0, 0), InputHandler::WHEEL));
- host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0, -1));
+ scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0, -1));
+ EXPECT_FALSE(scroll_result.did_scroll);
+ EXPECT_FALSE(scroll_result.did_overscroll_root);
EXPECT_EQ(gfx::Vector2dF().ToString(),
host_impl_->accumulated_root_overscroll().ToString());
@@ -4433,6 +4703,7 @@ TEST_F(LayerTreeHostImplTest, NoOverscrollOnFractionalDeviceScale) {
}
TEST_F(LayerTreeHostImplTest, NoOverscrollWhenNotAtEdge) {
+ InputHandlerScrollResult scroll_result;
gfx::Size surface_size(100, 100);
gfx::Size content_size(200, 200);
scoped_ptr<LayerImpl> root_clip =
@@ -4461,10 +4732,15 @@ TEST_F(LayerTreeHostImplTest, NoOverscrollWhenNotAtEdge) {
// called while scrolling up without reaching the edge of the content.
EXPECT_EQ(InputHandler::SCROLL_STARTED,
host_impl_->ScrollBegin(gfx::Point(0, 0), InputHandler::WHEEL));
- host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 100));
+ scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 100));
+ EXPECT_TRUE(scroll_result.did_scroll);
+ EXPECT_FALSE(scroll_result.did_overscroll_root);
EXPECT_EQ(gfx::Vector2dF().ToString(),
host_impl_->accumulated_root_overscroll().ToString());
- host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0, -2.30f));
+ scroll_result =
+ host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0, -2.30f));
+ EXPECT_TRUE(scroll_result.did_scroll);
+ EXPECT_FALSE(scroll_result.did_overscroll_root);
EXPECT_EQ(gfx::Vector2dF().ToString(),
host_impl_->accumulated_root_overscroll().ToString());
host_impl_->ScrollEnd();
@@ -4474,11 +4750,16 @@ TEST_F(LayerTreeHostImplTest, NoOverscrollWhenNotAtEdge) {
host_impl_->ScrollBegin(gfx::Point(0, 0),
InputHandler::NON_BUBBLING_GESTURE));
EXPECT_EQ(InputHandler::SCROLL_STARTED, host_impl_->FlingScrollBegin());
- host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 20));
+ scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 20));
+ EXPECT_TRUE(scroll_result.did_scroll);
+ EXPECT_TRUE(scroll_result.did_overscroll_root);
EXPECT_EQ(gfx::Vector2dF(0.000000f, 17.699997f).ToString(),
host_impl_->accumulated_root_overscroll().ToString());
- host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.02f, -0.01f));
+ scroll_result =
+ host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.02f, -0.01f));
+ EXPECT_FALSE(scroll_result.did_scroll);
+ EXPECT_FALSE(scroll_result.did_overscroll_root);
EXPECT_EQ(gfx::Vector2dF(0.000000f, 17.699997f).ToString(),
host_impl_->accumulated_root_overscroll().ToString());
host_impl_->ScrollEnd();
@@ -4486,7 +4767,10 @@ TEST_F(LayerTreeHostImplTest, NoOverscrollWhenNotAtEdge) {
// gloweffect without reaching edge.
EXPECT_EQ(InputHandler::SCROLL_STARTED,
host_impl_->ScrollBegin(gfx::Point(0, 0), InputHandler::WHEEL));
- host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(-0.12f, 0.1f));
+ scroll_result =
+ host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(-0.12f, 0.1f));
+ EXPECT_FALSE(scroll_result.did_scroll);
+ EXPECT_FALSE(scroll_result.did_overscroll_root);
EXPECT_EQ(gfx::Vector2dF().ToString(),
host_impl_->accumulated_root_overscroll().ToString());
host_impl_->ScrollEnd();
@@ -4564,7 +4848,6 @@ class BlendStateCheckLayer : public LayerImpl {
RGBA_8888)) {
resource_provider->AllocateForTesting(resource_id_);
SetBounds(gfx::Size(10, 10));
- SetContentBounds(gfx::Size(10, 10));
SetDrawsContent(true);
}
@@ -4574,7 +4857,7 @@ class BlendStateCheckLayer : public LayerImpl {
gfx::Rect quad_rect_;
gfx::Rect opaque_content_rect_;
gfx::Rect quad_visible_rect_;
- ResourceProvider::ResourceId resource_id_;
+ ResourceId resource_id_;
};
TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
@@ -4582,7 +4865,6 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
scoped_ptr<LayerImpl> root =
LayerImpl::Create(host_impl_->active_tree(), 1);
root->SetBounds(gfx::Size(10, 10));
- root->SetContentBounds(root->bounds());
root->SetDrawsContent(false);
root->SetHasRenderSurface(true);
host_impl_->active_tree()->SetRootLayer(root.Pass());
@@ -4602,7 +4884,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
// Opaque layer, drawn without blending.
layer1->SetContentsOpaque(true);
layer1->SetExpectation(false, false);
- layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
+ layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
EXPECT_TRUE(layer1->quads_appended());
@@ -4611,7 +4893,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
// Layer with translucent content and painting, so drawn with blending.
layer1->SetContentsOpaque(false);
layer1->SetExpectation(true, false);
- layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
+ layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
EXPECT_TRUE(layer1->quads_appended());
@@ -4621,7 +4903,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetContentsOpaque(true);
layer1->SetOpacity(0.5f);
layer1->SetExpectation(true, false);
- layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
+ layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
EXPECT_TRUE(layer1->quads_appended());
@@ -4631,7 +4913,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetContentsOpaque(true);
layer1->SetOpacity(0.5f);
layer1->SetExpectation(true, false);
- layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
+ layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
EXPECT_TRUE(layer1->quads_appended());
@@ -4649,11 +4931,11 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetContentsOpaque(true);
layer1->SetOpacity(1.f);
layer1->SetExpectation(false, false);
- layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
+ layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
layer2->SetContentsOpaque(true);
layer2->SetOpacity(1.f);
layer2->SetExpectation(false, false);
- layer2->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
+ layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
EXPECT_TRUE(layer1->quads_appended());
@@ -4664,9 +4946,9 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
// Child layer with opaque content, drawn without blending.
layer1->SetContentsOpaque(false);
layer1->SetExpectation(true, false);
- layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
+ layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
layer2->SetExpectation(false, false);
- layer2->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
+ layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
EXPECT_TRUE(layer1->quads_appended());
@@ -4678,9 +4960,9 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
// Child layer with opaque content, drawn without blending.
layer1->SetContentsOpaque(true);
layer1->SetExpectation(false, false);
- layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
+ layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
layer2->SetExpectation(false, false);
- layer2->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
+ layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
EXPECT_TRUE(layer1->quads_appended());
@@ -4696,9 +4978,9 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetOpacity(0.5f);
layer1->SetHasRenderSurface(true);
layer1->SetExpectation(false, true);
- layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
+ layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
layer2->SetExpectation(false, false);
- layer2->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
+ layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(
host_impl_->active_tree()->root_layer());
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
@@ -4713,11 +4995,11 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetContentsOpaque(true);
layer1->SetOpacity(1.f);
layer1->SetExpectation(false, false);
- layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
+ layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
layer2->SetContentsOpaque(true);
layer2->SetOpacity(0.5f);
layer2->SetExpectation(true, false);
- layer2->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
+ layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
EXPECT_TRUE(layer1->quads_appended());
@@ -4728,11 +5010,11 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetContentsOpaque(true);
layer1->SetOpacity(1.f);
layer1->SetExpectation(false, false);
- layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
+ layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
layer2->SetContentsOpaque(false);
layer2->SetOpacity(1.f);
layer2->SetExpectation(true, false);
- layer2->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
+ layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
EXPECT_TRUE(layer1->quads_appended());
@@ -4744,11 +5026,11 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetContentsOpaque(true);
layer1->SetOpacity(1.f);
layer1->SetExpectation(false, false);
- layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
+ layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
layer2->SetContentsOpaque(true);
layer2->SetOpacity(1.f);
layer2->SetExpectation(false, false);
- layer2->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
+ layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
EXPECT_TRUE(layer1->quads_appended());
@@ -4761,7 +5043,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 5));
layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
layer1->SetExpectation(true, false);
- layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
+ layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
EXPECT_TRUE(layer1->quads_appended());
@@ -4773,7 +5055,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 2));
layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
layer1->SetExpectation(true, false);
- layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
+ layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
EXPECT_TRUE(layer1->quads_appended());
@@ -4785,7 +5067,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetQuadVisibleRect(gfx::Rect(7, 5, 3, 5));
layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
layer1->SetExpectation(true, false);
- layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
+ layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
EXPECT_TRUE(layer1->quads_appended());
@@ -4798,7 +5080,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 2, 5));
layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
layer1->SetExpectation(false, false);
- layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
+ layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
EXPECT_TRUE(layer1->quads_appended());
@@ -4839,7 +5121,6 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest {
gfx::Rect layer_rect(viewport_size_);
child_->SetPosition(layer_rect.origin());
child_->SetBounds(layer_rect.size());
- child_->SetContentBounds(layer_rect.size());
child_->SetQuadRect(gfx::Rect(layer_rect.size()));
child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
@@ -4860,7 +5141,6 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest {
gfx::Rect layer_rect(0, 0, 0, 0);
child_->SetPosition(layer_rect.origin());
child_->SetBounds(layer_rect.size());
- child_->SetContentBounds(layer_rect.size());
child_->SetQuadRect(gfx::Rect(layer_rect.size()));
child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
@@ -4881,7 +5161,6 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest {
gfx::Rect layer_rect(500, 500, 200, 200);
child_->SetPosition(layer_rect.origin());
child_->SetBounds(layer_rect.size());
- child_->SetContentBounds(layer_rect.size());
child_->SetQuadRect(gfx::Rect(layer_rect.size()));
child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
@@ -4903,7 +5182,6 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest {
viewport_size_.height() + 10);
child_->SetPosition(layer_rect.origin());
child_->SetBounds(layer_rect.size());
- child_->SetContentBounds(layer_rect.size());
child_->SetQuadRect(gfx::Rect(layer_rect.size()));
child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
@@ -5069,7 +5347,6 @@ TEST_F(LayerTreeHostImplTest, ReshapeNotCalledUntilDraw) {
scoped_ptr<LayerImpl> root =
FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 1);
root->SetBounds(gfx::Size(10, 10));
- root->SetContentBounds(gfx::Size(10, 10));
root->SetDrawsContent(true);
root->SetHasRenderSurface(true);
host_impl_->active_tree()->SetRootLayer(root.Pass());
@@ -5128,8 +5405,10 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
scoped_ptr<LayerTreeHostImpl> layer_tree_host_impl =
LayerTreeHostImpl::Create(
settings, this, &proxy_, &stats_instrumentation_,
- shared_bitmap_manager_.get(), NULL, task_graph_runner_.get(), 0);
+ &shared_bitmap_manager_, NULL, &task_graph_runner_, 0);
layer_tree_host_impl->InitializeRenderer(output_surface.Pass());
+ layer_tree_host_impl->WillBeginImplFrame(
+ CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE));
layer_tree_host_impl->SetViewportSize(gfx::Size(500, 500));
scoped_ptr<LayerImpl> root =
@@ -5139,10 +5418,8 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
FakeDrawableLayerImpl::Create(layer_tree_host_impl->active_tree(), 2);
child->SetPosition(gfx::PointF(12.f, 13.f));
child->SetBounds(gfx::Size(14, 15));
- child->SetContentBounds(gfx::Size(14, 15));
child->SetDrawsContent(true);
root->SetBounds(gfx::Size(500, 500));
- root->SetContentBounds(gfx::Size(500, 500));
root->SetDrawsContent(true);
root->AddChild(child.Pass());
layer_tree_host_impl->active_tree()->SetRootLayer(root.Pass());
@@ -5196,10 +5473,8 @@ TEST_F(LayerTreeHostImplTest, RootLayerDoesntCreateExtraSurface) {
scoped_ptr<LayerImpl> child =
FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 2);
child->SetBounds(gfx::Size(10, 10));
- child->SetContentBounds(gfx::Size(10, 10));
child->SetDrawsContent(true);
root->SetBounds(gfx::Size(10, 10));
- root->SetContentBounds(gfx::Size(10, 10));
root->SetDrawsContent(true);
root->SetHasRenderSurface(true);
root->AddChild(child.Pass());
@@ -5227,7 +5502,7 @@ class FakeLayerWithQuads : public LayerImpl {
PopulateSharedQuadState(shared_quad_state);
SkColor gray = SkColorSetRGB(100, 100, 100);
- gfx::Rect quad_rect(content_bounds());
+ gfx::Rect quad_rect(bounds());
gfx::Rect visible_quad_rect(quad_rect);
SolidColorDrawQuad* my_quad =
render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
@@ -5406,6 +5681,7 @@ static scoped_ptr<LayerTreeHostImpl> SetupLayersForOpacity(
LayerTreeHostImplClient* client,
Proxy* proxy,
SharedBitmapManager* manager,
+ TaskGraphRunner* task_graph_runner,
RenderingStatsInstrumentation* stats_instrumentation) {
scoped_refptr<TestContextProvider> provider(TestContextProvider::Create());
scoped_ptr<OutputSurface> output_surface(
@@ -5415,9 +5691,12 @@ static scoped_ptr<LayerTreeHostImpl> SetupLayersForOpacity(
LayerTreeSettings settings;
settings.renderer_settings.partial_swap_enabled = partial_swap;
- scoped_ptr<LayerTreeHostImpl> my_host_impl = LayerTreeHostImpl::Create(
- settings, client, proxy, stats_instrumentation, manager, NULL, NULL, 0);
+ scoped_ptr<LayerTreeHostImpl> my_host_impl =
+ LayerTreeHostImpl::Create(settings, client, proxy, stats_instrumentation,
+ manager, nullptr, task_graph_runner, 0);
my_host_impl->InitializeRenderer(output_surface.Pass());
+ my_host_impl->WillBeginImplFrame(
+ CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE));
my_host_impl->SetViewportSize(gfx::Size(100, 100));
/*
@@ -5452,23 +5731,20 @@ static scoped_ptr<LayerTreeHostImpl> SetupLayersForOpacity(
root->SetHasRenderSurface(true);
root->SetPosition(root_rect.origin());
root->SetBounds(root_rect.size());
- root->SetContentBounds(root->bounds());
- root->draw_properties().visible_content_rect = root_rect;
+ root->draw_properties().visible_layer_rect = root_rect;
root->SetDrawsContent(false);
root->render_surface()->SetContentRect(gfx::Rect(root_rect.size()));
child->SetPosition(gfx::PointF(child_rect.x(), child_rect.y()));
child->SetOpacity(0.5f);
child->SetBounds(gfx::Size(child_rect.width(), child_rect.height()));
- child->SetContentBounds(child->bounds());
- child->draw_properties().visible_content_rect = child_rect;
+ child->draw_properties().visible_layer_rect = child_rect;
child->SetDrawsContent(false);
child->SetHasRenderSurface(true);
grand_child->SetPosition(grand_child_rect.origin());
grand_child->SetBounds(grand_child_rect.size());
- grand_child->SetContentBounds(grand_child->bounds());
- grand_child->draw_properties().visible_content_rect = grand_child_rect;
+ grand_child->draw_properties().visible_layer_rect = grand_child_rect;
grand_child->SetDrawsContent(true);
child->AddChild(grand_child.Pass());
@@ -5479,14 +5755,11 @@ static scoped_ptr<LayerTreeHostImpl> SetupLayersForOpacity(
}
TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorPartialSwap) {
- scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
- new TestSharedBitmapManager());
+ TestSharedBitmapManager shared_bitmap_manager;
+ TestTaskGraphRunner task_graph_runner;
scoped_ptr<LayerTreeHostImpl> my_host_impl =
- SetupLayersForOpacity(true,
- this,
- &proxy_,
- shared_bitmap_manager.get(),
- &stats_instrumentation_);
+ SetupLayersForOpacity(true, this, &proxy_, &shared_bitmap_manager,
+ &task_graph_runner, &stats_instrumentation_);
{
LayerTreeHostImpl::FrameData frame;
EXPECT_EQ(DRAW_SUCCESS, my_host_impl->PrepareToDraw(&frame));
@@ -5506,14 +5779,11 @@ TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorPartialSwap) {
}
TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorNoPartialSwap) {
- scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
- new TestSharedBitmapManager());
+ TestSharedBitmapManager shared_bitmap_manager;
+ TestTaskGraphRunner task_graph_runner;
scoped_ptr<LayerTreeHostImpl> my_host_impl =
- SetupLayersForOpacity(false,
- this,
- &proxy_,
- shared_bitmap_manager.get(),
- &stats_instrumentation_);
+ SetupLayersForOpacity(false, this, &proxy_, &shared_bitmap_manager,
+ &task_graph_runner, &stats_instrumentation_);
{
LayerTreeHostImpl::FrameData frame;
EXPECT_EQ(DRAW_SUCCESS, my_host_impl->PrepareToDraw(&frame));
@@ -5553,14 +5823,12 @@ TEST_F(LayerTreeHostImplTest, LayersFreeTextures) {
scoped_ptr<VideoLayerImpl> video_layer = VideoLayerImpl::Create(
host_impl_->active_tree(), 4, &provider, media::VIDEO_ROTATION_0);
video_layer->SetBounds(gfx::Size(10, 10));
- video_layer->SetContentBounds(gfx::Size(10, 10));
video_layer->SetDrawsContent(true);
root_layer->AddChild(video_layer.Pass());
scoped_ptr<IOSurfaceLayerImpl> io_surface_layer =
IOSurfaceLayerImpl::Create(host_impl_->active_tree(), 5);
io_surface_layer->SetBounds(gfx::Size(10, 10));
- io_surface_layer->SetContentBounds(gfx::Size(10, 10));
io_surface_layer->SetDrawsContent(true);
io_surface_layer->SetIOSurfaceProperties(1, gfx::Size(10, 10));
root_layer->AddChild(io_surface_layer.Pass());
@@ -5627,46 +5895,6 @@ TEST_F(LayerTreeHostImplTest, HasTransparentBackground) {
Mock::VerifyAndClearExpectations(&mock_context);
}
-TEST_F(LayerTreeHostImplTest, ReleaseContentsTextureShouldTriggerCommit) {
- set_reduce_memory_result(false);
-
- // If changing the memory limit wouldn't result in changing what was
- // committed, then no commit should be requested.
- set_reduce_memory_result(false);
- host_impl_->set_max_memory_needed_bytes(
- host_impl_->memory_allocation_limit_bytes() - 1);
- host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
- host_impl_->memory_allocation_limit_bytes() - 1));
- EXPECT_FALSE(did_request_commit_);
- did_request_commit_ = false;
-
- // If changing the memory limit would result in changing what was
- // committed, then a commit should be requested, even though nothing was
- // evicted.
- set_reduce_memory_result(false);
- host_impl_->set_max_memory_needed_bytes(
- host_impl_->memory_allocation_limit_bytes());
- host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
- host_impl_->memory_allocation_limit_bytes() - 1));
- EXPECT_TRUE(did_request_commit_);
- did_request_commit_ = false;
-
- // Especially if changing the memory limit caused evictions, we need
- // to re-commit.
- set_reduce_memory_result(true);
- host_impl_->set_max_memory_needed_bytes(1);
- host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
- host_impl_->memory_allocation_limit_bytes() - 1));
- EXPECT_TRUE(did_request_commit_);
- did_request_commit_ = false;
-
- // But if we set it to the same value that it was before, we shouldn't
- // re-commit.
- host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
- host_impl_->memory_allocation_limit_bytes()));
- EXPECT_FALSE(did_request_commit_);
-}
-
class LayerTreeHostImplTestWithDelegatingRenderer
: public LayerTreeHostImplTest {
protected:
@@ -5695,12 +5923,12 @@ class LayerTreeHostImplTestWithDelegatingRenderer
ASSERT_EQ(2u, root_render_pass->quad_list.size());
LayerImpl* child = host_impl_->active_tree()->root_layer()->children()[0];
- gfx::RectF expected_child_visible_rect(child->content_bounds());
+ gfx::RectF expected_child_visible_rect(child->bounds());
EXPECT_EQ(expected_child_visible_rect,
root_render_pass->quad_list.front()->visible_rect);
LayerImpl* root = host_impl_->active_tree()->root_layer();
- gfx::RectF expected_root_visible_rect(root->content_bounds());
+ gfx::RectF expected_root_visible_rect(root->bounds());
EXPECT_EQ(expected_root_visible_rect,
root_render_pass->quad_list.ElementAt(1)->visible_rect);
}
@@ -5716,7 +5944,6 @@ TEST_F(LayerTreeHostImplTestWithDelegatingRenderer, FrameIncludesDamageRect) {
SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
root->SetPosition(gfx::PointF());
root->SetBounds(gfx::Size(10, 10));
- root->SetContentBounds(gfx::Size(10, 10));
root->SetDrawsContent(true);
root->SetHasRenderSurface(true);
@@ -5725,7 +5952,6 @@ TEST_F(LayerTreeHostImplTestWithDelegatingRenderer, FrameIncludesDamageRect) {
SolidColorLayerImpl::Create(host_impl_->active_tree(), 2);
child->SetPosition(gfx::PointF(9.f, 9.f));
child->SetBounds(gfx::Size(1, 1));
- child->SetContentBounds(gfx::Size(1, 1));
child->SetDrawsContent(true);
root->AddChild(child.Pass());
@@ -5761,7 +5987,7 @@ class FakeMaskLayerImpl : public LayerImpl {
return make_scoped_ptr(new FakeMaskLayerImpl(tree_impl, id));
}
- void GetContentsResourceId(ResourceProvider::ResourceId* resource_id,
+ void GetContentsResourceId(ResourceId* resource_id,
gfx::Size* resource_size) const override {
*resource_id = 0;
}
@@ -5834,9 +6060,14 @@ TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) {
ASSERT_LE(1u, frame.render_passes[0]->quad_list.size());
const DrawQuad* quad = frame.render_passes[0]->quad_list.front();
+ bool clipped = false, force_aa = false;
+ gfx::QuadF device_layer_quad = MathUtil::MapQuad(
+ quad->shared_quad_state->quad_to_target_transform,
+ gfx::QuadF(quad->shared_quad_state->visible_quad_layer_rect), &clipped);
+ EXPECT_FALSE(clipped);
bool antialiased =
GLRendererWithSetupQuadForAntialiasing::ShouldAntialiasQuad(
- quad->quadTransform(), quad, false);
+ device_layer_quad, clipped, force_aa);
EXPECT_FALSE(antialiased);
host_impl_->DrawLayers(&frame);
@@ -5949,7 +6180,6 @@ TEST_F(LayerTreeHostImplTest,
scoped_ptr<VideoLayerImpl> video_layer = VideoLayerImpl::Create(
host_impl_->active_tree(), 2, &provider, media::VIDEO_ROTATION_0);
video_layer->SetBounds(gfx::Size(10, 10));
- video_layer->SetContentBounds(gfx::Size(10, 10));
video_layer->SetDrawsContent(true);
root_layer->AddChild(video_layer.Pass());
SetupRootLayerImpl(root_layer.Pass());
@@ -5968,9 +6198,8 @@ TEST_F(LayerTreeHostImplTest,
TEST_F(LayerTreeHostImplTest, DefaultMemoryAllocation) {
LayerTreeSettings settings;
host_impl_ = LayerTreeHostImpl::Create(
- settings, this, &proxy_, &stats_instrumentation_,
- shared_bitmap_manager_.get(), gpu_memory_buffer_manager_.get(),
- task_graph_runner_.get(), 0);
+ settings, this, &proxy_, &stats_instrumentation_, &shared_bitmap_manager_,
+ &gpu_memory_buffer_manager_, &task_graph_runner_, 0);
scoped_ptr<OutputSurface> output_surface(
FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()));
@@ -5978,51 +6207,6 @@ TEST_F(LayerTreeHostImplTest, DefaultMemoryAllocation) {
EXPECT_LT(0ul, host_impl_->memory_allocation_limit_bytes());
}
-TEST_F(LayerTreeHostImplTest, MemoryPolicy) {
- ManagedMemoryPolicy policy1(
- 456, gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING, 1000);
- int everything_cutoff_value = ManagedMemoryPolicy::PriorityCutoffToValue(
- gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING);
- int allow_nice_to_have_cutoff_value =
- ManagedMemoryPolicy::PriorityCutoffToValue(
- gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE);
- int nothing_cutoff_value = ManagedMemoryPolicy::PriorityCutoffToValue(
- gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING);
-
- // GPU rasterization should be disabled by default on the tree(s)
- EXPECT_FALSE(host_impl_->active_tree()->use_gpu_rasterization());
- EXPECT_TRUE(host_impl_->pending_tree() == NULL);
-
- host_impl_->SetVisible(true);
- host_impl_->SetMemoryPolicy(policy1);
- EXPECT_EQ(policy1.bytes_limit_when_visible, current_limit_bytes_);
- EXPECT_EQ(everything_cutoff_value, current_priority_cutoff_value_);
-
- host_impl_->SetVisible(false);
- EXPECT_EQ(0u, current_limit_bytes_);
- EXPECT_EQ(nothing_cutoff_value, current_priority_cutoff_value_);
-
- host_impl_->SetVisible(true);
- EXPECT_EQ(policy1.bytes_limit_when_visible, current_limit_bytes_);
- EXPECT_EQ(everything_cutoff_value, current_priority_cutoff_value_);
-
- // Now enable GPU rasterization and test if we get nice to have cutoff,
- // when visible.
- LayerTreeSettings settings;
- settings.gpu_rasterization_enabled = true;
- CreateHostImpl(settings, CreateOutputSurface());
- host_impl_->SetContentIsSuitableForGpuRasterization(true);
- host_impl_->SetHasGpuRasterizationTrigger(true);
- host_impl_->SetVisible(true);
- host_impl_->SetMemoryPolicy(policy1);
- EXPECT_EQ(policy1.bytes_limit_when_visible, current_limit_bytes_);
- EXPECT_EQ(allow_nice_to_have_cutoff_value, current_priority_cutoff_value_);
-
- host_impl_->SetVisible(false);
- EXPECT_EQ(0u, current_limit_bytes_);
- EXPECT_EQ(nothing_cutoff_value, current_priority_cutoff_value_);
-}
-
TEST_F(LayerTreeHostImplTest, RequireHighResWhenVisible) {
ASSERT_TRUE(host_impl_->active_tree());
@@ -6076,12 +6260,9 @@ TEST_F(LayerTreeHostImplTest, RequireHighResAfterGpuRasterizationToggles) {
class LayerTreeHostImplTestPrepareTiles : public LayerTreeHostImplTest {
public:
void SetUp() override {
- LayerTreeSettings settings;
- settings.impl_side_painting = true;
-
- fake_host_impl_ = new FakeLayerTreeHostImpl(settings, &proxy_,
- shared_bitmap_manager_.get(),
- task_graph_runner_.get());
+ fake_host_impl_ =
+ new FakeLayerTreeHostImpl(LayerTreeSettings(), &proxy_,
+ &shared_bitmap_manager_, &task_graph_runner_);
host_impl_.reset(fake_host_impl_);
host_impl_->InitializeRenderer(CreateOutputSurface());
host_impl_->SetViewportSize(gfx::Size(10, 10));
@@ -6111,16 +6292,14 @@ TEST_F(LayerTreeHostImplTest, UIResourceManagement) {
UIResourceBitmap bitmap(gfx::Size(1, 1), is_opaque);
host_impl_->CreateUIResource(ui_resource_id, bitmap);
EXPECT_EQ(1u, context3d->NumTextures());
- ResourceProvider::ResourceId id1 =
- host_impl_->ResourceIdForUIResource(ui_resource_id);
+ ResourceId id1 = host_impl_->ResourceIdForUIResource(ui_resource_id);
EXPECT_NE(0u, id1);
// Multiple requests with the same id is allowed. The previous texture is
// deleted.
host_impl_->CreateUIResource(ui_resource_id, bitmap);
EXPECT_EQ(1u, context3d->NumTextures());
- ResourceProvider::ResourceId id2 =
- host_impl_->ResourceIdForUIResource(ui_resource_id);
+ ResourceId id2 = host_impl_->ResourceIdForUIResource(ui_resource_id);
EXPECT_NE(0u, id2);
EXPECT_NE(id1, id2);
@@ -6163,8 +6342,7 @@ TEST_F(LayerTreeHostImplTest, CreateETC1UIResource) {
UIResourceId ui_resource_id = 1;
host_impl_->CreateUIResource(ui_resource_id, bitmap);
EXPECT_EQ(1u, context3d->NumTextures());
- ResourceProvider::ResourceId id1 =
- host_impl_->ResourceIdForUIResource(ui_resource_id);
+ ResourceId id1 = host_impl_->ResourceIdForUIResource(ui_resource_id);
EXPECT_NE(0u, id1);
}
@@ -6288,7 +6466,8 @@ TEST_F(LayerTreeHostImplTest, TouchFlingShouldLockToFirstScrolledLayer) {
// The grand child should have scrolled up to its limit.
scroll_info = host_impl_->ProcessScrollDeltas();
ASSERT_EQ(1u, scroll_info->scrolls.size());
- ExpectContains(*scroll_info, grand_child->id(), scroll_delta);
+ EXPECT_TRUE(
+ ScrollInfoContains(*scroll_info, grand_child->id(), scroll_delta));
EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
// The child should have received the bubbled delta, but the locked
@@ -6296,8 +6475,9 @@ TEST_F(LayerTreeHostImplTest, TouchFlingShouldLockToFirstScrolledLayer) {
EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), scroll_delta).did_scroll);
scroll_info = host_impl_->ProcessScrollDeltas();
ASSERT_EQ(2u, scroll_info->scrolls.size());
- ExpectContains(*scroll_info, grand_child->id(), scroll_delta);
- ExpectContains(*scroll_info, child->id(), scroll_delta);
+ EXPECT_TRUE(
+ ScrollInfoContains(*scroll_info, grand_child->id(), scroll_delta));
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info, child->id(), scroll_delta));
EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
// The first |ScrollBy| after the fling should re-lock the scrolling
@@ -6309,8 +6489,10 @@ TEST_F(LayerTreeHostImplTest, TouchFlingShouldLockToFirstScrolledLayer) {
// The child should have scrolled up to its limit.
scroll_info = host_impl_->ProcessScrollDeltas();
ASSERT_EQ(2u, scroll_info->scrolls.size());
- ExpectContains(*scroll_info, grand_child->id(), scroll_delta);
- ExpectContains(*scroll_info, child->id(), scroll_delta + scroll_delta);
+ EXPECT_TRUE(
+ ScrollInfoContains(*scroll_info, grand_child->id(), scroll_delta));
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info, child->id(),
+ scroll_delta + scroll_delta));
// As the locked layer is at it's limit, no further scrolling can occur.
EXPECT_FALSE(host_impl_->ScrollBy(gfx::Point(), scroll_delta).did_scroll);
@@ -6357,7 +6539,8 @@ TEST_F(LayerTreeHostImplTest, WheelFlingShouldBubble) {
// The root should have scrolled.
ASSERT_EQ(2u, scroll_info->scrolls.size());
- ExpectContains(*scroll_info.get(), root_scroll_id, gfx::Vector2d(0, 10));
+ EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), root_scroll_id,
+ gfx::Vector2d(0, 10)));
}
}
@@ -6381,7 +6564,6 @@ TEST_F(LayerTreeHostImplTest, ScrollUnknownNotOnAncestorChain) {
LayerImpl::Create(host_impl_->active_tree(), occluder_layer_id);
occluder_layer->SetDrawsContent(true);
occluder_layer->SetBounds(content_size);
- occluder_layer->SetContentBounds(content_size);
occluder_layer->SetPosition(gfx::PointF());
// The parent of the occluder is *above* the scroller.
@@ -6410,7 +6592,6 @@ TEST_F(LayerTreeHostImplTest, ScrollUnknownScrollAncestorMismatch) {
LayerImpl::Create(host_impl_->active_tree(), occluder_layer_id);
occluder_layer->SetDrawsContent(true);
occluder_layer->SetBounds(content_size);
- occluder_layer->SetContentBounds(content_size);
occluder_layer->SetPosition(gfx::PointF(-10.f, -10.f));
int child_scroll_clip_layer_id = 7;
@@ -6482,7 +6663,6 @@ TEST_F(LayerTreeHostImplTest, ScrollInvisibleScrollerWithVisibleDescendent) {
LayerImpl::Create(host_impl_->active_tree(), 9);
grand_child_layer->SetDrawsContent(true);
grand_child_layer->SetBounds(content_size);
- grand_child_layer->SetContentBounds(content_size);
// Move the grand child so it's not hit by our test point.
grand_child_layer->SetPosition(gfx::PointF(10.f, 10.f));
@@ -6519,7 +6699,6 @@ TEST_F(LayerTreeHostImplTest, ScrollInvisibleScrollerWithVisibleScrollChild) {
LayerImpl::Create(host_impl_->active_tree(), scroll_child_id);
scroll_child->SetDrawsContent(true);
scroll_child->SetBounds(content_size);
- scroll_child->SetContentBounds(content_size);
// Move the scroll child so it's not hit by our test point.
scroll_child->SetPosition(gfx::PointF(10.f, 10.f));
@@ -6561,7 +6740,6 @@ TEST_F(LayerTreeHostImplTest, LatencyInfoPassedToCompositorFrameMetadata) {
SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
root->SetPosition(gfx::PointF());
root->SetBounds(gfx::Size(10, 10));
- root->SetContentBounds(gfx::Size(10, 10));
root->SetDrawsContent(true);
root->SetHasRenderSurface(true);
@@ -6602,7 +6780,6 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToCompositorFrameMetadata) {
SolidColorLayerImpl::Create(host_impl_->active_tree(), root_layer_id);
root->SetPosition(gfx::PointF());
root->SetBounds(gfx::Size(10, 10));
- root->SetContentBounds(gfx::Size(10, 10));
root->SetDrawsContent(true);
root->SetHasRenderSurface(true);
@@ -6918,7 +7095,7 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationAtOrigin) {
// The top controls should properly animate until finished, despite the scroll
// offset being at the origin.
- base::TimeTicks animation_time = gfx::FrameTime::Now();
+ base::TimeTicks animation_time = base::TimeTicks::Now();
while (did_request_animate_) {
did_request_redraw_ = false;
did_request_animate_ = false;
@@ -6988,7 +7165,7 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationAfterScroll) {
EXPECT_FALSE(did_request_commit_);
// Animate the top controls to the limit.
- base::TimeTicks animation_time = gfx::FrameTime::Now();
+ base::TimeTicks animation_time = base::TimeTicks::Now();
while (did_request_animate_) {
did_request_redraw_ = false;
did_request_animate_ = false;
@@ -7052,7 +7229,7 @@ TEST_F(LayerTreeHostImplWithTopControlsTest,
EXPECT_FALSE(did_request_commit_);
// Animate the top controls to the limit.
- base::TimeTicks animation_time = gfx::FrameTime::Now();
+ base::TimeTicks animation_time = base::TimeTicks::Now();
while (did_request_animate_) {
did_request_redraw_ = false;
did_request_animate_ = false;
@@ -7163,7 +7340,6 @@ class LayerTreeHostImplVirtualViewportTest : public LayerTreeHostImplTest {
inner_scroll->SetScrollClipLayer(inner_clip->id());
inner_scroll->SetBounds(outer_viewport);
- inner_scroll->SetContentBounds(outer_viewport);
inner_scroll->SetPosition(gfx::PointF());
scoped_ptr<LayerImpl> outer_clip =
@@ -7176,14 +7352,12 @@ class LayerTreeHostImplVirtualViewportTest : public LayerTreeHostImplTest {
outer_scroll->SetScrollClipLayer(outer_clip->id());
outer_scroll->PushScrollOffsetFromMainThread(gfx::ScrollOffset());
outer_scroll->SetBounds(content_size);
- outer_scroll->SetContentBounds(content_size);
outer_scroll->SetPosition(gfx::PointF());
scoped_ptr<LayerImpl> contents =
LayerImpl::Create(layer_tree_impl, 8);
contents->SetDrawsContent(true);
contents->SetBounds(content_size);
- contents->SetContentBounds(content_size);
contents->SetPosition(gfx::PointF());
outer_scroll->AddChild(contents.Pass());
@@ -7256,13 +7430,17 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, FlingScrollBubblesToInner) {
// Make sure the fling goes to the outer viewport first
EXPECT_EQ(InputHandler::SCROLL_STARTED,
host_impl_->ScrollBegin(gfx::Point(), InputHandler::GESTURE));
+ EXPECT_EQ(outer_scroll, host_impl_->CurrentlyScrollingLayer());
EXPECT_EQ(InputHandler::SCROLL_STARTED, host_impl_->FlingScrollBegin());
+ EXPECT_EQ(outer_scroll, host_impl_->CurrentlyScrollingLayer());
gfx::Vector2d scroll_delta(inner_viewport.width(), inner_viewport.height());
host_impl_->ScrollBy(gfx::Point(), scroll_delta);
outer_expected += gfx::Vector2dF(scroll_delta.x(), scroll_delta.y());
+ EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), outer_scroll);
host_impl_->ScrollEnd();
+ EXPECT_EQ(nullptr, host_impl_->CurrentlyScrollingLayer());
EXPECT_VECTOR_EQ(inner_expected, inner_scroll->CurrentScrollOffset());
EXPECT_VECTOR_EQ(outer_expected, outer_scroll->CurrentScrollOffset());
@@ -7270,15 +7448,20 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, FlingScrollBubblesToInner) {
// Fling past the outer viewport boundry, make sure inner viewport scrolls.
EXPECT_EQ(InputHandler::SCROLL_STARTED,
host_impl_->ScrollBegin(gfx::Point(), InputHandler::GESTURE));
+ EXPECT_EQ(outer_scroll, host_impl_->CurrentlyScrollingLayer());
EXPECT_EQ(InputHandler::SCROLL_STARTED, host_impl_->FlingScrollBegin());
+ EXPECT_EQ(outer_scroll, host_impl_->CurrentlyScrollingLayer());
host_impl_->ScrollBy(gfx::Point(), scroll_delta);
outer_expected += gfx::Vector2dF(scroll_delta.x(), scroll_delta.y());
+ EXPECT_EQ(outer_scroll, host_impl_->CurrentlyScrollingLayer());
host_impl_->ScrollBy(gfx::Point(), scroll_delta);
inner_expected += gfx::Vector2dF(scroll_delta.x(), scroll_delta.y());
+ EXPECT_EQ(outer_scroll, host_impl_->CurrentlyScrollingLayer());
host_impl_->ScrollEnd();
+ EXPECT_EQ(nullptr, host_impl_->CurrentlyScrollingLayer());
EXPECT_VECTOR_EQ(inner_expected, inner_scroll->CurrentScrollOffset());
EXPECT_VECTOR_EQ(outer_expected, outer_scroll->CurrentScrollOffset());
@@ -7366,7 +7549,8 @@ TEST_F(LayerTreeHostImplVirtualViewportTest,
// The child should have scrolled up to its limit.
scroll_info = host_impl_->ProcessScrollDeltas();
ASSERT_EQ(1u, scroll_info->scrolls.size());
- ExpectContains(*scroll_info, child_scroll->id(), scroll_delta);
+ EXPECT_TRUE(
+ ScrollInfoContains(*scroll_info, child_scroll->id(), scroll_delta));
EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child_scroll);
// The first |ScrollBy| after the fling should re-lock the scrolling
@@ -7380,8 +7564,10 @@ TEST_F(LayerTreeHostImplVirtualViewportTest,
// The inner viewport should have scrolled up to its limit.
scroll_info = host_impl_->ProcessScrollDeltas();
ASSERT_EQ(2u, scroll_info->scrolls.size());
- ExpectContains(*scroll_info, child_scroll->id(), scroll_delta);
- ExpectContains(*scroll_info, inner_scroll->id(), scroll_delta);
+ EXPECT_TRUE(
+ ScrollInfoContains(*scroll_info, child_scroll->id(), scroll_delta));
+ EXPECT_TRUE(
+ ScrollInfoContains(*scroll_info, inner_scroll->id(), scroll_delta));
// As the locked layer is at its limit, no further scrolling can occur.
EXPECT_FALSE(host_impl_->ScrollBy(gfx::Point(), scroll_delta).did_scroll);
@@ -7392,6 +7578,34 @@ TEST_F(LayerTreeHostImplVirtualViewportTest,
}
}
+TEST_F(LayerTreeHostImplVirtualViewportTest,
+ ScrollBeginEventThatTargetsViewportLayerSkipsHitTest) {
+ gfx::Size content_size = gfx::Size(100, 160);
+ gfx::Size outer_viewport = gfx::Size(50, 80);
+ gfx::Size inner_viewport = gfx::Size(25, 40);
+
+ SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport);
+
+ LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer();
+ LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
+
+ scoped_ptr<LayerImpl> child =
+ CreateScrollableLayer(10, outer_viewport, outer_scroll);
+ LayerImpl* child_scroll = child.get();
+ outer_scroll->children()[0]->AddChild(child.Pass());
+
+ DrawFrame();
+
+ EXPECT_EQ(InputHandler::SCROLL_STARTED,
+ host_impl_->RootScrollBegin(InputHandler::GESTURE));
+ EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), inner_scroll);
+ host_impl_->ScrollEnd();
+ EXPECT_EQ(InputHandler::SCROLL_STARTED,
+ host_impl_->ScrollBegin(gfx::Point(), InputHandler::GESTURE));
+ EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child_scroll);
+ host_impl_->ScrollEnd();
+}
+
class LayerTreeHostImplWithImplicitLimitsTest : public LayerTreeHostImplTest {
public:
void SetUp() override {
@@ -7486,6 +7700,49 @@ TEST_F(LayerTreeHostImplTest, ScrollAnimated) {
EXPECT_EQ(NULL, host_impl_->CurrentlyScrollingLayer());
}
+// Evolved from LayerTreeHostImplTest.ScrollAnimated.
+TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimated) {
+ SetupScrollAndContentsLayers(gfx::Size(100, 200));
+ DrawFrame();
+
+ base::TimeTicks start_time =
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
+
+ EXPECT_EQ(InputHandler::SCROLL_STARTED,
+ host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)));
+
+ LayerImpl* scrolling_layer = host_impl_->CurrentlyScrollingLayer();
+
+ host_impl_->Animate(start_time);
+ host_impl_->UpdateAnimationState(true);
+
+ EXPECT_EQ(gfx::ScrollOffset(), scrolling_layer->CurrentScrollOffset());
+
+ host_impl_->Animate(start_time + base::TimeDelta::FromMilliseconds(50));
+ host_impl_->UpdateAnimationState(true);
+
+ float y = scrolling_layer->CurrentScrollOffset().y();
+ EXPECT_TRUE(y > 1 && y < 49);
+
+ // Update target.
+ EXPECT_EQ(InputHandler::SCROLL_STARTED,
+ host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)));
+
+ host_impl_->Animate(start_time + base::TimeDelta::FromMilliseconds(200));
+ host_impl_->UpdateAnimationState(true);
+
+ y = scrolling_layer->CurrentScrollOffset().y();
+ EXPECT_TRUE(y > 50 && y < 100);
+ EXPECT_EQ(scrolling_layer, host_impl_->CurrentlyScrollingLayer());
+
+ host_impl_->Animate(start_time + base::TimeDelta::FromMilliseconds(250));
+ host_impl_->UpdateAnimationState(true);
+
+ EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 100),
+ scrolling_layer->CurrentScrollOffset());
+ EXPECT_EQ(NULL, host_impl_->CurrentlyScrollingLayer());
+}
+
TEST_F(LayerTreeHostImplTest, InvalidLayerNotAddedToRasterQueue) {
host_impl_->CreatePendingTree();
@@ -7778,6 +8035,8 @@ class FakeVideoFrameController : public VideoFrameController {
};
TEST_F(LayerTreeHostImplTest, AddVideoFrameControllerInsideFrame) {
+ host_impl_->DidFinishImplFrame();
+
BeginFrameArgs begin_frame_args =
CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
FakeVideoFrameController controller;
@@ -7801,6 +8060,8 @@ TEST_F(LayerTreeHostImplTest, AddVideoFrameControllerInsideFrame) {
}
TEST_F(LayerTreeHostImplTest, AddVideoFrameControllerOutsideFrame) {
+ host_impl_->DidFinishImplFrame();
+
BeginFrameArgs begin_frame_args =
CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
FakeVideoFrameController controller;
@@ -7884,5 +8145,40 @@ TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusModes) {
EXPECT_TRUE(host_impl_->use_gpu_rasterization());
}
+// A mock output surface which lets us detect calls to ForceReclaimResources.
+class MockReclaimResourcesOutputSurface : public FakeOutputSurface {
+ public:
+ static scoped_ptr<MockReclaimResourcesOutputSurface> Create3d() {
+ return make_scoped_ptr(new MockReclaimResourcesOutputSurface(
+ TestContextProvider::Create(), TestContextProvider::Create(), false));
+ }
+
+ MOCK_METHOD0(ForceReclaimResources, void());
+
+ protected:
+ MockReclaimResourcesOutputSurface(
+ scoped_refptr<ContextProvider> context_provider,
+ scoped_refptr<ContextProvider> worker_context_provider,
+ bool delegated_rendering)
+ : FakeOutputSurface(context_provider,
+ worker_context_provider,
+ delegated_rendering) {}
+};
+
+// Display::Draw (and the planned Display Scheduler) currently rely on resources
+// being reclaimed to block drawing between BeginCommit / Swap. This test
+// ensures that BeginCommit triggers ForceReclaimResources. See
+// crbug.com/489515.
+TEST_F(LayerTreeHostImplTest, BeginCommitReclaimsResources) {
+ scoped_ptr<MockReclaimResourcesOutputSurface> output_surface(
+ MockReclaimResourcesOutputSurface::Create3d());
+ // Hold an unowned pointer to the output surface to use for mock expectations.
+ MockReclaimResourcesOutputSurface* mock_output_surface = output_surface.get();
+
+ CreateHostImpl(DefaultSettings(), output_surface.Pass());
+ EXPECT_CALL(*mock_output_surface, ForceReclaimResources()).Times(1);
+ host_impl_->BeginCommit();
+}
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_perftest.cc b/chromium/cc/trees/layer_tree_host_perftest.cc
index c8e2a8c02c1..eb8183fadf2 100644
--- a/chromium/cc/trees/layer_tree_host_perftest.cc
+++ b/chromium/cc/trees/layer_tree_host_perftest.cc
@@ -12,7 +12,6 @@
#include "base/strings/string_piece.h"
#include "base/time/time.h"
#include "cc/debug/lap_timer.h"
-#include "cc/layers/content_layer.h"
#include "cc/layers/nine_patch_layer.h"
#include "cc/layers/solid_color_layer.h"
#include "cc/layers/texture_layer.h"
@@ -45,7 +44,7 @@ class LayerTreeHostPerfTest : public LayerTreeTest {
}
void InitializeSettings(LayerTreeSettings* settings) override {
- settings->throttle_frame_production = false;
+ settings->renderer_settings.disable_gpu_vsync = true;
}
void BeginTest() override {
@@ -148,13 +147,13 @@ class LayerTreeHostPerfTestJsonReader : public LayerTreeHostPerfTest {
TEST_F(LayerTreeHostPerfTestJsonReader, TenTenSingleThread) {
SetTestName("10_10_single_thread");
ReadTestFile("10_10_layer_tree");
- RunTest(false, false, false);
+ RunTest(false, false);
}
-TEST_F(LayerTreeHostPerfTestJsonReader, TenTenThreadedImplSide) {
+TEST_F(LayerTreeHostPerfTestJsonReader, TenTenThreaded) {
SetTestName("10_10_threaded_impl_side");
ReadTestFile("10_10_layer_tree");
- RunTestWithImplSidePainting();
+ RunTest(true, false);
}
// Simulates a tab switcher scene with two stacks of 10 tabs each.
@@ -163,15 +162,14 @@ TEST_F(LayerTreeHostPerfTestJsonReader,
full_damage_each_frame_ = true;
SetTestName("10_10_single_thread_full_damage_each_frame");
ReadTestFile("10_10_layer_tree");
- RunTest(false, false, false);
+ RunTest(false, false);
}
-TEST_F(LayerTreeHostPerfTestJsonReader,
- TenTenThreadedImplSide_FullDamageEachFrame) {
+TEST_F(LayerTreeHostPerfTestJsonReader, TenTenThreaded_FullDamageEachFrame) {
full_damage_each_frame_ = true;
SetTestName("10_10_threaded_impl_side_full_damage_each_frame");
ReadTestFile("10_10_layer_tree");
- RunTestWithImplSidePainting();
+ RunTest(true, false);
}
// Invalidates a leaf layer in the tree on the main thread after every commit.
@@ -205,13 +203,13 @@ class LayerTreeHostPerfTestLeafInvalidates
TEST_F(LayerTreeHostPerfTestLeafInvalidates, TenTenSingleThread) {
SetTestName("10_10_single_thread_leaf_invalidates");
ReadTestFile("10_10_layer_tree");
- RunTest(false, false, false);
+ RunTest(false, false);
}
-TEST_F(LayerTreeHostPerfTestLeafInvalidates, TenTenThreadedImplSide) {
+TEST_F(LayerTreeHostPerfTestLeafInvalidates, TenTenThreaded) {
SetTestName("10_10_threaded_impl_side_leaf_invalidates");
ReadTestFile("10_10_layer_tree");
- RunTestWithImplSidePainting();
+ RunTest(true, false);
}
// Simulates main-thread scrolling on each frame.
@@ -246,18 +244,18 @@ TEST_F(ScrollingLayerTreePerfTest, LongScrollablePageSingleThread) {
// crbug.com/444219 is fixed.
bool old_verify_property_trees = verify_property_trees();
set_verify_property_trees(false);
- RunTest(false, false, false);
+ RunTest(false, false);
set_verify_property_trees(old_verify_property_trees);
}
-TEST_F(ScrollingLayerTreePerfTest, LongScrollablePageThreadedImplSide) {
+TEST_F(ScrollingLayerTreePerfTest, LongScrollablePageThreaded) {
SetTestName("long_scrollable_page_threaded_impl_side");
ReadTestFile("long_scrollable_page");
// TODO(vollick): Remove verify_property_trees setting after
// crbug.com/444219 is fixed.
bool old_verify_property_trees = verify_property_trees();
set_verify_property_trees(false);
- RunTestWithImplSidePainting();
+ RunTest(true, false);
set_verify_property_trees(old_verify_property_trees);
}
@@ -327,20 +325,20 @@ class BrowserCompositorInvalidateLayerTreePerfTest
bool clean_up_started_;
};
-TEST_F(BrowserCompositorInvalidateLayerTreePerfTest, DenseBrowserUI) {
+TEST_F(BrowserCompositorInvalidateLayerTreePerfTest, DenseBrowserUIThreaded) {
measure_commit_cost_ = true;
SetTestName("dense_layer_tree");
ReadTestFile("dense_layer_tree");
- RunTestWithImplSidePainting();
+ RunTest(true, false);
}
// Simulates a page with several large, transformed and animated layers.
-TEST_F(LayerTreeHostPerfTestJsonReader, HeavyPageThreadedImplSide) {
+TEST_F(LayerTreeHostPerfTestJsonReader, HeavyPageThreaded) {
begin_frame_driven_drawing_ = true;
measure_commit_cost_ = true;
SetTestName("heavy_page");
ReadTestFile("heavy_layer_tree");
- RunTestWithImplSidePainting();
+ RunTest(true, false);
}
} // namespace
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc
index b31d3e85395..e2715e3907c 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc
@@ -137,7 +137,8 @@ class LayerTreeHostBlendingPixelTest : public LayerTreeHostPixelResourceTest {
canvas.drawRect(
SkRect::MakeXYWH(0, i * kLaneHeight, kLaneWidth, kLaneHeight), paint);
}
- scoped_refptr<PictureImageLayer> layer = PictureImageLayer::Create();
+ scoped_refptr<PictureImageLayer> layer =
+ PictureImageLayer::Create(layer_settings());
layer->SetIsDrawable(true);
layer->SetBounds(gfx::Size(width, height));
layer->SetBitmap(backing_store);
@@ -147,7 +148,8 @@ class LayerTreeHostBlendingPixelTest : public LayerTreeHostPixelResourceTest {
void SetupMaskLayer(scoped_refptr<Layer> layer) {
const int kMaskOffset = 2;
gfx::Size bounds = layer->bounds();
- scoped_refptr<PictureImageLayer> mask = PictureImageLayer::Create();
+ scoped_refptr<PictureImageLayer> mask =
+ PictureImageLayer::Create(layer_settings());
mask->SetIsDrawable(true);
mask->SetIsMask(true);
mask->SetBounds(bounds);
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
index 0cb6aeaa846..6a4bebd4f35 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
@@ -46,11 +46,11 @@ class MaskContentLayerClient : public ContentLayerClient {
}
}
- void PaintContentsToDisplayList(
- DisplayItemList* display_list,
+ scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
const gfx::Rect& clip,
PaintingControlSetting picture_control) override {
NOTIMPLEMENTED();
+ return nullptr;
}
private:
@@ -67,7 +67,8 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskOfLayer) {
gfx::Size mask_bounds(50, 50);
MaskContentLayerClient client(mask_bounds);
- scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client);
+ scoped_refptr<PictureLayer> mask =
+ PictureLayer::Create(layer_settings(), &client);
mask->SetBounds(mask_bounds);
mask->SetIsDrawable(true);
mask->SetIsMask(true);
@@ -83,7 +84,8 @@ TEST_P(LayerTreeHostMasksPixelTest, ImageMaskOfLayer) {
gfx::Size mask_bounds(50, 50);
- scoped_refptr<PictureImageLayer> mask = PictureImageLayer::Create();
+ scoped_refptr<PictureImageLayer> mask =
+ PictureImageLayer::Create(layer_settings());
mask->SetIsDrawable(true);
mask->SetIsMask(true);
mask->SetBounds(mask_bounds);
@@ -111,7 +113,7 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskOfClippedLayer) {
gfx::Rect(100, 100), SK_ColorWHITE);
// Clip to the top half of the green layer.
- scoped_refptr<Layer> clip = Layer::Create();
+ scoped_refptr<Layer> clip = Layer::Create(layer_settings());
clip->SetPosition(gfx::Point(0, 0));
clip->SetBounds(gfx::Size(100, 50));
clip->SetMasksToBounds(true);
@@ -123,7 +125,8 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskOfClippedLayer) {
gfx::Size mask_bounds(50, 50);
MaskContentLayerClient client(mask_bounds);
- scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client);
+ scoped_refptr<PictureLayer> mask =
+ PictureLayer::Create(layer_settings(), &client);
mask->SetBounds(mask_bounds);
mask->SetIsDrawable(true);
mask->SetIsMask(true);
@@ -140,7 +143,8 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskWithReplica) {
gfx::Size mask_bounds(50, 50);
MaskContentLayerClient client(mask_bounds);
- scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client);
+ scoped_refptr<PictureLayer> mask =
+ PictureLayer::Create(layer_settings(), &client);
mask->SetBounds(mask_bounds);
mask->SetIsDrawable(true);
mask->SetIsMask(true);
@@ -153,7 +157,7 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskWithReplica) {
gfx::Transform replica_transform;
replica_transform.Rotate(-90.0);
- scoped_refptr<Layer> replica = Layer::Create();
+ scoped_refptr<Layer> replica = Layer::Create(layer_settings());
replica->SetTransformOrigin(gfx::Point3F(25.f, 25.f, 0.f));
replica->SetPosition(gfx::Point(50, 50));
replica->SetTransform(replica_transform);
@@ -169,14 +173,15 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskWithReplicaOfClippedLayer) {
gfx::Size mask_bounds(50, 50);
MaskContentLayerClient client(mask_bounds);
- scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client);
+ scoped_refptr<PictureLayer> mask =
+ PictureLayer::Create(layer_settings(), &client);
mask->SetBounds(mask_bounds);
mask->SetIsDrawable(true);
mask->SetIsMask(true);
// Clip to the bottom half of the green layer, and the left half of the
// replica.
- scoped_refptr<Layer> clip = Layer::Create();
+ scoped_refptr<Layer> clip = Layer::Create(layer_settings());
clip->SetPosition(gfx::Point(0, 25));
clip->SetBounds(gfx::Size(75, 75));
clip->SetMasksToBounds(true);
@@ -190,7 +195,7 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskWithReplicaOfClippedLayer) {
gfx::Transform replica_transform;
replica_transform.Rotate(-90.0);
- scoped_refptr<Layer> replica = Layer::Create();
+ scoped_refptr<Layer> replica = Layer::Create(layer_settings());
replica->SetTransformOrigin(gfx::Point3F(25.f, 25.f, 0.f));
replica->SetPosition(gfx::Point(50, 50));
replica->SetTransform(replica_transform);
@@ -207,7 +212,8 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskOfReplica) {
gfx::Size mask_bounds(50, 50);
MaskContentLayerClient client(mask_bounds);
- scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client);
+ scoped_refptr<PictureLayer> mask =
+ PictureLayer::Create(layer_settings(), &client);
mask->SetBounds(mask_bounds);
mask->SetIsDrawable(true);
mask->SetIsMask(true);
@@ -224,7 +230,7 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskOfReplica) {
replica_transform.Rotate(180.0);
replica_transform.Translate(50.0, 0.0);
- scoped_refptr<Layer> replica = Layer::Create();
+ scoped_refptr<Layer> replica = Layer::Create(layer_settings());
replica->SetTransformOrigin(gfx::Point3F(50.f, 50.f, 0.f));
replica->SetPosition(gfx::Point());
replica->SetTransform(replica_transform);
@@ -241,13 +247,14 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskOfReplicaOfClippedLayer) {
gfx::Size mask_bounds(50, 50);
MaskContentLayerClient client(mask_bounds);
- scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client);
+ scoped_refptr<PictureLayer> mask =
+ PictureLayer::Create(layer_settings(), &client);
mask->SetBounds(mask_bounds);
mask->SetIsDrawable(true);
mask->SetIsMask(true);
// Clip to the bottom 3/4 of the green layer, and the top 3/4 of the replica.
- scoped_refptr<Layer> clip = Layer::Create();
+ scoped_refptr<Layer> clip = Layer::Create(layer_settings());
clip->SetPosition(gfx::Point(0, 12));
clip->SetBounds(gfx::Size(100, 75));
clip->SetMasksToBounds(true);
@@ -265,7 +272,7 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskOfReplicaOfClippedLayer) {
replica_transform.Rotate(180.0);
replica_transform.Translate(50.0, 0.0);
- scoped_refptr<Layer> replica = Layer::Create();
+ scoped_refptr<Layer> replica = Layer::Create(layer_settings());
replica->SetTransformOrigin(gfx::Point3F(50.f, 50.f, 0.f));
replica->SetPosition(gfx::Point());
replica->SetTransform(replica_transform);
@@ -303,11 +310,11 @@ class CheckerContentLayerClient : public ContentLayerClient {
}
}
}
- void PaintContentsToDisplayList(
- DisplayItemList* display_list,
+ scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
const gfx::Rect& clip,
PaintingControlSetting picture_control) override {
NOTIMPLEMENTED();
+ return nullptr;
}
private:
@@ -334,11 +341,11 @@ class CircleContentLayerClient : public ContentLayerClient {
bounds_.width() / 4,
paint);
}
- void PaintContentsToDisplayList(
- DisplayItemList* display_list,
+ scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
const gfx::Rect& clip,
PaintingControlSetting picture_control) override {
NOTIMPLEMENTED();
+ return nullptr;
}
private:
@@ -369,7 +376,8 @@ TEST_P(LayerTreeHostMasksForBackgroundFiltersPixelTest,
gfx::Size picture_bounds(100, 100);
CheckerContentLayerClient picture_client(picture_bounds, SK_ColorGREEN, true);
- scoped_refptr<PictureLayer> picture = PictureLayer::Create(&picture_client);
+ scoped_refptr<PictureLayer> picture =
+ PictureLayer::Create(layer_settings(), &picture_client);
picture->SetBounds(picture_bounds);
picture->SetIsDrawable(true);
@@ -384,7 +392,8 @@ TEST_P(LayerTreeHostMasksForBackgroundFiltersPixelTest,
gfx::Size mask_bounds(100, 100);
CircleContentLayerClient mask_client(mask_bounds);
- scoped_refptr<PictureLayer> mask = PictureLayer::Create(&mask_client);
+ scoped_refptr<PictureLayer> mask =
+ PictureLayer::Create(layer_settings(), &mask_client);
mask->SetBounds(mask_bounds);
mask->SetIsDrawable(true);
mask->SetIsMask(true);
@@ -417,14 +426,14 @@ TEST_P(LayerTreeHostMasksForBackgroundFiltersPixelTest,
CheckerContentLayerClient picture_client_vertical(
picture_bounds, SK_ColorGREEN, true);
scoped_refptr<PictureLayer> picture_vertical =
- PictureLayer::Create(&picture_client_vertical);
+ PictureLayer::Create(layer_settings(), &picture_client_vertical);
picture_vertical->SetBounds(picture_bounds);
picture_vertical->SetIsDrawable(true);
CheckerContentLayerClient picture_client_horizontal(
picture_bounds, SK_ColorMAGENTA, false);
scoped_refptr<PictureLayer> picture_horizontal =
- PictureLayer::Create(&picture_client_horizontal);
+ PictureLayer::Create(layer_settings(), &picture_client_horizontal);
picture_horizontal->SetBounds(picture_bounds);
picture_horizontal->SetIsDrawable(true);
picture_horizontal->SetContentsOpaque(false);
@@ -435,7 +444,8 @@ TEST_P(LayerTreeHostMasksForBackgroundFiltersPixelTest,
gfx::Size mask_bounds(128, 128);
CircleContentLayerClient mask_client(mask_bounds);
- scoped_refptr<PictureLayer> mask = PictureLayer::Create(&mask_client);
+ scoped_refptr<PictureLayer> mask =
+ PictureLayer::Create(layer_settings(), &mask_client);
mask->SetBounds(mask_bounds);
mask->SetIsDrawable(true);
mask->SetIsMask(true);
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc b/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc
index b3729047aa5..6af0bb2f8d0 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc
@@ -485,18 +485,18 @@ class LayerTreeHostReadbackDeviceScalePixelTest
TEST_P(LayerTreeHostReadbackDeviceScalePixelTest, ReadbackSubrect) {
scoped_refptr<FakePictureLayer> background =
- FakePictureLayer::Create(&white_client_);
+ FakePictureLayer::Create(layer_settings(), &white_client_);
background->SetBounds(gfx::Size(100, 100));
background->SetIsDrawable(true);
scoped_refptr<FakePictureLayer> green =
- FakePictureLayer::Create(&green_client_);
+ FakePictureLayer::Create(layer_settings(), &green_client_);
green->SetBounds(gfx::Size(100, 100));
green->SetIsDrawable(true);
background->AddChild(green);
scoped_refptr<FakePictureLayer> blue =
- FakePictureLayer::Create(&blue_client_);
+ FakePictureLayer::Create(layer_settings(), &blue_client_);
blue->SetPosition(gfx::Point(50, 50));
blue->SetBounds(gfx::Size(25, 25));
blue->SetIsDrawable(true);
@@ -512,19 +512,19 @@ TEST_P(LayerTreeHostReadbackDeviceScalePixelTest, ReadbackSubrect) {
TEST_P(LayerTreeHostReadbackDeviceScalePixelTest, ReadbackNonRootLayerSubrect) {
scoped_refptr<FakePictureLayer> background =
- FakePictureLayer::Create(&white_client_);
+ FakePictureLayer::Create(layer_settings(), &white_client_);
background->SetBounds(gfx::Size(100, 100));
background->SetIsDrawable(true);
scoped_refptr<FakePictureLayer> green =
- FakePictureLayer::Create(&green_client_);
+ FakePictureLayer::Create(layer_settings(), &green_client_);
green->SetPosition(gfx::Point(10, 20));
green->SetBounds(gfx::Size(90, 80));
green->SetIsDrawable(true);
background->AddChild(green);
scoped_refptr<FakePictureLayer> blue =
- FakePictureLayer::Create(&blue_client_);
+ FakePictureLayer::Create(layer_settings(), &blue_client_);
blue->SetPosition(gfx::Point(50, 50));
blue->SetBounds(gfx::Size(25, 25));
blue->SetIsDrawable(true);
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc b/chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc
index 7dd6d7d856d..a5286a2473e 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc
@@ -21,6 +21,8 @@ class LayerTreeHostSynchronousPixelTest : public LayerTreePixelTest {
void InitializeSettings(LayerTreeSettings* settings) override {
LayerTreePixelTest::InitializeSettings(settings);
settings->single_thread_proxy_scheduler = false;
+ settings->use_zero_copy = true;
+ settings->use_one_copy = false;
}
void BeginTest() override {
@@ -36,7 +38,8 @@ TEST_F(LayerTreeHostSynchronousPixelTest, OneContentLayer) {
SkPaint green_paint;
green_paint.setColor(SkColorSetARGB(255, 0, 255, 0));
client.add_draw_rect(gfx::RectF(bounds), green_paint);
- scoped_refptr<PictureLayer> root = PictureLayer::Create(&client);
+ scoped_refptr<PictureLayer> root =
+ PictureLayer::Create(layer_settings(), &client);
root->SetBounds(bounds);
root->SetIsDrawable(true);
@@ -66,7 +69,8 @@ TEST_F(LayerTreeHostSynchronousGPUPixelTest, OneContentLayer) {
SkPaint green_paint;
green_paint.setColor(SkColorSetARGB(255, 0, 255, 0));
client.add_draw_rect(gfx::RectF(bounds), green_paint);
- scoped_refptr<PictureLayer> root = PictureLayer::Create(&client);
+ scoped_refptr<PictureLayer> root =
+ PictureLayer::Create(layer_settings(), &client);
root->SetBounds(bounds);
root->SetIsDrawable(true);
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc
new file mode 100644
index 00000000000..7a0af81f4e4
--- /dev/null
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc
@@ -0,0 +1,214 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/layers/content_layer_client.h"
+#include "cc/layers/picture_layer.h"
+#include "cc/output/copy_output_request.h"
+#include "cc/playback/display_item_list.h"
+#include "cc/playback/drawing_display_item.h"
+#include "cc/test/layer_tree_pixel_test.h"
+#include "cc/test/test_gpu_memory_buffer_manager.h"
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkPictureRecorder.h"
+
+#if !defined(OS_ANDROID)
+
+namespace cc {
+namespace {
+
+enum RasterMode {
+ PARTIAL_ONE_COPY,
+ FULL_ONE_COPY,
+ GPU,
+ BITMAP,
+};
+
+class LayerTreeHostTilesPixelTest : public LayerTreePixelTest {
+ protected:
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ LayerTreePixelTest::InitializeSettings(settings);
+ settings->use_display_lists = true;
+ switch (raster_mode_) {
+ case PARTIAL_ONE_COPY:
+ settings->use_one_copy = true;
+ settings->use_zero_copy = false;
+ settings->use_persistent_map_for_gpu_memory_buffers = true;
+ break;
+ case FULL_ONE_COPY:
+ settings->use_one_copy = true;
+ settings->use_zero_copy = false;
+ settings->use_persistent_map_for_gpu_memory_buffers = false;
+ break;
+ case BITMAP:
+ // This is done via context creation. No settings to change here!
+ break;
+ case GPU:
+ settings->gpu_rasterization_enabled = true;
+ settings->gpu_rasterization_forced = true;
+ break;
+ }
+ }
+
+ void BeginTest() override {
+ // Don't set up a readback target at the start of the test.
+ PostSetNeedsCommitToMainThread();
+ }
+
+ void DoReadback() {
+ Layer* target =
+ readback_target_ ? readback_target_ : layer_tree_host()->root_layer();
+ target->RequestCopyOfOutput(CreateCopyOutputRequest());
+ }
+
+ void RunRasterPixelTest(bool threaded,
+ RasterMode mode,
+ scoped_refptr<Layer> content_root,
+ base::FilePath file_name) {
+ raster_mode_ = mode;
+
+ PixelTestType test_type = PIXEL_TEST_SOFTWARE;
+ switch (mode) {
+ case PARTIAL_ONE_COPY:
+ case FULL_ONE_COPY:
+ case GPU:
+ test_type = PIXEL_TEST_GL;
+ break;
+ case BITMAP:
+ test_type = PIXEL_TEST_SOFTWARE;
+ }
+
+ if (threaded)
+ RunPixelTest(test_type, content_root, file_name);
+ else
+ RunSingleThreadedPixelTest(test_type, content_root, file_name);
+ }
+
+ base::FilePath ref_file_;
+ scoped_ptr<SkBitmap> result_bitmap_;
+ RasterMode raster_mode_;
+};
+
+class BlueYellowClient : public ContentLayerClient {
+ public:
+ explicit BlueYellowClient(const gfx::Size& size)
+ : size_(size), blue_top_(true) {}
+
+ void PaintContents(SkCanvas* canvas,
+ const gfx::Rect& clip,
+ PaintingControlSetting painting_status) override {}
+
+ scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
+ const gfx::Rect& clip,
+ PaintingControlSetting painting_status) override {
+ bool use_cached_picture = false;
+ scoped_refptr<DisplayItemList> display_list =
+ DisplayItemList::Create(clip, use_cached_picture);
+
+ SkPictureRecorder recorder;
+ skia::RefPtr<SkCanvas> canvas = skia::SharePtr(
+ recorder.beginRecording(gfx::RectToSkRect(gfx::Rect(size_))));
+ gfx::Rect top(0, 0, size_.width(), size_.height() / 2);
+ gfx::Rect bottom(0, size_.height() / 2, size_.width(), size_.height() / 2);
+
+ gfx::Rect blue_rect = blue_top_ ? top : bottom;
+ gfx::Rect yellow_rect = blue_top_ ? bottom : top;
+
+ SkPaint paint;
+ paint.setStyle(SkPaint::kFill_Style);
+
+ paint.setColor(SK_ColorBLUE);
+ canvas->drawRect(gfx::RectToSkRect(blue_rect), paint);
+ paint.setColor(SK_ColorYELLOW);
+ canvas->drawRect(gfx::RectToSkRect(yellow_rect), paint);
+
+ skia::RefPtr<SkPicture> picture =
+ skia::AdoptRef(recorder.endRecordingAsPicture());
+
+ auto* item = display_list->CreateAndAppendItem<DrawingDisplayItem>();
+ item->SetNew(picture.Pass());
+
+ display_list->Finalize();
+ return display_list;
+ }
+
+ bool FillsBoundsCompletely() const override { return true; }
+
+ void set_blue_top(bool b) { blue_top_ = b; }
+
+ private:
+ gfx::Size size_;
+ bool blue_top_;
+};
+
+class LayerTreeHostTilesTestPartialInvalidation
+ : public LayerTreeHostTilesPixelTest {
+ public:
+ LayerTreeHostTilesTestPartialInvalidation()
+ : client_(gfx::Size(200, 200)),
+ picture_layer_(PictureLayer::Create(layer_settings(), &client_)) {
+ picture_layer_->SetBounds(gfx::Size(200, 200));
+ picture_layer_->SetIsDrawable(true);
+ }
+
+ void DidCommitAndDrawFrame() override {
+ switch (layer_tree_host()->source_frame_number()) {
+ case 1:
+ // We have done one frame, so the layer's content has been rastered.
+ // Now we change the picture behind it to record something completely
+ // different, but we give a smaller invalidation rect. The layer should
+ // only re-raster the stuff in the rect. If it doesn't do partial raster
+ // it would re-raster the whole thing instead.
+ client_.set_blue_top(false);
+ picture_layer_->SetNeedsDisplayRect(gfx::Rect(50, 50, 100, 100));
+
+ // Add a copy request to see what happened!
+ DoReadback();
+ break;
+ }
+ }
+
+ protected:
+ BlueYellowClient client_;
+ scoped_refptr<PictureLayer> picture_layer_;
+};
+
+TEST_F(LayerTreeHostTilesTestPartialInvalidation,
+ PartialRaster_SingleThread_OneCopy) {
+ RunRasterPixelTest(
+ false, PARTIAL_ONE_COPY, picture_layer_,
+ base::FilePath(FILE_PATH_LITERAL("blue_yellow_partial_flipped.png")));
+}
+
+TEST_F(LayerTreeHostTilesTestPartialInvalidation,
+ FullRaster_SingleThread_OneCopy) {
+ RunRasterPixelTest(
+ false, FULL_ONE_COPY, picture_layer_,
+ base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png")));
+}
+
+TEST_F(LayerTreeHostTilesTestPartialInvalidation,
+ FullRaster_MultiThread_OneCopy) {
+ RunRasterPixelTest(
+ true, FULL_ONE_COPY, picture_layer_,
+ base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png")));
+}
+
+TEST_F(LayerTreeHostTilesTestPartialInvalidation,
+ PartialRaster_SingleThread_Software) {
+ RunRasterPixelTest(
+ false, BITMAP, picture_layer_,
+ base::FilePath(FILE_PATH_LITERAL("blue_yellow_partial_flipped.png")));
+}
+
+TEST_F(LayerTreeHostTilesTestPartialInvalidation,
+ PartialRaster_SingleThread_GpuRaster) {
+ RunRasterPixelTest(
+ false, GPU, picture_layer_,
+ base::FilePath(FILE_PATH_LITERAL("blue_yellow_partial_flipped.png")));
+}
+
+} // namespace
+} // namespace cc
+
+#endif // !defined(OS_ANDROID)
diff --git a/chromium/cc/trees/layer_tree_host_unittest.cc b/chromium/cc/trees/layer_tree_host_unittest.cc
index 98ac5a11d6e..6d9c9c67199 100644
--- a/chromium/cc/trees/layer_tree_host_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest.cc
@@ -13,7 +13,6 @@
#include "base/thread_task_runner_handle.h"
#include "cc/animation/timing_function.h"
#include "cc/debug/frame_rate_counter.h"
-#include "cc/layers/content_layer.h"
#include "cc/layers/content_layer_client.h"
#include "cc/layers/io_surface_layer.h"
#include "cc/layers/layer_impl.h"
@@ -31,12 +30,7 @@
#include "cc/quads/io_surface_draw_quad.h"
#include "cc/quads/render_pass_draw_quad.h"
#include "cc/quads/tile_draw_quad.h"
-#include "cc/resources/prioritized_resource.h"
-#include "cc/resources/prioritized_resource_manager.h"
-#include "cc/resources/resource_update_queue.h"
-#include "cc/test/fake_content_layer.h"
#include "cc/test/fake_content_layer_client.h"
-#include "cc/test/fake_content_layer_impl.h"
#include "cc/test/fake_layer_tree_host_client.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_painted_scrollbar_layer.h"
@@ -47,7 +41,6 @@
#include "cc/test/fake_scoped_ui_resource.h"
#include "cc/test/fake_video_frame_provider.h"
#include "cc/test/geometry_test_utils.h"
-#include "cc/test/impl_side_painting_settings.h"
#include "cc/test/layer_tree_test.h"
#include "cc/test/test_shared_bitmap_manager.h"
#include "cc/test/test_web_graphics_context_3d.h"
@@ -61,7 +54,6 @@
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/khronos/GLES2/gl2ext.h"
#include "third_party/skia/include/core/SkPicture.h"
-#include "ui/gfx/frame_time.h"
#include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/geometry/vector2d_conversions.h"
@@ -74,28 +66,15 @@ using testing::Mock;
namespace cc {
namespace {
-class LayerTreeHostTest : public LayerTreeTest {
- public:
- LayerTreeHostTest() : contents_texture_manager_(nullptr) {}
-
- void DidInitializeOutputSurface() override {
- contents_texture_manager_ = layer_tree_host()->contents_texture_manager();
- }
-
- protected:
- PrioritizedResourceManager* contents_texture_manager_;
-};
+class LayerTreeHostTest : public LayerTreeTest {};
class LayerTreeHostTestHasImplThreadTest : public LayerTreeHostTest {
public:
LayerTreeHostTestHasImplThreadTest() : threaded_(false) {}
- void RunTest(bool threaded,
- bool delegating_renderer,
- bool impl_side_painting) override {
+ void RunTest(bool threaded, bool delegating_renderer) override {
threaded_ = threaded;
- LayerTreeHostTest::RunTest(threaded, delegating_renderer,
- impl_side_painting);
+ LayerTreeHostTest::RunTest(threaded, delegating_renderer);
}
void BeginTest() override {
@@ -109,7 +88,7 @@ class LayerTreeHostTestHasImplThreadTest : public LayerTreeHostTest {
bool threaded_;
};
-SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestHasImplThreadTest);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestHasImplThreadTest);
class LayerTreeHostTestSetNeedsCommitInsideLayout : public LayerTreeHostTest {
protected:
@@ -128,8 +107,7 @@ class LayerTreeHostTestSetNeedsCommitInsideLayout : public LayerTreeHostTest {
void AfterTest() override {}
};
-SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(
- LayerTreeHostTestSetNeedsCommitInsideLayout);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommitInsideLayout);
class LayerTreeHostTestSetNeedsUpdateInsideLayout : public LayerTreeHostTest {
protected:
@@ -148,8 +126,7 @@ class LayerTreeHostTestSetNeedsUpdateInsideLayout : public LayerTreeHostTest {
void AfterTest() override {}
};
-SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(
- LayerTreeHostTestSetNeedsUpdateInsideLayout);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsUpdateInsideLayout);
// Test if the LTHI receives ReadyToActivate notifications from the TileManager
// when no raster tasks get scheduled.
@@ -193,7 +170,7 @@ class LayerTreeHostTestReadyToActivateEmpty : public LayerTreeHostTest {
size_t required_for_activation_count_;
};
-SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToActivateEmpty);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestReadyToActivateEmpty);
// Test if the LTHI receives ReadyToActivate notifications from the TileManager
// when some raster tasks flagged as REQUIRED_FOR_ACTIVATION got scheduled.
@@ -203,7 +180,7 @@ class LayerTreeHostTestReadyToActivateNonEmpty
void SetupTree() override {
client_.set_fill_with_nonsolid_color(true);
scoped_refptr<FakePictureLayer> root_layer =
- FakePictureLayer::Create(&client_);
+ FakePictureLayer::Create(layer_settings(), &client_);
root_layer->SetBounds(gfx::Size(1024, 1024));
root_layer->SetIsDrawable(true);
@@ -223,7 +200,7 @@ class LayerTreeHostTestReadyToActivateNonEmpty
// Multi-thread only because in single thread the commit goes directly to the
// active tree, so notify ready to activate is skipped.
-MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToActivateNonEmpty);
+MULTI_THREAD_TEST_F(LayerTreeHostTestReadyToActivateNonEmpty);
// Test if the LTHI receives ReadyToDraw notifications from the TileManager when
// no raster tasks get scheduled.
@@ -263,7 +240,7 @@ class LayerTreeHostTestReadyToDrawEmpty : public LayerTreeHostTest {
size_t required_for_draw_count_;
};
-SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToDrawEmpty);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestReadyToDrawEmpty);
// Test if the LTHI receives ReadyToDraw notifications from the TileManager when
// some raster tasks flagged as REQUIRED_FOR_DRAW got scheduled.
@@ -273,7 +250,7 @@ class LayerTreeHostTestReadyToDrawNonEmpty
void SetupTree() override {
client_.set_fill_with_nonsolid_color(true);
scoped_refptr<FakePictureLayer> root_layer =
- FakePictureLayer::Create(&client_);
+ FakePictureLayer::Create(layer_settings(), &client_);
root_layer->SetBounds(gfx::Size(1024, 1024));
root_layer->SetIsDrawable(true);
@@ -293,7 +270,104 @@ class LayerTreeHostTestReadyToDrawNonEmpty
// Note: With this test setup, we only get tiles flagged as REQUIRED_FOR_DRAW in
// single threaded mode.
-SINGLE_THREAD_IMPL_TEST_F(LayerTreeHostTestReadyToDrawNonEmpty);
+SINGLE_THREAD_TEST_F(LayerTreeHostTestReadyToDrawNonEmpty);
+
+class LayerTreeHostFreeWorkerContextResourcesTest : public LayerTreeHostTest {
+ public:
+ scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface() override {
+ auto output_surface = make_scoped_ptr(new testing::StrictMock<
+ MockSetWorkerContextShouldAggressivelyFreeResourcesOutputSurface>(
+ delegating_renderer()));
+
+ // At init, we expect one call to set visibility to true.
+ testing::Expectation visibility_true =
+ EXPECT_CALL(*output_surface,
+ SetWorkerContextShouldAggressivelyFreeResources(false))
+ .Times(1);
+
+ // After running, we should get exactly one call to
+ // FreeWorkerContextGpuResources.
+ EXPECT_CALL(*output_surface,
+ SetWorkerContextShouldAggressivelyFreeResources(true))
+ .After(visibility_true)
+ .WillOnce(testing::Invoke([this](bool is_visible) { EndTest(); }));
+ return output_surface.Pass();
+ }
+
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->gpu_rasterization_enabled = true;
+ settings->gpu_rasterization_forced = true;
+ }
+
+ void BeginTest() override {
+ // Logic is handled in InitializedRendererOnThread to ensure that our
+ // LTHI is fully set up.
+ }
+
+ void AfterTest() override {
+ // Expectations handled via mock.
+ }
+
+ private:
+ class MockSetWorkerContextShouldAggressivelyFreeResourcesOutputSurface
+ : public FakeOutputSurface {
+ public:
+ ~MockSetWorkerContextShouldAggressivelyFreeResourcesOutputSurface() {}
+ explicit MockSetWorkerContextShouldAggressivelyFreeResourcesOutputSurface(
+ bool delegated_rendering)
+ : FakeOutputSurface(TestContextProvider::Create(),
+ TestContextProvider::Create(),
+ delegated_rendering) {}
+ MOCK_METHOD1(SetWorkerContextShouldAggressivelyFreeResources,
+ void(bool is_visible));
+ };
+};
+
+// Test if the LTH successfully frees resources on the worker context when
+// visibility is set to false.
+class LayerTreeHostFreeWorkerContextResourcesOnInvisible
+ : public LayerTreeHostFreeWorkerContextResourcesTest {
+ public:
+ void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
+ bool success) override {
+ PostSetVisibleToMainThread(false);
+ }
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeHostFreeWorkerContextResourcesOnInvisible);
+
+// Test if the LTH successfully frees resources on the worker context when
+// hard memory limit is set to zero.
+class LayerTreeHostFreeWorkerContextResourcesOnZeroMemoryLimit
+ : public LayerTreeHostFreeWorkerContextResourcesTest {
+ public:
+ void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
+ bool success) override {
+ ManagedMemoryPolicy zero_policy(
+ 0, gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING, 0);
+ host_impl->SetMemoryPolicy(zero_policy);
+ }
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeHostFreeWorkerContextResourcesOnZeroMemoryLimit);
+
+// Test if the LTH successfully frees resources on the worker context when
+// hard memory limit is set to zero while using a synchronous compositor (like
+// Android WebView).
+class LayerTreeHostFreeWorkerContextResourcesOnZeroMemoryLimitSynchronous
+ : public LayerTreeHostFreeWorkerContextResourcesOnZeroMemoryLimit {
+ public:
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ LayerTreeHostFreeWorkerContextResourcesTest::InitializeSettings(settings);
+ settings->use_external_begin_frame_source = true;
+ settings->using_synchronous_renderer_compositor = true;
+ }
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeHostFreeWorkerContextResourcesOnZeroMemoryLimitSynchronous);
// Two setNeedsCommits in a row should lead to at least 1 commit and at least 1
// draw with frame 0.
@@ -368,7 +442,7 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2);
class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest {
protected:
void SetupTree() override {
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
root->CreateRenderSurface();
root->SetBounds(gfx::Size(10, 10));
layer_tree_host()->SetRootLayer(root);
@@ -502,10 +576,7 @@ class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest {
: num_draws_(0), bounds_(50, 50), invalid_rect_(10, 10, 20, 20) {}
void BeginTest() override {
- if (layer_tree_host()->settings().impl_side_painting)
- root_layer_ = FakePictureLayer::Create(&client_);
- else
- root_layer_ = ContentLayer::Create(&client_);
+ root_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
root_layer_->SetIsDrawable(true);
root_layer_->SetBounds(bounds_);
layer_tree_host()->SetRootLayer(root_layer_);
@@ -549,7 +620,7 @@ class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest {
const gfx::Size bounds_;
const gfx::Rect invalid_rect_;
FakeContentLayerClient client_;
- scoped_refptr<Layer> root_layer_;
+ scoped_refptr<FakePictureLayer> root_layer_;
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedrawRect);
@@ -563,7 +634,7 @@ class LayerTreeHostTestGpuRasterDeviceSizeChanged : public LayerTreeHostTest {
void BeginTest() override {
client_.set_fill_with_nonsolid_color(true);
- root_layer_ = FakePictureLayer::Create(&client_);
+ root_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
root_layer_->SetIsDrawable(true);
gfx::Transform transform;
// Translate the layer out of the viewport to force it to not update its
@@ -631,8 +702,7 @@ class LayerTreeHostTestGpuRasterDeviceSizeChanged : public LayerTreeHostTest {
scoped_refptr<FakePictureLayer> root_layer_;
};
-SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(
- LayerTreeHostTestGpuRasterDeviceSizeChanged);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterDeviceSizeChanged);
class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest {
public:
@@ -641,14 +711,11 @@ class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest {
}
void SetupTree() override {
- root_layer_ = Layer::Create();
+ root_layer_ = Layer::Create(layer_settings());
root_layer_->SetBounds(gfx::Size(10, 20));
root_layer_->CreateRenderSurface();
- if (layer_tree_host()->settings().impl_side_painting)
- scaled_layer_ = FakePictureLayer::Create(&client_);
- else
- scaled_layer_ = FakeContentLayer::Create(&client_);
+ scaled_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
scaled_layer_->SetBounds(gfx::Size(1, 1));
root_layer_->AddChild(scaled_layer_);
@@ -695,14 +762,14 @@ class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate
}
void SetupTree() override {
- root_layer_ = Layer::Create();
+ root_layer_ = Layer::Create(layer_settings());
root_layer_->SetBounds(gfx::Size(10, 20));
root_layer_->CreateRenderSurface();
bool paint_scrollbar = true;
bool has_thumb = false;
scrollbar_ = FakePaintedScrollbarLayer::Create(
- paint_scrollbar, has_thumb, root_layer_->id());
+ layer_settings(), paint_scrollbar, has_thumb, root_layer_->id());
scrollbar_->SetPosition(gfx::Point(0, 10));
scrollbar_->SetBounds(gfx::Size(10, 10));
@@ -752,10 +819,7 @@ class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest {
: num_draws_(0), bounds_(50, 50), invalid_rect_(10, 10, 20, 20) {}
void BeginTest() override {
- if (layer_tree_host()->settings().impl_side_painting)
- root_layer_ = FakePictureLayer::Create(&client_);
- else
- root_layer_ = ContentLayer::Create(&client_);
+ root_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
root_layer_->SetIsDrawable(true);
root_layer_->SetBounds(bounds_);
layer_tree_host()->SetRootLayer(root_layer_);
@@ -764,7 +828,7 @@ class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest {
}
void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
- if (num_draws_ == 3 && host_impl->settings().impl_side_painting)
+ if (num_draws_ == 3)
host_impl->SetNeedsRedrawRect(invalid_rect_);
}
@@ -810,10 +874,7 @@ class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest {
// Should force full frame damage on the next commit
PostSetNextCommitForcesRedrawToMainThread();
PostSetNeedsCommitToMainThread();
- if (host_impl->settings().impl_side_painting)
- host_impl->BlockNotifyReadyToActivateForTesting(true);
- else
- num_draws_++;
+ host_impl->BlockNotifyReadyToActivateForTesting(true);
break;
case 3:
host_impl->BlockNotifyReadyToActivateForTesting(false);
@@ -832,18 +893,16 @@ class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest {
const gfx::Size bounds_;
const gfx::Rect invalid_rect_;
FakeContentLayerClient client_;
- scoped_refptr<Layer> root_layer_;
+ scoped_refptr<FakePictureLayer> root_layer_;
};
-SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
- LayerTreeHostTestSetNextCommitForcesRedraw);
+// This test blocks activation which is not supported for single thread mode.
+MULTI_THREAD_BLOCKNOTIFY_TEST_F(LayerTreeHostTestSetNextCommitForcesRedraw);
// Tests that if a layer is not drawn because of some reason in the parent then
// its damage is preserved until the next time it is drawn.
class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest {
public:
- LayerTreeHostTestUndrawnLayersDamageLater() {}
-
void InitializeSettings(LayerTreeSettings* settings) override {
// If we don't set the minimum contents scale, it's harder to verify whether
// the damage we get is correct. For other scale amounts, please see
@@ -852,28 +911,19 @@ class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest {
}
void SetupTree() override {
- if (layer_tree_host()->settings().impl_side_painting)
- root_layer_ = FakePictureLayer::Create(&client_);
- else
- root_layer_ = ContentLayer::Create(&client_);
+ root_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
root_layer_->SetIsDrawable(true);
root_layer_->SetBounds(gfx::Size(50, 50));
layer_tree_host()->SetRootLayer(root_layer_);
// The initially transparent layer has a larger child layer, which is
// not initially drawn because of the this (parent) layer.
- if (layer_tree_host()->settings().impl_side_painting)
- parent_layer_ = FakePictureLayer::Create(&client_);
- else
- parent_layer_ = FakeContentLayer::Create(&client_);
+ parent_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
parent_layer_->SetBounds(gfx::Size(15, 15));
parent_layer_->SetOpacity(0.0f);
root_layer_->AddChild(parent_layer_);
- if (layer_tree_host()->settings().impl_side_painting)
- child_layer_ = FakePictureLayer::Create(&client_);
- else
- child_layer_ = FakeContentLayer::Create(&client_);
+ child_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
child_layer_->SetBounds(gfx::Size(25, 25));
parent_layer_->AddChild(child_layer_);
@@ -938,9 +988,9 @@ class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest {
private:
FakeContentLayerClient client_;
- scoped_refptr<Layer> root_layer_;
- scoped_refptr<Layer> parent_layer_;
- scoped_refptr<Layer> child_layer_;
+ scoped_refptr<FakePictureLayer> root_layer_;
+ scoped_refptr<FakePictureLayer> parent_layer_;
+ scoped_refptr<FakePictureLayer> child_layer_;
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUndrawnLayersDamageLater);
@@ -955,17 +1005,16 @@ class LayerTreeHostTestDamageWithScale : public LayerTreeHostTest {
client_.set_fill_with_nonsolid_color(true);
scoped_ptr<FakePicturePile> pile(
- new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
- ImplSidePaintingSettings().default_tile_grid_size));
- root_layer_ =
- FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
+ new FakePicturePile(LayerTreeSettings().minimum_contents_scale,
+ LayerTreeSettings().default_tile_grid_size));
+ root_layer_ = FakePictureLayer::CreateWithRecordingSource(
+ layer_settings(), &client_, pile.Pass());
root_layer_->SetBounds(gfx::Size(50, 50));
- pile.reset(
- new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
- ImplSidePaintingSettings().default_tile_grid_size));
- child_layer_ =
- FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
+ pile.reset(new FakePicturePile(LayerTreeSettings().minimum_contents_scale,
+ LayerTreeSettings().default_tile_grid_size));
+ child_layer_ = FakePictureLayer::CreateWithRecordingSource(
+ layer_settings(), &client_, pile.Pass());
child_layer_->SetBounds(gfx::Size(25, 25));
child_layer_->SetIsDrawable(true);
child_layer_->SetContentsOpaque(true);
@@ -1051,79 +1100,7 @@ class LayerTreeHostTestDamageWithScale : public LayerTreeHostTest {
scoped_refptr<Layer> child_layer_;
};
-MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestDamageWithScale);
-
-// Tests that if a layer is not drawn because of some reason in the parent,
-// causing its content bounds to not be computed, then when it is later drawn,
-// its content bounds get pushed.
-class LayerTreeHostTestUndrawnLayersPushContentBoundsLater
- : public LayerTreeHostTest {
- public:
- LayerTreeHostTestUndrawnLayersPushContentBoundsLater()
- : root_layer_(Layer::Create()) {}
-
- void SetupTree() override {
- root_layer_->CreateRenderSurface();
- root_layer_->SetIsDrawable(true);
- root_layer_->SetBounds(gfx::Size(20, 20));
- layer_tree_host()->SetRootLayer(root_layer_);
-
- parent_layer_ = Layer::Create();
- parent_layer_->SetBounds(gfx::Size(20, 20));
- parent_layer_->SetOpacity(0.0f);
- root_layer_->AddChild(parent_layer_);
-
- child_layer_ = Layer::Create();
- child_layer_->SetBounds(gfx::Size(15, 15));
- parent_layer_->AddChild(child_layer_);
-
- LayerTreeHostTest::SetupTree();
- }
-
- void BeginTest() override { PostSetNeedsCommitToMainThread(); }
-
- void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
- LayerImpl* root = host_impl->active_tree()->root_layer();
- LayerImpl* parent = root->children()[0];
- LayerImpl* child = parent->children()[0];
-
- switch (host_impl->active_tree()->source_frame_number()) {
- case 0:
- EXPECT_EQ(0.f, parent->opacity());
- EXPECT_EQ(gfx::SizeF(), child->content_bounds());
- break;
- case 1:
- EXPECT_EQ(1.f, parent->opacity());
- EXPECT_EQ(gfx::SizeF(15.f, 15.f), child->content_bounds());
- EndTest();
- break;
- default:
- NOTREACHED();
- }
- }
-
- void DidCommit() override {
- switch (layer_tree_host()->source_frame_number()) {
- case 1:
- parent_layer_->SetOpacity(1.0f);
- break;
- case 2:
- break;
- default:
- NOTREACHED();
- }
- }
-
- void AfterTest() override {}
-
- private:
- scoped_refptr<Layer> root_layer_;
- scoped_refptr<Layer> parent_layer_;
- scoped_refptr<Layer> child_layer_;
-};
-
-SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(
- LayerTreeHostTestUndrawnLayersPushContentBoundsLater);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDamageWithScale);
// This test verifies that properties on the layer tree host are commited
// to the impl side.
@@ -1168,8 +1145,7 @@ class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails
void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
EXPECT_EQ(frame_count_with_pending_tree_, 0);
- if (impl->settings().impl_side_painting)
- impl->BlockNotifyReadyToActivateForTesting(true);
+ impl->BlockNotifyReadyToActivateForTesting(true);
}
void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl,
@@ -1180,27 +1156,21 @@ class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails
if (frame_count_with_pending_tree_ == 1) {
EXPECT_EQ(first_frame_time_.ToInternalValue(), 0);
first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time;
- } else if (frame_count_with_pending_tree_ == 2 &&
- impl->settings().impl_side_painting) {
+ } else if (frame_count_with_pending_tree_ == 2) {
impl->BlockNotifyReadyToActivateForTesting(false);
}
}
void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
- if (frame_count_with_pending_tree_ > 1) {
- EXPECT_NE(first_frame_time_.ToInternalValue(), 0);
- EXPECT_NE(first_frame_time_.ToInternalValue(),
- impl->CurrentBeginFrameArgs().frame_time.ToInternalValue());
- EndTest();
- return;
- }
-
- EXPECT_FALSE(impl->settings().impl_side_painting);
+ EXPECT_GT(frame_count_with_pending_tree_, 1);
+ EXPECT_NE(first_frame_time_.ToInternalValue(), 0);
+ EXPECT_NE(first_frame_time_.ToInternalValue(),
+ impl->CurrentBeginFrameArgs().frame_time.ToInternalValue());
EndTest();
}
+
void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
- if (impl->settings().impl_side_painting)
- EXPECT_NE(frame_count_with_pending_tree_, 1);
+ EXPECT_GT(frame_count_with_pending_tree_, 1);
}
void AfterTest() override {}
@@ -1210,7 +1180,8 @@ class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails
base::TimeTicks first_frame_time_;
};
-SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
+// This test blocks activation which is not supported for single thread mode.
+MULTI_THREAD_BLOCKNOTIFY_TEST_F(
LayerTreeHostTestFrameTimeUpdatesAfterActivationFails);
// This test verifies that LayerTreeHostImpl's current frame time gets
@@ -1234,7 +1205,7 @@ class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest {
// Since we might use a low-resolution clock on Windows, we need to
// make sure that the clock has incremented past first_frame_time_.
- while (first_frame_time_ == gfx::FrameTime::Now()) {
+ while (first_frame_time_ == base::TimeTicks::Now()) {
}
return;
@@ -1271,7 +1242,8 @@ class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest {
void SetupTree() override {
LayerTreeHostTest::SetupTree();
- scoped_refptr<FakePictureLayer> layer = FakePictureLayer::Create(&client_);
+ scoped_refptr<FakePictureLayer> layer =
+ FakePictureLayer::Create(layer_settings(), &client_);
layer->set_always_update_resources(true);
scroll_layer_ = layer;
@@ -1291,7 +1263,9 @@ class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest {
void BeginTest() override { PostSetNeedsCommitToMainThread(); }
- void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
+ void ApplyViewportDeltas(const gfx::Vector2dF& scroll_delta,
+ const gfx::Vector2dF&,
+ const gfx::Vector2dF& elastic_overscroll_delta,
float scale,
float) override {
gfx::ScrollOffset offset = scroll_layer_->scroll_offset();
@@ -1335,7 +1309,8 @@ class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest {
scoped_refptr<Layer> scroll_layer_;
};
-MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestStartPageScaleAnimation);
+// Single thread proxy does not support impl-side page scale changes.
+MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation);
class LayerTreeHostTestSetVisible : public LayerTreeHostTest {
public:
@@ -1377,11 +1352,11 @@ class TestOpacityChangeLayerDelegate : public ContentLayerClient {
if (test_layer_)
test_layer_->SetOpacity(0.f);
}
- void PaintContentsToDisplayList(
- DisplayItemList* display_list,
+ scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
const gfx::Rect& clip,
PaintingControlSetting picture_control) override {
NOTIMPLEMENTED();
+ return nullptr;
}
bool FillsBoundsCompletely() const override { return false; }
@@ -1389,78 +1364,34 @@ class TestOpacityChangeLayerDelegate : public ContentLayerClient {
Layer* test_layer_;
};
-class ContentLayerWithUpdateTracking : public ContentLayer {
- public:
- static scoped_refptr<ContentLayerWithUpdateTracking> Create(
- ContentLayerClient* client) {
- return make_scoped_refptr(new ContentLayerWithUpdateTracking(client));
- }
-
- int PaintContentsCount() { return paint_contents_count_; }
- void ResetPaintContentsCount() { paint_contents_count_ = 0; }
-
- bool Update(ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion) override {
- bool updated = ContentLayer::Update(queue, occlusion);
- paint_contents_count_++;
- return updated;
- }
-
- private:
- explicit ContentLayerWithUpdateTracking(ContentLayerClient* client)
- : ContentLayer(client), paint_contents_count_(0) {
- SetBounds(gfx::Size(10, 10));
- SetIsDrawable(true);
- }
- ~ContentLayerWithUpdateTracking() override {}
-
- int paint_contents_count_;
-};
-
// Layer opacity change during paint should not prevent compositor resources
// from being updated during commit.
class LayerTreeHostTestOpacityChange : public LayerTreeHostTest {
public:
LayerTreeHostTestOpacityChange() : test_opacity_change_delegate_() {}
- void BeginTest() override {
- if (layer_tree_host()->settings().impl_side_painting) {
- update_check_picture_layer_ =
- FakePictureLayer::Create(&test_opacity_change_delegate_);
- test_opacity_change_delegate_.SetTestLayer(
- update_check_picture_layer_.get());
- is_impl_paint_ = true;
- } else {
- update_check_content_layer_ = ContentLayerWithUpdateTracking::Create(
- &test_opacity_change_delegate_);
- test_opacity_change_delegate_.SetTestLayer(
- update_check_content_layer_.get());
- is_impl_paint_ = false;
- }
- layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
- if (layer_tree_host()->settings().impl_side_painting)
- layer_tree_host()->root_layer()->AddChild(update_check_picture_layer_);
- else
- layer_tree_host()->root_layer()->AddChild(update_check_content_layer_);
+ void SetupTree() override {
+ LayerTreeHostTest::SetupTree();
- PostSetNeedsCommitToMainThread();
+ update_check_picture_layer_ = FakePictureLayer::Create(
+ layer_settings(), &test_opacity_change_delegate_);
+ test_opacity_change_delegate_.SetTestLayer(
+ update_check_picture_layer_.get());
+ layer_tree_host()->root_layer()->AddChild(update_check_picture_layer_);
}
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { EndTest(); }
void AfterTest() override {
// Update() should have been called once.
- if (is_impl_paint_)
- EXPECT_EQ(1u, update_check_picture_layer_->update_count());
- else
- EXPECT_EQ(1, update_check_content_layer_->PaintContentsCount());
+ EXPECT_EQ(1, update_check_picture_layer_->update_count());
}
private:
TestOpacityChangeLayerDelegate test_opacity_change_delegate_;
- scoped_refptr<ContentLayerWithUpdateTracking> update_check_content_layer_;
scoped_refptr<FakePictureLayer> update_check_picture_layer_;
- bool is_impl_paint_;
};
MULTI_THREAD_TEST_F(LayerTreeHostTestOpacityChange);
@@ -1470,15 +1401,10 @@ class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
public:
LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers() {}
- void InitializeSettings(LayerTreeSettings* settings) override {
- // PictureLayer can only be used with impl side painting enabled.
- settings->impl_side_painting = true;
- }
-
void BeginTest() override {
client_.set_fill_with_nonsolid_color(true);
- root_layer_ = FakePictureLayer::Create(&client_);
- child_layer_ = FakePictureLayer::Create(&client_);
+ root_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
+ child_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
layer_tree_host()->SetViewportSize(gfx::Size(60, 60));
layer_tree_host()->SetDeviceScaleFactor(1.5);
@@ -1573,666 +1499,6 @@ class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers);
-// TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
-// Verify atomicity of commits and reuse of textures.
-class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest {
- public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->renderer_settings.texture_id_allocation_chunk_size = 1;
- // Make sure partial texture updates are turned off.
- settings->max_partial_texture_updates = 0;
- // Linear fade animator prevents scrollbars from drawing immediately.
- settings->scrollbar_animator = LayerTreeSettings::NO_ANIMATOR;
- }
-
- void SetupTree() override {
- layer_ = FakeContentLayer::Create(&client_);
- layer_->SetBounds(gfx::Size(10, 20));
-
- bool paint_scrollbar = true;
- bool has_thumb = false;
- scrollbar_ = FakePaintedScrollbarLayer::Create(
- paint_scrollbar, has_thumb, layer_->id());
- scrollbar_->SetPosition(gfx::Point(0, 10));
- scrollbar_->SetBounds(gfx::Size(10, 10));
-
- layer_->AddChild(scrollbar_);
-
- layer_tree_host()->SetRootLayer(layer_);
- LayerTreeHostTest::SetupTree();
- }
-
- void BeginTest() override {
- drew_frame_ = -1;
- PostSetNeedsCommitToMainThread();
- }
-
- void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
- ASSERT_EQ(0u, impl->settings().max_partial_texture_updates);
-
- TestWebGraphicsContext3D* context = TestContext();
-
- switch (impl->active_tree()->source_frame_number()) {
- case 0:
- // Number of textures should be one for each layer
- ASSERT_EQ(2u, context->NumTextures());
- // Number of textures used for commit should be one for each layer.
- EXPECT_EQ(2u, context->NumUsedTextures());
- // Verify that used texture is correct.
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
-
- context->ResetUsedTextures();
- break;
- case 1:
- // Number of textures should be one for scrollbar layer since it was
- // requested and deleted on the impl-thread, and double for the content
- // layer since its first texture is used by impl thread and cannot by
- // used for update.
- ASSERT_EQ(3u, context->NumTextures());
- // Number of textures used for commit should be one for each layer.
- EXPECT_EQ(2u, context->NumUsedTextures());
- // First textures should not have been used.
- EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
- // New textures should have been used.
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
- context->ResetUsedTextures();
- break;
- case 2:
- EndTest();
- break;
- default:
- NOTREACHED();
- break;
- }
- }
-
- void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
- TestWebGraphicsContext3D* context = TestContext();
-
- if (drew_frame_ == impl->active_tree()->source_frame_number()) {
- EXPECT_EQ(0u, context->NumUsedTextures()) << "For frame " << drew_frame_;
- return;
- }
- drew_frame_ = impl->active_tree()->source_frame_number();
-
- // We draw/ship one texture each frame for each layer.
- EXPECT_EQ(2u, context->NumUsedTextures());
- context->ResetUsedTextures();
-
- if (!TestEnded())
- PostSetNeedsCommitToMainThread();
- }
-
- void Layout() override {
- layer_->SetNeedsDisplay();
- scrollbar_->SetNeedsDisplay();
- }
-
- void AfterTest() override {}
-
- protected:
- FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> layer_;
- scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
- int drew_frame_;
-};
-
-MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
- LayerTreeHostTestDirectRendererAtomicCommit);
-
-// TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
-class LayerTreeHostTestDelegatingRendererAtomicCommit
- : public LayerTreeHostTestDirectRendererAtomicCommit {
- public:
- void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
- ASSERT_EQ(0u, impl->settings().max_partial_texture_updates);
-
- TestWebGraphicsContext3D* context = TestContext();
-
- switch (impl->active_tree()->source_frame_number()) {
- case 0:
- // Number of textures should be one for each layer
- ASSERT_EQ(2u, context->NumTextures());
- // Number of textures used for commit should be one for each layer.
- EXPECT_EQ(2u, context->NumUsedTextures());
- // Verify that used texture is correct.
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
- break;
- case 1:
- // Number of textures should be doubled as the first context layer
- // texture is being used by the impl-thread and cannot be used for
- // update. The scrollbar behavior is different direct renderer because
- // UI resource deletion with delegating renderer occurs after tree
- // activation.
- ASSERT_EQ(4u, context->NumTextures());
- // Number of textures used for commit should still be
- // one for each layer.
- EXPECT_EQ(2u, context->NumUsedTextures());
- // First textures should not have been used.
- EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
- EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
- // New textures should have been used.
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
- break;
- case 2:
- EndTest();
- break;
- default:
- NOTREACHED();
- break;
- }
- }
-};
-
-MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(
- LayerTreeHostTestDelegatingRendererAtomicCommit);
-
-static void SetLayerPropertiesForTesting(Layer* layer,
- Layer* parent,
- const gfx::Transform& transform,
- const gfx::Point3F& transform_origin,
- const gfx::PointF& position,
- const gfx::Size& bounds,
- bool opaque) {
- layer->RemoveAllChildren();
- if (parent)
- parent->AddChild(layer);
- layer->SetTransform(transform);
- layer->SetTransformOrigin(transform_origin);
- layer->SetPosition(position);
- layer->SetBounds(bounds);
- layer->SetContentsOpaque(opaque);
-}
-
-// TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
-class LayerTreeHostTestAtomicCommitWithPartialUpdate
- : public LayerTreeHostTest {
- public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->renderer_settings.texture_id_allocation_chunk_size = 1;
- // Allow one partial texture update.
- settings->max_partial_texture_updates = 1;
- // No partial updates when impl side painting is enabled.
- settings->impl_side_painting = false;
- }
-
- void SetupTree() override {
- parent_ = FakeContentLayer::Create(&client_);
- parent_->SetBounds(gfx::Size(10, 20));
-
- child_ = FakeContentLayer::Create(&client_);
- child_->SetPosition(gfx::Point(0, 10));
- child_->SetBounds(gfx::Size(3, 10));
-
- parent_->AddChild(child_);
-
- layer_tree_host()->SetRootLayer(parent_);
- LayerTreeHostTest::SetupTree();
- }
-
- void BeginTest() override { PostSetNeedsCommitToMainThread(); }
-
- void DidCommitAndDrawFrame() override {
- switch (layer_tree_host()->source_frame_number()) {
- case 1:
- parent_->SetNeedsDisplay();
- child_->SetNeedsDisplay();
- break;
- case 2:
- // Damage part of layers.
- parent_->SetNeedsDisplayRect(gfx::Rect(5, 5));
- child_->SetNeedsDisplayRect(gfx::Rect(5, 5));
- break;
- case 3:
- child_->SetNeedsDisplay();
- layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
- break;
- case 4:
- layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
- break;
- case 5:
- EndTest();
- break;
- default:
- NOTREACHED() << layer_tree_host()->source_frame_number();
- break;
- }
- }
-
- void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
- ASSERT_EQ(1u, impl->settings().max_partial_texture_updates);
-
- TestWebGraphicsContext3D* context = TestContext();
-
- switch (impl->active_tree()->source_frame_number()) {
- case 0:
- // Number of textures should be one for each layer.
- ASSERT_EQ(2u, context->NumTextures());
- // Number of textures used for commit should be one for each layer.
- EXPECT_EQ(2u, context->NumUsedTextures());
- // Verify that used textures are correct.
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
- context->ResetUsedTextures();
- break;
- case 1:
- if (HasImplThread()) {
- // Number of textures should be two for each content layer.
- ASSERT_EQ(4u, context->NumTextures());
- } else {
- // In single thread we can always do partial updates, so the limit has
- // no effect.
- ASSERT_EQ(2u, context->NumTextures());
- }
- // Number of textures used for commit should be one for each content
- // layer.
- EXPECT_EQ(2u, context->NumUsedTextures());
-
- if (HasImplThread()) {
- // First content textures should not have been used.
- EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
- EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
- // New textures should have been used.
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
- } else {
- // In single thread we can always do partial updates, so the limit has
- // no effect.
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
- }
-
- context->ResetUsedTextures();
- break;
- case 2:
- if (HasImplThread()) {
- // Number of textures should be two for each content layer.
- ASSERT_EQ(4u, context->NumTextures());
- } else {
- // In single thread we can always do partial updates, so the limit has
- // no effect.
- ASSERT_EQ(2u, context->NumTextures());
- }
- // Number of textures used for commit should be one for each content
- // layer.
- EXPECT_EQ(2u, context->NumUsedTextures());
-
- if (HasImplThread()) {
- // One content layer does a partial update also.
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
- EXPECT_FALSE(context->UsedTexture(context->TextureAt(3)));
- } else {
- // In single thread we can always do partial updates, so the limit has
- // no effect.
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
- EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
- }
-
- context->ResetUsedTextures();
- break;
- case 3:
- // No textures should be used for commit.
- EXPECT_EQ(0u, context->NumUsedTextures());
-
- context->ResetUsedTextures();
- break;
- case 4:
- // Number of textures used for commit should be one, for the
- // content layer.
- EXPECT_EQ(1u, context->NumUsedTextures());
-
- context->ResetUsedTextures();
- break;
- default:
- NOTREACHED();
- break;
- }
- }
-
- void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
- EXPECT_LT(impl->active_tree()->source_frame_number(), 5);
-
- TestWebGraphicsContext3D* context = TestContext();
-
- // Number of textures used for drawing should one per layer except for
- // frame 3 where the viewport only contains one layer.
- if (impl->active_tree()->source_frame_number() == 3) {
- EXPECT_EQ(1u, context->NumUsedTextures());
- } else {
- EXPECT_EQ(2u, context->NumUsedTextures())
- << "For frame " << impl->active_tree()->source_frame_number();
- }
-
- context->ResetUsedTextures();
- }
-
- void AfterTest() override {}
-
- private:
- FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> parent_;
- scoped_refptr<FakeContentLayer> child_;
-};
-
-// Partial updates are not possible with a delegating renderer.
-SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
- LayerTreeHostTestAtomicCommitWithPartialUpdate);
-
-// TODO(sohanjg) : Make it work with impl-side painting.
-class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
- : public LayerTreeHostTest {
- protected:
- void SetupTree() override {
- root_layer_ = FakeContentLayer::Create(&client_);
- root_layer_->SetBounds(gfx::Size(100, 100));
-
- surface_layer1_ = FakeContentLayer::Create(&client_);
- surface_layer1_->SetBounds(gfx::Size(100, 100));
- surface_layer1_->SetForceRenderSurface(true);
- surface_layer1_->SetOpacity(0.5f);
- root_layer_->AddChild(surface_layer1_);
-
- surface_layer2_ = FakeContentLayer::Create(&client_);
- surface_layer2_->SetBounds(gfx::Size(100, 100));
- surface_layer2_->SetForceRenderSurface(true);
- surface_layer2_->SetOpacity(0.5f);
- surface_layer1_->AddChild(surface_layer2_);
-
- replica_layer1_ = FakeContentLayer::Create(&client_);
- surface_layer1_->SetReplicaLayer(replica_layer1_.get());
-
- replica_layer2_ = FakeContentLayer::Create(&client_);
- surface_layer2_->SetReplicaLayer(replica_layer2_.get());
-
- layer_tree_host()->SetRootLayer(root_layer_);
- LayerTreeHostTest::SetupTree();
- }
-
- void BeginTest() override { PostSetNeedsCommitToMainThread(); }
-
- void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
- Renderer* renderer = host_impl->renderer();
- RenderPassId surface1_render_pass_id = host_impl->active_tree()
- ->root_layer()
- ->children()[0]
- ->render_surface()
- ->GetRenderPassId();
- RenderPassId surface2_render_pass_id = host_impl->active_tree()
- ->root_layer()
- ->children()[0]
- ->children()[0]
- ->render_surface()
- ->GetRenderPassId();
-
- switch (host_impl->active_tree()->source_frame_number()) {
- case 0:
- EXPECT_TRUE(
- renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id));
- EXPECT_TRUE(
- renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id));
-
- // Reduce the memory limit to only fit the root layer and one render
- // surface. This prevents any contents drawing into surfaces
- // from being allocated.
- host_impl->SetMemoryPolicy(ManagedMemoryPolicy(100 * 100 * 4 * 2));
- break;
- case 1:
- EXPECT_FALSE(
- renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id));
- EXPECT_FALSE(
- renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id));
-
- EndTest();
- break;
- }
- }
-
- void DidCommitAndDrawFrame() override {
- if (layer_tree_host()->source_frame_number() < 2)
- root_layer_->SetNeedsDisplay();
- }
-
- void AfterTest() override {
- EXPECT_LE(2u, root_layer_->update_count());
- EXPECT_LE(2u, surface_layer1_->update_count());
- EXPECT_LE(2u, surface_layer2_->update_count());
- }
-
- FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> root_layer_;
- scoped_refptr<FakeContentLayer> surface_layer1_;
- scoped_refptr<FakeContentLayer> replica_layer1_;
- scoped_refptr<FakeContentLayer> surface_layer2_;
- scoped_refptr<FakeContentLayer> replica_layer2_;
-};
-
-// Surfaces don't exist with a delegated renderer.
-SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
- LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit);
-
-class EvictionTestLayer : public Layer {
- public:
- static scoped_refptr<EvictionTestLayer> Create() {
- return make_scoped_refptr(new EvictionTestLayer());
- }
-
- bool Update(ResourceUpdateQueue*, const OcclusionTracker<Layer>*) override;
- bool DrawsContent() const override { return true; }
-
- scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
- void PushPropertiesTo(LayerImpl* impl) override;
- void SetTexturePriorities(const PriorityCalculator&) override;
-
- bool HaveBackingTexture() const {
- return texture_.get() ? texture_->have_backing_texture() : false;
- }
-
- private:
- EvictionTestLayer() : Layer() {}
- ~EvictionTestLayer() override {}
-
- void CreateTextureIfNeeded() {
- if (texture_)
- return;
- texture_ = PrioritizedResource::Create(
- layer_tree_host()->contents_texture_manager());
- texture_->SetDimensions(gfx::Size(10, 10), RGBA_8888);
- bitmap_.allocN32Pixels(10, 10);
- }
-
- scoped_ptr<PrioritizedResource> texture_;
- SkBitmap bitmap_;
-};
-
-class EvictionTestLayerImpl : public LayerImpl {
- public:
- static scoped_ptr<EvictionTestLayerImpl> Create(LayerTreeImpl* tree_impl,
- int id) {
- return make_scoped_ptr(new EvictionTestLayerImpl(tree_impl, id));
- }
- ~EvictionTestLayerImpl() override {}
-
- void AppendQuads(RenderPass* render_pass,
- AppendQuadsData* append_quads_data) override {
- ASSERT_TRUE(has_texture_);
- ASSERT_NE(0u, layer_tree_impl()->resource_provider()->num_resources());
- }
-
- void SetHasTexture(bool has_texture) { has_texture_ = has_texture; }
-
- private:
- EvictionTestLayerImpl(LayerTreeImpl* tree_impl, int id)
- : LayerImpl(tree_impl, id), has_texture_(false) {}
-
- bool has_texture_;
-};
-
-void EvictionTestLayer::SetTexturePriorities(const PriorityCalculator&) {
- CreateTextureIfNeeded();
- if (!texture_)
- return;
- texture_->set_request_priority(PriorityCalculator::UIPriority(true));
-}
-
-bool EvictionTestLayer::Update(ResourceUpdateQueue* queue,
- const OcclusionTracker<Layer>* occlusion) {
- CreateTextureIfNeeded();
- if (!texture_)
- return false;
-
- gfx::Rect full_rect(0, 0, 10, 10);
- ResourceUpdate upload = ResourceUpdate::Create(
- texture_.get(), &bitmap_, full_rect, full_rect, gfx::Vector2d());
- queue->AppendFullUpload(upload);
- return true;
-}
-
-scoped_ptr<LayerImpl> EvictionTestLayer::CreateLayerImpl(
- LayerTreeImpl* tree_impl) {
- return EvictionTestLayerImpl::Create(tree_impl, layer_id_);
-}
-
-void EvictionTestLayer::PushPropertiesTo(LayerImpl* layer_impl) {
- Layer::PushPropertiesTo(layer_impl);
-
- EvictionTestLayerImpl* test_layer_impl =
- static_cast<EvictionTestLayerImpl*>(layer_impl);
- test_layer_impl->SetHasTexture(texture_->have_backing_texture());
-}
-
-class LayerTreeHostTestEvictTextures : public LayerTreeHostTest {
- public:
- LayerTreeHostTestEvictTextures()
- : layer_(EvictionTestLayer::Create()),
- impl_for_evict_textures_(0),
- num_commits_(0) {}
-
- void BeginTest() override {
- layer_tree_host()->SetRootLayer(layer_);
- layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
-
- gfx::Transform identity_matrix;
- SetLayerPropertiesForTesting(layer_.get(),
- 0,
- identity_matrix,
- gfx::Point3F(0.f, 0.f, 0.f),
- gfx::PointF(0.f, 0.f),
- gfx::Size(10, 20),
- true);
-
- PostSetNeedsCommitToMainThread();
- }
-
- void PostEvictTextures() {
- ImplThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::Bind(&LayerTreeHostTestEvictTextures::EvictTexturesOnImplThread,
- base::Unretained(this)));
- }
-
- void EvictTexturesOnImplThread() {
- DCHECK(impl_for_evict_textures_);
- impl_for_evict_textures_->EvictTexturesForTesting();
- }
-
- // Commit 1: Just commit and draw normally, then post an eviction at the end
- // that will trigger a commit.
- // Commit 2: Triggered by the eviction, let it go through and then set
- // needsCommit.
- // Commit 3: Triggered by the setNeedsCommit. In Layout(), post an eviction
- // task, which will be handled before the commit. Don't set needsCommit, it
- // should have been posted. A frame should not be drawn (note,
- // didCommitAndDrawFrame may be called anyway).
- // Commit 4: Triggered by the eviction, let it go through and then set
- // needsCommit.
- // Commit 5: Triggered by the setNeedsCommit, post an eviction task in
- // Layout(), a frame should not be drawn but a commit will be posted.
- // Commit 6: Triggered by the eviction, post an eviction task in
- // Layout(), which will be a noop, letting the commit (which recreates the
- // textures) go through and draw a frame, then end the test.
- //
- // Commits 1+2 test the eviction recovery path where eviction happens outside
- // of the beginFrame/commit pair.
- // Commits 3+4 test the eviction recovery path where eviction happens inside
- // the beginFrame/commit pair.
- // Commits 5+6 test the path where an eviction happens during the eviction
- // recovery path.
- void DidCommit() override {
- switch (num_commits_) {
- case 1:
- EXPECT_TRUE(layer_->HaveBackingTexture());
- PostEvictTextures();
- break;
- case 2:
- EXPECT_TRUE(layer_->HaveBackingTexture());
- layer_tree_host()->SetNeedsCommit();
- break;
- case 3:
- break;
- case 4:
- EXPECT_TRUE(layer_->HaveBackingTexture());
- layer_tree_host()->SetNeedsCommit();
- break;
- case 5:
- break;
- case 6:
- EXPECT_TRUE(layer_->HaveBackingTexture());
- EndTest();
- break;
- default:
- NOTREACHED();
- break;
- }
- }
-
- void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
- impl_for_evict_textures_ = impl;
- }
-
- void Layout() override {
- ++num_commits_;
- switch (num_commits_) {
- case 1:
- case 2:
- break;
- case 3:
- PostEvictTextures();
- break;
- case 4:
- // We couldn't check in didCommitAndDrawFrame on commit 3,
- // so check here.
- EXPECT_FALSE(layer_->HaveBackingTexture());
- break;
- case 5:
- PostEvictTextures();
- break;
- case 6:
- // We couldn't check in didCommitAndDrawFrame on commit 5,
- // so check here.
- EXPECT_FALSE(layer_->HaveBackingTexture());
- PostEvictTextures();
- break;
- default:
- NOTREACHED();
- break;
- }
- }
-
- void AfterTest() override {}
-
- private:
- FakeContentLayerClient client_;
- scoped_refptr<EvictionTestLayer> layer_;
- LayerTreeHostImpl* impl_for_evict_textures_;
- int num_commits_;
-};
-
-MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestEvictTextures);
-
class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
public:
LayerTreeHostTestContinuousInvalidate()
@@ -2242,11 +1508,7 @@ class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
- if (layer_tree_host()->settings().impl_side_painting)
- layer_ = FakePictureLayer::Create(&client_);
- else
- layer_ = FakeContentLayer::Create(&client_);
-
+ layer_ = FakePictureLayer::Create(layer_settings(), &client_);
layer_->SetBounds(gfx::Size(10, 10));
layer_->SetPosition(gfx::PointF(0.f, 0.f));
layer_->SetIsDrawable(true);
@@ -2364,6 +1626,8 @@ class LayerTreeHostTestCompositeImmediatelyStateTransitions
void InitializeSettings(LayerTreeSettings* settings) override {
settings->single_thread_proxy_scheduler = false;
+ settings->use_zero_copy = true;
+ settings->use_one_copy = false;
}
void BeginTest() override {
@@ -2414,263 +1678,13 @@ class LayerTreeHostTestCompositeImmediatelyStateTransitions
SINGLE_THREAD_TEST_F(LayerTreeHostTestCompositeImmediatelyStateTransitions);
-class LayerTreeHostWithProxy : public LayerTreeHost {
- public:
- LayerTreeHostWithProxy(FakeLayerTreeHostClient* client,
- scoped_ptr<FakeProxy> proxy,
- LayerTreeHost::InitParams* params)
- : LayerTreeHost(params) {
- proxy->SetLayerTreeHost(this);
- client->SetLayerTreeHost(this);
- InitializeForTesting(proxy.Pass());
- }
-};
-
-TEST(LayerTreeHostTest, LimitPartialUpdates) {
- // When partial updates are not allowed, max updates should be 0.
- {
- FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
-
- scoped_ptr<FakeProxy> proxy(new FakeProxy);
- proxy->GetRendererCapabilities().allow_partial_texture_updates = false;
- proxy->SetMaxPartialTextureUpdates(5);
-
- LayerTreeSettings settings;
- settings.impl_side_painting = false;
- settings.max_partial_texture_updates = 10;
-
- LayerTreeHost::InitParams params;
- params.client = &client;
- params.settings = &settings;
- LayerTreeHostWithProxy host(&client, proxy.Pass(), &params);
-
- EXPECT_EQ(0u, host.MaxPartialTextureUpdates());
- }
-
- // When partial updates are allowed,
- // max updates should be limited by the proxy.
- {
- FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
-
- scoped_ptr<FakeProxy> proxy(new FakeProxy);
- proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
- proxy->SetMaxPartialTextureUpdates(5);
-
- LayerTreeSettings settings;
- settings.impl_side_painting = false;
- settings.max_partial_texture_updates = 10;
-
- LayerTreeHost::InitParams params;
- params.client = &client;
- params.settings = &settings;
- LayerTreeHostWithProxy host(&client, proxy.Pass(), &params);
-
- EXPECT_EQ(5u, host.MaxPartialTextureUpdates());
- }
-
- // When partial updates are allowed,
- // max updates should also be limited by the settings.
- {
- FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
-
- scoped_ptr<FakeProxy> proxy(new FakeProxy);
- proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
- proxy->SetMaxPartialTextureUpdates(20);
-
- LayerTreeSettings settings;
- settings.impl_side_painting = false;
- settings.max_partial_texture_updates = 10;
-
- LayerTreeHost::InitParams params;
- params.client = &client;
- params.settings = &settings;
- LayerTreeHostWithProxy host(&client, proxy.Pass(), &params);
-
- EXPECT_EQ(10u, host.MaxPartialTextureUpdates());
- }
-}
-
-TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) {
- FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
-
- LayerTreeSettings settings;
- settings.max_partial_texture_updates = 4;
- settings.single_thread_proxy_scheduler = false;
- settings.impl_side_painting = false;
-
- scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
- new TestSharedBitmapManager());
- LayerTreeHost::InitParams params;
- params.client = &client;
- params.shared_bitmap_manager = shared_bitmap_manager.get();
- params.settings = &settings;
- params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
- scoped_ptr<LayerTreeHost> host =
- LayerTreeHost::CreateSingleThreaded(&client, &params);
- client.SetLayerTreeHost(host.get());
- host->Composite(base::TimeTicks::Now());
-
- EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
-}
-
-TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) {
- FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_SOFTWARE);
-
- LayerTreeSettings settings;
- settings.max_partial_texture_updates = 4;
- settings.single_thread_proxy_scheduler = false;
- settings.impl_side_painting = false;
-
- scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
- new TestSharedBitmapManager());
- LayerTreeHost::InitParams params;
- params.client = &client;
- params.shared_bitmap_manager = shared_bitmap_manager.get();
- params.settings = &settings;
- params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
- scoped_ptr<LayerTreeHost> host =
- LayerTreeHost::CreateSingleThreaded(&client, &params);
- client.SetLayerTreeHost(host.get());
- host->Composite(base::TimeTicks::Now());
-
- EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
-}
-
-TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) {
- FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_3D);
-
- LayerTreeSettings settings;
- settings.max_partial_texture_updates = 4;
- settings.single_thread_proxy_scheduler = false;
- settings.impl_side_painting = false;
-
- scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
- new TestSharedBitmapManager());
- LayerTreeHost::InitParams params;
- params.client = &client;
- params.shared_bitmap_manager = shared_bitmap_manager.get();
- params.settings = &settings;
- params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
- scoped_ptr<LayerTreeHost> host =
- LayerTreeHost::CreateSingleThreaded(&client, &params);
- client.SetLayerTreeHost(host.get());
- host->Composite(base::TimeTicks::Now());
-
- EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
-}
-
-TEST(LayerTreeHostTest,
- PartialUpdatesWithDelegatingRendererAndSoftwareContent) {
- FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_SOFTWARE);
-
- LayerTreeSettings settings;
- settings.max_partial_texture_updates = 4;
- settings.single_thread_proxy_scheduler = false;
- settings.impl_side_painting = false;
-
- scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
- new TestSharedBitmapManager());
- LayerTreeHost::InitParams params;
- params.client = &client;
- params.shared_bitmap_manager = shared_bitmap_manager.get();
- params.settings = &settings;
- params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
- scoped_ptr<LayerTreeHost> host =
- LayerTreeHost::CreateSingleThreaded(&client, &params);
- client.SetLayerTreeHost(host.get());
- host->Composite(base::TimeTicks::Now());
-
- EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
-}
-
-// TODO(sohanjg) : Remove it once impl-side painting ships everywhere.
-class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
- : public LayerTreeHostTest {
- public:
- LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted()
- : root_layer_(FakeContentLayer::Create(&client_)),
- child_layer1_(FakeContentLayer::Create(&client_)),
- child_layer2_(FakeContentLayer::Create(&client_)),
- num_commits_(0) {}
-
- void BeginTest() override {
- layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
- root_layer_->SetBounds(gfx::Size(100, 100));
- child_layer1_->SetBounds(gfx::Size(100, 100));
- child_layer2_->SetBounds(gfx::Size(100, 100));
- root_layer_->AddChild(child_layer1_);
- root_layer_->AddChild(child_layer2_);
- layer_tree_host()->SetRootLayer(root_layer_);
- PostSetNeedsCommitToMainThread();
- }
-
- void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
- bool visible) override {
- if (visible) {
- // One backing should remain unevicted.
- EXPECT_EQ(100u * 100u * 4u * 1u,
- contents_texture_manager_->MemoryUseBytes());
- } else {
- EXPECT_EQ(0u, contents_texture_manager_->MemoryUseBytes());
- }
-
- // Make sure that contents textures are marked as having been
- // purged.
- EXPECT_TRUE(host_impl->active_tree()->ContentsTexturesPurged());
- // End the test in this state.
- EndTest();
- }
-
- void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
- ++num_commits_;
- switch (num_commits_) {
- case 1:
- // All three backings should have memory.
- EXPECT_EQ(100u * 100u * 4u * 3u,
- contents_texture_manager_->MemoryUseBytes());
-
- // Set a new policy that will kick out 1 of the 3 resources.
- // Because a resource was evicted, a commit will be kicked off.
- host_impl->SetMemoryPolicy(
- ManagedMemoryPolicy(100 * 100 * 4 * 2,
- gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
- 1000));
- break;
- case 2:
- // Only two backings should have memory.
- EXPECT_EQ(100u * 100u * 4u * 2u,
- contents_texture_manager_->MemoryUseBytes());
- // Become backgrounded, which will cause 1 more resource to be
- // evicted.
- PostSetVisibleToMainThread(false);
- break;
- default:
- // No further commits should happen because this is not visible
- // anymore.
- NOTREACHED();
- break;
- }
- }
-
- void AfterTest() override {}
-
- private:
- FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> root_layer_;
- scoped_refptr<FakeContentLayer> child_layer1_;
- scoped_refptr<FakeContentLayer> child_layer2_;
- int num_commits_;
-};
-
-SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(
- LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted);
-
class LayerTreeHostTestLCDChange : public LayerTreeHostTest {
public:
void SetupTree() override {
num_tiles_rastered_ = 0;
- scoped_refptr<Layer> root_layer = PictureLayer::Create(&client_);
+ scoped_refptr<Layer> root_layer =
+ PictureLayer::Create(layer_settings(), &client_);
client_.set_fill_with_nonsolid_color(true);
root_layer->SetIsDrawable(true);
root_layer->SetBounds(gfx::Size(10, 10));
@@ -2751,7 +1765,7 @@ class LayerTreeHostTestLCDChange : public LayerTreeHostTest {
int num_tiles_rastered_;
};
-SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestLCDChange);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLCDChange);
// Verify that the BeginFrame notification is used to initiate rendering.
class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest {
@@ -2886,7 +1900,7 @@ class LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync
: public LayerTreeHostTestAbortedCommitDoesntStall {
void InitializeSettings(LayerTreeSettings* settings) override {
LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
- settings->throttle_frame_production = false;
+ settings->renderer_settings.disable_gpu_vsync = true;
}
};
@@ -2895,14 +1909,11 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync);
class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
: public LayerTreeHostTest {
protected:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->impl_side_painting = true;
- }
-
void SetupTree() override {
LayerTreeHostTest::SetupTree();
- scoped_refptr<Layer> layer = PictureLayer::Create(&client_);
+ scoped_refptr<Layer> layer =
+ PictureLayer::Create(layer_settings(), &client_);
layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
layer->SetBounds(gfx::Size(10, 10));
layer_tree_host()->root_layer()->AddChild(layer);
@@ -2919,7 +1930,7 @@ class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
FakeContentLayerClient client_;
};
-MULTI_THREAD_TEST_F(
+SINGLE_AND_MULTI_THREAD_TEST_F(
LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation);
class LayerTreeHostTestChangeLayerPropertiesInPaintContents
@@ -2937,11 +1948,11 @@ class LayerTreeHostTestChangeLayerPropertiesInPaintContents
layer_->SetBounds(gfx::Size(2, 2));
}
- void PaintContentsToDisplayList(
- DisplayItemList* display_list,
+ scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
const gfx::Rect& clip,
PaintingControlSetting picture_control) override {
NOTIMPLEMENTED();
+ return nullptr;
}
bool FillsBoundsCompletely() const override { return false; }
@@ -2953,19 +1964,13 @@ class LayerTreeHostTestChangeLayerPropertiesInPaintContents
LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {}
void SetupTree() override {
- if (layer_tree_host()->settings().impl_side_painting) {
- scoped_refptr<PictureLayer> root_layer = PictureLayer::Create(&client_);
- layer_tree_host()->SetRootLayer(root_layer);
- } else {
- scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_);
- layer_tree_host()->SetRootLayer(root_layer);
- }
- Layer* root_layer = layer_tree_host()->root_layer();
+ scoped_refptr<PictureLayer> root_layer =
+ PictureLayer::Create(layer_settings(), &client_);
root_layer->SetIsDrawable(true);
root_layer->SetBounds(gfx::Size(1, 1));
+ client_.set_layer(root_layer.get());
- client_.set_layer(root_layer);
-
+ layer_tree_host()->SetRootLayer(root_layer);
LayerTreeHostTest::SetupTree();
}
@@ -3041,7 +2046,8 @@ class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest {
io_surface_id_ = 9;
io_surface_size_ = gfx::Size(6, 7);
- scoped_refptr<IOSurfaceLayer> io_surface_layer = IOSurfaceLayer::Create();
+ scoped_refptr<IOSurfaceLayer> io_surface_layer =
+ IOSurfaceLayer::Create(layer_settings());
io_surface_layer->SetBounds(gfx::Size(10, 10));
io_surface_layer->SetIsDrawable(true);
io_surface_layer->SetContentsOpaque(true);
@@ -3102,10 +2108,10 @@ class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest {
const IOSurfaceDrawQuad* io_surface_draw_quad =
IOSurfaceDrawQuad::MaterialCast(quad);
EXPECT_EQ(io_surface_size_, io_surface_draw_quad->io_surface_size);
- EXPECT_NE(0u, io_surface_draw_quad->io_surface_resource_id);
+ EXPECT_NE(0u, io_surface_draw_quad->io_surface_resource_id());
EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_RECTANGLE_ARB),
resource_provider->TargetForTesting(
- io_surface_draw_quad->io_surface_resource_id));
+ io_surface_draw_quad->io_surface_resource_id()));
if (delegating_renderer()) {
// The io surface layer's resource should be sent to the parent.
@@ -3182,28 +2188,21 @@ class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest {
int frame_;
};
-// Flaky on all platforms: http://crbug.com/327498
-TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_DelegatingRenderer) {
- RunTest(true, true, true);
-}
-
-TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_GLRenderer) {
- RunTest(true, false, true);
-}
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNumFramesPending);
class LayerTreeHostTestResourcelessSoftwareDraw : public LayerTreeHostTest {
public:
void SetupTree() override {
- root_layer_ = FakePictureLayer::Create(&client_);
+ root_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
root_layer_->SetIsDrawable(true);
root_layer_->SetBounds(gfx::Size(50, 50));
- parent_layer_ = FakePictureLayer::Create(&client_);
+ parent_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
parent_layer_->SetIsDrawable(true);
parent_layer_->SetBounds(gfx::Size(50, 50));
parent_layer_->SetForceRenderSurface(true);
- child_layer_ = FakePictureLayer::Create(&client_);
+ child_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
child_layer_->SetIsDrawable(true);
child_layer_->SetBounds(gfx::Size(50, 50));
@@ -3280,7 +2279,7 @@ class LayerTreeHostTestResourcelessSoftwareDraw : public LayerTreeHostTest {
int swap_count_;
};
-MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestResourcelessSoftwareDraw);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestResourcelessSoftwareDraw);
// Test for UI Resource management.
class LayerTreeHostTestUIResource : public LayerTreeHostTest {
@@ -3325,7 +2324,7 @@ class LayerTreeHostTestUIResource : public LayerTreeHostTest {
}
}
- void PerformTest(LayerTreeHostImpl* impl) {
+ void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
TestWebGraphicsContext3D* context = TestContext();
int frame = impl->active_tree()->source_frame_number();
@@ -3354,16 +2353,6 @@ class LayerTreeHostTestUIResource : public LayerTreeHostTest {
}
}
- void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
- if (!impl->settings().impl_side_painting)
- PerformTest(impl);
- }
-
- void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
- if (impl->settings().impl_side_painting)
- PerformTest(impl);
- }
-
void AfterTest() override {}
private:
@@ -3420,8 +2409,9 @@ class PushPropertiesCountingLayerImpl : public LayerImpl {
class PushPropertiesCountingLayer : public Layer {
public:
- static scoped_refptr<PushPropertiesCountingLayer> Create() {
- return new PushPropertiesCountingLayer();
+ static scoped_refptr<PushPropertiesCountingLayer> Create(
+ const LayerSettings& settings) {
+ return new PushPropertiesCountingLayer(settings);
}
void PushPropertiesTo(LayerImpl* layer) override {
@@ -3448,8 +2438,10 @@ class PushPropertiesCountingLayer : public Layer {
}
private:
- PushPropertiesCountingLayer()
- : push_properties_count_(0), persist_needs_push_properties_(false) {
+ explicit PushPropertiesCountingLayer(const LayerSettings& settings)
+ : Layer(settings),
+ push_properties_count_(0),
+ persist_needs_push_properties_(false) {
SetBounds(gfx::Size(1, 1));
}
~PushPropertiesCountingLayer() override {}
@@ -3472,12 +2464,13 @@ class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest {
}
void SetupTree() override {
- root_ = PushPropertiesCountingLayer::Create();
+ root_ = PushPropertiesCountingLayer::Create(layer_settings());
root_->CreateRenderSurface();
- child_ = PushPropertiesCountingLayer::Create();
- child2_ = PushPropertiesCountingLayer::Create();
- grandchild_ = PushPropertiesCountingLayer::Create();
- leaf_always_pushing_layer_ = PushPropertiesCountingLayer::Create();
+ child_ = PushPropertiesCountingLayer::Create(layer_settings());
+ child2_ = PushPropertiesCountingLayer::Create(layer_settings());
+ grandchild_ = PushPropertiesCountingLayer::Create(layer_settings());
+ leaf_always_pushing_layer_ =
+ PushPropertiesCountingLayer::Create(layer_settings());
leaf_always_pushing_layer_->set_persist_needs_push_properties(true);
root_->AddChild(child_);
@@ -3485,7 +2478,7 @@ class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest {
child_->AddChild(grandchild_);
child2_->AddChild(leaf_always_pushing_layer_);
- other_root_ = PushPropertiesCountingLayer::Create();
+ other_root_ = PushPropertiesCountingLayer::Create(layer_settings());
other_root_->CreateRenderSurface();
// Don't set the root layer here.
@@ -3854,9 +2847,8 @@ class LayerTreeHostTestImplLayersPushProperties
size_t expected_push_properties_grandchild2_impl_;
};
-TEST_F(LayerTreeHostTestImplLayersPushProperties, DelegatingRenderer) {
- RunTestWithImplSidePainting();
-}
+// In single thread there's no pending tree to push properties from.
+MULTI_THREAD_TEST_F(LayerTreeHostTestImplLayersPushProperties);
class LayerTreeHostTestPropertyChangesDuringUpdateArePushed
: public LayerTreeHostTest {
@@ -3864,14 +2856,14 @@ class LayerTreeHostTestPropertyChangesDuringUpdateArePushed
void BeginTest() override { PostSetNeedsCommitToMainThread(); }
void SetupTree() override {
- root_ = Layer::Create();
+ root_ = Layer::Create(layer_settings());
root_->CreateRenderSurface();
root_->SetBounds(gfx::Size(1, 1));
bool paint_scrollbar = true;
bool has_thumb = false;
scrollbar_layer_ = FakePaintedScrollbarLayer::Create(
- paint_scrollbar, has_thumb, root_->id());
+ layer_settings(), paint_scrollbar, has_thumb, root_->id());
root_->AddChild(scrollbar_layer_);
@@ -3921,9 +2913,9 @@ class LayerTreeHostTestSetDrawableCausesCommit : public LayerTreeHostTest {
void BeginTest() override { PostSetNeedsCommitToMainThread(); }
void SetupTree() override {
- root_ = PushPropertiesCountingLayer::Create();
+ root_ = PushPropertiesCountingLayer::Create(layer_settings());
root_->CreateRenderSurface();
- child_ = PushPropertiesCountingLayer::Create();
+ child_ = PushPropertiesCountingLayer::Create(layer_settings());
root_->AddChild(child_);
layer_tree_host()->SetRootLayer(root_);
@@ -3983,12 +2975,12 @@ class LayerTreeHostTestCasePushPropertiesThreeGrandChildren
}
void SetupTree() override {
- root_ = PushPropertiesCountingLayer::Create();
+ root_ = PushPropertiesCountingLayer::Create(layer_settings());
root_->CreateRenderSurface();
- child_ = PushPropertiesCountingLayer::Create();
- grandchild1_ = PushPropertiesCountingLayer::Create();
- grandchild2_ = PushPropertiesCountingLayer::Create();
- grandchild3_ = PushPropertiesCountingLayer::Create();
+ child_ = PushPropertiesCountingLayer::Create(layer_settings());
+ grandchild1_ = PushPropertiesCountingLayer::Create(layer_settings());
+ grandchild2_ = PushPropertiesCountingLayer::Create(layer_settings());
+ grandchild3_ = PushPropertiesCountingLayer::Create(layer_settings());
root_->AddChild(child_);
child_->AddChild(grandchild1_);
@@ -4388,7 +3380,6 @@ class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest {
: num_commits_(0), callback_count_(0) {}
void BeginTest() override {
- EXPECT_TRUE(HasImplThread());
PostSetNeedsCommitToMainThread();
}
@@ -4440,13 +3431,7 @@ class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest {
int callback_count_;
};
-TEST_F(LayerTreeHostTestTreeActivationCallback, DirectRenderer) {
- RunTest(true, false, true);
-}
-
-TEST_F(LayerTreeHostTestTreeActivationCallback, DelegatingRenderer) {
- RunTest(true, true, true);
-}
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestTreeActivationCallback);
class LayerInvalidateCausesDraw : public LayerTreeHostTest {
public:
@@ -4496,8 +3481,8 @@ class LayerTreeHostTestVideoLayerInvalidate : public LayerInvalidateCausesDraw {
public:
void SetupTree() override {
LayerTreeHostTest::SetupTree();
- scoped_refptr<VideoLayer> video_layer =
- VideoLayer::Create(&provider_, media::VIDEO_ROTATION_0);
+ scoped_refptr<VideoLayer> video_layer = VideoLayer::Create(
+ layer_settings(), &provider_, media::VIDEO_ROTATION_0);
video_layer->SetBounds(gfx::Size(10, 10));
video_layer->SetIsDrawable(true);
layer_tree_host()->root_layer()->AddChild(video_layer);
@@ -4519,7 +3504,8 @@ class LayerTreeHostTestIOSurfaceLayerInvalidate
public:
void SetupTree() override {
LayerTreeHostTest::SetupTree();
- scoped_refptr<IOSurfaceLayer> layer = IOSurfaceLayer::Create();
+ scoped_refptr<IOSurfaceLayer> layer =
+ IOSurfaceLayer::Create(layer_settings());
layer->SetBounds(gfx::Size(10, 10));
uint32_t fake_io_surface_id = 7;
layer->SetIOSurfaceProperties(fake_io_surface_id, layer->bounds());
@@ -4530,25 +3516,23 @@ class LayerTreeHostTestIOSurfaceLayerInvalidate
}
};
-// TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
-SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
- LayerTreeHostTestIOSurfaceLayerInvalidate);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestIOSurfaceLayerInvalidate);
class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest {
protected:
void SetupTree() override {
- root_layer_ = Layer::Create();
+ root_layer_ = Layer::Create(layer_settings());
root_layer_->CreateRenderSurface();
root_layer_->SetPosition(gfx::Point());
root_layer_->SetBounds(gfx::Size(10, 10));
- parent_layer_ = SolidColorLayer::Create();
+ parent_layer_ = SolidColorLayer::Create(layer_settings());
parent_layer_->SetPosition(gfx::Point());
parent_layer_->SetBounds(gfx::Size(10, 10));
parent_layer_->SetIsDrawable(true);
root_layer_->AddChild(parent_layer_);
- child_layer_ = SolidColorLayer::Create();
+ child_layer_ = SolidColorLayer::Create(layer_settings());
child_layer_->SetPosition(gfx::Point());
child_layer_->SetBounds(gfx::Size(10, 10));
child_layer_->SetIsDrawable(true);
@@ -4603,12 +3587,8 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushHiddenLayer);
class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest {
protected:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->impl_side_painting = true;
- }
-
void SetupTree() override {
- root_layer_ = FakePictureLayer::Create(&client_);
+ root_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
root_layer_->SetBounds(gfx::Size(10, 10));
layer_tree_host()->SetRootLayer(root_layer_);
@@ -4625,7 +3605,7 @@ class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest {
void DidCommit() override {
// The layer should be updated even though the viewport is empty, so we
// are capable of drawing it on the impl tree.
- EXPECT_GT(root_layer_->update_count(), 0u);
+ EXPECT_GT(root_layer_->update_count(), 0);
EndTest();
}
@@ -4637,72 +3617,10 @@ class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest {
MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport);
-class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest {
- public:
- LayerTreeHostTestAbortEvictedTextures()
- : num_will_begin_main_frames_(0), num_impl_commits_(0) {}
-
- protected:
- void SetupTree() override {
- scoped_refptr<SolidColorLayer> root_layer = SolidColorLayer::Create();
- root_layer->SetBounds(gfx::Size(200, 200));
- root_layer->SetIsDrawable(true);
- root_layer->CreateRenderSurface();
-
- layer_tree_host()->SetRootLayer(root_layer);
- LayerTreeHostTest::SetupTree();
- }
-
- void BeginTest() override { PostSetNeedsCommitToMainThread(); }
-
- void WillBeginMainFrame() override {
- num_will_begin_main_frames_++;
- switch (num_will_begin_main_frames_) {
- case 2:
- // Send a redraw to the compositor thread. This will (wrongly) be
- // ignored unless aborting resets the texture state.
- layer_tree_host()->SetNeedsRedraw();
- break;
- }
- }
-
- void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
- num_impl_commits_++;
- }
-
- void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
- switch (impl->SourceAnimationFrameNumber()) {
- case 1:
- // Prevent draws until commit.
- impl->active_tree()->SetContentsTexturesPurged();
- EXPECT_FALSE(impl->CanDraw());
- // Trigger an abortable commit.
- impl->SetNeedsCommit();
- break;
- case 2:
- EndTest();
- break;
- }
- }
-
- void AfterTest() override {
- // Ensure that the commit was truly aborted.
- EXPECT_EQ(2, num_will_begin_main_frames_);
- EXPECT_EQ(1, num_impl_commits_);
- }
-
- private:
- int num_will_begin_main_frames_;
- int num_impl_commits_;
-};
-
-// Commits can only be aborted when using the thread proxy.
-MULTI_THREAD_TEST_F(LayerTreeHostTestAbortEvictedTextures);
-
class LayerTreeHostTestMaxTransferBufferUsageBytes : public LayerTreeHostTest {
protected:
void InitializeSettings(LayerTreeSettings* settings) override {
- settings->impl_side_painting = true;
+ // Testing async uploads.
settings->use_zero_copy = false;
settings->use_one_copy = false;
}
@@ -4720,7 +3638,7 @@ class LayerTreeHostTestMaxTransferBufferUsageBytes : public LayerTreeHostTest {
void SetupTree() override {
client_.set_fill_with_nonsolid_color(true);
scoped_refptr<FakePictureLayer> root_layer =
- FakePictureLayer::Create(&client_);
+ FakePictureLayer::Create(layer_settings(), &client_);
root_layer->SetBounds(gfx::Size(1024, 1024));
root_layer->SetIsDrawable(true);
@@ -4748,99 +3666,6 @@ class LayerTreeHostTestMaxTransferBufferUsageBytes : public LayerTreeHostTest {
// Impl-side painting is a multi-threaded compositor feature.
MULTI_THREAD_TEST_F(LayerTreeHostTestMaxTransferBufferUsageBytes);
-// Test ensuring that memory limits are sent to the prioritized resource
-// manager.
-class LayerTreeHostTestMemoryLimits : public LayerTreeHostTest {
- public:
- LayerTreeHostTestMemoryLimits() : num_commits_(0) {}
-
- void BeginTest() override { PostSetNeedsCommitToMainThread(); }
-
- void WillCommit() override {
- // Some commits are aborted, so increment number of attempted commits here.
- num_commits_++;
- }
-
- void DidCommit() override {
- switch (num_commits_) {
- case 1:
- // Verify default values.
- EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
- layer_tree_host()
- ->contents_texture_manager()
- ->MaxMemoryLimitBytes());
- EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
- layer_tree_host()
- ->contents_texture_manager()
- ->ExternalPriorityCutoff());
- PostSetNeedsCommitToMainThread();
- break;
- case 2:
- // The values should remain the same until the commit after the policy
- // is changed.
- EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
- layer_tree_host()
- ->contents_texture_manager()
- ->MaxMemoryLimitBytes());
- EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
- layer_tree_host()
- ->contents_texture_manager()
- ->ExternalPriorityCutoff());
- break;
- case 3:
- // Verify values were correctly passed.
- EXPECT_EQ(16u * 1024u * 1024u,
- layer_tree_host()
- ->contents_texture_manager()
- ->MaxMemoryLimitBytes());
- EXPECT_EQ(PriorityCalculator::AllowVisibleAndNearbyCutoff(),
- layer_tree_host()
- ->contents_texture_manager()
- ->ExternalPriorityCutoff());
- EndTest();
- break;
- case 4:
- // Make sure no extra commits happen.
- NOTREACHED();
- break;
- }
- }
-
- void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
- switch (num_commits_) {
- case 1:
- break;
- case 2:
- // This will trigger a commit because the priority cutoff has changed.
- impl->SetMemoryPolicy(ManagedMemoryPolicy(
- 16u * 1024u * 1024u,
- gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
- 1000));
- break;
- case 3:
- // This will not trigger a commit because the priority cutoff has not
- // changed, and there is already enough memory for all allocations.
- impl->SetMemoryPolicy(ManagedMemoryPolicy(
- 32u * 1024u * 1024u,
- gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
- 1000));
- break;
- case 4:
- NOTREACHED();
- break;
- }
- }
-
- void AfterTest() override {}
-
- private:
- int num_commits_;
-};
-
-SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestMemoryLimits);
-
-} // namespace
-
class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface
: public LayerTreeHostTest {
protected:
@@ -4874,10 +3699,7 @@ class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface
}
void SetupTree() override {
- if (layer_tree_host()->settings().impl_side_painting)
- root_ = FakePictureLayer::Create(&client_);
- else
- root_ = FakeContentLayer::Create(&client_);
+ root_ = FakePictureLayer::Create(layer_settings(), &client_);
root_->SetBounds(gfx::Size(20, 20));
layer_tree_host()->SetRootLayer(root_);
LayerTreeHostTest::SetupTree();
@@ -5026,7 +3848,12 @@ class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest {
if (commit_complete_count_ == 1) {
// This commit will be aborted because no actual update.
PostSetNeedsUpdateLayersToMainThread();
- } else {
+ }
+ }
+
+ void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
+ int frame = host_impl->active_tree()->source_frame_number();
+ if (frame == 2) {
EndTest();
}
}
@@ -5079,7 +3906,7 @@ class LayerTreeHostTestKeepSwapPromise : public LayerTreeTest {
LayerTreeHostTestKeepSwapPromise() {}
void BeginTest() override {
- layer_ = SolidColorLayer::Create();
+ layer_ = SolidColorLayer::Create(layer_settings());
layer_->SetIsDrawable(true);
layer_->SetBounds(gfx::Size(10, 10));
layer_tree_host()->SetRootLayer(layer_);
@@ -5344,10 +4171,6 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor);
class LayerTreeHostTestHighResRequiredAfterEvictingUIResources
: public LayerTreeHostTest {
protected:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->impl_side_painting = true;
- }
-
void SetupTree() override {
LayerTreeHostTest::SetupTree();
ui_resource_ = FakeScopedUIResource::Create(layer_tree_host());
@@ -5389,8 +4212,6 @@ class LayerTreeHostTestHighResRequiredAfterEvictingUIResources
class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest {
protected:
void InitializeSettings(LayerTreeSettings* settings) override {
- settings->impl_side_painting = true;
-
EXPECT_FALSE(settings->gpu_rasterization_enabled);
EXPECT_FALSE(settings->gpu_rasterization_forced);
}
@@ -5398,7 +4219,8 @@ class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest {
void SetupTree() override {
LayerTreeHostTest::SetupTree();
- scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
+ scoped_refptr<PictureLayer> layer =
+ PictureLayer::Create(layer_settings(), &layer_client_);
layer->SetBounds(gfx::Size(10, 10));
layer->SetIsDrawable(true);
layer_tree_host()->root_layer()->AddChild(layer);
@@ -5443,8 +4265,6 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationDefault);
class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest {
protected:
void InitializeSettings(LayerTreeSettings* settings) override {
- settings->impl_side_painting = true;
-
EXPECT_FALSE(settings->gpu_rasterization_enabled);
settings->gpu_rasterization_enabled = true;
}
@@ -5452,7 +4272,8 @@ class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest {
void SetupTree() override {
LayerTreeHostTest::SetupTree();
- scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
+ scoped_refptr<PictureLayer> layer =
+ PictureLayer::Create(layer_settings(), &layer_client_);
layer->SetBounds(gfx::Size(10, 10));
layer->SetIsDrawable(true);
layer_tree_host()->root_layer()->AddChild(layer);
@@ -5506,8 +4327,6 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled);
class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest {
protected:
void InitializeSettings(LayerTreeSettings* settings) override {
- ASSERT_TRUE(settings->impl_side_painting);
-
EXPECT_FALSE(settings->gpu_rasterization_forced);
settings->gpu_rasterization_forced = true;
}
@@ -5516,7 +4335,7 @@ class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest {
LayerTreeHostTest::SetupTree();
scoped_refptr<FakePictureLayer> layer =
- FakePictureLayer::Create(&layer_client_);
+ FakePictureLayer::Create(layer_settings(), &layer_client_);
layer->SetBounds(gfx::Size(10, 10));
layer->SetIsDrawable(true);
layer_tree_host()->root_layer()->AddChild(layer);
@@ -5565,7 +4384,7 @@ class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest {
FakeContentLayerClient layer_client_;
};
-SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestGpuRasterizationForced);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationForced);
class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest {
public:
@@ -5576,17 +4395,11 @@ class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest {
enum { kExpectedNumCommits = 10 };
void SetupTree() override {
- scoped_refptr<Layer> root_layer = Layer::Create();
+ scoped_refptr<Layer> root_layer = Layer::Create(layer_settings());
root_layer->SetBounds(bounds_);
root_layer->CreateRenderSurface();
- if (layer_tree_host()->settings().impl_side_painting) {
- picture_layer_ = FakePictureLayer::Create(&client_);
- child_layer_ = picture_layer_.get();
- } else {
- content_layer_ = ContentLayerWithUpdateTracking::Create(&client_);
- child_layer_ = content_layer_.get();
- }
+ child_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
child_layer_->SetBounds(bounds_);
child_layer_->SetIsDrawable(true);
root_layer->AddChild(child_layer_);
@@ -5621,10 +4434,7 @@ class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest {
void AfterTest() override {
EXPECT_LE(kExpectedNumCommits, num_commits_);
EXPECT_LE(kExpectedNumCommits, num_draws_);
- int update_count = content_layer_.get()
- ? content_layer_->PaintContentsCount()
- : picture_layer_->update_count();
- EXPECT_LE(kExpectedNumCommits, update_count);
+ EXPECT_LE(kExpectedNumCommits, child_layer_->update_count());
}
void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
@@ -5654,9 +4464,7 @@ class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest {
int num_draws_;
const gfx::Size bounds_;
FakeContentLayerClient client_;
- scoped_refptr<ContentLayerWithUpdateTracking> content_layer_;
- scoped_refptr<FakePictureLayer> picture_layer_;
- Layer* child_layer_;
+ scoped_refptr<FakePictureLayer> child_layer_;
};
MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousPainting);
@@ -5792,10 +4600,6 @@ class LayerTreeHostTestActivateOnInvisible : public LayerTreeHostTest {
LayerTreeHostTestActivateOnInvisible()
: activation_count_(0), visible_(true) {}
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->impl_side_painting = true;
- }
-
void BeginTest() override {
// Kick off the test with a commit.
PostSetNeedsCommitToMainThread();
@@ -5841,7 +4645,8 @@ class LayerTreeHostTestActivateOnInvisible : public LayerTreeHostTest {
};
// TODO(vmpstr): Enable with single thread impl-side painting.
-MULTI_THREAD_TEST_F(LayerTreeHostTestActivateOnInvisible);
+// This test blocks activation which is not supported for single thread mode.
+MULTI_THREAD_BLOCKNOTIFY_TEST_F(LayerTreeHostTestActivateOnInvisible);
// Do a synchronous composite and assert that the swap promise succeeds.
class LayerTreeHostTestSynchronousCompositeSwapPromise
@@ -5851,6 +4656,8 @@ class LayerTreeHostTestSynchronousCompositeSwapPromise
void InitializeSettings(LayerTreeSettings* settings) override {
settings->single_thread_proxy_scheduler = false;
+ settings->use_zero_copy = true;
+ settings->use_one_copy = false;
}
void BeginTest() override {
@@ -5858,14 +4665,14 @@ class LayerTreeHostTestSynchronousCompositeSwapPromise
scoped_ptr<SwapPromise> swap_promise0(
new TestSwapPromise(&swap_promise_result_[0]));
layer_tree_host()->QueueSwapPromise(swap_promise0.Pass());
- layer_tree_host()->Composite(gfx::FrameTime::Now());
+ layer_tree_host()->Composite(base::TimeTicks::Now());
// Fail to swap (no damage).
scoped_ptr<SwapPromise> swap_promise1(
new TestSwapPromise(&swap_promise_result_[1]));
layer_tree_host()->QueueSwapPromise(swap_promise1.Pass());
layer_tree_host()->SetNeedsCommit();
- layer_tree_host()->Composite(gfx::FrameTime::Now());
+ layer_tree_host()->Composite(base::TimeTicks::Now());
// Fail to draw (not visible).
scoped_ptr<SwapPromise> swap_promise2(
@@ -5873,7 +4680,7 @@ class LayerTreeHostTestSynchronousCompositeSwapPromise
layer_tree_host()->QueueSwapPromise(swap_promise2.Pass());
layer_tree_host()->SetNeedsDisplayOnAllLayers();
layer_tree_host()->SetVisible(false);
- layer_tree_host()->Composite(gfx::FrameTime::Now());
+ layer_tree_host()->Composite(base::TimeTicks::Now());
EndTest();
}
@@ -5919,8 +4726,7 @@ class LayerTreeHostTestSynchronousCompositeSwapPromise
TestSwapPromiseResult swap_promise_result_[3];
};
-// Impl-side painting is not supported for synchronous compositing.
-SINGLE_THREAD_NOIMPL_TEST_F(LayerTreeHostTestSynchronousCompositeSwapPromise);
+SINGLE_THREAD_TEST_F(LayerTreeHostTestSynchronousCompositeSwapPromise);
// Make sure page scale and top control deltas are applied to the client even
// when the LayerTreeHost doesn't have a root layer.
@@ -5955,15 +4761,6 @@ class LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer
deltas_sent_to_client_ = true;
}
- void ApplyViewportDeltas(
- const gfx::Vector2d& scroll,
- float scale_delta,
- float top_controls_delta) override {
- EXPECT_EQ(info_.page_scale_delta, scale_delta);
- EXPECT_EQ(info_.top_controls_delta, top_controls_delta);
- deltas_sent_to_client_ = true;
- }
-
void AfterTest() override {
EXPECT_TRUE(deltas_sent_to_client_);
}
@@ -5984,21 +4781,22 @@ class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest {
posted_ = false;
client_.set_fill_with_nonsolid_color(true);
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
root->SetBounds(gfx::Size(500, 500));
- scoped_refptr<Layer> pinch = Layer::Create();
+ scoped_refptr<Layer> pinch = Layer::Create(layer_settings());
pinch->SetBounds(gfx::Size(500, 500));
pinch->SetScrollClipLayerId(root->id());
pinch->SetIsContainerForFixedPositionLayers(true);
root->AddChild(pinch);
scoped_ptr<FakePicturePile> pile(
- new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
- ImplSidePaintingSettings().default_tile_grid_size));
+ new FakePicturePile(LayerTreeSettings().minimum_contents_scale,
+ LayerTreeSettings().default_tile_grid_size));
pile->SetPlaybackAllowedEvent(&playback_allowed_event_);
scoped_refptr<FakePictureLayer> layer =
- FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
+ FakePictureLayer::CreateWithRecordingSource(layer_settings(), &client_,
+ pile.Pass());
layer->SetBounds(gfx::Size(500, 500));
layer->SetContentsOpaque(true);
// Avoid LCD text on the layer so we don't cause extra commits when we
@@ -6026,8 +4824,8 @@ class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest {
const TileDrawQuad* quad = TileDrawQuad::MaterialCast(draw_quad);
float quad_scale =
quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width());
- float transform_scale =
- SkMScalarToFloat(quad->quadTransform().matrix().get(0, 0));
+ float transform_scale = SkMScalarToFloat(
+ quad->shared_quad_state->quad_to_target_transform.matrix().get(0, 0));
float scale = quad_scale / transform_scale;
if (frame_scale != 0.f && frame_scale != scale)
return 0.f;
@@ -6156,7 +4954,9 @@ class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest {
base::WaitableEvent playback_allowed_event_;
};
-MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestCrispUpAfterPinchEnds);
+// This test does pinching on the impl side which is not supported in single
+// thread.
+MULTI_THREAD_TEST_F(LayerTreeHostTestCrispUpAfterPinchEnds);
class LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy
: public LayerTreeHostTestCrispUpAfterPinchEnds {
@@ -6181,28 +4981,30 @@ class LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy
}
};
-MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy);
+// This test does pinching on the impl side which is not supported in single
+// thread.
+MULTI_THREAD_TEST_F(LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy);
class RasterizeWithGpuRasterizationCreatesResources : public LayerTreeHostTest {
protected:
RasterizeWithGpuRasterizationCreatesResources() {}
void InitializeSettings(LayerTreeSettings* settings) override {
- settings->impl_side_painting = true;
settings->gpu_rasterization_forced = true;
}
void SetupTree() override {
client_.set_fill_with_nonsolid_color(true);
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
root->SetBounds(gfx::Size(500, 500));
scoped_ptr<FakePicturePile> pile(
- new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
- ImplSidePaintingSettings().default_tile_grid_size));
+ new FakePicturePile(LayerTreeSettings().minimum_contents_scale,
+ LayerTreeSettings().default_tile_grid_size));
scoped_refptr<FakePictureLayer> layer =
- FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
+ FakePictureLayer::CreateWithRecordingSource(layer_settings(), &client_,
+ pile.Pass());
layer->SetBounds(gfx::Size(500, 500));
layer->SetContentsOpaque(true);
root->AddChild(layer);
@@ -6225,14 +5027,13 @@ class RasterizeWithGpuRasterizationCreatesResources : public LayerTreeHostTest {
FakeContentLayerClient client_;
};
-MULTI_THREAD_IMPL_TEST_F(RasterizeWithGpuRasterizationCreatesResources);
+SINGLE_AND_MULTI_THREAD_TEST_F(RasterizeWithGpuRasterizationCreatesResources);
class GpuRasterizationRasterizesBorderTiles : public LayerTreeHostTest {
protected:
GpuRasterizationRasterizesBorderTiles() : viewport_size_(1024, 2048) {}
void InitializeSettings(LayerTreeSettings* settings) override {
- settings->impl_side_painting = true;
settings->gpu_rasterization_enabled = true;
settings->gpu_rasterization_forced = true;
}
@@ -6241,10 +5042,11 @@ class GpuRasterizationRasterizesBorderTiles : public LayerTreeHostTest {
client_.set_fill_with_nonsolid_color(true);
scoped_ptr<FakePicturePile> pile(
- new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
- ImplSidePaintingSettings().default_tile_grid_size));
+ new FakePicturePile(LayerTreeSettings().minimum_contents_scale,
+ LayerTreeSettings().default_tile_grid_size));
scoped_refptr<FakePictureLayer> root =
- FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
+ FakePictureLayer::CreateWithRecordingSource(layer_settings(), &client_,
+ pile.Pass());
root->SetBounds(gfx::Size(10000, 10000));
root->SetContentsOpaque(true);
@@ -6270,7 +5072,7 @@ class GpuRasterizationRasterizesBorderTiles : public LayerTreeHostTest {
gfx::Size viewport_size_;
};
-MULTI_THREAD_IMPL_TEST_F(GpuRasterizationRasterizesBorderTiles);
+SINGLE_AND_MULTI_THREAD_TEST_F(GpuRasterizationRasterizesBorderTiles);
class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles
: public LayerTreeHostTest {
@@ -6278,30 +5080,27 @@ class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles
LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles()
: playback_allowed_event_(true, true) {}
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->impl_side_painting = true;
- }
-
void SetupTree() override {
step_ = 1;
continuous_draws_ = 0;
client_.set_fill_with_nonsolid_color(true);
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
root->SetBounds(gfx::Size(500, 500));
- scoped_refptr<Layer> pinch = Layer::Create();
+ scoped_refptr<Layer> pinch = Layer::Create(layer_settings());
pinch->SetBounds(gfx::Size(500, 500));
pinch->SetScrollClipLayerId(root->id());
pinch->SetIsContainerForFixedPositionLayers(true);
root->AddChild(pinch);
scoped_ptr<FakePicturePile> pile(
- new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale,
- ImplSidePaintingSettings().default_tile_grid_size));
+ new FakePicturePile(LayerTreeSettings().minimum_contents_scale,
+ LayerTreeSettings().default_tile_grid_size));
pile->SetPlaybackAllowedEvent(&playback_allowed_event_);
scoped_refptr<FakePictureLayer> layer =
- FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass());
+ FakePictureLayer::CreateWithRecordingSource(layer_settings(), &client_,
+ pile.Pass());
layer->SetBounds(gfx::Size(500, 500));
layer->SetContentsOpaque(true);
// Avoid LCD text on the layer so we don't cause extra commits when we
@@ -6326,8 +5125,8 @@ class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles
const TileDrawQuad* quad = TileDrawQuad::MaterialCast(draw_quad);
float quad_scale =
quad->tex_coord_rect.width() / static_cast<float>(quad->rect.width());
- float transform_scale =
- SkMScalarToFloat(quad->quadTransform().matrix().get(0, 0));
+ float transform_scale = SkMScalarToFloat(
+ quad->shared_quad_state->quad_to_target_transform.matrix().get(0, 0));
float scale = quad_scale / transform_scale;
if (frame_scale != 0.f && frame_scale != scale)
return 0.f;
@@ -6460,7 +5259,7 @@ class LayerTreeHostTestOneActivatePerPrepareTiles : public LayerTreeHostTest {
void SetupTree() override {
client_.set_fill_with_nonsolid_color(true);
scoped_refptr<FakePictureLayer> root_layer =
- FakePictureLayer::Create(&client_);
+ FakePictureLayer::Create(layer_settings(), &client_);
root_layer->SetBounds(gfx::Size(1500, 1500));
root_layer->SetIsDrawable(true);
@@ -6505,7 +5304,7 @@ class LayerTreeHostTestOneActivatePerPrepareTiles : public LayerTreeHostTest {
size_t scheduled_prepare_tiles_count_;
};
-MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestOneActivatePerPrepareTiles);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestOneActivatePerPrepareTiles);
class LayerTreeHostTestFrameTimingRequestsSaveTimestamps
: public LayerTreeHostTest {
@@ -6515,12 +5314,12 @@ class LayerTreeHostTestFrameTimingRequestsSaveTimestamps
void SetupTree() override {
scoped_refptr<FakePictureLayer> root_layer =
- FakePictureLayer::Create(&client_);
+ FakePictureLayer::Create(layer_settings(), &client_);
root_layer->SetBounds(gfx::Size(200, 200));
root_layer->SetIsDrawable(true);
scoped_refptr<FakePictureLayer> child_layer =
- FakePictureLayer::Create(&client_);
+ FakePictureLayer::Create(layer_settings(), &client_);
child_layer->SetBounds(gfx::Size(1500, 1500));
child_layer->SetIsDrawable(true);
@@ -6591,7 +5390,8 @@ class LayerTreeHostTestFrameTimingRequestsSaveTimestamps
bool check_results_on_commit_;
};
-MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestFrameTimingRequestsSaveTimestamps);
+// Frame timing is not implemented in single thread proxy.
+MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimingRequestsSaveTimestamps);
class LayerTreeHostTestActivationCausesPrepareTiles : public LayerTreeHostTest {
public:
@@ -6601,7 +5401,7 @@ class LayerTreeHostTestActivationCausesPrepareTiles : public LayerTreeHostTest {
void SetupTree() override {
client_.set_fill_with_nonsolid_color(true);
scoped_refptr<FakePictureLayer> root_layer =
- FakePictureLayer::Create(&client_);
+ FakePictureLayer::Create(layer_settings(), &client_);
root_layer->SetBounds(gfx::Size(150, 150));
root_layer->SetIsDrawable(true);
@@ -6635,7 +5435,9 @@ class LayerTreeHostTestActivationCausesPrepareTiles : public LayerTreeHostTest {
int scheduled_prepare_tiles_count_;
};
-MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestActivationCausesPrepareTiles);
+// This test is testing activation from a pending tree and doesn't make sense
+// with single thread commit-to-active.
+MULTI_THREAD_TEST_F(LayerTreeHostTestActivationCausesPrepareTiles);
// This tests an assertion that DidCommit and WillCommit happen in the same
// stack frame with no tasks that run between them. Various embedders of
@@ -6674,90 +5476,11 @@ class LayerTreeHostTestNoTasksBetweenWillAndDidCommit
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoTasksBetweenWillAndDidCommit);
-// Verify that if a LayerImpl holds onto a copy request for multiple
-// frames that it will continue to have a render surface through
-// multiple commits, even though the Layer itself has no reason
-// to have a render surface.
-class LayerPreserveRenderSurfaceFromOutputRequests : public LayerTreeHostTest {
- protected:
- void SetupTree() override {
- scoped_refptr<Layer> root = Layer::Create();
- root->CreateRenderSurface();
- root->SetBounds(gfx::Size(10, 10));
- child_ = Layer::Create();
- child_->SetBounds(gfx::Size(20, 20));
- root->AddChild(child_);
-
- layer_tree_host()->SetRootLayer(root);
- LayerTreeHostTest::SetupTree();
- }
-
- static void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}
-
- void BeginTest() override {
- child_->RequestCopyOfOutput(
- CopyOutputRequest::CreateBitmapRequest(base::Bind(CopyOutputCallback)));
- EXPECT_TRUE(child_->HasCopyRequest());
- PostSetNeedsCommitToMainThread();
- }
-
- void DidCommit() override { EXPECT_FALSE(child_->HasCopyRequest()); }
-
- void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
- LayerImpl* child_impl = host_impl->sync_tree()->LayerById(child_->id());
-
- switch (host_impl->sync_tree()->source_frame_number()) {
- case 0:
- EXPECT_TRUE(child_impl->HasCopyRequest());
- EXPECT_TRUE(child_impl->render_surface());
- break;
- case 1:
- if (host_impl->proxy()->CommitToActiveTree()) {
- EXPECT_TRUE(child_impl->HasCopyRequest());
- EXPECT_TRUE(child_impl->render_surface());
- } else {
- EXPECT_FALSE(child_impl->HasCopyRequest());
- EXPECT_FALSE(child_impl->render_surface());
- }
- break;
- default:
- NOTREACHED();
- break;
- }
- }
-
- void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
- LayerImpl* child_impl = host_impl->active_tree()->LayerById(child_->id());
- EXPECT_TRUE(child_impl->HasCopyRequest());
- EXPECT_TRUE(child_impl->render_surface());
-
- switch (host_impl->active_tree()->source_frame_number()) {
- case 0:
- // Lose output surface to prevent drawing and cause another commit.
- host_impl->DidLoseOutputSurface();
- break;
- case 1:
- EndTest();
- break;
- default:
- NOTREACHED();
- break;
- }
- }
-
- void AfterTest() override {}
-
- private:
- scoped_refptr<Layer> child_;
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerPreserveRenderSurfaceFromOutputRequests);
-
class LayerTreeHostTestUpdateCopyRequests : public LayerTreeHostTest {
protected:
void SetupTree() override {
- root = Layer::Create();
- child = Layer::Create();
+ root = Layer::Create(layer_settings());
+ child = Layer::Create(layer_settings());
root->AddChild(child);
layer_tree_host()->SetRootLayer(root);
LayerTreeHostTest::SetupTree();
@@ -6799,21 +5522,21 @@ class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest {
// the surface bounds to be larger. It also has a parent that clips the
// masked layer and its surface.
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
- scoped_refptr<Layer> clipping_layer = Layer::Create();
+ scoped_refptr<Layer> clipping_layer = Layer::Create(layer_settings());
root->AddChild(clipping_layer);
scoped_refptr<FakePictureLayer> content_layer =
- FakePictureLayer::Create(&client_);
+ FakePictureLayer::Create(layer_settings(), &client_);
clipping_layer->AddChild(content_layer);
scoped_refptr<FakePictureLayer> content_child_layer =
- FakePictureLayer::Create(&client_);
+ FakePictureLayer::Create(layer_settings(), &client_);
content_layer->AddChild(content_child_layer);
scoped_refptr<FakePictureLayer> mask_layer =
- FakePictureLayer::Create(&client_);
+ FakePictureLayer::Create(layer_settings(), &client_);
content_layer->SetMaskLayer(mask_layer.get());
gfx::Size root_size(100, 100);
@@ -6893,17 +5616,17 @@ class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest {
// +-- Content Layer
// +--Mask
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
- scoped_refptr<Layer> scaling_layer = Layer::Create();
+ scoped_refptr<Layer> scaling_layer = Layer::Create(layer_settings());
root->AddChild(scaling_layer);
scoped_refptr<FakePictureLayer> content_layer =
- FakePictureLayer::Create(&client_);
+ FakePictureLayer::Create(layer_settings(), &client_);
scaling_layer->AddChild(content_layer);
scoped_refptr<FakePictureLayer> mask_layer =
- FakePictureLayer::Create(&client_);
+ FakePictureLayer::Create(layer_settings(), &client_);
content_layer->SetMaskLayer(mask_layer.get());
gfx::Size root_size(100, 100);
@@ -6988,14 +5711,14 @@ class LayerTreeTestMaskLayerWithDifferentBounds : public LayerTreeTest {
// The mask layer has bounds 100x100 but is attached to a layer with bounds
// 50x50.
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
scoped_refptr<FakePictureLayer> content_layer =
- FakePictureLayer::Create(&client_);
+ FakePictureLayer::Create(layer_settings(), &client_);
root->AddChild(content_layer);
scoped_refptr<FakePictureLayer> mask_layer =
- FakePictureLayer::Create(&client_);
+ FakePictureLayer::Create(layer_settings(), &client_);
content_layer->SetMaskLayer(mask_layer.get());
gfx::Size root_size(100, 100);
@@ -7076,17 +5799,17 @@ class LayerTreeTestReflectionMaskLayerWithDifferentBounds
// The replica's mask layer has bounds 100x100 but the replica is of a
// layer with bounds 50x50.
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
scoped_refptr<FakePictureLayer> content_layer =
- FakePictureLayer::Create(&client_);
+ FakePictureLayer::Create(layer_settings(), &client_);
root->AddChild(content_layer);
- scoped_refptr<Layer> replica_layer = Layer::Create();
+ scoped_refptr<Layer> replica_layer = Layer::Create(layer_settings());
content_layer->SetReplicaLayer(replica_layer.get());
scoped_refptr<FakePictureLayer> mask_layer =
- FakePictureLayer::Create(&client_);
+ FakePictureLayer::Create(layer_settings(), &client_);
replica_layer->SetMaskLayer(mask_layer.get());
gfx::Size root_size(100, 100);
@@ -7169,20 +5892,20 @@ class LayerTreeTestReflectionMaskLayerForSurfaceWithUnclippedChild
// The replica is of a layer with bounds 50x50, but it has a child that
// causes the surface bounds to be larger.
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
scoped_refptr<FakePictureLayer> content_layer =
- FakePictureLayer::Create(&client_);
+ FakePictureLayer::Create(layer_settings(), &client_);
root->AddChild(content_layer);
- content_child_layer_ = FakePictureLayer::Create(&client_);
+ content_child_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
content_layer->AddChild(content_child_layer_);
- scoped_refptr<Layer> replica_layer = Layer::Create();
+ scoped_refptr<Layer> replica_layer = Layer::Create(layer_settings());
content_layer->SetReplicaLayer(replica_layer.get());
scoped_refptr<FakePictureLayer> mask_layer =
- FakePictureLayer::Create(&client_);
+ FakePictureLayer::Create(layer_settings(), &client_);
replica_layer->SetMaskLayer(mask_layer.get());
gfx::Size root_size(100, 100);
@@ -7262,4 +5985,77 @@ class LayerTreeTestReflectionMaskLayerForSurfaceWithUnclippedChild
SINGLE_AND_MULTI_THREAD_TEST_F(
LayerTreeTestReflectionMaskLayerForSurfaceWithUnclippedChild);
+class LayerTreeTestPageScaleFlags : public LayerTreeTest {
+ protected:
+ void SetupTree() override {
+ // -root
+ // -pre page scale
+ // -page scale
+ // -page scale child1
+ // -page scale grandchild
+ // -page scale child2
+ // -post page scale
+
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
+ scoped_refptr<Layer> pre_page_scale = Layer::Create(layer_settings());
+ scoped_refptr<Layer> page_scale = Layer::Create(layer_settings());
+ scoped_refptr<Layer> page_scale_child1 = Layer::Create(layer_settings());
+ scoped_refptr<Layer> page_scale_grandchild =
+ Layer::Create(layer_settings());
+ scoped_refptr<Layer> page_scale_child2 = Layer::Create(layer_settings());
+ scoped_refptr<Layer> post_page_scale = Layer::Create(layer_settings());
+
+ root->AddChild(pre_page_scale);
+ root->AddChild(page_scale);
+ root->AddChild(post_page_scale);
+
+ page_scale->AddChild(page_scale_child1);
+ page_scale->AddChild(page_scale_child2);
+ page_scale_child1->AddChild(page_scale_grandchild);
+
+ layer_tree_host()->SetRootLayer(root);
+ LayerTreeTest::SetupTree();
+
+ scoped_refptr<Layer> overscroll_elasticity_layer = nullptr;
+ scoped_refptr<Layer> inner_viewport_scroll_layer = nullptr;
+ scoped_refptr<Layer> outer_viewport_scroll_layer = nullptr;
+ layer_tree_host()->RegisterViewportLayers(
+ overscroll_elasticity_layer, page_scale, inner_viewport_scroll_layer,
+ outer_viewport_scroll_layer);
+
+ affected_by_page_scale_.push_back(page_scale->id());
+ affected_by_page_scale_.push_back(page_scale_child1->id());
+ affected_by_page_scale_.push_back(page_scale_child2->id());
+ affected_by_page_scale_.push_back(page_scale_grandchild->id());
+
+ not_affected_by_page_scale_.push_back(root->id());
+ not_affected_by_page_scale_.push_back(pre_page_scale->id());
+ not_affected_by_page_scale_.push_back(post_page_scale->id());
+ }
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
+ LayerTreeHostCommon::CallFunctionForSubtree(
+ host_impl->sync_tree()->root_layer(), [this](LayerImpl* layer) {
+ const std::vector<int>& list =
+ layer->IsAffectedByPageScale()
+ ? this->affected_by_page_scale_
+ : this->not_affected_by_page_scale_;
+ EXPECT_TRUE(std::find(list.begin(), list.end(), layer->id()) !=
+ list.end());
+ });
+
+ EndTest();
+ }
+
+ void AfterTest() override {}
+
+ std::vector<int> affected_by_page_scale_;
+ std::vector<int> not_affected_by_page_scale_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestPageScaleFlags);
+
+} // namespace
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_unittest_animation.cc b/chromium/cc/trees/layer_tree_host_unittest_animation.cc
index ed27a03a2f8..9b16e39cb83 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_animation.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_animation.cc
@@ -12,8 +12,8 @@
#include "cc/layers/layer.h"
#include "cc/layers/layer_impl.h"
#include "cc/test/animation_test_common.h"
-#include "cc/test/fake_content_layer.h"
#include "cc/test/fake_content_layer_client.h"
+#include "cc/test/fake_picture_layer.h"
#include "cc/test/layer_tree_test.h"
#include "cc/trees/layer_tree_impl.h"
@@ -231,12 +231,12 @@ class LayerTreeHostAnimationTestAddAnimationWithTimingFunction
void SetupTree() override {
LayerTreeHostAnimationTest::SetupTree();
- content_ = FakeContentLayer::Create(&client_);
- content_->SetBounds(gfx::Size(4, 4));
- layer_tree_host()->root_layer()->AddChild(content_);
+ picture_ = FakePictureLayer::Create(layer_settings(), &client_);
+ picture_->SetBounds(gfx::Size(4, 4));
+ layer_tree_host()->root_layer()->AddChild(picture_);
}
- void BeginTest() override { PostAddAnimationToMainThread(content_.get()); }
+ void BeginTest() override { PostAddAnimationToMainThread(picture_.get()); }
void AnimateLayers(LayerTreeHostImpl* host_impl,
base::TimeTicks monotonic_time) override {
@@ -265,7 +265,7 @@ class LayerTreeHostAnimationTestAddAnimationWithTimingFunction
void AfterTest() override {}
FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> content_;
+ scoped_refptr<FakePictureLayer> picture_;
};
SINGLE_AND_MULTI_THREAD_TEST_F(
@@ -280,13 +280,13 @@ class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes
void SetupTree() override {
LayerTreeHostAnimationTest::SetupTree();
- content_ = FakeContentLayer::Create(&client_);
- content_->SetBounds(gfx::Size(4, 4));
- content_->set_layer_animation_delegate(this);
- layer_tree_host()->root_layer()->AddChild(content_);
+ picture_ = FakePictureLayer::Create(layer_settings(), &client_);
+ picture_->SetBounds(gfx::Size(4, 4));
+ picture_->set_layer_animation_delegate(this);
+ layer_tree_host()->root_layer()->AddChild(picture_);
}
- void BeginTest() override { PostAddAnimationToMainThread(content_.get()); }
+ void BeginTest() override { PostAddAnimationToMainThread(picture_.get()); }
void NotifyAnimationStarted(base::TimeTicks monotonic_time,
Animation::TargetProperty target_property,
@@ -321,7 +321,7 @@ class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes
base::TimeTicks main_start_time_;
base::TimeTicks impl_start_time_;
FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> content_;
+ scoped_refptr<FakePictureLayer> picture_;
};
SINGLE_AND_MULTI_THREAD_TEST_F(
@@ -360,8 +360,8 @@ class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity
: public LayerTreeHostAnimationTest {
public:
LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity()
- : update_check_layer_(FakeContentLayer::Create(&client_)) {
- }
+ : update_check_layer_(
+ FakePictureLayer::Create(layer_settings(), &client_)) {}
void SetupTree() override {
update_check_layer_->SetOpacity(0.f);
@@ -385,7 +385,7 @@ class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity
void AfterTest() override {
// Update() should have been called once, proving that the layer was not
// skipped.
- EXPECT_EQ(1u, update_check_layer_->update_count());
+ EXPECT_EQ(1, update_check_layer_->update_count());
// clear update_check_layer_ so LayerTreeHost dies.
update_check_layer_ = NULL;
@@ -393,7 +393,7 @@ class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity
private:
FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> update_check_layer_;
+ scoped_refptr<FakePictureLayer> update_check_layer_;
};
SINGLE_AND_MULTI_THREAD_TEST_F(
@@ -410,7 +410,7 @@ class LayerTreeHostAnimationTestLayerAddedWithAnimation
void DidCommit() override {
if (layer_tree_host()->source_frame_number() == 1) {
- scoped_refptr<Layer> layer = Layer::Create();
+ scoped_refptr<Layer> layer = Layer::Create(layer_settings());
layer->set_layer_animation_delegate(this);
// Any valid AnimationCurve will do here.
@@ -475,8 +475,6 @@ class LayerTreeHostAnimationTestCancelAnimateCommit
int num_begin_frames_;
int num_commit_calls_;
int num_draw_calls_;
- FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> content_;
};
MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCancelAnimateCommit);
@@ -558,15 +556,15 @@ class LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw
void SetupTree() override {
LayerTreeHostAnimationTest::SetupTree();
- content_ = FakeContentLayer::Create(&client_);
- content_->SetBounds(gfx::Size(4, 4));
- content_->set_layer_animation_delegate(this);
- layer_tree_host()->root_layer()->AddChild(content_);
+ picture_ = FakePictureLayer::Create(layer_settings(), &client_);
+ picture_->SetBounds(gfx::Size(4, 4));
+ picture_->set_layer_animation_delegate(this);
+ layer_tree_host()->root_layer()->AddChild(picture_);
}
void BeginTest() override {
layer_tree_host()->SetViewportSize(gfx::Size());
- PostAddAnimationToMainThread(content_.get());
+ PostAddAnimationToMainThread(picture_.get());
}
void NotifyAnimationStarted(base::TimeTicks monotonic_time,
@@ -586,7 +584,7 @@ class LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw
private:
int started_times_;
FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> content_;
+ scoped_refptr<FakePictureLayer> picture_;
};
SINGLE_AND_MULTI_THREAD_TEST_F(
@@ -598,10 +596,10 @@ class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
: public LayerTreeHostAnimationTest {
void SetupTree() override {
LayerTreeHostAnimationTest::SetupTree();
- content_ = FakeContentLayer::Create(&client_);
- content_->SetBounds(gfx::Size(4, 4));
- content_->set_layer_animation_delegate(this);
- layer_tree_host()->root_layer()->AddChild(content_);
+ picture_ = FakePictureLayer::Create(layer_settings(), &client_);
+ picture_->SetBounds(gfx::Size(4, 4));
+ picture_->set_layer_animation_delegate(this);
+ layer_tree_host()->root_layer()->AddChild(picture_);
}
void InitializeSettings(LayerTreeSettings* settings) override {
@@ -636,12 +634,12 @@ class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
switch (layer_tree_host()->source_frame_number()) {
case 1:
// The animation is longer than 1 BeginFrame interval.
- AddOpacityTransitionToLayer(content_.get(), 0.1, 0.2f, 0.8f, false);
+ AddOpacityTransitionToLayer(picture_.get(), 0.1, 0.2f, 0.8f, false);
added_animations_++;
break;
case 2:
// This second animation will not be drawn so it should not start.
- AddAnimatedTransformToLayer(content_.get(), 0.1, 5, 5);
+ AddAnimatedTransformToLayer(picture_.get(), 0.1, 5, 5);
added_animations_++;
break;
}
@@ -667,7 +665,7 @@ class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
int added_animations_;
int started_times_;
FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> content_;
+ scoped_refptr<FakePictureLayer> picture_;
};
MULTI_THREAD_TEST_F(
@@ -684,7 +682,7 @@ class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
void SetupTree() override {
LayerTreeHostAnimationTest::SetupTree();
- scroll_layer_ = FakeContentLayer::Create(&client_);
+ scroll_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
scroll_layer_->SetBounds(gfx::Size(1000, 1000));
scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20));
@@ -722,7 +720,7 @@ class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
private:
FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> scroll_layer_;
+ scoped_refptr<FakePictureLayer> scroll_layer_;
};
SINGLE_AND_MULTI_THREAD_TEST_F(
@@ -741,7 +739,7 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
void SetupTree() override {
LayerTreeHostAnimationTest::SetupTree();
- scroll_layer_ = FakeContentLayer::Create(&client_);
+ scroll_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
scroll_layer_->SetBounds(gfx::Size(10000, 10000));
scroll_layer_->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0));
@@ -777,8 +775,7 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
}
void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
- if (host_impl->settings().impl_side_painting)
- host_impl->BlockNotifyReadyToActivateForTesting(true);
+ host_impl->BlockNotifyReadyToActivateForTesting(true);
}
void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
@@ -812,8 +809,6 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
}
void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
- if (!host_impl->settings().impl_side_painting)
- return;
if (host_impl->pending_tree()->source_frame_number() != 1)
return;
LayerImpl* scroll_layer_impl =
@@ -836,7 +831,7 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
private:
FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> scroll_layer_;
+ scoped_refptr<FakePictureLayer> scroll_layer_;
const gfx::ScrollOffset final_postion_;
};
@@ -860,7 +855,7 @@ class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
AddOpacityTransitionToLayer(
layer_tree_host()->root_layer(), 1, 0.f, 0.5f, true);
- scoped_refptr<Layer> layer = Layer::Create();
+ scoped_refptr<Layer> layer = Layer::Create(layer_settings());
layer_tree_host()->root_layer()->AddChild(layer);
layer->set_layer_animation_delegate(this);
layer->SetBounds(gfx::Size(4, 4));
@@ -869,8 +864,7 @@ class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
}
void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
- if (host_impl->settings().impl_side_painting)
- host_impl->BlockNotifyReadyToActivateForTesting(true);
+ host_impl->BlockNotifyReadyToActivateForTesting(true);
}
void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
@@ -878,8 +872,7 @@ class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
// blocking activation. We want to verify that even with activation blocked,
// the animation on the layer that's already in the active tree won't get a
// head start.
- if (host_impl->settings().impl_side_painting &&
- host_impl->pending_tree()->source_frame_number() != 2) {
+ if (host_impl->pending_tree()->source_frame_number() != 2) {
host_impl->BlockNotifyReadyToActivateForTesting(false);
}
}
@@ -891,8 +884,7 @@ class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
return;
frame_count_with_pending_tree_++;
- if (frame_count_with_pending_tree_ == 2 &&
- host_impl->settings().impl_side_painting) {
+ if (frame_count_with_pending_tree_ == 2) {
host_impl->BlockNotifyReadyToActivateForTesting(false);
}
}
@@ -925,20 +917,70 @@ class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
int frame_count_with_pending_tree_;
};
-SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
+// This test blocks activation which is not supported for single thread mode.
+MULTI_THREAD_BLOCKNOTIFY_TEST_F(
LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers);
-class LayerTreeHostAnimationTestAddAnimationAfterAnimating
+// When a layer with an animation is removed from the tree and later re-added,
+// the animation should resume.
+class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded
: public LayerTreeHostAnimationTest {
public:
- LayerTreeHostAnimationTestAddAnimationAfterAnimating()
- : num_swap_buffers_(0) {}
+ LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded() {}
+
+ void SetupTree() override {
+ LayerTreeHostAnimationTest::SetupTree();
+ layer_ = Layer::Create(layer_settings());
+ layer_->SetBounds(gfx::Size(4, 4));
+ layer_tree_host()->root_layer()->AddChild(layer_);
+ AddOpacityTransitionToLayer(layer_.get(), 10000.0, 0.1f, 0.9f, true);
+ }
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ void DidCommit() override {
+ switch (layer_tree_host()->source_frame_number()) {
+ case 1:
+ layer_->RemoveFromParent();
+ break;
+ case 2:
+ layer_tree_host()->root_layer()->AddChild(layer_);
+ break;
+ }
+ }
+ void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
+ switch (host_impl->active_tree()->source_frame_number()) {
+ case 0:
+ EXPECT_TRUE(host_impl->animation_registrar()->needs_animate_layers());
+ break;
+ case 1:
+ EXPECT_FALSE(host_impl->animation_registrar()->needs_animate_layers());
+ break;
+ case 2:
+ EXPECT_TRUE(host_impl->animation_registrar()->needs_animate_layers());
+ EndTest();
+ break;
+ }
+ }
+
+ void AfterTest() override {}
+
+ private:
+ scoped_refptr<Layer> layer_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded);
+
+class LayerTreeHostAnimationTestAddAnimationAfterAnimating
+ : public LayerTreeHostAnimationTest {
+ public:
void SetupTree() override {
LayerTreeHostAnimationTest::SetupTree();
- content_ = Layer::Create();
- content_->SetBounds(gfx::Size(4, 4));
- layer_tree_host()->root_layer()->AddChild(content_);
+ layer_ = Layer::Create(layer_settings());
+ layer_->SetBounds(gfx::Size(4, 4));
+ layer_tree_host()->root_layer()->AddChild(layer_);
}
void BeginTest() override { PostSetNeedsCommitToMainThread(); }
@@ -952,7 +994,7 @@ class LayerTreeHostAnimationTestAddAnimationAfterAnimating
case 2:
// Second frame: add an animation to the content layer. The root layer
// animation has caused us to animate already during this frame.
- AddOpacityTransitionToLayer(content_.get(), 0.1, 5, 5, false);
+ AddOpacityTransitionToLayer(layer_.get(), 0.1, 5, 5, false);
break;
}
}
@@ -960,35 +1002,83 @@ class LayerTreeHostAnimationTestAddAnimationAfterAnimating
void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
// After both animations have started, verify that they have valid
// start times.
- num_swap_buffers_++;
+ if (host_impl->active_tree()->source_frame_number() < 2)
+ return;
AnimationRegistrar::AnimationControllerMap controllers_copy =
host_impl->animation_registrar()
->active_animation_controllers_for_testing();
- if (controllers_copy.size() == 2u) {
- EndTest();
- EXPECT_GE(num_swap_buffers_, 3);
- for (auto& it : controllers_copy) {
- int id = it.first;
- if (id == host_impl->RootLayer()->id()) {
- Animation* anim = it.second->GetAnimation(Animation::TRANSFORM);
- EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
- } else if (id == host_impl->RootLayer()->children()[0]->id()) {
- Animation* anim = it.second->GetAnimation(Animation::OPACITY);
- EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
- }
+ EXPECT_EQ(2u, controllers_copy.size());
+ for (auto& it : controllers_copy) {
+ int id = it.first;
+ if (id == host_impl->RootLayer()->id()) {
+ Animation* anim = it.second->GetAnimation(Animation::TRANSFORM);
+ EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
+ } else if (id == host_impl->RootLayer()->children()[0]->id()) {
+ Animation* anim = it.second->GetAnimation(Animation::OPACITY);
+ EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
}
+ EndTest();
}
}
void AfterTest() override {}
private:
- scoped_refptr<Layer> content_;
- int num_swap_buffers_;
+ scoped_refptr<Layer> layer_;
};
SINGLE_AND_MULTI_THREAD_TEST_F(
LayerTreeHostAnimationTestAddAnimationAfterAnimating);
+class LayerTreeHostAnimationTestNotifyAnimationFinished
+ : public LayerTreeHostAnimationTest {
+ public:
+ LayerTreeHostAnimationTestNotifyAnimationFinished()
+ : called_animation_started_(false), called_animation_finished_(false) {}
+
+ void SetupTree() override {
+ LayerTreeHostAnimationTest::SetupTree();
+ picture_ = FakePictureLayer::Create(layer_settings(), &client_);
+ picture_->SetBounds(gfx::Size(4, 4));
+ picture_->set_layer_animation_delegate(this);
+ layer_tree_host()->root_layer()->AddChild(picture_);
+ }
+
+ void BeginTest() override {
+ layer_tree_host()->SetViewportSize(gfx::Size());
+ PostAddLongAnimationToMainThread(picture_.get());
+ }
+
+ void NotifyAnimationStarted(base::TimeTicks monotonic_time,
+ Animation::TargetProperty target_property,
+ int group) override {
+ called_animation_started_ = true;
+ layer_tree_host()->AnimateLayers(
+ base::TimeTicks::FromInternalValue(std::numeric_limits<int64>::max()));
+ PostSetNeedsCommitToMainThread();
+ }
+
+ void NotifyAnimationFinished(base::TimeTicks monotonic_time,
+ Animation::TargetProperty target_property,
+ int group) override {
+ called_animation_finished_ = true;
+ EndTest();
+ }
+
+ void AfterTest() override {
+ EXPECT_TRUE(called_animation_started_);
+ EXPECT_TRUE(called_animation_finished_);
+ }
+
+ private:
+ bool called_animation_started_;
+ bool called_animation_finished_;
+ FakeContentLayerClient client_;
+ scoped_refptr<FakePictureLayer> picture_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeHostAnimationTestNotifyAnimationFinished);
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_unittest_animation_timelines.cc b/chromium/cc/trees/layer_tree_host_unittest_animation_timelines.cc
new file mode 100644
index 00000000000..4bf8e83d221
--- /dev/null
+++ b/chromium/cc/trees/layer_tree_host_unittest_animation_timelines.cc
@@ -0,0 +1,923 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/trees/layer_tree_host.h"
+
+#include "cc/animation/animation_curve.h"
+#include "cc/animation/animation_host.h"
+#include "cc/animation/animation_id_provider.h"
+#include "cc/animation/animation_player.h"
+#include "cc/animation/animation_timeline.h"
+#include "cc/animation/element_animations.h"
+#include "cc/animation/layer_animation_controller.h"
+#include "cc/animation/scroll_offset_animation_curve.h"
+#include "cc/animation/timing_function.h"
+#include "cc/base/time_util.h"
+#include "cc/layers/layer.h"
+#include "cc/layers/layer_impl.h"
+#include "cc/test/animation_test_common.h"
+#include "cc/test/fake_content_layer_client.h"
+#include "cc/test/fake_picture_layer.h"
+#include "cc/test/layer_tree_test.h"
+#include "cc/trees/layer_tree_impl.h"
+
+namespace cc {
+namespace {
+
+class LayerTreeHostTimelinesTest : public LayerTreeTest {
+ public:
+ LayerTreeHostTimelinesTest()
+ : timeline_id_(AnimationIdProvider::NextTimelineId()),
+ player_id_(AnimationIdProvider::NextPlayerId()),
+ player_child_id_(AnimationIdProvider::NextPlayerId()) {
+ timeline_ = AnimationTimeline::Create(timeline_id_);
+ player_ = AnimationPlayer::Create(player_id_);
+ player_child_ = AnimationPlayer::Create(player_child_id_);
+
+ player_->set_layer_animation_delegate(this);
+ }
+
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->use_compositor_animation_timelines = true;
+ }
+
+ void InitializeLayerSettings(LayerSettings* layer_settings) override {
+ layer_settings->use_compositor_animation_timelines = true;
+ }
+
+ void SetupTree() override { LayerTreeTest::SetupTree(); }
+
+ void AttachPlayersToTimeline() {
+ layer_tree_host()->animation_host()->AddAnimationTimeline(timeline_.get());
+ timeline_->AttachPlayer(player_.get());
+ timeline_->AttachPlayer(player_child_.get());
+ }
+
+ protected:
+ scoped_refptr<AnimationTimeline> timeline_;
+ scoped_refptr<AnimationPlayer> player_;
+ scoped_refptr<AnimationPlayer> player_child_;
+
+ const int timeline_id_;
+ const int player_id_;
+ const int player_child_id_;
+};
+
+// Add a layer animation and confirm that
+// LayerTreeHostImpl::UpdateAnimationState does get called.
+// Evolved frome LayerTreeHostAnimationTestAddAnimation
+class LayerTreeHostTimelinesTestAddAnimation
+ : public LayerTreeHostTimelinesTest {
+ public:
+ LayerTreeHostTimelinesTestAddAnimation()
+ : update_animation_state_was_called_(false) {}
+
+ void BeginTest() override {
+ AttachPlayersToTimeline();
+ player_->AttachLayer(layer_tree_host()->root_layer()->id());
+ PostAddInstantAnimationToMainThreadPlayer(player_.get());
+ }
+
+ void UpdateAnimationState(LayerTreeHostImpl* host_impl,
+ bool has_unfinished_animation) override {
+ EXPECT_FALSE(has_unfinished_animation);
+ update_animation_state_was_called_ = true;
+ }
+
+ void NotifyAnimationStarted(base::TimeTicks monotonic_time,
+ Animation::TargetProperty target_property,
+ int group) override {
+ EXPECT_LT(base::TimeTicks(), monotonic_time);
+
+ LayerAnimationController* controller =
+ player_->element_animations()->layer_animation_controller();
+ Animation* animation = controller->GetAnimation(Animation::OPACITY);
+ if (animation)
+ player_->RemoveAnimation(animation->id());
+
+ EndTest();
+ }
+
+ void AfterTest() override { EXPECT_TRUE(update_animation_state_was_called_); }
+
+ private:
+ bool update_animation_state_was_called_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestAddAnimation);
+
+// Add a layer animation to a layer, but continually fail to draw. Confirm that
+// after a while, we do eventually force a draw.
+// Evolved from LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws.
+class LayerTreeHostTimelinesTestCheckerboardDoesNotStarveDraws
+ : public LayerTreeHostTimelinesTest {
+ public:
+ LayerTreeHostTimelinesTestCheckerboardDoesNotStarveDraws()
+ : started_animating_(false) {}
+
+ void BeginTest() override {
+ AttachPlayersToTimeline();
+ player_->AttachLayer(layer_tree_host()->root_layer()->id());
+ PostAddAnimationToMainThreadPlayer(player_.get());
+ }
+
+ void AnimateLayers(LayerTreeHostImpl* host_impl,
+ base::TimeTicks monotonic_time) override {
+ started_animating_ = true;
+ }
+
+ void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
+ if (started_animating_)
+ EndTest();
+ }
+
+ DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame,
+ DrawResult draw_result) override {
+ return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
+ }
+
+ void AfterTest() override {}
+
+ private:
+ bool started_animating_;
+};
+
+// Starvation can only be an issue with the MT compositor.
+MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestCheckerboardDoesNotStarveDraws);
+
+// Ensures that animations eventually get deleted.
+// Evolved from LayerTreeHostAnimationTestAnimationsGetDeleted.
+class LayerTreeHostTimelinesTestAnimationsGetDeleted
+ : public LayerTreeHostTimelinesTest {
+ public:
+ LayerTreeHostTimelinesTestAnimationsGetDeleted()
+ : started_animating_(false) {}
+
+ void BeginTest() override {
+ AttachPlayersToTimeline();
+ player_->AttachLayer(layer_tree_host()->root_layer()->id());
+ PostAddAnimationToMainThreadPlayer(player_.get());
+ }
+
+ void AnimateLayers(LayerTreeHostImpl* host_impl,
+ base::TimeTicks monotonic_time) override {
+ bool have_animations = !host_impl->animation_host()
+ ->animation_registrar()
+ ->active_animation_controllers_for_testing()
+ .empty();
+ if (!started_animating_ && have_animations) {
+ started_animating_ = true;
+ return;
+ }
+
+ if (started_animating_ && !have_animations)
+ EndTest();
+ }
+
+ void NotifyAnimationFinished(base::TimeTicks monotonic_time,
+ Animation::TargetProperty target_property,
+ int group) override {
+ // Animations on the impl-side controller only get deleted during a commit,
+ // so we need to schedule a commit.
+ layer_tree_host()->SetNeedsCommit();
+ }
+
+ void AfterTest() override {}
+
+ private:
+ bool started_animating_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestAnimationsGetDeleted);
+
+// Ensure that an animation's timing function is respected.
+// Evolved from LayerTreeHostAnimationTestAddAnimationWithTimingFunction.
+class LayerTreeHostTimelinesTestAddAnimationWithTimingFunction
+ : public LayerTreeHostTimelinesTest {
+ public:
+ LayerTreeHostTimelinesTestAddAnimationWithTimingFunction() {}
+
+ void SetupTree() override {
+ LayerTreeHostTimelinesTest::SetupTree();
+ picture_ = FakePictureLayer::Create(layer_settings(), &client_);
+ picture_->SetBounds(gfx::Size(4, 4));
+ layer_tree_host()->root_layer()->AddChild(picture_);
+
+ AttachPlayersToTimeline();
+ player_child_->AttachLayer(picture_->id());
+ }
+
+ void BeginTest() override {
+ PostAddAnimationToMainThreadPlayer(player_child_.get());
+ }
+
+ void AnimateLayers(LayerTreeHostImpl* host_impl,
+ base::TimeTicks monotonic_time) override {
+ scoped_refptr<AnimationTimeline> timeline_impl =
+ host_impl->animation_host()->GetTimelineById(timeline_id_);
+ scoped_refptr<AnimationPlayer> player_child_impl =
+ timeline_impl->GetPlayerById(player_child_id_);
+
+ LayerAnimationController* controller_impl =
+ player_child_impl->element_animations()->layer_animation_controller();
+ if (!controller_impl)
+ return;
+
+ Animation* animation = controller_impl->GetAnimation(Animation::OPACITY);
+ if (!animation)
+ return;
+
+ const FloatAnimationCurve* curve =
+ animation->curve()->ToFloatAnimationCurve();
+ float start_opacity = curve->GetValue(base::TimeDelta());
+ float end_opacity = curve->GetValue(curve->Duration());
+ float linearly_interpolated_opacity =
+ 0.25f * end_opacity + 0.75f * start_opacity;
+ base::TimeDelta time = TimeUtil::Scale(curve->Duration(), 0.25f);
+ // If the linear timing function associated with this animation was not
+ // picked up, then the linearly interpolated opacity would be different
+ // because of the default ease timing function.
+ EXPECT_FLOAT_EQ(linearly_interpolated_opacity, curve->GetValue(time));
+
+ EndTest();
+ }
+
+ void AfterTest() override {}
+
+ FakeContentLayerClient client_;
+ scoped_refptr<FakePictureLayer> picture_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeHostTimelinesTestAddAnimationWithTimingFunction);
+
+// Ensures that main thread animations have their start times synchronized with
+// impl thread animations.
+// Evolved from LayerTreeHostAnimationTestSynchronizeAnimationStartTimes.
+class LayerTreeHostTimelinesTestSynchronizeAnimationStartTimes
+ : public LayerTreeHostTimelinesTest {
+ public:
+ LayerTreeHostTimelinesTestSynchronizeAnimationStartTimes() {}
+
+ void SetupTree() override {
+ LayerTreeHostTimelinesTest::SetupTree();
+ picture_ = FakePictureLayer::Create(layer_settings(), &client_);
+ picture_->SetBounds(gfx::Size(4, 4));
+
+ layer_tree_host()->root_layer()->AddChild(picture_);
+
+ AttachPlayersToTimeline();
+ player_child_->set_layer_animation_delegate(this);
+ player_child_->AttachLayer(picture_->id());
+ }
+
+ void BeginTest() override {
+ PostAddAnimationToMainThreadPlayer(player_child_.get());
+ }
+
+ void NotifyAnimationStarted(base::TimeTicks monotonic_time,
+ Animation::TargetProperty target_property,
+ int group) override {
+ LayerAnimationController* controller =
+ player_child_->element_animations()->layer_animation_controller();
+ Animation* animation = controller->GetAnimation(Animation::OPACITY);
+ main_start_time_ = animation->start_time();
+ controller->RemoveAnimation(animation->id());
+ EndTest();
+ }
+
+ void UpdateAnimationState(LayerTreeHostImpl* impl_host,
+ bool has_unfinished_animation) override {
+ scoped_refptr<AnimationTimeline> timeline_impl =
+ impl_host->animation_host()->GetTimelineById(timeline_id_);
+ scoped_refptr<AnimationPlayer> player_child_impl =
+ timeline_impl->GetPlayerById(player_child_id_);
+
+ LayerAnimationController* controller =
+ player_child_impl->element_animations()->layer_animation_controller();
+ Animation* animation = controller->GetAnimation(Animation::OPACITY);
+ if (!animation)
+ return;
+
+ impl_start_time_ = animation->start_time();
+ }
+
+ void AfterTest() override {
+ EXPECT_EQ(impl_start_time_, main_start_time_);
+ EXPECT_LT(base::TimeTicks(), impl_start_time_);
+ }
+
+ private:
+ base::TimeTicks main_start_time_;
+ base::TimeTicks impl_start_time_;
+ FakeContentLayerClient client_;
+ scoped_refptr<FakePictureLayer> picture_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeHostTimelinesTestSynchronizeAnimationStartTimes);
+
+// Ensures that notify animation finished is called.
+// Evolved from LayerTreeHostAnimationTestAnimationFinishedEvents.
+class LayerTreeHostTimelinesTestAnimationFinishedEvents
+ : public LayerTreeHostTimelinesTest {
+ public:
+ LayerTreeHostTimelinesTestAnimationFinishedEvents() {}
+
+ void BeginTest() override {
+ AttachPlayersToTimeline();
+ player_->AttachLayer(layer_tree_host()->root_layer()->id());
+ PostAddInstantAnimationToMainThreadPlayer(player_.get());
+ }
+
+ void NotifyAnimationFinished(base::TimeTicks monotonic_time,
+ Animation::TargetProperty target_property,
+ int group) override {
+ LayerAnimationController* controller =
+ player_->element_animations()->layer_animation_controller();
+ Animation* animation = controller->GetAnimation(Animation::OPACITY);
+ if (animation)
+ controller->RemoveAnimation(animation->id());
+ EndTest();
+ }
+
+ void AfterTest() override {}
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeHostTimelinesTestAnimationFinishedEvents);
+
+// Ensures that when opacity is being animated, this value does not cause the
+// subtree to be skipped.
+// Evolved from LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity.
+class LayerTreeHostTimelinesTestDoNotSkipLayersWithAnimatedOpacity
+ : public LayerTreeHostTimelinesTest {
+ public:
+ LayerTreeHostTimelinesTestDoNotSkipLayersWithAnimatedOpacity()
+ : update_check_layer_(
+ FakePictureLayer::Create(layer_settings(), &client_)) {}
+
+ void SetupTree() override {
+ update_check_layer_->SetOpacity(0.f);
+ layer_tree_host()->SetRootLayer(update_check_layer_);
+ LayerTreeHostTimelinesTest::SetupTree();
+
+ AttachPlayersToTimeline();
+ player_->AttachLayer(update_check_layer_->id());
+ }
+
+ void BeginTest() override {
+ PostAddAnimationToMainThreadPlayer(player_.get());
+ }
+
+ void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
+ scoped_refptr<AnimationTimeline> timeline_impl =
+ host_impl->animation_host()->GetTimelineById(timeline_id_);
+ scoped_refptr<AnimationPlayer> player_impl =
+ timeline_impl->GetPlayerById(player_id_);
+
+ LayerAnimationController* controller_impl =
+ player_impl->element_animations()->layer_animation_controller();
+ Animation* animation_impl =
+ controller_impl->GetAnimation(Animation::OPACITY);
+ controller_impl->RemoveAnimation(animation_impl->id());
+ EndTest();
+ }
+
+ void AfterTest() override {
+ // Update() should have been called once, proving that the layer was not
+ // skipped.
+ EXPECT_EQ(1, update_check_layer_->update_count());
+
+ // clear update_check_layer_ so LayerTreeHost dies.
+ update_check_layer_ = NULL;
+ }
+
+ private:
+ FakeContentLayerClient client_;
+ scoped_refptr<FakePictureLayer> update_check_layer_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeHostTimelinesTestDoNotSkipLayersWithAnimatedOpacity);
+
+// Layers added to tree with existing active animations should have the
+// animation correctly recognized.
+// Evolved from LayerTreeHostAnimationTestLayerAddedWithAnimation.
+class LayerTreeHostTimelinesTestLayerAddedWithAnimation
+ : public LayerTreeHostTimelinesTest {
+ public:
+ LayerTreeHostTimelinesTestLayerAddedWithAnimation() {}
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ void DidCommit() override {
+ if (layer_tree_host()->source_frame_number() == 1) {
+ AttachPlayersToTimeline();
+
+ scoped_refptr<Layer> layer = Layer::Create(layer_settings());
+ player_->AttachLayer(layer->id());
+ player_->set_layer_animation_delegate(this);
+
+ // Any valid AnimationCurve will do here.
+ scoped_ptr<AnimationCurve> curve(new FakeFloatAnimationCurve());
+ scoped_ptr<Animation> animation(
+ Animation::Create(curve.Pass(), 1, 1, Animation::OPACITY));
+ player_->AddAnimation(animation.Pass());
+
+ // We add the animation *before* attaching the layer to the tree.
+ layer_tree_host()->root_layer()->AddChild(layer);
+ }
+ }
+
+ void AnimateLayers(LayerTreeHostImpl* impl_host,
+ base::TimeTicks monotonic_time) override {
+ EndTest();
+ }
+
+ void AfterTest() override {}
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeHostTimelinesTestLayerAddedWithAnimation);
+
+// Make sure the main thread can still execute animations when CanDraw() is not
+// true.
+// Evolved from LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw
+class LayerTreeHostTimelinesTestRunAnimationWhenNotCanDraw
+ : public LayerTreeHostTimelinesTest {
+ public:
+ LayerTreeHostTimelinesTestRunAnimationWhenNotCanDraw() : started_times_(0) {}
+
+ void SetupTree() override {
+ LayerTreeHostTimelinesTest::SetupTree();
+ picture_ = FakePictureLayer::Create(layer_settings(), &client_);
+ picture_->SetBounds(gfx::Size(4, 4));
+ layer_tree_host()->root_layer()->AddChild(picture_);
+
+ AttachPlayersToTimeline();
+ player_child_->AttachLayer(picture_->id());
+ player_child_->set_layer_animation_delegate(this);
+ }
+
+ void BeginTest() override {
+ layer_tree_host()->SetViewportSize(gfx::Size());
+ PostAddAnimationToMainThreadPlayer(player_child_.get());
+ }
+
+ void NotifyAnimationStarted(base::TimeTicks monotonic_time,
+ Animation::TargetProperty target_property,
+ int group) override {
+ started_times_++;
+ }
+
+ void NotifyAnimationFinished(base::TimeTicks monotonic_time,
+ Animation::TargetProperty target_property,
+ int group) override {
+ EndTest();
+ }
+
+ void AfterTest() override { EXPECT_EQ(1, started_times_); }
+
+ private:
+ int started_times_;
+ FakeContentLayerClient client_;
+ scoped_refptr<FakePictureLayer> picture_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeHostTimelinesTestRunAnimationWhenNotCanDraw);
+
+// Animations should not be started when frames are being skipped due to
+// checkerboard.
+// Evolved from LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations.
+class LayerTreeHostTimelinesTestCheckerboardDoesntStartAnimations
+ : public LayerTreeHostTimelinesTest {
+ void SetupTree() override {
+ LayerTreeHostTimelinesTest::SetupTree();
+ picture_ = FakePictureLayer::Create(layer_settings(), &client_);
+ picture_->SetBounds(gfx::Size(4, 4));
+ layer_tree_host()->root_layer()->AddChild(picture_);
+
+ AttachPlayersToTimeline();
+ player_child_->AttachLayer(picture_->id());
+ player_child_->set_layer_animation_delegate(this);
+ }
+
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ // Make sure that drawing many times doesn't cause a checkerboarded
+ // animation to start so we avoid flake in this test.
+ settings->timeout_and_draw_when_animation_checkerboards = false;
+ LayerTreeHostTimelinesTest::InitializeSettings(settings);
+ }
+
+ void BeginTest() override {
+ prevented_draw_ = 0;
+ added_animations_ = 0;
+ started_times_ = 0;
+
+ PostSetNeedsCommitToMainThread();
+ }
+
+ DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ DrawResult draw_result) override {
+ if (added_animations_ < 2)
+ return draw_result;
+ if (TestEnded())
+ return draw_result;
+ // Act like there is checkerboard when the second animation wants to draw.
+ ++prevented_draw_;
+ if (prevented_draw_ > 2)
+ EndTest();
+ return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
+ }
+
+ void DidCommitAndDrawFrame() override {
+ switch (layer_tree_host()->source_frame_number()) {
+ case 1:
+ // The animation is longer than 1 BeginFrame interval.
+ AddOpacityTransitionToPlayer(player_child_.get(), 0.1, 0.2f, 0.8f,
+ false);
+ added_animations_++;
+ break;
+ case 2:
+ // This second animation will not be drawn so it should not start.
+ AddAnimatedTransformToPlayer(player_child_.get(), 0.1, 5, 5);
+ added_animations_++;
+ break;
+ }
+ }
+
+ void NotifyAnimationStarted(base::TimeTicks monotonic_time,
+ Animation::TargetProperty target_property,
+ int group) override {
+ if (TestEnded())
+ return;
+ started_times_++;
+ }
+
+ void AfterTest() override {
+ // Make sure we tried to draw the second animation but failed.
+ EXPECT_LT(0, prevented_draw_);
+ // The first animation should be started, but the second should not because
+ // of checkerboard.
+ EXPECT_EQ(1, started_times_);
+ }
+
+ int prevented_draw_;
+ int added_animations_;
+ int started_times_;
+ FakeContentLayerClient client_;
+ scoped_refptr<FakePictureLayer> picture_;
+};
+
+MULTI_THREAD_TEST_F(
+ LayerTreeHostTimelinesTestCheckerboardDoesntStartAnimations);
+
+// Verifies that scroll offset animations are only accepted when impl-scrolling
+// is supported, and that when scroll offset animations are accepted,
+// scroll offset updates are sent back to the main thread.
+// Evolved from LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
+class LayerTreeHostTimelinesTestScrollOffsetChangesArePropagated
+ : public LayerTreeHostTimelinesTest {
+ public:
+ LayerTreeHostTimelinesTestScrollOffsetChangesArePropagated() {}
+
+ void SetupTree() override {
+ LayerTreeHostTimelinesTest::SetupTree();
+
+ scroll_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
+ scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
+ scroll_layer_->SetBounds(gfx::Size(1000, 1000));
+ scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20));
+ layer_tree_host()->root_layer()->AddChild(scroll_layer_);
+
+ AttachPlayersToTimeline();
+ player_child_->AttachLayer(scroll_layer_->id());
+ }
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ void DidCommit() override {
+ switch (layer_tree_host()->source_frame_number()) {
+ case 1: {
+ scoped_ptr<ScrollOffsetAnimationCurve> curve(
+ ScrollOffsetAnimationCurve::Create(
+ gfx::ScrollOffset(500.f, 550.f),
+ EaseInOutTimingFunction::Create()));
+ scoped_ptr<Animation> animation(
+ Animation::Create(curve.Pass(), 1, 0, Animation::SCROLL_OFFSET));
+ animation->set_needs_synchronized_start_time(true);
+ bool impl_scrolling_supported =
+ layer_tree_host()->proxy()->SupportsImplScrolling();
+ if (impl_scrolling_supported)
+ player_child_->AddAnimation(animation.Pass());
+ else
+ EndTest();
+ break;
+ }
+ default:
+ if (scroll_layer_->scroll_offset().x() > 10 &&
+ scroll_layer_->scroll_offset().y() > 20)
+ EndTest();
+ }
+ }
+
+ void AfterTest() override {}
+
+ private:
+ FakeContentLayerClient client_;
+ scoped_refptr<FakePictureLayer> scroll_layer_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeHostTimelinesTestScrollOffsetChangesArePropagated);
+
+// Verifies that when the main thread removes a scroll animation and sets a new
+// scroll position, the active tree takes on exactly this new scroll position
+// after activation, and the main thread doesn't receive a spurious scroll
+// delta.
+// Evolved from LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
+class LayerTreeHostTimelinesTestScrollOffsetAnimationRemoval
+ : public LayerTreeHostTimelinesTest {
+ public:
+ LayerTreeHostTimelinesTestScrollOffsetAnimationRemoval()
+ : final_postion_(50.0, 100.0) {}
+
+ void SetupTree() override {
+ LayerTreeHostTimelinesTest::SetupTree();
+
+ scroll_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
+ scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
+ scroll_layer_->SetBounds(gfx::Size(10000, 10000));
+ scroll_layer_->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0));
+ layer_tree_host()->root_layer()->AddChild(scroll_layer_);
+
+ scoped_ptr<ScrollOffsetAnimationCurve> curve(
+ ScrollOffsetAnimationCurve::Create(gfx::ScrollOffset(6500.f, 7500.f),
+ EaseInOutTimingFunction::Create()));
+ scoped_ptr<Animation> animation(
+ Animation::Create(curve.Pass(), 1, 0, Animation::SCROLL_OFFSET));
+ animation->set_needs_synchronized_start_time(true);
+
+ AttachPlayersToTimeline();
+ player_child_->AttachLayer(scroll_layer_->id());
+ player_child_->AddAnimation(animation.Pass());
+ }
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ void BeginMainFrame(const BeginFrameArgs& args) override {
+ switch (layer_tree_host()->source_frame_number()) {
+ case 0:
+ break;
+ case 1: {
+ Animation* animation = player_child_->element_animations()
+ ->layer_animation_controller()
+ ->GetAnimation(Animation::SCROLL_OFFSET);
+ player_child_->RemoveAnimation(animation->id());
+ scroll_layer_->SetScrollOffset(final_postion_);
+ break;
+ }
+ default:
+ EXPECT_EQ(final_postion_, scroll_layer_->scroll_offset());
+ }
+ }
+
+ void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
+ host_impl->BlockNotifyReadyToActivateForTesting(true);
+ }
+
+ void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
+ const BeginFrameArgs& args) override {
+ if (!host_impl->pending_tree())
+ return;
+
+ if (!host_impl->active_tree()->root_layer()) {
+ host_impl->BlockNotifyReadyToActivateForTesting(false);
+ return;
+ }
+
+ scoped_refptr<AnimationTimeline> timeline_impl =
+ host_impl->animation_host()->GetTimelineById(timeline_id_);
+ scoped_refptr<AnimationPlayer> player_impl =
+ timeline_impl->GetPlayerById(player_child_id_);
+
+ LayerImpl* scroll_layer_impl =
+ host_impl->active_tree()->root_layer()->children()[0];
+ Animation* animation = player_impl->element_animations()
+ ->layer_animation_controller()
+ ->GetAnimation(Animation::SCROLL_OFFSET);
+
+ if (!animation || animation->run_state() != Animation::RUNNING) {
+ host_impl->BlockNotifyReadyToActivateForTesting(false);
+ return;
+ }
+
+ // Block activation until the running animation has a chance to produce a
+ // scroll delta.
+ gfx::Vector2dF scroll_delta = scroll_layer_impl->ScrollDelta();
+ if (scroll_delta.x() < 1.f || scroll_delta.y() < 1.f)
+ return;
+
+ host_impl->BlockNotifyReadyToActivateForTesting(false);
+ }
+
+ void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
+ if (host_impl->pending_tree()->source_frame_number() != 1)
+ return;
+ LayerImpl* scroll_layer_impl =
+ host_impl->pending_tree()->root_layer()->children()[0];
+ EXPECT_EQ(final_postion_, scroll_layer_impl->CurrentScrollOffset());
+ }
+
+ void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
+ if (host_impl->active_tree()->source_frame_number() != 1)
+ return;
+ LayerImpl* scroll_layer_impl =
+ host_impl->active_tree()->root_layer()->children()[0];
+ EXPECT_EQ(final_postion_, scroll_layer_impl->CurrentScrollOffset());
+ EndTest();
+ }
+
+ void AfterTest() override {
+ EXPECT_EQ(final_postion_, scroll_layer_->scroll_offset());
+ }
+
+ private:
+ FakeContentLayerClient client_;
+ scoped_refptr<FakePictureLayer> scroll_layer_;
+ const gfx::ScrollOffset final_postion_;
+};
+
+MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestScrollOffsetAnimationRemoval);
+
+// When animations are simultaneously added to an existing layer and to a new
+// layer, they should start at the same time, even when there's already a
+// running animation on the existing layer.
+// Evolved from LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers.
+class LayerTreeHostTimelinesTestAnimationsAddedToNewAndExistingLayers
+ : public LayerTreeHostTimelinesTest {
+ public:
+ LayerTreeHostTimelinesTestAnimationsAddedToNewAndExistingLayers()
+ : frame_count_with_pending_tree_(0) {}
+
+ void BeginTest() override {
+ AttachPlayersToTimeline();
+ PostSetNeedsCommitToMainThread();
+ }
+
+ void DidCommit() override {
+ if (layer_tree_host()->source_frame_number() == 1) {
+ player_->AttachLayer(layer_tree_host()->root_layer()->id());
+ AddAnimatedTransformToPlayer(player_.get(), 4, 1, 1);
+ } else if (layer_tree_host()->source_frame_number() == 2) {
+ AddOpacityTransitionToPlayer(player_.get(), 1, 0.f, 0.5f, true);
+
+ scoped_refptr<Layer> layer = Layer::Create(layer_settings());
+ layer_tree_host()->root_layer()->AddChild(layer);
+ layer->SetBounds(gfx::Size(4, 4));
+
+ player_child_->AttachLayer(layer->id());
+ player_child_->set_layer_animation_delegate(this);
+ AddOpacityTransitionToPlayer(player_child_.get(), 1, 0.f, 0.5f, true);
+ }
+ }
+
+ void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
+ host_impl->BlockNotifyReadyToActivateForTesting(true);
+ }
+
+ void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
+ // For the commit that added animations to new and existing layers, keep
+ // blocking activation. We want to verify that even with activation blocked,
+ // the animation on the layer that's already in the active tree won't get a
+ // head start.
+ if (host_impl->pending_tree()->source_frame_number() != 2) {
+ host_impl->BlockNotifyReadyToActivateForTesting(false);
+ }
+ }
+
+ void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
+ const BeginFrameArgs& args) override {
+ if (!host_impl->pending_tree() ||
+ host_impl->pending_tree()->source_frame_number() != 2)
+ return;
+
+ frame_count_with_pending_tree_++;
+ if (frame_count_with_pending_tree_ == 2) {
+ host_impl->BlockNotifyReadyToActivateForTesting(false);
+ }
+ }
+
+ void UpdateAnimationState(LayerTreeHostImpl* host_impl,
+ bool has_unfinished_animation) override {
+ scoped_refptr<AnimationTimeline> timeline_impl =
+ host_impl->animation_host()->GetTimelineById(timeline_id_);
+ scoped_refptr<AnimationPlayer> player_impl =
+ timeline_impl->GetPlayerById(player_id_);
+ scoped_refptr<AnimationPlayer> player_child_impl =
+ timeline_impl->GetPlayerById(player_child_id_);
+
+ // wait for tree activation.
+ if (!player_impl->element_animations())
+ return;
+
+ LayerAnimationController* root_controller_impl =
+ player_impl->element_animations()->layer_animation_controller();
+ Animation* root_animation =
+ root_controller_impl->GetAnimation(Animation::OPACITY);
+ if (!root_animation || root_animation->run_state() != Animation::RUNNING)
+ return;
+
+ LayerAnimationController* child_controller_impl =
+ player_child_impl->element_animations()->layer_animation_controller();
+ Animation* child_animation =
+ child_controller_impl->GetAnimation(Animation::OPACITY);
+ EXPECT_EQ(Animation::RUNNING, child_animation->run_state());
+ EXPECT_EQ(root_animation->start_time(), child_animation->start_time());
+ root_controller_impl->AbortAnimations(Animation::OPACITY);
+ root_controller_impl->AbortAnimations(Animation::TRANSFORM);
+ child_controller_impl->AbortAnimations(Animation::OPACITY);
+ EndTest();
+ }
+
+ void AfterTest() override {}
+
+ private:
+ int frame_count_with_pending_tree_;
+};
+
+// This test blocks activation which is not supported for single thread mode.
+MULTI_THREAD_BLOCKNOTIFY_TEST_F(
+ LayerTreeHostTimelinesTestAnimationsAddedToNewAndExistingLayers);
+
+// Evolved from LayerTreeHostAnimationTestAddAnimationAfterAnimating.
+class LayerTreeHostTimelinesTestAddAnimationAfterAnimating
+ : public LayerTreeHostTimelinesTest {
+ public:
+ void SetupTree() override {
+ LayerTreeHostTimelinesTest::SetupTree();
+ content_ = Layer::Create(layer_settings());
+ content_->SetBounds(gfx::Size(4, 4));
+ layer_tree_host()->root_layer()->AddChild(content_);
+
+ AttachPlayersToTimeline();
+
+ player_->AttachLayer(layer_tree_host()->root_layer()->id());
+ player_child_->AttachLayer(content_->id());
+ }
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ void DidCommit() override {
+ switch (layer_tree_host()->source_frame_number()) {
+ case 1:
+ // First frame: add an animation to the root layer.
+ AddAnimatedTransformToPlayer(player_.get(), 0.1, 5, 5);
+ break;
+ case 2:
+ // Second frame: add an animation to the content layer. The root layer
+ // animation has caused us to animate already during this frame.
+ AddOpacityTransitionToPlayer(player_child_.get(), 0.1, 5, 5, false);
+ break;
+ }
+ }
+
+ void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
+ // After both animations have started, verify that they have valid
+ // start times.
+ if (host_impl->active_tree()->source_frame_number() < 2)
+ return;
+ AnimationRegistrar::AnimationControllerMap controllers_copy =
+ host_impl->animation_host()
+ ->animation_registrar()
+ ->active_animation_controllers_for_testing();
+ EXPECT_EQ(2u, controllers_copy.size());
+ for (auto& it : controllers_copy) {
+ int id = it.first;
+ if (id == host_impl->RootLayer()->id()) {
+ Animation* anim = it.second->GetAnimation(Animation::TRANSFORM);
+ EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
+ } else if (id == host_impl->RootLayer()->children()[0]->id()) {
+ Animation* anim = it.second->GetAnimation(Animation::OPACITY);
+ EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
+ }
+ EndTest();
+ }
+ }
+
+ void AfterTest() override {}
+
+ private:
+ scoped_refptr<Layer> content_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeHostTimelinesTestAddAnimationAfterAnimating);
+
+} // namespace
+} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_unittest_context.cc b/chromium/cc/trees/layer_tree_host_unittest_context.cc
index 82e47b89b0e..d25d047d0a7 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_context.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_context.cc
@@ -5,7 +5,6 @@
#include "cc/trees/layer_tree_host.h"
#include "base/basictypes.h"
-#include "cc/layers/content_layer.h"
#include "cc/layers/delegated_frame_provider.h"
#include "cc/layers/delegated_frame_resource_collection.h"
#include "cc/layers/heads_up_display_layer.h"
@@ -20,9 +19,7 @@
#include "cc/output/filter_operations.h"
#include "cc/resources/single_release_callback.h"
#include "cc/test/failure_output_surface.h"
-#include "cc/test/fake_content_layer.h"
#include "cc/test/fake_content_layer_client.h"
-#include "cc/test/fake_content_layer_impl.h"
#include "cc/test/fake_delegated_renderer_layer.h"
#include "cc/test/fake_delegated_renderer_layer_impl.h"
#include "cc/test/fake_layer_tree_host_client.h"
@@ -31,6 +28,7 @@
#include "cc/test/fake_painted_scrollbar_layer.h"
#include "cc/test/fake_picture_layer.h"
#include "cc/test/fake_picture_layer_impl.h"
+#include "cc/test/fake_resource_provider.h"
#include "cc/test/fake_scoped_ui_resource.h"
#include "cc/test/fake_scrollbar.h"
#include "cc/test/fake_video_frame_provider.h"
@@ -70,6 +68,9 @@ class LayerTreeHostContextTest : public LayerTreeTest {
}
void LoseContext() {
+ // CreateFakeOutputSurface happens on a different thread, so lock context3d_
+ // to make sure we don't set it to null after recreating it there.
+ base::AutoLock lock(context3d_lock_);
// For sanity-checking tests, they should only call this when the
// context is not lost.
CHECK(context3d_);
@@ -90,6 +91,7 @@ class LayerTreeHostContextTest : public LayerTreeTest {
}
scoped_ptr<TestWebGraphicsContext3D> context3d = CreateContext3d();
+ base::AutoLock lock(context3d_lock_);
context3d_ = context3d.get();
if (context_should_support_io_surface_) {
@@ -107,10 +109,9 @@ class LayerTreeHostContextTest : public LayerTreeTest {
LayerTreeHostImpl::FrameData* frame,
DrawResult draw_result) override {
if (draw_result == DRAW_ABORTED_MISSING_HIGH_RES_CONTENT) {
- // Only valid for single-threaded impl-side painting, which activates
+ // Only valid for single-threaded compositing, which activates
// immediately and will try to draw again when content has finished.
DCHECK(!host_impl->proxy()->HasImplThread());
- DCHECK(host_impl->settings().impl_side_painting);
return draw_result;
}
EXPECT_EQ(DRAW_SUCCESS, draw_result);
@@ -148,7 +149,11 @@ class LayerTreeHostContextTest : public LayerTreeTest {
void ExpectCreateToFail() { ++times_to_expect_create_failed_; }
protected:
+ // Protects use of context3d_ so LoseContext and CreateFakeOutputSurface
+ // can both use it on different threads.
+ base::Lock context3d_lock_;
TestWebGraphicsContext3D* context3d_;
+
int times_to_fail_create_;
int times_to_lose_during_commit_;
int times_to_lose_during_draw_;
@@ -385,6 +390,8 @@ class MultipleCompositeDoesNotCreateOutputSurface
void InitializeSettings(LayerTreeSettings* settings) override {
settings->single_thread_proxy_scheduler = false;
+ settings->use_zero_copy = true;
+ settings->use_one_copy = false;
}
void RequestNewOutputSurface() override {
@@ -393,8 +400,8 @@ class MultipleCompositeDoesNotCreateOutputSurface
}
void BeginTest() override {
- layer_tree_host()->Composite(base::TimeTicks());
- layer_tree_host()->Composite(base::TimeTicks());
+ layer_tree_host()->Composite(base::TimeTicks::FromInternalValue(1));
+ layer_tree_host()->Composite(base::TimeTicks::FromInternalValue(2));
}
scoped_ptr<OutputSurface> CreateOutputSurface() override {
@@ -409,7 +416,8 @@ class MultipleCompositeDoesNotCreateOutputSurface
int request_count_;
};
-SINGLE_THREAD_NOIMPL_TEST_F(MultipleCompositeDoesNotCreateOutputSurface);
+// This test uses Composite() which only exists for single thread.
+SINGLE_THREAD_TEST_F(MultipleCompositeDoesNotCreateOutputSurface);
// This test makes sure that once a SingleThreadProxy issues a
// DidFailToInitializeOutputSurface, that future Composite calls will not
@@ -422,6 +430,8 @@ class FailedCreateDoesNotCreateExtraOutputSurface
void InitializeSettings(LayerTreeSettings* settings) override {
settings->single_thread_proxy_scheduler = false;
+ settings->use_zero_copy = true;
+ settings->use_one_copy = false;
}
void RequestNewOutputSurface() override {
@@ -439,12 +449,12 @@ class FailedCreateDoesNotCreateExtraOutputSurface
void BeginTest() override {
// First composite tries to create a surface.
- layer_tree_host()->Composite(base::TimeTicks());
+ layer_tree_host()->Composite(base::TimeTicks::FromInternalValue(1));
EXPECT_EQ(num_requests_, 2);
EXPECT_TRUE(has_failed_);
// Second composite should not request or fail.
- layer_tree_host()->Composite(base::TimeTicks());
+ layer_tree_host()->Composite(base::TimeTicks::FromInternalValue(2));
EXPECT_EQ(num_requests_, 2);
EndTest();
}
@@ -463,7 +473,8 @@ class FailedCreateDoesNotCreateExtraOutputSurface
bool has_failed_;
};
-SINGLE_THREAD_NOIMPL_TEST_F(FailedCreateDoesNotCreateExtraOutputSurface);
+// This test uses Composite() which only exists for single thread.
+SINGLE_THREAD_TEST_F(FailedCreateDoesNotCreateExtraOutputSurface);
class LayerTreeHostContextTestCommitAfterDelayedOutputSurface
: public LayerTreeHostContextTest {
@@ -473,6 +484,8 @@ class LayerTreeHostContextTestCommitAfterDelayedOutputSurface
void InitializeSettings(LayerTreeSettings* settings) override {
settings->single_thread_proxy_scheduler = false;
+ settings->use_zero_copy = true;
+ settings->use_one_copy = false;
}
void RequestNewOutputSurface() override {
@@ -489,7 +502,9 @@ class LayerTreeHostContextTestCommitAfterDelayedOutputSurface
LayerTreeHostContextTest::CreateOutputSurface());
}
- void BeginTest() override { layer_tree_host()->Composite(base::TimeTicks()); }
+ void BeginTest() override {
+ layer_tree_host()->Composite(base::TimeTicks::FromInternalValue(1));
+ }
void ScheduleComposite() override {
if (creating_output_)
@@ -501,8 +516,8 @@ class LayerTreeHostContextTestCommitAfterDelayedOutputSurface
bool creating_output_;
};
-SINGLE_THREAD_NOIMPL_TEST_F(
- LayerTreeHostContextTestCommitAfterDelayedOutputSurface);
+// This test uses Composite() which only exists for single thread.
+SINGLE_THREAD_TEST_F(LayerTreeHostContextTestCommitAfterDelayedOutputSurface);
class LayerTreeHostContextTestAvoidUnnecessaryComposite
: public LayerTreeHostContextTest {
@@ -512,6 +527,8 @@ class LayerTreeHostContextTestAvoidUnnecessaryComposite
void InitializeSettings(LayerTreeSettings* settings) override {
settings->single_thread_proxy_scheduler = false;
+ settings->use_zero_copy = true;
+ settings->use_one_copy = false;
}
void RequestNewOutputSurface() override {
@@ -522,7 +539,7 @@ class LayerTreeHostContextTestAvoidUnnecessaryComposite
void BeginTest() override {
in_composite_ = true;
- layer_tree_host()->Composite(base::TimeTicks());
+ layer_tree_host()->Composite(base::TimeTicks::FromInternalValue(1));
in_composite_ = false;
}
@@ -533,13 +550,15 @@ class LayerTreeHostContextTestAvoidUnnecessaryComposite
bool in_composite_;
};
-SINGLE_THREAD_NOIMPL_TEST_F(LayerTreeHostContextTestAvoidUnnecessaryComposite);
+// This test uses Composite() which only exists for single thread.
+SINGLE_THREAD_TEST_F(LayerTreeHostContextTestAvoidUnnecessaryComposite);
+// This test uses PictureLayer to check for a working context.
class LayerTreeHostContextTestLostContextSucceedsWithContent
: public LayerTreeHostContextTestLostContextSucceeds {
public:
void SetupTree() override {
- root_ = Layer::Create();
+ root_ = Layer::Create(layer_settings());
root_->SetBounds(gfx::Size(10, 10));
root_->SetIsDrawable(true);
@@ -548,10 +567,7 @@ class LayerTreeHostContextTestLostContextSucceedsWithContent
paint.setColor(SkColorSetARGB(100, 80, 200, 200));
client_.add_draw_rect(gfx::Rect(0, 0, 5, 5), paint);
- if (layer_tree_host()->settings().impl_side_painting)
- layer_ = FakePictureLayer::Create(&client_);
- else
- layer_ = FakeContentLayer::Create(&client_);
+ layer_ = FakePictureLayer::Create(layer_settings(), &client_);
layer_->SetBounds(gfx::Size(10, 10));
layer_->SetIsDrawable(true);
@@ -570,21 +586,12 @@ class LayerTreeHostContextTestLostContextSucceedsWithContent
}
void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
- if (!host_impl->settings().impl_side_painting) {
- FakeContentLayerImpl* content_impl = static_cast<FakeContentLayerImpl*>(
- host_impl->active_tree()->root_layer()->children()[0]);
- // Even though the context was lost, we should have a resource. The
- // TestWebGraphicsContext3D ensures that this resource is created with
- // the active context.
- EXPECT_TRUE(content_impl->HaveResourceForTileAt(0, 0));
- } else {
- FakePictureLayerImpl* picture_impl = static_cast<FakePictureLayerImpl*>(
- host_impl->active_tree()->root_layer()->children()[0]);
- EXPECT_TRUE(picture_impl->HighResTiling()
- ->TileAt(0, 0)
- ->draw_info()
- .IsReadyToDraw());
- }
+ FakePictureLayerImpl* picture_impl = static_cast<FakePictureLayerImpl*>(
+ host_impl->active_tree()->root_layer()->children()[0]);
+ EXPECT_TRUE(picture_impl->HighResTiling()
+ ->TileAt(0, 0)
+ ->draw_info()
+ .IsReadyToDraw());
}
protected:
@@ -593,7 +600,6 @@ class LayerTreeHostContextTestLostContextSucceedsWithContent
scoped_refptr<Layer> layer_;
};
-// This test uses TiledLayer and PictureLayer to check for a working context.
SINGLE_AND_MULTI_THREAD_TEST_F(
LayerTreeHostContextTestLostContextSucceedsWithContent);
@@ -639,15 +645,10 @@ class LayerTreeHostContextTestLostContextAndEvictTextures
paint.setColor(SkColorSetARGB(100, 80, 200, 200));
client_.add_draw_rect(gfx::Rect(0, 0, 5, 5), paint);
- if (layer_tree_host()->settings().impl_side_painting) {
- picture_layer_ = FakePictureLayer::Create(&client_);
- picture_layer_->SetBounds(gfx::Size(10, 20));
- layer_tree_host()->SetRootLayer(picture_layer_);
- } else {
- content_layer_ = FakeContentLayer::Create(&client_);
- content_layer_->SetBounds(gfx::Size(10, 20));
- layer_tree_host()->SetRootLayer(content_layer_);
- }
+ scoped_refptr<FakePictureLayer> picture_layer =
+ FakePictureLayer::Create(layer_settings(), &client_);
+ picture_layer->SetBounds(gfx::Size(10, 20));
+ layer_tree_host()->SetRootLayer(picture_layer);
LayerTreeHostContextTest::SetupTree();
}
@@ -679,9 +680,6 @@ class LayerTreeHostContextTestLostContextAndEvictTextures
void DidCommitAndDrawFrame() override {
if (num_commits_ > 1)
return;
- if (!layer_tree_host()->settings().impl_side_painting) {
- EXPECT_TRUE(content_layer_->HaveBackingAt(0, 0));
- }
PostEvictTextures();
}
@@ -697,18 +695,12 @@ class LayerTreeHostContextTestLostContextAndEvictTextures
}
void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
- if (impl->settings().impl_side_painting) {
- FakePictureLayerImpl* picture_impl =
- static_cast<FakePictureLayerImpl*>(impl->active_tree()->root_layer());
- EXPECT_TRUE(picture_impl->HighResTiling()
- ->TileAt(0, 0)
- ->draw_info()
- .IsReadyToDraw());
- } else {
- FakeContentLayerImpl* content_impl =
- static_cast<FakeContentLayerImpl*>(impl->active_tree()->root_layer());
- EXPECT_TRUE(content_impl->HaveResourceForTileAt(0, 0));
- }
+ FakePictureLayerImpl* picture_impl =
+ static_cast<FakePictureLayerImpl*>(impl->active_tree()->root_layer());
+ EXPECT_TRUE(picture_impl->HighResTiling()
+ ->TileAt(0, 0)
+ ->draw_info()
+ .IsReadyToDraw());
impl_host_ = impl;
if (lost_context_)
@@ -722,8 +714,6 @@ class LayerTreeHostContextTestLostContextAndEvictTextures
protected:
bool lose_after_evict_;
FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> content_layer_;
- scoped_refptr<FakePictureLayer> picture_layer_;
LayerTreeHostImpl* impl_host_;
int num_commits_;
bool lost_context_;
@@ -732,143 +722,60 @@ class LayerTreeHostContextTestLostContextAndEvictTextures
TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
LoseAfterEvict_SingleThread_DirectRenderer) {
lose_after_evict_ = true;
- RunTest(false, false, false);
+ RunTest(false, false);
}
TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
LoseAfterEvict_SingleThread_DelegatingRenderer) {
lose_after_evict_ = true;
- RunTest(false, true, false);
+ RunTest(false, true);
}
TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
- LoseAfterEvict_MultiThread_DirectRenderer_MainThreadPaint) {
+ LoseAfterEvict_MultiThread_DirectRenderer) {
lose_after_evict_ = true;
- RunTest(true, false, false);
+ RunTest(true, false);
}
TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
- LoseAfterEvict_MultiThread_DelegatingRenderer_MainThreadPaint) {
+ LoseAfterEvict_MultiThread_DelegatingRenderer) {
lose_after_evict_ = true;
- RunTest(true, true, false);
-}
-
-// Flaky on all platforms, http://crbug.com/310979
-TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
- DISABLED_LoseAfterEvict_MultiThread_DelegatingRenderer_ImplSidePaint) {
- lose_after_evict_ = true;
- RunTest(true, true, true);
+ RunTest(true, true);
}
TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
LoseBeforeEvict_SingleThread_DirectRenderer) {
lose_after_evict_ = false;
- RunTest(false, false, false);
+ RunTest(false, false);
}
TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
LoseBeforeEvict_SingleThread_DelegatingRenderer) {
lose_after_evict_ = false;
- RunTest(false, true, false);
-}
-
-TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
- LoseBeforeEvict_MultiThread_DirectRenderer_MainThreadPaint) {
- lose_after_evict_ = false;
- RunTest(true, false, false);
-}
-
-TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
- LoseBeforeEvict_MultiThread_DirectRenderer_ImplSidePaint) {
- lose_after_evict_ = false;
- RunTest(true, false, true);
+ RunTest(false, true);
}
TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
- LoseBeforeEvict_MultiThread_DelegatingRenderer_MainThreadPaint) {
+ LoseBeforeEvict_MultiThread_DirectRenderer) {
lose_after_evict_ = false;
- RunTest(true, true, false);
+ RunTest(true, false);
}
TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
- LoseBeforeEvict_MultiThread_DelegatingRenderer_ImplSidePaint) {
+ LoseBeforeEvict_MultiThread_DelegatingRenderer) {
lose_after_evict_ = false;
- RunTest(true, true, true);
+ RunTest(true, true);
}
-class LayerTreeHostContextTestLostContextWhileUpdatingResources
- : public LayerTreeHostContextTest {
- public:
- LayerTreeHostContextTestLostContextWhileUpdatingResources()
- : num_children_(50), times_to_lose_on_end_query_(3) {}
-
- scoped_ptr<TestWebGraphicsContext3D> CreateContext3d() override {
- scoped_ptr<TestWebGraphicsContext3D> context =
- LayerTreeHostContextTest::CreateContext3d();
- if (times_to_lose_on_end_query_) {
- --times_to_lose_on_end_query_;
- context->set_times_end_query_succeeds(5);
- }
- return context.Pass();
- }
-
- void SetupTree() override {
- if (layer_tree_host()->settings().impl_side_painting)
- parent_ = FakePictureLayer::Create(&client_);
- else
- parent_ = FakeContentLayer::Create(&client_);
-
- parent_->SetBounds(gfx::Size(num_children_, 1));
-
- for (int i = 0; i < num_children_; i++) {
- scoped_refptr<Layer> child;
- if (layer_tree_host()->settings().impl_side_painting)
- child = FakePictureLayer::Create(&client_);
- else
- child = FakeContentLayer::Create(&client_);
- child->SetPosition(gfx::PointF(i, 0.f));
- child->SetBounds(gfx::Size(1, 1));
- parent_->AddChild(child);
- }
-
- layer_tree_host()->SetRootLayer(parent_);
- LayerTreeHostContextTest::SetupTree();
- }
-
- void BeginTest() override { PostSetNeedsCommitToMainThread(); }
-
- void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
- EXPECT_EQ(0, times_to_lose_on_end_query_);
- EndTest();
- }
-
- void AfterTest() override { EXPECT_EQ(0, times_to_lose_on_end_query_); }
-
- private:
- FakeContentLayerClient client_;
- scoped_refptr<Layer> parent_;
- int num_children_;
- int times_to_lose_on_end_query_;
-};
-
-SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(
- LayerTreeHostContextTestLostContextWhileUpdatingResources);
-
class LayerTreeHostContextTestLayersNotified : public LayerTreeHostContextTest {
public:
LayerTreeHostContextTestLayersNotified()
: LayerTreeHostContextTest(), num_commits_(0) {}
void SetupTree() override {
- if (layer_tree_host()->settings().impl_side_painting) {
- root_ = FakePictureLayer::Create(&client_);
- child_ = FakePictureLayer::Create(&client_);
- grandchild_ = FakePictureLayer::Create(&client_);
- } else {
- root_ = FakeContentLayer::Create(&client_);
- child_ = FakeContentLayer::Create(&client_);
- grandchild_ = FakeContentLayer::Create(&client_);
- }
+ root_ = FakePictureLayer::Create(layer_settings(), &client_);
+ child_ = FakePictureLayer::Create(layer_settings(), &client_);
+ grandchild_ = FakePictureLayer::Create(layer_settings(), &client_);
root_->AddChild(child_);
child_->AddChild(grandchild_);
@@ -885,54 +792,29 @@ class LayerTreeHostContextTestLayersNotified : public LayerTreeHostContextTest {
FakePictureLayerImpl* root_picture = NULL;
FakePictureLayerImpl* child_picture = NULL;
FakePictureLayerImpl* grandchild_picture = NULL;
- FakeContentLayerImpl* root_content = NULL;
- FakeContentLayerImpl* child_content = NULL;
- FakeContentLayerImpl* grandchild_content = NULL;
-
- if (host_impl->settings().impl_side_painting) {
- root_picture = static_cast<FakePictureLayerImpl*>(
- host_impl->active_tree()->root_layer());
- child_picture =
- static_cast<FakePictureLayerImpl*>(root_picture->children()[0]);
- grandchild_picture =
- static_cast<FakePictureLayerImpl*>(child_picture->children()[0]);
- } else {
- root_content = static_cast<FakeContentLayerImpl*>(
- host_impl->active_tree()->root_layer());
- child_content =
- static_cast<FakeContentLayerImpl*>(root_content->children()[0]);
- grandchild_content =
- static_cast<FakeContentLayerImpl*>(child_content->children()[0]);
- }
+ root_picture = static_cast<FakePictureLayerImpl*>(
+ host_impl->active_tree()->root_layer());
+ child_picture =
+ static_cast<FakePictureLayerImpl*>(root_picture->children()[0]);
+ grandchild_picture =
+ static_cast<FakePictureLayerImpl*>(child_picture->children()[0]);
++num_commits_;
switch (num_commits_) {
case 1:
- if (host_impl->settings().impl_side_painting) {
- EXPECT_EQ(0u, root_picture->release_resources_count());
- EXPECT_EQ(0u, child_picture->release_resources_count());
- EXPECT_EQ(0u, grandchild_picture->release_resources_count());
- } else {
- EXPECT_EQ(0u, root_content->lost_output_surface_count());
- EXPECT_EQ(0u, child_content->lost_output_surface_count());
- EXPECT_EQ(0u, grandchild_content->lost_output_surface_count());
- }
+ EXPECT_EQ(0u, root_picture->release_resources_count());
+ EXPECT_EQ(0u, child_picture->release_resources_count());
+ EXPECT_EQ(0u, grandchild_picture->release_resources_count());
// Lose the context and struggle to recreate it.
LoseContext();
times_to_fail_create_ = 1;
break;
case 2:
- if (host_impl->settings().impl_side_painting) {
- EXPECT_TRUE(root_picture->release_resources_count());
- EXPECT_TRUE(child_picture->release_resources_count());
- EXPECT_TRUE(grandchild_picture->release_resources_count());
- } else {
- EXPECT_TRUE(root_content->lost_output_surface_count());
- EXPECT_TRUE(child_content->lost_output_surface_count());
- EXPECT_TRUE(grandchild_content->lost_output_surface_count());
- }
+ EXPECT_TRUE(root_picture->release_resources_count());
+ EXPECT_TRUE(child_picture->release_resources_count());
+ EXPECT_TRUE(grandchild_picture->release_resources_count());
EndTest();
break;
@@ -963,14 +845,8 @@ class LayerTreeHostContextTestDontUseLostResources
child_output_surface_ = FakeOutputSurface::Create3d();
child_output_surface_->BindToClient(&output_surface_client_);
shared_bitmap_manager_.reset(new TestSharedBitmapManager());
- child_resource_provider_ =
- ResourceProvider::Create(child_output_surface_.get(),
- shared_bitmap_manager_.get(),
- NULL,
- NULL,
- 0,
- false,
- 1);
+ child_resource_provider_ = FakeResourceProvider::Create(
+ child_output_surface_.get(), shared_bitmap_manager_.get());
}
static void EmptyReleaseCallback(unsigned sync_point, bool lost) {}
@@ -1004,10 +880,9 @@ class LayerTreeHostContextTestDontUseLostResources
delegated_frame_provider_ = new DelegatedFrameProvider(
delegated_resource_collection_.get(), frame_data.Pass());
- ResourceProvider::ResourceId resource =
- child_resource_provider_->CreateResource(
- gfx::Size(4, 4), GL_CLAMP_TO_EDGE,
- ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888);
+ ResourceId resource = child_resource_provider_->CreateResource(
+ gfx::Size(4, 4), GL_CLAMP_TO_EDGE,
+ ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888);
ResourceProvider::ScopedWriteLockGL lock(child_resource_provider_.get(),
resource);
@@ -1015,26 +890,25 @@ class LayerTreeHostContextTestDontUseLostResources
gl->GenMailboxCHROMIUM(mailbox.name);
GLuint sync_point = gl->InsertSyncPointCHROMIUM();
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
root->SetBounds(gfx::Size(10, 10));
root->SetIsDrawable(true);
scoped_refptr<FakeDelegatedRendererLayer> delegated =
- FakeDelegatedRendererLayer::Create(delegated_frame_provider_.get());
+ FakeDelegatedRendererLayer::Create(layer_settings(),
+ delegated_frame_provider_.get());
delegated->SetBounds(gfx::Size(10, 10));
delegated->SetIsDrawable(true);
root->AddChild(delegated);
- scoped_refptr<Layer> layer;
- if (layer_tree_host()->settings().impl_side_painting)
- layer = PictureLayer::Create(&client_);
- else
- layer = ContentLayer::Create(&client_);
+ scoped_refptr<PictureLayer> layer =
+ PictureLayer::Create(layer_settings(), &client_);
layer->SetBounds(gfx::Size(10, 10));
layer->SetIsDrawable(true);
root->AddChild(layer);
- scoped_refptr<TextureLayer> texture = TextureLayer::CreateForMailbox(NULL);
+ scoped_refptr<TextureLayer> texture =
+ TextureLayer::CreateForMailbox(layer_settings_, NULL);
texture->SetBounds(gfx::Size(10, 10));
texture->SetIsDrawable(true);
texture->SetTextureMailbox(
@@ -1044,37 +918,31 @@ class LayerTreeHostContextTestDontUseLostResources
EmptyReleaseCallback)));
root->AddChild(texture);
- scoped_refptr<Layer> mask;
- if (layer_tree_host()->settings().impl_side_painting)
- mask = PictureLayer::Create(&client_);
- else
- mask = ContentLayer::Create(&client_);
+ scoped_refptr<PictureLayer> mask =
+ PictureLayer::Create(layer_settings_, &client_);
mask->SetBounds(gfx::Size(10, 10));
- scoped_refptr<Layer> layer_with_mask;
- if (layer_tree_host()->settings().impl_side_painting)
- layer_with_mask = PictureLayer::Create(&client_);
- else
- layer_with_mask = ContentLayer::Create(&client_);
+ scoped_refptr<PictureLayer> layer_with_mask =
+ PictureLayer::Create(layer_settings_, &client_);
layer_with_mask->SetBounds(gfx::Size(10, 10));
layer_with_mask->SetIsDrawable(true);
layer_with_mask->SetMaskLayer(mask.get());
root->AddChild(layer_with_mask);
- scoped_refptr<VideoLayer> video_color =
- VideoLayer::Create(&color_frame_provider_, media::VIDEO_ROTATION_0);
+ scoped_refptr<VideoLayer> video_color = VideoLayer::Create(
+ layer_settings_, &color_frame_provider_, media::VIDEO_ROTATION_0);
video_color->SetBounds(gfx::Size(10, 10));
video_color->SetIsDrawable(true);
root->AddChild(video_color);
- scoped_refptr<VideoLayer> video_hw =
- VideoLayer::Create(&hw_frame_provider_, media::VIDEO_ROTATION_0);
+ scoped_refptr<VideoLayer> video_hw = VideoLayer::Create(
+ layer_settings_, &hw_frame_provider_, media::VIDEO_ROTATION_0);
video_hw->SetBounds(gfx::Size(10, 10));
video_hw->SetIsDrawable(true);
root->AddChild(video_hw);
- scoped_refptr<VideoLayer> video_scaled_hw =
- VideoLayer::Create(&scaled_hw_frame_provider_, media::VIDEO_ROTATION_0);
+ scoped_refptr<VideoLayer> video_scaled_hw = VideoLayer::Create(
+ layer_settings_, &scaled_hw_frame_provider_, media::VIDEO_ROTATION_0);
video_scaled_hw->SetBounds(gfx::Size(10, 10));
video_scaled_hw->SetIsDrawable(true);
root->AddChild(video_scaled_hw);
@@ -1082,28 +950,26 @@ class LayerTreeHostContextTestDontUseLostResources
color_video_frame_ = VideoFrame::CreateColorFrame(
gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta());
hw_video_frame_ = VideoFrame::WrapNativeTexture(
+ media::VideoFrame::ARGB,
gpu::MailboxHolder(mailbox, GL_TEXTURE_2D, sync_point),
media::VideoFrame::ReleaseMailboxCB(), gfx::Size(4, 4),
- gfx::Rect(0, 0, 4, 4), gfx::Size(4, 4), base::TimeDelta(),
- false /* allow_overlay */, true /* has_alpha */);
+ gfx::Rect(0, 0, 4, 4), gfx::Size(4, 4), base::TimeDelta());
scaled_hw_video_frame_ = VideoFrame::WrapNativeTexture(
+ media::VideoFrame::ARGB,
gpu::MailboxHolder(mailbox, GL_TEXTURE_2D, sync_point),
media::VideoFrame::ReleaseMailboxCB(), gfx::Size(4, 4),
- gfx::Rect(0, 0, 3, 2), gfx::Size(4, 4), base::TimeDelta(),
- false /* allow_overlay */, true /* has_alpha */);
+ gfx::Rect(0, 0, 3, 2), gfx::Size(4, 4), base::TimeDelta());
color_frame_provider_.set_frame(color_video_frame_);
hw_frame_provider_.set_frame(hw_video_frame_);
scaled_hw_frame_provider_.set_frame(scaled_hw_video_frame_);
- if (!delegating_renderer()) {
- // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
- scoped_refptr<IOSurfaceLayer> io_surface = IOSurfaceLayer::Create();
- io_surface->SetBounds(gfx::Size(10, 10));
- io_surface->SetIsDrawable(true);
- io_surface->SetIOSurfaceProperties(1, gfx::Size(10, 10));
- root->AddChild(io_surface);
- }
+ scoped_refptr<IOSurfaceLayer> io_surface =
+ IOSurfaceLayer::Create(layer_settings_);
+ io_surface->SetBounds(gfx::Size(10, 10));
+ io_surface->SetIsDrawable(true);
+ io_surface->SetIOSurfaceProperties(1, gfx::Size(10, 10));
+ root->AddChild(io_surface);
// Enable the hud.
LayerTreeDebugState debug_state;
@@ -1112,7 +978,8 @@ class LayerTreeHostContextTestDontUseLostResources
scoped_refptr<PaintedScrollbarLayer> scrollbar =
PaintedScrollbarLayer::Create(
- scoped_ptr<Scrollbar>(new FakeScrollbar).Pass(), layer->id());
+ layer_settings_, scoped_ptr<Scrollbar>(new FakeScrollbar).Pass(),
+ layer->id());
scrollbar->SetBounds(gfx::Size(10, 10));
scrollbar->SetIsDrawable(true);
root->AddChild(scrollbar);
@@ -1189,27 +1056,22 @@ class LayerTreeHostContextTestDontUseLostResources
FakeVideoFrameProvider color_frame_provider_;
FakeVideoFrameProvider hw_frame_provider_;
FakeVideoFrameProvider scaled_hw_frame_provider_;
+
+ LayerSettings layer_settings_;
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestDontUseLostResources);
-class ImplSidePaintingLayerTreeHostContextTest
- : public LayerTreeHostContextTest {
- public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->impl_side_painting = true;
- }
-};
-
class LayerTreeHostContextTestImplSidePainting
- : public ImplSidePaintingLayerTreeHostContextTest {
+ : public LayerTreeHostContextTest {
public:
void SetupTree() override {
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
root->SetBounds(gfx::Size(10, 10));
root->SetIsDrawable(true);
- scoped_refptr<PictureLayer> picture = PictureLayer::Create(&client_);
+ scoped_refptr<PictureLayer> picture =
+ PictureLayer::Create(layer_settings(), &client_);
picture->SetBounds(gfx::Size(10, 10));
picture->SetIsDrawable(true);
root->AddChild(picture);
@@ -1231,16 +1093,16 @@ class LayerTreeHostContextTestImplSidePainting
FakeContentLayerClient client_;
};
-MULTI_THREAD_TEST_F(LayerTreeHostContextTestImplSidePainting);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestImplSidePainting);
class ScrollbarLayerLostContext : public LayerTreeHostContextTest {
public:
ScrollbarLayerLostContext() : commits_(0) {}
void BeginTest() override {
- scoped_refptr<Layer> scroll_layer = Layer::Create();
- scrollbar_layer_ =
- FakePaintedScrollbarLayer::Create(false, true, scroll_layer->id());
+ scoped_refptr<Layer> scroll_layer = Layer::Create(layer_settings());
+ scrollbar_layer_ = FakePaintedScrollbarLayer::Create(
+ layer_settings(), false, true, scroll_layer->id());
scrollbar_layer_->SetBounds(gfx::Size(10, 100));
layer_tree_host()->root_layer()->AddChild(scrollbar_layer_);
layer_tree_host()->root_layer()->AddChild(scroll_layer);
@@ -1328,24 +1190,13 @@ class UIResourceLostTest : public LayerTreeHostContextTest {
class UIResourceLostTestSimple : public UIResourceLostTest {
public:
- // This is called when the commit is complete and the new layer tree has been
- // activated.
+ // This is called when the new layer tree has been activated.
virtual void StepCompleteOnImplThread(LayerTreeHostImpl* impl) = 0;
- void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
- if (!impl->settings().impl_side_painting) {
- StepCompleteOnImplThread(impl);
- PostStepCompleteToMainThread();
- ++time_step_;
- }
- }
-
void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
- if (impl->settings().impl_side_painting) {
- StepCompleteOnImplThread(impl);
- PostStepCompleteToMainThread();
- ++time_step_;
- }
+ StepCompleteOnImplThread(impl);
+ PostStepCompleteToMainThread();
+ ++time_step_;
}
};
@@ -1585,15 +1436,7 @@ class UIResourceLostBeforeActivateTree : public UIResourceLostTest {
UIResourceId test_id_;
};
-TEST_F(UIResourceLostBeforeActivateTree,
- RunMultiThread_DirectRenderer_ImplSidePaint) {
- RunTest(true, false, true);
-}
-
-TEST_F(UIResourceLostBeforeActivateTree,
- RunMultiThread_DelegatingRenderer_ImplSidePaint) {
- RunTest(true, true, true);
-}
+SINGLE_AND_MULTI_THREAD_TEST_F(UIResourceLostBeforeActivateTree);
// Resources evicted explicitly and by visibility changes.
class UIResourceLostEviction : public UIResourceLostTestSimple {
@@ -1685,15 +1528,9 @@ class LayerTreeHostContextTestSurfaceCreateCallback
: LayerTreeHostContextTest() {}
void SetupTree() override {
- if (layer_tree_host()->settings().impl_side_painting) {
- picture_layer_ = FakePictureLayer::Create(&client_);
- picture_layer_->SetBounds(gfx::Size(10, 20));
- layer_tree_host()->SetRootLayer(picture_layer_);
- } else {
- content_layer_ = FakeContentLayer::Create(&client_);
- content_layer_->SetBounds(gfx::Size(10, 20));
- layer_tree_host()->SetRootLayer(content_layer_);
- }
+ picture_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
+ picture_layer_->SetBounds(gfx::Size(10, 20));
+ layer_tree_host()->SetRootLayer(picture_layer_);
LayerTreeHostContextTest::SetupTree();
}
@@ -1703,30 +1540,18 @@ class LayerTreeHostContextTestSurfaceCreateCallback
void DidCommit() override {
switch (layer_tree_host()->source_frame_number()) {
case 1:
- if (layer_tree_host()->settings().impl_side_painting)
- EXPECT_EQ(1u, picture_layer_->output_surface_created_count());
- else
- EXPECT_EQ(1u, content_layer_->output_surface_created_count());
+ EXPECT_EQ(1u, picture_layer_->output_surface_created_count());
layer_tree_host()->SetNeedsCommit();
break;
case 2:
- if (layer_tree_host()->settings().impl_side_painting)
- EXPECT_EQ(1u, picture_layer_->output_surface_created_count());
- else
- EXPECT_EQ(1u, content_layer_->output_surface_created_count());
+ EXPECT_EQ(1u, picture_layer_->output_surface_created_count());
layer_tree_host()->SetNeedsCommit();
break;
case 3:
- if (layer_tree_host()->settings().impl_side_painting)
- EXPECT_EQ(1u, picture_layer_->output_surface_created_count());
- else
- EXPECT_EQ(1u, content_layer_->output_surface_created_count());
+ EXPECT_EQ(1u, picture_layer_->output_surface_created_count());
break;
case 4:
- if (layer_tree_host()->settings().impl_side_painting)
- EXPECT_EQ(2u, picture_layer_->output_surface_created_count());
- else
- EXPECT_EQ(2u, content_layer_->output_surface_created_count());
+ EXPECT_EQ(2u, picture_layer_->output_surface_created_count());
layer_tree_host()->SetNeedsCommit();
break;
}
@@ -1753,7 +1578,6 @@ class LayerTreeHostContextTestSurfaceCreateCallback
protected:
FakeContentLayerClient client_;
scoped_refptr<FakePictureLayer> picture_layer_;
- scoped_refptr<FakeContentLayer> content_layer_;
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestSurfaceCreateCallback);
diff --git a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
index 5766a192106..e29cb21333e 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
@@ -5,9 +5,9 @@
#include "cc/layers/layer_iterator.h"
#include "cc/output/copy_output_request.h"
#include "cc/output/copy_output_result.h"
-#include "cc/test/fake_content_layer.h"
#include "cc/test/fake_content_layer_client.h"
#include "cc/test/fake_output_surface.h"
+#include "cc/test/fake_picture_layer.h"
#include "cc/test/layer_tree_test.h"
#include "cc/trees/layer_tree_impl.h"
#include "gpu/GLES2/gl2extchromium.h"
@@ -23,10 +23,10 @@ class LayerTreeHostCopyRequestTestMultipleRequests
: public LayerTreeHostCopyRequestTest {
protected:
void SetupTree() override {
- root = FakeContentLayer::Create(&client_);
+ root = FakePictureLayer::Create(layer_settings(), &client_);
root->SetBounds(gfx::Size(20, 20));
- child = FakeContentLayer::Create(&client_);
+ child = FakePictureLayer::Create(layer_settings(), &client_);
child->SetBounds(gfx::Size(10, 10));
root->AddChild(child);
@@ -114,48 +114,47 @@ class LayerTreeHostCopyRequestTestMultipleRequests
bool use_gl_renderer_;
std::vector<gfx::Size> callbacks_;
FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> root;
- scoped_refptr<FakeContentLayer> child;
+ scoped_refptr<FakePictureLayer> root;
+ scoped_refptr<FakePictureLayer> child;
};
// Readback can't be done with a delegating renderer.
-// Disabled due to flake: http://crbug.com/448521
TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
- DISABLED_GLRenderer_RunSingleThread) {
+ GLRenderer_RunSingleThread) {
use_gl_renderer_ = true;
- RunTest(false, false, false);
+ RunTest(false, false);
}
TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
- GLRenderer_RunMultiThread_MainThreadPainting) {
+ GLRenderer_RunMultiThread) {
use_gl_renderer_ = true;
- RunTest(true, false, false);
+ RunTest(true, false);
}
TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
SoftwareRenderer_RunSingleThread) {
use_gl_renderer_ = false;
- RunTest(false, false, false);
+ RunTest(false, false);
}
TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
- SoftwareRenderer_RunMultiThread_MainThreadPainting) {
+ SoftwareRenderer_RunMultiThread) {
use_gl_renderer_ = false;
- RunTest(true, false, false);
+ RunTest(true, false);
}
class LayerTreeHostCopyRequestTestLayerDestroyed
: public LayerTreeHostCopyRequestTest {
protected:
void SetupTree() override {
- root_ = FakeContentLayer::Create(&client_);
+ root_ = FakePictureLayer::Create(layer_settings(), &client_);
root_->SetBounds(gfx::Size(20, 20));
- main_destroyed_ = FakeContentLayer::Create(&client_);
+ main_destroyed_ = FakePictureLayer::Create(layer_settings(), &client_);
main_destroyed_->SetBounds(gfx::Size(15, 15));
root_->AddChild(main_destroyed_);
- impl_destroyed_ = FakeContentLayer::Create(&client_);
+ impl_destroyed_ = FakePictureLayer::Create(layer_settings(), &client_);
impl_destroyed_->SetBounds(gfx::Size(10, 10));
root_->AddChild(impl_destroyed_);
@@ -229,9 +228,9 @@ class LayerTreeHostCopyRequestTestLayerDestroyed
int callback_count_;
FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> root_;
- scoped_refptr<FakeContentLayer> main_destroyed_;
- scoped_refptr<FakeContentLayer> impl_destroyed_;
+ scoped_refptr<FakePictureLayer> root_;
+ scoped_refptr<FakePictureLayer> main_destroyed_;
+ scoped_refptr<FakePictureLayer> impl_destroyed_;
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCopyRequestTestLayerDestroyed);
@@ -240,20 +239,20 @@ class LayerTreeHostCopyRequestTestInHiddenSubtree
: public LayerTreeHostCopyRequestTest {
protected:
void SetupTree() override {
- root_ = FakeContentLayer::Create(&client_);
+ root_ = FakePictureLayer::Create(layer_settings(), &client_);
root_->SetBounds(gfx::Size(20, 20));
- grand_parent_layer_ = FakeContentLayer::Create(&client_);
+ grand_parent_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
grand_parent_layer_->SetBounds(gfx::Size(15, 15));
root_->AddChild(grand_parent_layer_);
// parent_layer_ owns a render surface.
- parent_layer_ = FakeContentLayer::Create(&client_);
+ parent_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
parent_layer_->SetBounds(gfx::Size(15, 15));
parent_layer_->SetForceRenderSurface(true);
grand_parent_layer_->AddChild(parent_layer_);
- copy_layer_ = FakeContentLayer::Create(&client_);
+ copy_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
copy_layer_->SetBounds(gfx::Size(10, 10));
parent_layer_->AddChild(copy_layer_);
@@ -326,34 +325,34 @@ class LayerTreeHostCopyRequestTestInHiddenSubtree
int callback_count_;
FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> root_;
- scoped_refptr<FakeContentLayer> grand_parent_layer_;
- scoped_refptr<FakeContentLayer> parent_layer_;
- scoped_refptr<FakeContentLayer> copy_layer_;
+ scoped_refptr<FakePictureLayer> root_;
+ scoped_refptr<FakePictureLayer> grand_parent_layer_;
+ scoped_refptr<FakePictureLayer> parent_layer_;
+ scoped_refptr<FakePictureLayer> copy_layer_;
};
-SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
+SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
LayerTreeHostCopyRequestTestInHiddenSubtree);
class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest
: public LayerTreeHostCopyRequestTest {
protected:
void SetupTree() override {
- root_ = FakeContentLayer::Create(&client_);
+ root_ = FakePictureLayer::Create(layer_settings(), &client_);
root_->SetBounds(gfx::Size(20, 20));
- grand_parent_layer_ = FakeContentLayer::Create(&client_);
+ grand_parent_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
grand_parent_layer_->SetBounds(gfx::Size(15, 15));
grand_parent_layer_->SetHideLayerAndSubtree(true);
root_->AddChild(grand_parent_layer_);
// parent_layer_ owns a render surface.
- parent_layer_ = FakeContentLayer::Create(&client_);
+ parent_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
parent_layer_->SetBounds(gfx::Size(15, 15));
parent_layer_->SetForceRenderSurface(true);
grand_parent_layer_->AddChild(parent_layer_);
- copy_layer_ = FakeContentLayer::Create(&client_);
+ copy_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
copy_layer_->SetBounds(gfx::Size(10, 10));
parent_layer_->AddChild(copy_layer_);
@@ -403,10 +402,10 @@ class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest
FakeContentLayerClient client_;
bool did_draw_;
- scoped_refptr<FakeContentLayer> root_;
- scoped_refptr<FakeContentLayer> grand_parent_layer_;
- scoped_refptr<FakeContentLayer> parent_layer_;
- scoped_refptr<FakeContentLayer> copy_layer_;
+ scoped_refptr<FakePictureLayer> root_;
+ scoped_refptr<FakePictureLayer> grand_parent_layer_;
+ scoped_refptr<FakePictureLayer> parent_layer_;
+ scoped_refptr<FakePictureLayer> copy_layer_;
};
// No output to copy for delegated renderers.
@@ -417,15 +416,15 @@ class LayerTreeHostCopyRequestTestClippedOut
: public LayerTreeHostCopyRequestTest {
protected:
void SetupTree() override {
- root_ = FakeContentLayer::Create(&client_);
+ root_ = FakePictureLayer::Create(layer_settings(), &client_);
root_->SetBounds(gfx::Size(20, 20));
- parent_layer_ = FakeContentLayer::Create(&client_);
+ parent_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
parent_layer_->SetBounds(gfx::Size(15, 15));
parent_layer_->SetMasksToBounds(true);
root_->AddChild(parent_layer_);
- copy_layer_ = FakeContentLayer::Create(&client_);
+ copy_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
copy_layer_->SetPosition(gfx::Point(15, 15));
copy_layer_->SetBounds(gfx::Size(10, 10));
parent_layer_->AddChild(copy_layer_);
@@ -453,9 +452,9 @@ class LayerTreeHostCopyRequestTestClippedOut
void AfterTest() override {}
FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> root_;
- scoped_refptr<FakeContentLayer> parent_layer_;
- scoped_refptr<FakeContentLayer> copy_layer_;
+ scoped_refptr<FakePictureLayer> root_;
+ scoped_refptr<FakePictureLayer> parent_layer_;
+ scoped_refptr<FakePictureLayer> copy_layer_;
};
SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
@@ -465,10 +464,10 @@ class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw
: public LayerTreeHostCopyRequestTest {
protected:
void SetupTree() override {
- root_ = FakeContentLayer::Create(&client_);
+ root_ = FakePictureLayer::Create(layer_settings(), &client_);
root_->SetBounds(gfx::Size(20, 20));
- copy_layer_ = FakeContentLayer::Create(&client_);
+ copy_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
copy_layer_->SetBounds(gfx::Size(10, 10));
root_->AddChild(copy_layer_);
@@ -513,11 +512,24 @@ class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw
void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
- EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
- ++callback_count_;
- if (callback_count_ == 2)
- EndTest();
+ // The first frame can't be drawn.
+ switch (callback_count_) {
+ case 0:
+ EXPECT_TRUE(result->IsEmpty());
+ EXPECT_EQ(gfx::Size(), result->size());
+ break;
+ case 1:
+ EXPECT_FALSE(result->IsEmpty());
+ EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
+ EndTest();
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+
+ ++callback_count_;
}
void AfterTest() override { EXPECT_TRUE(saw_copy_request_); }
@@ -525,11 +537,11 @@ class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw
bool saw_copy_request_;
int callback_count_;
FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> root_;
- scoped_refptr<FakeContentLayer> copy_layer_;
+ scoped_refptr<FakePictureLayer> root_;
+ scoped_refptr<FakePictureLayer> copy_layer_;
};
-SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
+SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
LayerTreeHostTestAsyncTwoReadbacksWithoutDraw);
class LayerTreeHostCopyRequestTestLostOutputSurface
@@ -547,10 +559,10 @@ class LayerTreeHostCopyRequestTestLostOutputSurface
}
void SetupTree() override {
- root_ = FakeContentLayer::Create(&client_);
+ root_ = FakePictureLayer::Create(layer_settings(), &client_);
root_->SetBounds(gfx::Size(20, 20));
- copy_layer_ = FakeContentLayer::Create(&client_);
+ copy_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
copy_layer_->SetBounds(gfx::Size(10, 10));
root_->AddChild(copy_layer_);
@@ -652,12 +664,12 @@ class LayerTreeHostCopyRequestTestLostOutputSurface
size_t num_textures_without_readback_;
size_t num_textures_after_loss_;
FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> root_;
- scoped_refptr<FakeContentLayer> copy_layer_;
+ scoped_refptr<FakePictureLayer> root_;
+ scoped_refptr<FakePictureLayer> copy_layer_;
scoped_ptr<CopyOutputResult> result_;
};
-SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
+SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
LayerTreeHostCopyRequestTestLostOutputSurface);
class LayerTreeHostCopyRequestTestCountTextures
@@ -669,10 +681,12 @@ class LayerTreeHostCopyRequestTestCountTextures
}
void SetupTree() override {
- root_ = FakeContentLayer::Create(&client_);
+ client_.set_fill_with_nonsolid_color(true);
+
+ root_ = FakePictureLayer::Create(layer_settings(), &client_);
root_->SetBounds(gfx::Size(20, 20));
- copy_layer_ = FakeContentLayer::Create(&client_);
+ copy_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
copy_layer_->SetBounds(gfx::Size(10, 10));
root_->AddChild(copy_layer_);
@@ -728,8 +742,8 @@ class LayerTreeHostCopyRequestTestCountTextures
size_t num_textures_with_readback_;
unsigned waited_sync_point_after_readback_;
FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> root_;
- scoped_refptr<FakeContentLayer> copy_layer_;
+ scoped_refptr<FakePictureLayer> root_;
+ scoped_refptr<FakePictureLayer> copy_layer_;
};
class LayerTreeHostCopyRequestTestCreatesTexture
@@ -763,7 +777,7 @@ class LayerTreeHostCopyRequestTestCreatesTexture
}
};
-SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
+SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
LayerTreeHostCopyRequestTestCreatesTexture);
class LayerTreeHostCopyRequestTestProvideTexture
@@ -816,17 +830,17 @@ class LayerTreeHostCopyRequestTestProvideTexture
unsigned sync_point_;
};
-SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
+SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
LayerTreeHostCopyRequestTestProvideTexture);
class LayerTreeHostCopyRequestTestDestroyBeforeCopy
: public LayerTreeHostCopyRequestTest {
protected:
void SetupTree() override {
- root_ = FakeContentLayer::Create(&client_);
+ root_ = FakePictureLayer::Create(layer_settings(), &client_);
root_->SetBounds(gfx::Size(20, 20));
- copy_layer_ = FakeContentLayer::Create(&client_);
+ copy_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
copy_layer_->SetBounds(gfx::Size(10, 10));
root_->AddChild(copy_layer_);
@@ -889,8 +903,8 @@ class LayerTreeHostCopyRequestTestDestroyBeforeCopy
int callback_count_;
FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> root_;
- scoped_refptr<FakeContentLayer> copy_layer_;
+ scoped_refptr<FakePictureLayer> root_;
+ scoped_refptr<FakePictureLayer> copy_layer_;
};
SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
@@ -900,10 +914,10 @@ class LayerTreeHostCopyRequestTestShutdownBeforeCopy
: public LayerTreeHostCopyRequestTest {
protected:
void SetupTree() override {
- root_ = FakeContentLayer::Create(&client_);
+ root_ = FakePictureLayer::Create(layer_settings(), &client_);
root_->SetBounds(gfx::Size(20, 20));
- copy_layer_ = FakeContentLayer::Create(&client_);
+ copy_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
copy_layer_->SetBounds(gfx::Size(10, 10));
root_->AddChild(copy_layer_);
@@ -960,8 +974,8 @@ class LayerTreeHostCopyRequestTestShutdownBeforeCopy
int callback_count_;
FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> root_;
- scoped_refptr<FakeContentLayer> copy_layer_;
+ scoped_refptr<FakePictureLayer> root_;
+ scoped_refptr<FakePictureLayer> copy_layer_;
};
SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
@@ -971,10 +985,11 @@ class LayerTreeHostCopyRequestTestMultipleDrawsHiddenCopyRequest
: public LayerTreeHostCopyRequestTest {
protected:
void SetupTree() override {
- scoped_refptr<FakeContentLayer> root = FakeContentLayer::Create(&client_);
+ scoped_refptr<FakePictureLayer> root =
+ FakePictureLayer::Create(layer_settings(), &client_);
root->SetBounds(gfx::Size(20, 20));
- child_ = FakeContentLayer::Create(&client_);
+ child_ = FakePictureLayer::Create(layer_settings(), &client_);
child_->SetBounds(gfx::Size(10, 10));
root->AddChild(child_);
child_->SetHideLayerAndSubtree(true);
@@ -1009,10 +1024,9 @@ class LayerTreeHostCopyRequestTestMultipleDrawsHiddenCopyRequest
bool saw_root = false;
bool saw_child = false;
- for (LayerIterator<LayerImpl> it = LayerIterator<LayerImpl>::Begin(
- frame_data->render_surface_layer_list);
- it != LayerIterator<LayerImpl>::End(
- frame_data->render_surface_layer_list);
+ for (LayerIterator it =
+ LayerIterator::Begin(frame_data->render_surface_layer_list);
+ it != LayerIterator::End(frame_data->render_surface_layer_list);
++it) {
if (it.represents_itself()) {
if (*it == root)
@@ -1073,7 +1087,7 @@ class LayerTreeHostCopyRequestTestMultipleDrawsHiddenCopyRequest
void AfterTest() override {}
- scoped_refptr<FakeContentLayer> child_;
+ scoped_refptr<FakePictureLayer> child_;
FakeContentLayerClient client_;
int num_draws_;
bool copy_happened_;
diff --git a/chromium/cc/trees/layer_tree_host_unittest_damage.cc b/chromium/cc/trees/layer_tree_host_unittest_damage.cc
index daff40beb2d..fc5cacf087e 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_damage.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_damage.cc
@@ -7,9 +7,8 @@
#include "base/bind.h"
#include "base/callback.h"
#include "base/location.h"
-#include "base/message_loop/message_loop_proxy.h"
#include "base/time/time.h"
-#include "cc/test/fake_content_layer.h"
+#include "cc/layers/solid_color_layer.h"
#include "cc/test/fake_content_layer_client.h"
#include "cc/test/fake_painted_scrollbar_layer.h"
#include "cc/test/fake_picture_layer.h"
@@ -28,7 +27,8 @@ class LayerTreeHostDamageTestSetNeedsRedraw
: public LayerTreeHostDamageTest {
void SetupTree() override {
// Viewport is 10x10.
- scoped_refptr<FakeContentLayer> root = FakeContentLayer::Create(&client_);
+ scoped_refptr<FakePictureLayer> root =
+ FakePictureLayer::Create(layer_settings(), &client_);
root->SetBounds(gfx::Size(10, 10));
layer_tree_host()->SetRootLayer(root);
@@ -89,7 +89,8 @@ class LayerTreeHostDamageTestSetViewportSize
: public LayerTreeHostDamageTest {
void SetupTree() override {
// Viewport is 10x10.
- scoped_refptr<FakeContentLayer> root = FakeContentLayer::Create(&client_);
+ scoped_refptr<FakePictureLayer> root =
+ FakePictureLayer::Create(layer_settings(), &client_);
root->SetBounds(gfx::Size(10, 10));
layer_tree_host()->SetRootLayer(root);
@@ -155,11 +156,12 @@ class LayerTreeHostDamageTestNoDamageDoesNotSwap
}
void SetupTree() override {
- scoped_refptr<FakeContentLayer> root = FakeContentLayer::Create(&client_);
+ scoped_refptr<FakePictureLayer> root =
+ FakePictureLayer::Create(layer_settings(), &client_);
root->SetBounds(gfx::Size(10, 10));
// Most of the layer isn't visible.
- content_ = FakeContentLayer::Create(&client_);
+ content_ = FakePictureLayer::Create(layer_settings(), &client_);
content_->SetBounds(gfx::Size(2000, 100));
root->AddChild(content_);
@@ -227,21 +229,20 @@ class LayerTreeHostDamageTestNoDamageDoesNotSwap
}
FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> content_;
+ scoped_refptr<FakePictureLayer> content_;
int expect_swap_and_succeed_;
int did_swaps_;
int did_swap_and_succeed_;
};
-SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(
- LayerTreeHostDamageTestNoDamageDoesNotSwap);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDamageTestNoDamageDoesNotSwap);
class LayerTreeHostDamageTestForcedFullDamage : public LayerTreeHostDamageTest {
void BeginTest() override { PostSetNeedsCommitToMainThread(); }
void SetupTree() override {
- root_ = FakeContentLayer::Create(&client_);
- child_ = FakeContentLayer::Create(&client_);
+ root_ = FakePictureLayer::Create(layer_settings(), &client_);
+ child_ = FakePictureLayer::Create(layer_settings(), &client_);
root_->SetBounds(gfx::Size(500, 500));
child_->SetPosition(gfx::Point(100, 100));
@@ -293,21 +294,6 @@ class LayerTreeHostDamageTestForcedFullDamage : public LayerTreeHostDamageTest {
// should match the invalidation.
EXPECT_EQ(gfx::RectF(100+10, 100+11, 12, 13).ToString(),
root_damage.ToString());
-
- // TODO(danakj): Remove this when impl side painting is always on.
- if (delegating_renderer() ||
- host_impl->settings().impl_side_painting) {
- // When using a delegating renderer, or using impl side painting, the
- // entire child is considered damaged as we need to replace its
- // resources with newly created ones. The damaged area is kept as it
- // is, but entire child is painted.
-
- // The paint rect should match the layer bounds.
- gfx::RectF paint_rect = child_->LastPaintRect();
- paint_rect.set_origin(child_->position());
- EXPECT_EQ(gfx::RectF(100, 100, 30, 30).ToString(),
- paint_rect.ToString());
- }
EXPECT_FALSE(frame_data->has_no_damage);
// If we damage part of the frame, but also damage the full
@@ -340,33 +326,35 @@ class LayerTreeHostDamageTestForcedFullDamage : public LayerTreeHostDamageTest {
void AfterTest() override {}
FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> root_;
- scoped_refptr<FakeContentLayer> child_;
+ scoped_refptr<FakePictureLayer> root_;
+ scoped_refptr<FakePictureLayer> child_;
gfx::Rect child_damage_rect_;
};
-SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostDamageTestForcedFullDamage);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDamageTestForcedFullDamage);
class LayerTreeHostScrollbarDamageTest : public LayerTreeHostDamageTest {
void SetupTree() override {
- scoped_refptr<Layer> root_layer = Layer::Create();
+ scoped_refptr<Layer> root_layer = Layer::Create(layer_settings());
root_layer->SetBounds(gfx::Size(400, 400));
root_layer->SetMasksToBounds(true);
layer_tree_host()->SetRootLayer(root_layer);
- scoped_refptr<Layer> scroll_clip_layer = Layer::Create();
- scoped_refptr<Layer> content_layer = FakeContentLayer::Create(&client_);
+ scoped_refptr<Layer> scroll_clip_layer = Layer::Create(layer_settings());
+ scoped_refptr<Layer> content_layer =
+ FakePictureLayer::Create(layer_settings(), &client_);
content_layer->SetScrollClipLayerId(scroll_clip_layer->id());
content_layer->SetScrollOffset(gfx::ScrollOffset(10, 20));
content_layer->SetBounds(gfx::Size(100, 200));
+ content_layer->SetIsDrawable(true);
scroll_clip_layer->SetBounds(
gfx::Size(content_layer->bounds().width() - 30,
content_layer->bounds().height() - 50));
scroll_clip_layer->AddChild(content_layer);
root_layer->AddChild(scroll_clip_layer);
- scoped_refptr<Layer> scrollbar_layer =
- FakePaintedScrollbarLayer::Create(false, true, content_layer->id());
+ scoped_refptr<Layer> scrollbar_layer = FakePaintedScrollbarLayer::Create(
+ layer_settings(), false, true, content_layer->id());
scrollbar_layer->SetPosition(gfx::Point(300, 300));
scrollbar_layer->SetBounds(gfx::Size(10, 100));
scrollbar_layer->ToScrollbarLayer()->SetClipLayer(scroll_clip_layer->id());
@@ -443,13 +431,25 @@ class LayerTreeHostDamageTestScrollbarDoesDamage
host_impl->SetNeedsRedraw();
break;
case 3:
- scroll_layer->SetBounds(gfx::Size(root->bounds().width() + 60,
- root->bounds().height() + 100));
- host_impl->SetNeedsRedraw();
+ // We will resize the content layer, on the main thread.
+ MainThreadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::Bind(
+ &LayerTreeHostDamageTestScrollbarDoesDamage::ResizeScrollLayer,
+ base::Unretained(this)));
break;
}
}
+ void ResizeScrollLayer() {
+ EXPECT_EQ(3, did_swaps_);
+ Layer* root = layer_tree_host()->root_layer();
+ Layer* scroll_clip_layer = root->child_at(0);
+ Layer* scroll_layer = scroll_clip_layer->child_at(0);
+ scroll_layer->SetBounds(
+ gfx::Size(root->bounds().width() + 60, root->bounds().height() + 100));
+ }
+
void AfterTest() override { EXPECT_EQ(4, did_swaps_); }
int did_swaps_;
diff --git a/chromium/cc/trees/layer_tree_host_unittest_delegated.cc b/chromium/cc/trees/layer_tree_host_unittest_delegated.cc
index 2864eb82ad6..2ebb337e807 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_delegated.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_delegated.cc
@@ -135,7 +135,7 @@ class LayerTreeHostDelegatedTest : public LayerTreeTest {
}
void AddTransferableResource(DelegatedFrameData* frame,
- ResourceProvider::ResourceId resource_id) {
+ ResourceId resource_id) {
TransferableResource resource;
resource.id = resource_id;
resource.mailbox_holder.texture_target = GL_TEXTURE_2D;
@@ -147,8 +147,7 @@ class LayerTreeHostDelegatedTest : public LayerTreeTest {
frame->resource_list.push_back(resource);
}
- void AddTextureQuad(DelegatedFrameData* frame,
- ResourceProvider::ResourceId resource_id) {
+ void AddTextureQuad(DelegatedFrameData* frame, ResourceId resource_id) {
RenderPass* render_pass = frame->render_pass_list[0];
SharedQuadState* sqs = render_pass->CreateAndAppendSharedQuadState();
TextureDrawQuad* quad =
@@ -201,9 +200,9 @@ class LayerTreeHostDelegatedTest : public LayerTreeTest {
background_filters);
}
- static ResourceProvider::ResourceId AppendResourceId(
- std::vector<ResourceProvider::ResourceId>* resources_in_last_sent_frame,
- ResourceProvider::ResourceId resource_id) {
+ static ResourceId AppendResourceId(
+ std::vector<ResourceId>* resources_in_last_sent_frame,
+ ResourceId resource_id) {
resources_in_last_sent_frame->push_back(resource_id);
return resource_id;
}
@@ -214,19 +213,18 @@ class LayerTreeHostDelegatedTest : public LayerTreeTest {
if (!delegated_frame_data)
return;
- std::vector<ResourceProvider::ResourceId> resources_in_last_sent_frame;
+ std::vector<ResourceId> resources_in_last_sent_frame;
for (size_t i = 0; i < delegated_frame_data->resource_list.size(); ++i) {
resources_in_last_sent_frame.push_back(
delegated_frame_data->resource_list[i].id);
}
- std::vector<ResourceProvider::ResourceId> resources_to_return;
+ std::vector<ResourceId> resources_to_return;
const TransferableResourceArray& resources_held_by_parent =
output_surface()->resources_held_by_parent();
for (size_t i = 0; i < resources_held_by_parent.size(); ++i) {
- ResourceProvider::ResourceId resource_in_parent =
- resources_held_by_parent[i].id;
+ ResourceId resource_in_parent = resources_held_by_parent[i].id;
bool resource_in_parent_is_not_part_of_frame =
std::find(resources_in_last_sent_frame.begin(),
resources_in_last_sent_frame.end(),
@@ -274,7 +272,7 @@ class LayerTreeHostDelegatedTestCaseSingleDelegatedLayer
}
void SetupTree() override {
- root_ = Layer::Create();
+ root_ = Layer::Create(layer_settings());
root_->SetBounds(gfx::Size(15, 15));
layer_tree_host()->SetRootLayer(root_);
@@ -310,7 +308,7 @@ class LayerTreeHostDelegatedTestCaseSingleDelegatedLayer
scoped_refptr<DelegatedRendererLayer> CreateDelegatedLayer(
DelegatedFrameProvider* frame_provider) {
scoped_refptr<DelegatedRendererLayer> delegated =
- FakeDelegatedRendererLayer::Create(frame_provider);
+ FakeDelegatedRendererLayer::Create(layer_settings(), frame_provider);
delegated->SetBounds(gfx::Size(10, 10));
delegated->SetIsDrawable(true);
@@ -432,7 +430,7 @@ class LayerTreeHostDelegatedTestDontUseLostChildIdAfterCommit
}
};
-MULTI_THREAD_IMPL_TEST_F(
+SINGLE_AND_MULTI_THREAD_TEST_F(
LayerTreeHostDelegatedTestDontUseLostChildIdAfterCommit);
// Test that we can gracefully handle invalid frames after the context was lost.
@@ -804,18 +802,18 @@ class LayerTreeHostDelegatedTestRemapResourcesInQuads
EXPECT_EQ(1u, map.count(999));
EXPECT_EQ(1u, map.count(555));
- ResourceProvider::ResourceId parent_resource_id1 = map.find(999)->second;
+ ResourceId parent_resource_id1 = map.find(999)->second;
EXPECT_NE(parent_resource_id1, 999u);
- ResourceProvider::ResourceId parent_resource_id2 = map.find(555)->second;
+ ResourceId parent_resource_id2 = map.find(555)->second;
EXPECT_NE(parent_resource_id2, 555u);
// The resources in the quads should be remapped to the parent's namespace.
const TextureDrawQuad* quad1 = TextureDrawQuad::MaterialCast(
delegated_impl->RenderPassesInDrawOrder()[0]->quad_list.ElementAt(0));
- EXPECT_EQ(parent_resource_id1, quad1->resource_id);
+ EXPECT_EQ(parent_resource_id1, quad1->resource_id());
const TextureDrawQuad* quad2 = TextureDrawQuad::MaterialCast(
delegated_impl->RenderPassesInDrawOrder()[0]->quad_list.ElementAt(1));
- EXPECT_EQ(parent_resource_id2, quad2->resource_id);
+ EXPECT_EQ(parent_resource_id2, quad2->resource_id());
EndTest();
}
@@ -1057,7 +1055,7 @@ class LayerTreeHostDelegatedTestFrameBeforeAck
EXPECT_EQ(1u, pass->quad_list.size());
const TextureDrawQuad* quad =
TextureDrawQuad::MaterialCast(pass->quad_list.front());
- EXPECT_EQ(map.find(999)->second, quad->resource_id);
+ EXPECT_EQ(map.find(999)->second, quad->resource_id());
EndTest();
}
@@ -1169,13 +1167,13 @@ class LayerTreeHostDelegatedTestFrameBeforeTakeResources
EXPECT_EQ(3u, pass->quad_list.size());
const TextureDrawQuad* quad1 =
TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(0));
- EXPECT_EQ(map.find(999)->second, quad1->resource_id);
+ EXPECT_EQ(map.find(999)->second, quad1->resource_id());
const TextureDrawQuad* quad2 =
TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(1));
- EXPECT_EQ(map.find(555)->second, quad2->resource_id);
+ EXPECT_EQ(map.find(555)->second, quad2->resource_id());
const TextureDrawQuad* quad3 =
TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(2));
- EXPECT_EQ(map.find(444)->second, quad3->resource_id);
+ EXPECT_EQ(map.find(444)->second, quad3->resource_id());
}
void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
@@ -1288,10 +1286,10 @@ class LayerTreeHostDelegatedTestBadFrame
EXPECT_EQ(2u, pass->quad_list.size());
const TextureDrawQuad* quad1 =
TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(0));
- EXPECT_EQ(map.find(999)->second, quad1->resource_id);
+ EXPECT_EQ(map.find(999)->second, quad1->resource_id());
const TextureDrawQuad* quad2 =
TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(1));
- EXPECT_EQ(map.find(555)->second, quad2->resource_id);
+ EXPECT_EQ(map.find(555)->second, quad2->resource_id());
break;
}
case 2: {
@@ -1310,10 +1308,10 @@ class LayerTreeHostDelegatedTestBadFrame
EXPECT_EQ(2u, pass->quad_list.size());
const TextureDrawQuad* quad1 =
TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(0));
- EXPECT_EQ(map.find(999)->second, quad1->resource_id);
+ EXPECT_EQ(map.find(999)->second, quad1->resource_id());
const TextureDrawQuad* quad2 =
TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(1));
- EXPECT_EQ(map.find(555)->second, quad2->resource_id);
+ EXPECT_EQ(map.find(555)->second, quad2->resource_id());
break;
}
case 3: {
@@ -1328,7 +1326,7 @@ class LayerTreeHostDelegatedTestBadFrame
EXPECT_EQ(1u, pass->quad_list.size());
const TextureDrawQuad* quad1 =
TextureDrawQuad::MaterialCast(pass->quad_list.front());
- EXPECT_EQ(map.find(999)->second, quad1->resource_id);
+ EXPECT_EQ(map.find(999)->second, quad1->resource_id());
break;
}
}
@@ -2288,7 +2286,8 @@ class LayerTreeHostDelegatedTestActiveFrameIsValid
bool drew_with_pending_tree_;
};
-MULTI_THREAD_IMPL_TEST_F(LayerTreeHostDelegatedTestActiveFrameIsValid);
+// This test blocks activation which is not supported for single thread mode.
+MULTI_THREAD_BLOCKNOTIFY_TEST_F(LayerTreeHostDelegatedTestActiveFrameIsValid);
} // namespace
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_unittest_no_message_loop.cc b/chromium/cc/trees/layer_tree_host_unittest_no_message_loop.cc
deleted file mode 100644
index ef948f70240..00000000000
--- a/chromium/cc/trees/layer_tree_host_unittest_no_message_loop.cc
+++ /dev/null
@@ -1,248 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/thread_task_runner_handle.h"
-#include "base/threading/simple_thread.h"
-#include "cc/layers/delegated_frame_provider.h"
-#include "cc/layers/delegated_frame_resource_collection.h"
-#include "cc/layers/delegated_renderer_layer.h"
-#include "cc/layers/layer.h"
-#include "cc/layers/solid_color_layer.h"
-#include "cc/output/delegated_frame_data.h"
-#include "cc/output/output_surface.h"
-#include "cc/output/output_surface_client.h"
-#include "cc/resources/resource_provider.h"
-#include "cc/scheduler/begin_frame_source.h"
-#include "cc/test/fake_delegated_renderer_layer.h"
-#include "cc/test/test_context_provider.h"
-#include "cc/trees/layer_tree_host.h"
-#include "cc/trees/layer_tree_host_client.h"
-#include "cc/trees/layer_tree_host_single_thread_client.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/core/SkColor.h"
-#include "ui/gfx/frame_time.h"
-
-namespace cc {
-namespace {
-
-class NoMessageLoopOutputSurface : public OutputSurface {
- public:
- NoMessageLoopOutputSurface() : OutputSurface(TestContextProvider::Create()) {}
- ~NoMessageLoopOutputSurface() override {}
-
- // OutputSurface overrides.
- void SwapBuffers(CompositorFrame* frame) override {
- DCHECK(client_);
- client_->DidSwapBuffers();
- client_->DidSwapBuffersComplete();
- }
-};
-
-class LayerTreeHostNoMessageLoopTest
- : public testing::Test,
- public base::DelegateSimpleThread::Delegate,
- public LayerTreeHostClient,
- public LayerTreeHostSingleThreadClient {
- public:
- LayerTreeHostNoMessageLoopTest()
- : did_initialize_output_surface_(false),
- did_commit_(false),
- did_commit_and_draw_frame_(false),
- size_(100, 100),
- no_loop_thread_(this, "LayerTreeHostNoMessageLoopTest") {}
- ~LayerTreeHostNoMessageLoopTest() override {}
-
- // LayerTreeHostClient overrides.
- void WillBeginMainFrame() override {}
- void BeginMainFrame(const BeginFrameArgs& args) override {}
- void BeginMainFrameNotExpectedSoon() override {}
- void DidBeginMainFrame() override {}
- void Layout() override {}
- void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta,
- const gfx::Vector2dF& outer_delta,
- const gfx::Vector2dF& elastic_overscroll_delta,
- float page_scale,
- float top_controls_delta) override {}
- void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
- float page_scale,
- float top_controls_delta) override {}
- void RequestNewOutputSurface() override {
- layer_tree_host_->SetOutputSurface(
- make_scoped_ptr<OutputSurface>(new NoMessageLoopOutputSurface));
- }
- void DidInitializeOutputSurface() override {
- did_initialize_output_surface_ = true;
- }
- void DidFailToInitializeOutputSurface() override {}
- void WillCommit() override {}
- void DidCommit() override { did_commit_ = true; }
- void DidCommitAndDrawFrame() override { did_commit_and_draw_frame_ = true; }
- void DidCompleteSwapBuffers() override {}
- void DidCompletePageScaleAnimation() override {}
-
- // LayerTreeHostSingleThreadClient overrides.
- void DidPostSwapBuffers() override {}
- void DidAbortSwapBuffers() override {}
-
- void RunTest() {
- no_loop_thread_.Start();
- no_loop_thread_.Join();
- }
-
- // base::DelegateSimpleThread::Delegate override.
- void Run() override {
- ASSERT_FALSE(base::ThreadTaskRunnerHandle::IsSet());
- RunTestWithoutMessageLoop();
- EXPECT_FALSE(base::ThreadTaskRunnerHandle::IsSet());
- }
-
- protected:
- virtual void RunTestWithoutMessageLoop() = 0;
-
- void SetupLayerTreeHost() {
- LayerTreeSettings settings;
- settings.single_thread_proxy_scheduler = false;
- settings.verify_property_trees = true;
- settings.raster_enabled = false;
-
- LayerTreeHost::InitParams params;
- params.client = this;
- params.settings = &settings;
- layer_tree_host_ = LayerTreeHost::CreateSingleThreaded(this, &params);
- layer_tree_host_->SetViewportSize(size_);
- layer_tree_host_->SetRootLayer(root_layer_);
- }
-
- void Composite() {
- did_commit_ = false;
- did_commit_and_draw_frame_ = false;
- layer_tree_host_->Composite(gfx::FrameTime::Now());
- EXPECT_TRUE(did_initialize_output_surface_);
- EXPECT_TRUE(did_commit_);
- EXPECT_TRUE(did_commit_and_draw_frame_);
- }
-
- void TearDownLayerTreeHost() {
- // Explicit teardown to make failures easier to debug.
- layer_tree_host_ = nullptr;
- root_layer_ = nullptr;
- }
-
- // All protected member variables are accessed only on |no_loop_thread_|.
- scoped_ptr<LayerTreeHost> layer_tree_host_;
- scoped_refptr<Layer> root_layer_;
-
- bool did_initialize_output_surface_;
- bool did_commit_;
- bool did_commit_and_draw_frame_;
- gfx::Size size_;
-
- private:
- base::DelegateSimpleThread no_loop_thread_;
-};
-
-class LayerTreeHostNoMessageLoopSmokeTest
- : public LayerTreeHostNoMessageLoopTest {
- protected:
- void RunTestWithoutMessageLoop() override {
- gfx::Size size(100, 100);
-
- // Set up root layer.
- {
- scoped_refptr<SolidColorLayer> solid_color_layer =
- SolidColorLayer::Create();
- solid_color_layer->SetBackgroundColor(SK_ColorRED);
- solid_color_layer->SetBounds(size_);
- solid_color_layer->SetIsDrawable(true);
- root_layer_ = solid_color_layer;
- }
-
- SetupLayerTreeHost();
- Composite();
- TearDownLayerTreeHost();
- }
-};
-
-TEST_F(LayerTreeHostNoMessageLoopSmokeTest, SmokeTest) {
- RunTest();
-}
-
-class LayerTreeHostNoMessageLoopDelegatedLayer
- : public LayerTreeHostNoMessageLoopTest,
- public DelegatedFrameResourceCollectionClient {
- protected:
- void RunTestWithoutMessageLoop() override {
- resource_collection_ = new DelegatedFrameResourceCollection;
- frame_provider_ = new DelegatedFrameProvider(
- resource_collection_.get(), CreateFrameDataWithResource(998));
-
- root_layer_ = Layer::Create();
- delegated_layer_ =
- FakeDelegatedRendererLayer::Create(frame_provider_.get());
- delegated_layer_->SetBounds(size_);
- delegated_layer_->SetIsDrawable(true);
- root_layer_->AddChild(delegated_layer_);
-
- SetupLayerTreeHost();
-
- // Draw first frame.
- Composite();
-
- // Prepare and draw second frame.
- frame_provider_->SetFrameData(CreateFrameDataWithResource(999));
- Composite();
-
- // Resource from first frame should be returned.
- CheckReturnedResource(1u);
-
- TearDownLayerTreeHost();
- delegated_layer_ = NULL;
- frame_provider_ = NULL;
-
- // Resource from second frame should be returned.
- CheckReturnedResource(1u);
- resource_collection_ = NULL;
- }
-
- // DelegatedFrameResourceCollectionClient overrides.
- void UnusedResourcesAreAvailable() override {}
-
- private:
- scoped_ptr<DelegatedFrameData> CreateFrameDataWithResource(
- ResourceProvider::ResourceId resource_id) {
- scoped_ptr<DelegatedFrameData> frame(new DelegatedFrameData);
- gfx::Rect frame_rect(size_);
-
- scoped_ptr<RenderPass> root_pass(RenderPass::Create());
- root_pass->SetNew(
- RenderPassId(1, 1), frame_rect, frame_rect, gfx::Transform());
- frame->render_pass_list.push_back(root_pass.Pass());
-
- TransferableResource resource;
- resource.id = resource_id;
- resource.mailbox_holder.texture_target = GL_TEXTURE_2D;
- resource.mailbox_holder.mailbox = gpu::Mailbox::Generate();
- frame->resource_list.push_back(resource);
-
- return frame.Pass();
- }
-
- void CheckReturnedResource(size_t expected_num) {
- ReturnedResourceArray returned_resources;
- resource_collection_->TakeUnusedResourcesForChildCompositor(
- &returned_resources);
- EXPECT_EQ(expected_num, returned_resources.size());
- }
-
- scoped_refptr<DelegatedFrameResourceCollection> resource_collection_;
- scoped_refptr<DelegatedFrameProvider> frame_provider_;
- scoped_refptr<DelegatedRendererLayer> delegated_layer_;
-};
-
-TEST_F(LayerTreeHostNoMessageLoopDelegatedLayer, SingleDelegatedLayer) {
- RunTest();
-}
-
-} // namespace
-} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc b/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc
index 9974ae4066b..37c56d1e74a 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc
@@ -30,11 +30,11 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnLayer
: public LayerTreeHostOcclusionTest {
public:
void SetupTree() override {
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
root->SetBounds(gfx::Size(100, 100));
root->SetIsDrawable(true);
- scoped_refptr<Layer> child = Layer::Create();
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
child->SetBounds(gfx::Size(50, 60));
child->SetPosition(gfx::PointF(10.f, 5.5f));
child->SetContentsOpaque(true);
@@ -76,18 +76,18 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnSurface
: public LayerTreeHostOcclusionTest {
public:
void SetupTree() override {
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
root->SetBounds(gfx::Size(100, 100));
root->SetIsDrawable(true);
- scoped_refptr<Layer> child = Layer::Create();
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
child->SetBounds(gfx::Size(1, 1));
child->SetPosition(gfx::PointF(10.f, 5.5f));
child->SetIsDrawable(true);
child->SetForceRenderSurface(true);
root->AddChild(child);
- scoped_refptr<Layer> child2 = Layer::Create();
+ scoped_refptr<Layer> child2 = Layer::Create(layer_settings());
child2->SetBounds(gfx::Size(10, 12));
child2->SetPosition(gfx::PointF(13.f, 8.5f));
child2->SetContentsOpaque(true);
@@ -128,28 +128,29 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnMask
: public LayerTreeHostOcclusionTest {
public:
void SetupTree() override {
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
root->SetBounds(gfx::Size(100, 100));
root->SetIsDrawable(true);
- scoped_refptr<Layer> child = Layer::Create();
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
child->SetBounds(gfx::Size(30, 40));
child->SetPosition(gfx::PointF(10.f, 5.5f));
child->SetIsDrawable(true);
root->AddChild(child);
- scoped_refptr<Layer> make_surface_bigger = Layer::Create();
+ scoped_refptr<Layer> make_surface_bigger = Layer::Create(layer_settings());
make_surface_bigger->SetBounds(gfx::Size(100, 100));
make_surface_bigger->SetPosition(gfx::PointF(-10.f, -15.f));
make_surface_bigger->SetIsDrawable(true);
child->AddChild(make_surface_bigger);
- scoped_refptr<Layer> mask = PictureLayer::Create(&client_);
+ scoped_refptr<Layer> mask =
+ PictureLayer::Create(layer_settings(), &client_);
mask->SetBounds(gfx::Size(30, 40));
mask->SetIsDrawable(true);
child->SetMaskLayer(mask.get());
- scoped_refptr<Layer> child2 = Layer::Create();
+ scoped_refptr<Layer> child2 = Layer::Create(layer_settings());
child2->SetBounds(gfx::Size(10, 12));
child2->SetPosition(gfx::PointF(13.f, 8.5f));
child2->SetContentsOpaque(true);
@@ -198,29 +199,30 @@ class LayerTreeHostOcclusionTestDrawPropertiesInsideReplica
: public LayerTreeHostOcclusionTest {
public:
void SetupTree() override {
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
root->SetBounds(gfx::Size(100, 100));
root->SetIsDrawable(true);
- scoped_refptr<Layer> child = Layer::Create();
+ scoped_refptr<Layer> child = Layer::Create(layer_settings());
child->SetBounds(gfx::Size(1, 1));
child->SetPosition(gfx::PointF(10.f, 5.5f));
child->SetIsDrawable(true);
child->SetForceRenderSurface(true);
root->AddChild(child);
- scoped_refptr<Layer> replica = Layer::Create();
+ scoped_refptr<Layer> replica = Layer::Create(layer_settings());
gfx::Transform translate;
translate.Translate(20.f, 4.f);
replica->SetTransform(translate);
child->SetReplicaLayer(replica.get());
- scoped_refptr<Layer> mask = PictureLayer::Create(&client_);
+ scoped_refptr<Layer> mask =
+ PictureLayer::Create(layer_settings(), &client_);
mask->SetBounds(gfx::Size(30, 40));
mask->SetIsDrawable(true);
child->SetMaskLayer(mask.get());
- scoped_refptr<Layer> child2 = Layer::Create();
+ scoped_refptr<Layer> child2 = Layer::Create(layer_settings());
child2->SetBounds(gfx::Size(10, 12));
child2->SetPosition(gfx::PointF(13.f, 8.5f));
child2->SetContentsOpaque(true);
diff --git a/chromium/cc/trees/layer_tree_host_unittest_picture.cc b/chromium/cc/trees/layer_tree_host_unittest_picture.cc
index 6f222f71e71..7a0d7bfa520 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_picture.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_picture.cc
@@ -17,10 +17,10 @@ namespace {
class LayerTreeHostPictureTest : public LayerTreeTest {
protected:
void SetupTreeWithSinglePictureLayer(const gfx::Size& size) {
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
root->SetBounds(size);
- root_picture_layer_ = FakePictureLayer::Create(&client_);
+ root_picture_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
root_picture_layer_->SetBounds(size);
root->AddChild(root_picture_layer_);
@@ -57,7 +57,7 @@ class LayerTreeHostPictureTestTwinLayer
// Add a new picture layer so the activate will have a pending layer
// without an active twin.
scoped_refptr<FakePictureLayer> picture =
- FakePictureLayer::Create(&client_);
+ FakePictureLayer::Create(layer_settings(), &client_);
layer_tree_host()->root_layer()->AddChild(picture);
break;
}
@@ -107,24 +107,16 @@ class LayerTreeHostPictureTestTwinLayer
active_picture_impl->GetPendingOrActiveTwinLayer());
EXPECT_EQ(active_picture_impl,
pending_picture_impl->GetPendingOrActiveTwinLayer());
- EXPECT_EQ(nullptr, active_picture_impl->GetRecycledTwinLayer());
}
void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
LayerImpl* active_root_impl = impl->active_tree()->root_layer();
- LayerImpl* recycle_root_impl = impl->recycle_tree()->root_layer();
-
if (active_root_impl->children().empty()) {
EXPECT_EQ(2, activates_);
} else {
FakePictureLayerImpl* active_picture_impl =
static_cast<FakePictureLayerImpl*>(active_root_impl->children()[0]);
- FakePictureLayerImpl* recycle_picture_impl =
- static_cast<FakePictureLayerImpl*>(recycle_root_impl->children()[0]);
-
EXPECT_EQ(nullptr, active_picture_impl->GetPendingOrActiveTwinLayer());
- EXPECT_EQ(recycle_picture_impl,
- active_picture_impl->GetRecycledTwinLayer());
}
++activates_;
@@ -136,7 +128,7 @@ class LayerTreeHostPictureTestTwinLayer
};
// There is no pending layers in single thread mode.
-MULTI_THREAD_IMPL_TEST_F(LayerTreeHostPictureTestTwinLayer);
+MULTI_THREAD_TEST_F(LayerTreeHostPictureTestTwinLayer);
class LayerTreeHostPictureTestResizeViewportWithGpuRaster
: public LayerTreeHostPictureTest {
@@ -145,11 +137,11 @@ class LayerTreeHostPictureTestResizeViewportWithGpuRaster
}
void SetupTree() override {
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
root->SetBounds(gfx::Size(768, 960));
client_.set_fill_with_nonsolid_color(true);
- picture_ = FakePictureLayer::Create(&client_);
+ picture_ = FakePictureLayer::Create(layer_settings(), &client_);
picture_->SetBounds(gfx::Size(768, 960));
root->AddChild(picture_);
@@ -199,7 +191,7 @@ class LayerTreeHostPictureTestResizeViewportWithGpuRaster
scoped_refptr<FakePictureLayer> picture_;
};
-SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(
+SINGLE_AND_MULTI_THREAD_TEST_F(
LayerTreeHostPictureTestResizeViewportWithGpuRaster);
class LayerTreeHostPictureTestChangeLiveTilesRectWithRecycleTree
@@ -208,13 +200,13 @@ class LayerTreeHostPictureTestChangeLiveTilesRectWithRecycleTree
frame_ = 0;
did_post_commit_ = false;
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
root->SetBounds(gfx::Size(100, 100));
// The layer is big enough that the live tiles rect won't cover the full
// layer.
client_.set_fill_with_nonsolid_color(true);
- picture_ = FakePictureLayer::Create(&client_);
+ picture_ = FakePictureLayer::Create(layer_settings(), &client_);
picture_->SetBounds(gfx::Size(100, 100000));
root->AddChild(picture_);
@@ -228,13 +220,9 @@ class LayerTreeHostPictureTestChangeLiveTilesRectWithRecycleTree
LayerImpl* child = impl->active_tree()->root_layer()->children()[0];
FakePictureLayerImpl* picture_impl =
static_cast<FakePictureLayerImpl*>(child);
- FakePictureLayerImpl* recycled_impl = static_cast<FakePictureLayerImpl*>(
- picture_impl->GetRecycledTwinLayer());
-
switch (++frame_) {
case 1: {
PictureLayerTiling* tiling = picture_impl->HighResTiling();
- PictureLayerTiling* recycled_tiling = recycled_impl->HighResTiling();
int num_tiles_y = tiling->TilingDataForTesting().num_tiles_y();
// There should be tiles at the top of the picture layer but not at the
@@ -242,52 +230,34 @@ class LayerTreeHostPictureTestChangeLiveTilesRectWithRecycleTree
EXPECT_TRUE(tiling->TileAt(0, 0));
EXPECT_FALSE(tiling->TileAt(0, num_tiles_y));
- // The recycled tiling has no tiles.
- EXPECT_FALSE(recycled_tiling->TileAt(0, 0));
- EXPECT_FALSE(recycled_tiling->TileAt(0, num_tiles_y));
-
- // The live tiles rect matches on the recycled tree.
- EXPECT_EQ(tiling->live_tiles_rect(),
- recycled_tiling->live_tiles_rect());
-
// Make the bottom of the layer visible.
- picture_impl->SetPosition(gfx::PointF(0.f, -100000.f + 100.f));
+ gfx::Transform transform;
+ transform.Translate(0.f, -100000.f + 100.f);
+ picture_impl->SetTransform(transform);
+ picture_impl->UpdatePropertyTreeTransform();
impl->SetNeedsRedraw();
break;
}
case 2: {
PictureLayerTiling* tiling = picture_impl->HighResTiling();
- PictureLayerTiling* recycled_tiling = recycled_impl->HighResTiling();
// There not be tiles at the top of the layer now.
EXPECT_FALSE(tiling->TileAt(0, 0));
- // The recycled twin tiling should not have unshared tiles at the top
- // either.
- EXPECT_FALSE(recycled_tiling->TileAt(0, 0));
-
// Make the top of the layer visible again.
- picture_impl->SetPosition(gfx::PointF());
+ picture_impl->SetTransform(gfx::Transform());
+ picture_impl->UpdatePropertyTreeTransform();
impl->SetNeedsRedraw();
break;
}
case 3: {
PictureLayerTiling* tiling = picture_impl->HighResTiling();
- PictureLayerTiling* recycled_tiling = recycled_impl->HighResTiling();
int num_tiles_y = tiling->TilingDataForTesting().num_tiles_y();
// There should be tiles at the top of the picture layer again.
EXPECT_TRUE(tiling->TileAt(0, 0));
EXPECT_FALSE(tiling->TileAt(0, num_tiles_y));
- // The recycled tiling should have no tiles.
- EXPECT_FALSE(recycled_tiling->TileAt(0, 0));
- EXPECT_FALSE(recycled_tiling->TileAt(0, num_tiles_y));
-
- // The live tiles rect matches on the recycled tree.
- EXPECT_EQ(tiling->live_tiles_rect(),
- recycled_tiling->live_tiles_rect());
-
// Make a new main frame without changing the picture layer at all, so
// it won't need to update or push properties.
did_post_commit_ = true;
@@ -328,20 +298,19 @@ class LayerTreeHostPictureTestChangeLiveTilesRectWithRecycleTree
};
// Multi-thread only since there is no recycle tree in single thread.
-MULTI_THREAD_IMPL_TEST_F(
- LayerTreeHostPictureTestChangeLiveTilesRectWithRecycleTree);
+MULTI_THREAD_TEST_F(LayerTreeHostPictureTestChangeLiveTilesRectWithRecycleTree);
class LayerTreeHostPictureTestRSLLMembership : public LayerTreeHostPictureTest {
void SetupTree() override {
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
root->SetBounds(gfx::Size(100, 100));
- child_ = Layer::Create();
+ child_ = Layer::Create(layer_settings());
root->AddChild(child_);
// Don't be solid color so the layer has tilings/tiles.
client_.set_fill_with_nonsolid_color(true);
- picture_ = FakePictureLayer::Create(&client_);
+ picture_ = FakePictureLayer::Create(layer_settings(), &client_);
picture_->SetBounds(gfx::Size(100, 100));
child_->AddChild(picture_);
@@ -417,15 +386,15 @@ class LayerTreeHostPictureTestRSLLMembership : public LayerTreeHostPictureTest {
scoped_refptr<FakePictureLayer> picture_;
};
-SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostPictureTestRSLLMembership);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostPictureTestRSLLMembership);
class LayerTreeHostPictureTestRSLLMembershipWithScale
: public LayerTreeHostPictureTest {
void SetupTree() override {
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
root->SetBounds(gfx::Size(100, 100));
- pinch_ = Layer::Create();
+ pinch_ = Layer::Create(layer_settings());
pinch_->SetBounds(gfx::Size(500, 500));
pinch_->SetScrollClipLayerId(root->id());
pinch_->SetIsContainerForFixedPositionLayers(true);
@@ -433,7 +402,7 @@ class LayerTreeHostPictureTestRSLLMembershipWithScale
// Don't be solid color so the layer has tilings/tiles.
client_.set_fill_with_nonsolid_color(true);
- picture_ = FakePictureLayer::Create(&client_);
+ picture_ = FakePictureLayer::Create(layer_settings(), &client_);
picture_->SetBounds(gfx::Size(100, 100));
pinch_->AddChild(picture_);
@@ -568,7 +537,7 @@ class LayerTreeHostPictureTestRSLLMembershipWithScale
// Multi-thread only because in single thread you can't pinch zoom on the
// compositor thread.
// Disabled due to flakiness. See http://crbug.com/460581
-// MULTI_THREAD_IMPL_TEST_F(LayerTreeHostPictureTestRSLLMembershipWithScale);
+// MULTI_THREAD_TEST_F(LayerTreeHostPictureTestRSLLMembershipWithScale);
} // namespace
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_unittest_proxy.cc b/chromium/cc/trees/layer_tree_host_unittest_proxy.cc
index 313510371e7..66340e7bbff 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_proxy.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_proxy.cc
@@ -7,16 +7,8 @@
#include "cc/test/layer_tree_test.h"
#include "cc/trees/thread_proxy.h"
-#define THREAD_PROXY_NO_IMPL_TEST_F(TEST_FIXTURE_NAME) \
- TEST_F(TEST_FIXTURE_NAME, Run_MainThreadPaint) { \
- Run(true, false); \
- }
-
-#define THREAD_PROXY_TEST_F(TEST_FIXTURE_NAME) \
- THREAD_PROXY_NO_IMPL_TEST_F(TEST_FIXTURE_NAME); \
- TEST_F(TEST_FIXTURE_NAME, Run_ImplSidePaint) { \
- Run(true, true); \
- }
+#define THREAD_PROXY_TEST_F(TEST_FIXTURE_NAME) \
+ TEST_F(TEST_FIXTURE_NAME, MultiThread) { Run(true); }
// Do common tests for single thread proxy and thread proxy.
// TODO(simonhong): Add SINGLE_THREAD_PROXY_TEST_F
@@ -30,11 +22,11 @@ class ProxyTest : public LayerTreeTest {
ProxyTest() {}
~ProxyTest() override {}
- void Run(bool threaded, bool impl_side_painting) {
+ void Run(bool threaded) {
// We don't need to care about delegating mode.
bool delegating_renderer = true;
- RunTest(threaded, delegating_renderer, impl_side_painting);
+ RunTest(threaded, delegating_renderer);
}
void BeginTest() override {}
diff --git a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc
index 4e77a2d245f..dc075b563cf 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -19,6 +19,7 @@
#include "cc/test/geometry_test_utils.h"
#include "cc/test/layer_tree_test.h"
#include "cc/test/test_shared_bitmap_manager.h"
+#include "cc/test/test_task_graph_runner.h"
#include "cc/trees/layer_tree_impl.h"
#include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/geometry/size_conversions.h"
@@ -39,7 +40,7 @@ class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest {
void BeginTest() override {
Layer* root_layer = layer_tree_host()->root_layer();
- scoped_refptr<Layer> scroll_layer = Layer::Create();
+ scoped_refptr<Layer> scroll_layer = Layer::Create(layer_settings());
root_layer->AddChild(scroll_layer);
// Create an effective max_scroll_offset of (100, 100).
scroll_layer->SetBounds(gfx::Size(root_layer->bounds().width() + 100,
@@ -92,7 +93,9 @@ class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest {
}
}
- void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
+ void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta,
+ const gfx::Vector2dF& outer_delta,
+ const gfx::Vector2dF& elastic_overscroll_delta,
float scale,
float top_controls_delta) override {
num_scrolls_++;
@@ -117,7 +120,7 @@ class LayerTreeHostScrollTestScrollMultipleRedraw
void BeginTest() override {
Layer* root_layer = layer_tree_host()->root_layer();
- scroll_layer_ = Layer::Create();
+ scroll_layer_ = Layer::Create(layer_settings());
root_layer->AddChild(scroll_layer_);
// Create an effective max_scroll_offset of (100, 100).
scroll_layer_->SetBounds(gfx::Size(root_layer->bounds().width() + 100,
@@ -154,7 +157,7 @@ class LayerTreeHostScrollTestScrollMultipleRedraw
LayerImpl* scroll_layer =
impl->active_tree()->LayerById(scroll_layer_->id());
if (impl->active_tree()->source_frame_number() == 0 &&
- impl->SourceAnimationFrameNumber() == 1) {
+ impl->SourceAnimationFrameNumberForTesting() == 1) {
// First draw after first commit.
EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2d());
scroll_layer->ScrollBy(scroll_amount_);
@@ -163,7 +166,7 @@ class LayerTreeHostScrollTestScrollMultipleRedraw
EXPECT_VECTOR_EQ(scroll_layer->BaseScrollOffset(), initial_scroll_);
PostSetNeedsRedrawToMainThread();
} else if (impl->active_tree()->source_frame_number() == 0 &&
- impl->SourceAnimationFrameNumber() == 2) {
+ impl->SourceAnimationFrameNumberForTesting() == 2) {
// Second draw after first commit.
EXPECT_EQ(scroll_layer->ScrollDelta(), scroll_amount_);
scroll_layer->ScrollBy(scroll_amount_);
@@ -174,7 +177,7 @@ class LayerTreeHostScrollTestScrollMultipleRedraw
PostSetNeedsCommitToMainThread();
} else if (impl->active_tree()->source_frame_number() == 1) {
// Third or later draw after second commit.
- EXPECT_GE(impl->SourceAnimationFrameNumber(), 3);
+ EXPECT_GE(impl->SourceAnimationFrameNumberForTesting(), 3u);
EXPECT_VECTOR_EQ(scroll_layer_->ScrollDelta(), gfx::Vector2d());
EXPECT_VECTOR_EQ(
scroll_layer_->scroll_offset(),
@@ -184,7 +187,9 @@ class LayerTreeHostScrollTestScrollMultipleRedraw
}
}
- void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
+ void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta,
+ const gfx::Vector2dF& outer_delta,
+ const gfx::Vector2dF& elastic_overscroll_delta,
float scale,
float top_controls_delta) override {
num_scrolls_++;
@@ -221,7 +226,7 @@ class LayerTreeHostScrollTestScrollAbortedCommit
void SetupTree() override {
LayerTreeHostScrollTest::SetupTree();
Layer* root_layer = layer_tree_host()->root_layer();
- scoped_refptr<Layer> root_scroll_layer = Layer::Create();
+ scoped_refptr<Layer> root_scroll_layer = Layer::Create(layer_settings());
root_scroll_layer->SetScrollClipLayerId(root_layer->id());
root_scroll_layer->SetScrollOffset(initial_scroll_);
root_scroll_layer->SetBounds(gfx::Size(200, 200));
@@ -301,7 +306,7 @@ class LayerTreeHostScrollTestScrollAbortedCommit
impl->active_tree()->root_layer()->children()[0];
if (impl->active_tree()->source_frame_number() == 0 &&
- impl->SourceAnimationFrameNumber() == 1) {
+ impl->SourceAnimationFrameNumberForTesting() == 1) {
// First draw
EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d());
root_scroll_layer->ScrollBy(impl_scroll_);
@@ -317,7 +322,7 @@ class LayerTreeHostScrollTestScrollAbortedCommit
// To simplify the testing flow, don't redraw here, just commit.
impl->SetNeedsCommit();
} else if (impl->active_tree()->source_frame_number() == 0 &&
- impl->SourceAnimationFrameNumber() == 2) {
+ impl->SourceAnimationFrameNumberForTesting() == 2) {
// Test a second draw after an aborted commit.
// The scroll/scale values should be baked into the offset/scale factor
// since the main thread consumed but aborted the begin frame.
@@ -340,7 +345,7 @@ class LayerTreeHostScrollTestScrollAbortedCommit
// Commit for source frame 1 is aborted.
NOTREACHED();
} else if (impl->active_tree()->source_frame_number() == 2 &&
- impl->SourceAnimationFrameNumber() == 3) {
+ impl->SourceAnimationFrameNumberForTesting() == 3) {
// Third draw after the second full commit.
EXPECT_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d());
root_scroll_layer->ScrollBy(impl_scroll_);
@@ -350,7 +355,7 @@ class LayerTreeHostScrollTestScrollAbortedCommit
EXPECT_VECTOR_EQ(root_scroll_layer->BaseScrollOffset(),
gfx::ScrollOffsetWithDelta(initial_scroll_, delta));
} else if (impl->active_tree()->source_frame_number() == 2 &&
- impl->SourceAnimationFrameNumber() == 4) {
+ impl->SourceAnimationFrameNumberForTesting() == 4) {
// Final draw after the second aborted commit.
EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d());
gfx::Vector2dF delta =
@@ -364,7 +369,9 @@ class LayerTreeHostScrollTestScrollAbortedCommit
}
}
- void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
+ void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta,
+ const gfx::Vector2dF& outer_delta,
+ const gfx::Vector2dF& elastic_overscroll_delta,
float scale,
float top_controls_delta) override {
num_impl_scrolls_++;
@@ -403,7 +410,7 @@ class LayerTreeHostScrollTestFractionalScroll : public LayerTreeHostScrollTest {
void SetupTree() override {
LayerTreeHostScrollTest::SetupTree();
Layer* root_layer = layer_tree_host()->root_layer();
- scoped_refptr<Layer> root_scroll_layer = Layer::Create();
+ scoped_refptr<Layer> root_scroll_layer = Layer::Create(layer_settings());
root_scroll_layer->SetScrollClipLayerId(root_layer->id());
root_scroll_layer->SetBounds(
gfx::Size(root_layer->bounds().width() + 100,
@@ -470,10 +477,11 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest {
void SetupTree() override {
layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_);
- scoped_refptr<Layer> root_layer = Layer::Create();
+ scoped_refptr<Layer> root_layer = Layer::Create(layer_settings());
root_layer->SetBounds(gfx::Size(10, 10));
- root_scroll_layer_ = FakePictureLayer::Create(&fake_content_layer_client_);
+ root_scroll_layer_ =
+ FakePictureLayer::Create(layer_settings(), &fake_content_layer_client_);
root_scroll_layer_->SetBounds(gfx::Size(110, 110));
root_scroll_layer_->SetPosition(gfx::Point());
@@ -483,7 +491,8 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest {
root_scroll_layer_->SetIsContainerForFixedPositionLayers(true);
root_layer->AddChild(root_scroll_layer_);
- child_layer_ = FakePictureLayer::Create(&fake_content_layer_client_);
+ child_layer_ =
+ FakePictureLayer::Create(layer_settings(), &fake_content_layer_client_);
child_layer_->set_did_scroll_callback(
base::Bind(&LayerTreeHostScrollTestCaseWithChild::DidScroll,
base::Unretained(this)));
@@ -534,7 +543,9 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest {
final_scroll_offset_ = expected_scroll_layer_->scroll_offset();
}
- void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
+ void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta,
+ const gfx::Vector2dF& outer_delta,
+ const gfx::Vector2dF& elastic_overscroll_delta,
float scale,
float top_controls_delta) override {
num_scrolls_++;
@@ -670,101 +681,89 @@ TEST_F(LayerTreeHostScrollTestCaseWithChild,
DeviceScaleFactor1_ScrollChild_DirectRenderer) {
device_scale_factor_ = 1.f;
scroll_child_layer_ = true;
- RunTest(true, false, true);
+ RunTest(true, false);
}
TEST_F(LayerTreeHostScrollTestCaseWithChild,
DeviceScaleFactor1_ScrollChild_DelegatingRenderer) {
device_scale_factor_ = 1.f;
scroll_child_layer_ = true;
- RunTest(true, true, true);
+ RunTest(true, true);
}
TEST_F(LayerTreeHostScrollTestCaseWithChild,
DeviceScaleFactor15_ScrollChild_DirectRenderer) {
device_scale_factor_ = 1.5f;
scroll_child_layer_ = true;
- RunTest(true, false, true);
+ RunTest(true, false);
}
TEST_F(LayerTreeHostScrollTestCaseWithChild,
DeviceScaleFactor15_ScrollChild_DelegatingRenderer) {
device_scale_factor_ = 1.5f;
scroll_child_layer_ = true;
- RunTest(true, true, true);
+ RunTest(true, true);
}
TEST_F(LayerTreeHostScrollTestCaseWithChild,
DeviceScaleFactor2_ScrollChild_DirectRenderer) {
device_scale_factor_ = 2.f;
scroll_child_layer_ = true;
- RunTest(true, false, true);
+ RunTest(true, false);
}
TEST_F(LayerTreeHostScrollTestCaseWithChild,
DeviceScaleFactor2_ScrollChild_DelegatingRenderer) {
device_scale_factor_ = 2.f;
scroll_child_layer_ = true;
- RunTest(true, true, true);
+ RunTest(true, true);
}
TEST_F(LayerTreeHostScrollTestCaseWithChild,
DeviceScaleFactor1_ScrollRootScrollLayer_DirectRenderer) {
device_scale_factor_ = 1.f;
scroll_child_layer_ = false;
- RunTest(true, false, true);
+ RunTest(true, false);
}
TEST_F(LayerTreeHostScrollTestCaseWithChild,
DeviceScaleFactor1_ScrollRootScrollLayer_DelegatingRenderer) {
device_scale_factor_ = 1.f;
scroll_child_layer_ = false;
- RunTest(true, true, true);
+ RunTest(true, true);
}
TEST_F(LayerTreeHostScrollTestCaseWithChild,
DeviceScaleFactor15_ScrollRootScrollLayer_DirectRenderer) {
device_scale_factor_ = 1.5f;
scroll_child_layer_ = false;
- RunTest(true, false, true);
+ RunTest(true, false);
}
TEST_F(LayerTreeHostScrollTestCaseWithChild,
DeviceScaleFactor15_ScrollRootScrollLayer_DelegatingRenderer) {
device_scale_factor_ = 1.5f;
scroll_child_layer_ = false;
- RunTest(true, true, true);
+ RunTest(true, true);
}
TEST_F(LayerTreeHostScrollTestCaseWithChild,
DeviceScaleFactor2_ScrollRootScrollLayer_DirectRenderer) {
device_scale_factor_ = 2.f;
scroll_child_layer_ = false;
- RunTest(true, false, true);
+ RunTest(true, false);
}
TEST_F(LayerTreeHostScrollTestCaseWithChild,
DeviceScaleFactor2_ScrollRootScrollLayer_DelegatingRenderer) {
device_scale_factor_ = 2.f;
scroll_child_layer_ = false;
- RunTest(true, true, true);
+ RunTest(true, true);
}
-class ImplSidePaintingScrollTest : public LayerTreeHostScrollTest {
+class LayerTreeHostScrollTestSimple : public LayerTreeHostScrollTest {
public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->impl_side_painting = true;
- }
-
- void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
- if (impl->pending_tree())
- impl->SetNeedsRedraw();
- }
-};
-
-class ImplSidePaintingScrollTestSimple : public ImplSidePaintingScrollTest {
- public:
- ImplSidePaintingScrollTestSimple()
+ LayerTreeHostScrollTestSimple()
: initial_scroll_(10, 20),
main_thread_scroll_(40, 5),
impl_thread_scroll1_(2, -1),
@@ -774,7 +773,7 @@ class ImplSidePaintingScrollTestSimple : public ImplSidePaintingScrollTest {
void SetupTree() override {
LayerTreeHostScrollTest::SetupTree();
Layer* root_layer = layer_tree_host()->root_layer();
- scoped_refptr<Layer> root_scroll_layer = Layer::Create();
+ scoped_refptr<Layer> root_scroll_layer = Layer::Create(layer_settings());
root_scroll_layer->SetScrollClipLayerId(root_layer->id());
root_scroll_layer->SetScrollOffset(initial_scroll_);
root_scroll_layer->SetBounds(
@@ -817,7 +816,8 @@ class ImplSidePaintingScrollTestSimple : public ImplSidePaintingScrollTest {
}
void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
- ImplSidePaintingScrollTest::DrawLayersOnThread(impl);
+ if (impl->pending_tree())
+ impl->SetNeedsRedraw();
LayerImpl* root = impl->active_tree()->root_layer();
LayerImpl* scroll_layer = root->children()[0];
@@ -868,7 +868,9 @@ class ImplSidePaintingScrollTestSimple : public ImplSidePaintingScrollTest {
}
}
- void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
+ void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta,
+ const gfx::Vector2dF& outer_delta,
+ const gfx::Vector2dF& elastic_overscroll_delta,
float scale,
float top_controls_delta) override {
num_scrolls_++;
@@ -884,22 +886,22 @@ class ImplSidePaintingScrollTestSimple : public ImplSidePaintingScrollTest {
int num_scrolls_;
};
-MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestSimple);
+// This tests scrolling on the impl side which is only possible with a thread.
+MULTI_THREAD_TEST_F(LayerTreeHostScrollTestSimple);
// This test makes sure that layers pick up scrolls that occur between
// beginning a commit and finishing a commit (aka scroll deltas not
// included in sent scroll delta) still apply to layers that don't
// push properties.
-class ImplSidePaintingScrollTestImplOnlyScroll
- : public ImplSidePaintingScrollTest {
+class LayerTreeHostScrollTestImplOnlyScroll : public LayerTreeHostScrollTest {
public:
- ImplSidePaintingScrollTestImplOnlyScroll()
+ LayerTreeHostScrollTestImplOnlyScroll()
: initial_scroll_(20, 10), impl_thread_scroll_(-2, 3), impl_scale_(2.f) {}
void SetupTree() override {
LayerTreeHostScrollTest::SetupTree();
Layer* root_layer = layer_tree_host()->root_layer();
- scoped_refptr<Layer> root_scroll_layer = Layer::Create();
+ scoped_refptr<Layer> root_scroll_layer = Layer::Create(layer_settings());
root_scroll_layer->SetScrollClipLayerId(root_layer->id());
root_scroll_layer->SetScrollOffset(initial_scroll_);
root_scroll_layer->SetBounds(
@@ -986,7 +988,8 @@ class ImplSidePaintingScrollTestImplOnlyScroll
}
void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
- ImplSidePaintingScrollTest::DrawLayersOnThread(impl);
+ if (impl->pending_tree())
+ impl->SetNeedsRedraw();
LayerImpl* root = impl->active_tree()->root_layer();
LayerImpl* scroll_layer = root->children()[0];
@@ -1024,7 +1027,8 @@ class ImplSidePaintingScrollTestImplOnlyScroll
float impl_scale_;
};
-MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestImplOnlyScroll);
+// This tests scrolling on the impl side which is only possible with a thread.
+MULTI_THREAD_TEST_F(LayerTreeHostScrollTestImplOnlyScroll);
class LayerTreeHostScrollTestScrollZeroMaxScrollOffset
: public LayerTreeHostScrollTest {
@@ -1033,7 +1037,7 @@ class LayerTreeHostScrollTestScrollZeroMaxScrollOffset
void SetupTree() override {
LayerTreeTest::SetupTree();
- scoped_refptr<Layer> scroll_layer = Layer::Create();
+ scoped_refptr<Layer> scroll_layer = Layer::Create(layer_settings());
layer_tree_host()->root_layer()->AddChild(scroll_layer);
}
@@ -1126,13 +1130,14 @@ TEST(LayerTreeHostFlingTest, DidStopFlingingThread) {
impl_thread.task_runner().get(), &received_stop_flinging);
FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
- ASSERT_TRUE(impl_thread.task_runner().get());
- scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
- new TestSharedBitmapManager());
+ ASSERT_TRUE(impl_thread.task_runner());
+ TestSharedBitmapManager shared_bitmap_manager;
+ TestTaskGraphRunner task_graph_runner;
LayerTreeHost::InitParams params;
params.client = &client;
- params.shared_bitmap_manager = shared_bitmap_manager.get();
+ params.shared_bitmap_manager = &shared_bitmap_manager;
+ params.task_graph_runner = &task_graph_runner;
params.settings = &settings;
params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
scoped_ptr<LayerTreeHost> layer_tree_host =
@@ -1156,7 +1161,7 @@ class LayerTreeHostScrollTestLayerStructureChange
: scroll_destroy_whole_tree_(false) {}
void SetupTree() override {
- scoped_refptr<Layer> root_layer = Layer::Create();
+ scoped_refptr<Layer> root_layer = Layer::Create(layer_settings());
root_layer->SetBounds(gfx::Size(10, 10));
Layer* root_scroll_layer =
@@ -1208,7 +1213,7 @@ class LayerTreeHostScrollTestLayerStructureChange
Layer* CreateScrollLayer(Layer* parent, FakeLayerScrollClient* client) {
scoped_refptr<PictureLayer> scroll_layer =
- PictureLayer::Create(&fake_content_layer_client_);
+ PictureLayer::Create(layer_settings(), &fake_content_layer_client_);
scroll_layer->SetBounds(gfx::Size(110, 110));
scroll_layer->SetPosition(gfx::Point(0, 0));
scroll_layer->SetIsDrawable(true);
@@ -1233,12 +1238,12 @@ class LayerTreeHostScrollTestLayerStructureChange
};
TEST_F(LayerTreeHostScrollTestLayerStructureChange, ScrollDestroyLayer) {
- RunTest(true, false, true);
+ RunTest(true, false);
}
TEST_F(LayerTreeHostScrollTestLayerStructureChange, ScrollDestroyWholeTree) {
scroll_destroy_whole_tree_ = true;
- RunTest(true, false, true);
+ RunTest(true, false);
}
} // namespace
diff --git a/chromium/cc/trees/layer_tree_host_unittest_video.cc b/chromium/cc/trees/layer_tree_host_unittest_video.cc
index ffeda727fe3..31854ac68a9 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_video.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_video.cc
@@ -23,12 +23,12 @@ class LayerTreeHostVideoTestSetNeedsDisplay
: public LayerTreeHostVideoTest {
public:
void SetupTree() override {
- scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> root = Layer::Create(layer_settings());
root->SetBounds(gfx::Size(10, 10));
root->SetIsDrawable(true);
- scoped_refptr<VideoLayer> video =
- VideoLayer::Create(&video_frame_provider_, media::VIDEO_ROTATION_90);
+ scoped_refptr<VideoLayer> video = VideoLayer::Create(
+ layer_settings(), &video_frame_provider_, media::VIDEO_ROTATION_90);
video->SetPosition(gfx::PointF(3.f, 3.f));
video->SetBounds(gfx::Size(4, 5));
video->SetIsDrawable(true);
diff --git a/chromium/cc/trees/layer_tree_impl.cc b/chromium/cc/trees/layer_tree_impl.cc
index 01a4cfd19ec..d4d2dee7f23 100644
--- a/chromium/cc/trees/layer_tree_impl.cc
+++ b/chromium/cc/trees/layer_tree_impl.cc
@@ -10,13 +10,13 @@
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"
+#include "cc/animation/animation_host.h"
#include "cc/animation/keyframed_animation_curve.h"
#include "cc/animation/scrollbar_animation_controller.h"
#include "cc/animation/scrollbar_animation_controller_linear_fade.h"
#include "cc/animation/scrollbar_animation_controller_thinning.h"
#include "cc/base/math_util.h"
#include "cc/base/synced_property.h"
-#include "cc/base/util.h"
#include "cc/debug/devtools_instrumentation.h"
#include "cc/debug/traced_value.h"
#include "cc/input/layer_scroll_offset_delegate.h"
@@ -30,6 +30,9 @@
#include "cc/trees/layer_tree_host_common.h"
#include "cc/trees/layer_tree_host_impl.h"
#include "cc/trees/occlusion_tracker.h"
+#include "cc/trees/property_tree.h"
+#include "cc/trees/property_tree_builder.h"
+#include "ui/gfx/geometry/box_f.h"
#include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/geometry/vector2d_conversions.h"
@@ -57,7 +60,6 @@ LayerTreeImpl::LayerTreeImpl(
max_page_scale_factor_(0),
elastic_overscroll_(elastic_overscroll),
scrolling_layer_id_from_previous_tree_(0),
- contents_textures_purged_(false),
viewport_size_invalid_(false),
needs_update_draw_properties_(true),
needs_full_tree_sync_(true),
@@ -112,9 +114,9 @@ void LayerTreeImpl::GatherFrameTimingRequestIds(
});
}
-bool LayerTreeImpl::IsExternalFlingActive() const {
+bool LayerTreeImpl::IsExternalScrollActive() const {
return root_layer_scroll_offset_delegate_ &&
- root_layer_scroll_offset_delegate_->IsExternalFlingActive();
+ root_layer_scroll_offset_delegate_->IsExternalScrollActive();
}
void LayerTreeImpl::DidUpdateScrollOffset(int layer_id) {
@@ -189,6 +191,40 @@ scoped_ptr<LayerImpl> LayerTreeImpl::DetachLayerTree() {
return root_layer_.Pass();
}
+static void UpdateClipTreeForBoundsDeltaOnLayer(LayerImpl* layer,
+ ClipTree* clip_tree) {
+ if (layer && layer->masks_to_bounds()) {
+ ClipNode* clip_node = clip_tree->Node(layer->clip_tree_index());
+ if (clip_node) {
+ DCHECK_EQ(layer->id(), clip_node->owner_id);
+ gfx::Size bounds = layer->bounds();
+ if (clip_node->data.clip.size() != bounds) {
+ clip_node->data.clip.set_size(bounds);
+ clip_tree->set_needs_update(true);
+ }
+ }
+ }
+}
+
+void LayerTreeImpl::UpdatePropertyTreesForBoundsDelta() {
+ DCHECK(IsActiveTree());
+ LayerImpl* inner_container = InnerViewportContainerLayer();
+ LayerImpl* outer_container = OuterViewportContainerLayer();
+
+ UpdateClipTreeForBoundsDeltaOnLayer(inner_container,
+ &property_trees_.clip_tree);
+ UpdateClipTreeForBoundsDeltaOnLayer(InnerViewportScrollLayer(),
+ &property_trees_.clip_tree);
+ UpdateClipTreeForBoundsDeltaOnLayer(outer_container,
+ &property_trees_.clip_tree);
+
+ TransformTree& transform_tree = property_trees_.transform_tree;
+ if (inner_container)
+ transform_tree.SetInnerViewportBoundsDelta(inner_container->bounds_delta());
+ if (outer_container)
+ transform_tree.SetOuterViewportBoundsDelta(outer_container->bounds_delta());
+}
+
void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) {
// The request queue should have been processed and does not require a push.
DCHECK_EQ(ui_resource_request_queue_.size(), 0u);
@@ -235,11 +271,6 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) {
target_tree->set_background_color(background_color());
target_tree->set_has_transparent_background(has_transparent_background());
- if (ContentsTexturesPurged())
- target_tree->SetContentsTexturesPurged();
- else
- target_tree->ResetContentsTexturesPurged();
-
if (ViewportSizeInvalid())
target_tree->SetViewportSizeInvalid();
else
@@ -313,6 +344,21 @@ float LayerTreeImpl::ClampPageScaleFactorToLimits(
return page_scale_factor;
}
+void LayerTreeImpl::UpdatePropertyTreeScrollingAndAnimationFromMainThread() {
+ // TODO(enne): This should get replaced by pulling out scrolling and
+ // animations into their own trees. Then scrolls and animations would have
+ // their own ways of synchronizing across commits. This occurs to push
+ // updates from scrolling deltas on the compositor thread that have occurred
+ // after begin frame and updates from animations that have ticked since begin
+ // frame to a newly-committed property tree.
+ if (!root_layer())
+ return;
+ LayerTreeHostCommon::CallFunctionForSubtree(
+ root_layer(), [](LayerImpl* layer) {
+ layer->UpdatePropertyTreeForScrollingAndAnimationIfNeeded();
+ });
+}
+
void LayerTreeImpl::SetPageScaleOnActiveTree(float active_page_scale) {
DCHECK(IsActiveTree());
if (page_scale_factor()->SetCurrent(
@@ -334,11 +380,21 @@ void LayerTreeImpl::PushPageScaleFactorAndLimits(const float* page_scale_factor,
bool changed_page_scale = false;
if (page_scale_factor) {
DCHECK(!IsActiveTree() || !layer_tree_host_impl_->pending_tree());
+ changed_page_scale |= page_scale_factor_->Delta() != 1.f;
+ // TODO(enne): Once CDP goes away, ignore this call below. The only time
+ // the property trees will differ is if there's been a page scale on the
+ // compositor thread after the begin frame, which is the delta check above.
changed_page_scale |=
page_scale_factor_->PushFromMainThread(*page_scale_factor);
}
- if (IsActiveTree())
+ if (IsActiveTree()) {
+ // TODO(enne): Pushing from pending to active should never require
+ // DidUpdatePageScale. The values should already be set by the fully
+ // computed property trees being synced from one tree to another. Remove
+ // this once CDP goes away.
changed_page_scale |= page_scale_factor_->PushPendingToActive();
+ }
+
changed_page_scale |=
SetPageScaleFactorLimits(min_page_scale_factor, max_page_scale_factor);
@@ -414,6 +470,21 @@ void LayerTreeImpl::DidUpdatePageScale() {
max_page_scale_factor_);
}
+ if (page_scale_layer() && page_scale_layer()->transform_tree_index() != -1) {
+ TransformNode* node = property_trees_.transform_tree.Node(
+ page_scale_layer()->transform_tree_index());
+ node->data.post_local_scale_factor = current_page_scale_factor();
+ node->data.needs_local_transform_update = true;
+ // TODO(enne): property trees can't ask the layer these things, but
+ // the page scale layer should *just* be the page scale.
+ DCHECK_EQ(page_scale_layer()->position().ToString(),
+ gfx::PointF().ToString());
+ DCHECK_EQ(page_scale_layer()->transform_origin().ToString(),
+ gfx::Point3F().ToString());
+ node->data.update_post_local_transform(gfx::PointF(), gfx::Point3F());
+ property_trees_.transform_tree.set_needs_update(true);
+ }
+
ForceScrollbarParameterUpdateAfterScaleChange(page_scale_layer());
HideInnerViewportScrollbarsIfNearMinimumScale();
@@ -464,7 +535,7 @@ gfx::Rect LayerTreeImpl::RootScrollLayerDeviceViewportBounds() const {
return gfx::Rect();
LayerImpl* layer = root_scroll_layer->children()[0];
return MathUtil::MapEnclosingClippedRect(layer->screen_space_transform(),
- gfx::Rect(layer->content_bounds()));
+ gfx::Rect(layer->bounds()));
}
void LayerTreeImpl::ApplySentScrollAndScaleDeltasFromAbortedCommit() {
@@ -547,6 +618,7 @@ bool LayerTreeImpl::UpdateDrawProperties(bool update_lcd_text) {
root_layer(), DrawViewportSize(),
layer_tree_host_impl_->DrawTransform(), device_scale_factor(),
current_page_scale_factor(), page_scale_layer,
+ inner_viewport_scroll_layer_, outer_viewport_scroll_layer_,
elastic_overscroll()->Current(IsActiveTree()),
overscroll_elasticity_layer_, resource_provider()->max_texture_size(),
settings().can_use_lcd_text, settings().layers_always_allowed_lcd_text,
@@ -561,7 +633,7 @@ bool LayerTreeImpl::UpdateDrawProperties(bool update_lcd_text) {
TRACE_EVENT2("cc", "LayerTreeImpl::UpdateDrawProperties::Occlusion",
"IsActive", IsActiveTree(), "SourceFrameNumber",
source_frame_number_);
- OcclusionTracker<LayerImpl> occlusion_tracker(
+ OcclusionTracker occlusion_tracker(
root_layer()->render_surface()->content_rect());
occlusion_tracker.set_minimum_tracking_size(
settings().minimum_occlusion_tracking_size);
@@ -569,8 +641,8 @@ bool LayerTreeImpl::UpdateDrawProperties(bool update_lcd_text) {
// LayerIterator is used here instead of CallFunctionForSubtree to only
// UpdateTilePriorities on layers that will be visible (and thus have valid
// draw properties) and not because any ordering is required.
- auto end = LayerIterator<LayerImpl>::End(&render_surface_layer_list_);
- for (auto it = LayerIterator<LayerImpl>::Begin(&render_surface_layer_list_);
+ LayerIterator end = LayerIterator::End(&render_surface_layer_list_);
+ for (LayerIterator it = LayerIterator::Begin(&render_surface_layer_list_);
it != end; ++it) {
occlusion_tracker.EnterLayer(it);
@@ -678,6 +750,14 @@ bool LayerTreeImpl::UpdateDrawProperties(bool update_lcd_text) {
return true;
}
+void LayerTreeImpl::BuildPropertyTreesForTesting() {
+ PropertyTreeBuilder::BuildPropertyTrees(
+ root_layer_.get(), page_scale_layer_, inner_viewport_scroll_layer_,
+ outer_viewport_scroll_layer_, current_page_scale_factor(),
+ device_scale_factor(), gfx::Rect(DrawViewportSize()),
+ layer_tree_host_impl_->DrawTransform(), &property_trees_);
+}
+
const LayerImplList& LayerTreeImpl::RenderSurfaceLayerList() const {
// If this assert triggers, then the list is dirty.
DCHECK(!needs_update_draw_properties_);
@@ -700,18 +780,26 @@ gfx::Size LayerTreeImpl::ScrollableSize() const {
return root_scroll_layer->children()[0]->bounds();
}
-LayerImpl* LayerTreeImpl::LayerById(int id) {
- LayerIdMap::iterator iter = layer_id_map_.find(id);
+LayerImpl* LayerTreeImpl::LayerById(int id) const {
+ LayerIdMap::const_iterator iter = layer_id_map_.find(id);
return iter != layer_id_map_.end() ? iter->second : NULL;
}
void LayerTreeImpl::RegisterLayer(LayerImpl* layer) {
DCHECK(!LayerById(layer->id()));
layer_id_map_[layer->id()] = layer;
+ if (layer_tree_host_impl_->animation_host())
+ layer_tree_host_impl_->animation_host()->RegisterLayer(
+ layer->id(),
+ IsActiveTree() ? LayerTreeType::ACTIVE : LayerTreeType::PENDING);
}
void LayerTreeImpl::UnregisterLayer(LayerImpl* layer) {
DCHECK(LayerById(layer->id()));
+ if (layer_tree_host_impl_->animation_host())
+ layer_tree_host_impl_->animation_host()->UnregisterLayer(
+ layer->id(),
+ IsActiveTree() ? LayerTreeType::ACTIVE : LayerTreeType::PENDING);
layer_id_map_.erase(layer->id());
}
@@ -751,24 +839,6 @@ void LayerTreeImpl::DidBecomeActive() {
source_frame_number_);
}
-bool LayerTreeImpl::ContentsTexturesPurged() const {
- return contents_textures_purged_;
-}
-
-void LayerTreeImpl::SetContentsTexturesPurged() {
- if (contents_textures_purged_)
- return;
- contents_textures_purged_ = true;
- layer_tree_host_impl_->OnCanDrawStateChangedForTree();
-}
-
-void LayerTreeImpl::ResetContentsTexturesPurged() {
- if (!contents_textures_purged_)
- return;
- contents_textures_purged_ = false;
- layer_tree_host_impl_->OnCanDrawStateChangedForTree();
-}
-
bool LayerTreeImpl::RequiresHighResToDraw() const {
return layer_tree_host_impl_->RequiresHighResToDraw();
}
@@ -881,8 +951,8 @@ BeginFrameArgs LayerTreeImpl::CurrentBeginFrameArgs() const {
return layer_tree_host_impl_->CurrentBeginFrameArgs();
}
-base::TimeDelta LayerTreeImpl::begin_impl_frame_interval() const {
- return layer_tree_host_impl_->begin_impl_frame_interval();
+base::TimeDelta LayerTreeImpl::CurrentBeginFrameInterval() const {
+ return layer_tree_host_impl_->CurrentBeginFrameInterval();
}
void LayerTreeImpl::SetNeedsCommit() {
@@ -960,12 +1030,9 @@ AnimationRegistrar* LayerTreeImpl::GetAnimationRegistrar() const {
void LayerTreeImpl::GetAllPrioritizedTilesForTracing(
std::vector<PrioritizedTile>* prioritized_tiles) const {
- typedef LayerIterator<LayerImpl> LayerIteratorType;
- LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list_);
- for (LayerIteratorType it =
- LayerIteratorType::Begin(&render_surface_layer_list_);
- it != end;
- ++it) {
+ LayerIterator end = LayerIterator::End(&render_surface_layer_list_);
+ for (LayerIterator it = LayerIterator::Begin(&render_surface_layer_list_);
+ it != end; ++it) {
if (!it.represents_itself())
continue;
LayerImpl* layer_impl = *it;
@@ -982,10 +1049,9 @@ void LayerTreeImpl::AsValueInto(base::trace_event::TracedValue* state) const {
state->EndDictionary();
state->BeginArray("render_surface_layer_list");
- typedef LayerIterator<LayerImpl> LayerIteratorType;
- LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list_);
- for (LayerIteratorType it = LayerIteratorType::Begin(
- &render_surface_layer_list_); it != end; ++it) {
+ LayerIterator end = LayerIterator::End(&render_surface_layer_list_);
+ for (LayerIterator it = LayerIterator::Begin(&render_surface_layer_list_);
+ it != end; ++it) {
if (!it.represents_itself())
continue;
TracedValue::AppendIDRef(*it, state);
@@ -1075,9 +1141,9 @@ void LayerTreeImpl::QueueSwapPromise(scoped_ptr<SwapPromise> swap_promise) {
void LayerTreeImpl::PassSwapPromises(
ScopedPtrVector<SwapPromise>* new_swap_promise) {
- // Any left over promises have failed to swap before the next frame.
- BreakSwapPromises(SwapPromise::SWAP_FAILS);
- swap_promise_list_.swap(*new_swap_promise);
+ swap_promise_list_.insert_and_take(swap_promise_list_.end(),
+ new_swap_promise);
+ new_swap_promise->clear();
}
void LayerTreeImpl::FinishSwapPromises(CompositorFrameMetadata* metadata) {
@@ -1101,8 +1167,7 @@ void LayerTreeImpl::set_ui_resource_request_queue(
ui_resource_request_queue_ = queue;
}
-ResourceProvider::ResourceId LayerTreeImpl::ResourceIdForUIResource(
- UIResourceId uid) const {
+ResourceId LayerTreeImpl::ResourceIdForUIResource(UIResourceId uid) const {
return layer_tree_host_impl_->ResourceIdForUIResource(uid);
}
@@ -1238,9 +1303,7 @@ static bool PointHitsRect(
static bool PointHitsRegion(const gfx::PointF& screen_space_point,
const gfx::Transform& screen_space_transform,
- const Region& layer_space_region,
- float layer_content_scale_x,
- float layer_content_scale_y) {
+ const Region& layer_space_region) {
// If the transform is not invertible, then assume that this point doesn't hit
// this region.
gfx::Transform inverse_screen_space_transform(
@@ -1251,12 +1314,8 @@ static bool PointHitsRegion(const gfx::PointF& screen_space_point,
// Transform the hit test point from screen space to the local space of the
// given region.
bool clipped = false;
- gfx::PointF hit_test_point_in_content_space = MathUtil::ProjectPoint(
+ gfx::PointF hit_test_point_in_layer_space = MathUtil::ProjectPoint(
inverse_screen_space_transform, screen_space_point, &clipped);
- gfx::PointF hit_test_point_in_layer_space =
- gfx::ScalePoint(hit_test_point_in_content_space,
- 1.f / layer_content_scale_x,
- 1.f / layer_content_scale_y);
// If ProjectPoint could not project to a valid value, then we assume that
// this point doesn't hit this region.
@@ -1289,10 +1348,8 @@ static bool PointIsClippedBySurfaceOrClipRect(
return true;
if (LayerClipsSubtree(layer) &&
- !PointHitsRect(screen_space_point,
- layer->screen_space_transform(),
- gfx::Rect(layer->content_bounds()),
- NULL))
+ !PointHitsRect(screen_space_point, layer->screen_space_transform(),
+ gfx::Rect(layer->bounds()), NULL))
return true;
}
@@ -1304,7 +1361,7 @@ static bool PointIsClippedBySurfaceOrClipRect(
static bool PointHitsLayer(const LayerImpl* layer,
const gfx::PointF& screen_space_point,
float* distance_to_intersection) {
- gfx::RectF content_rect(layer->content_bounds());
+ gfx::RectF content_rect(layer->bounds());
if (!PointHitsRect(screen_space_point,
layer->screen_space_transform(),
content_rect,
@@ -1340,9 +1397,11 @@ static void FindClosestMatchingLayer(
LayerImpl* layer,
const Functor& func,
FindClosestMatchingLayerDataForRecursion* data_for_recursion) {
- for (int i = layer->children().size() - 1; i >= 0; --i) {
- FindClosestMatchingLayer(
- screen_space_point, layer->children()[i], func, data_for_recursion);
+ size_t children_size = layer->children().size();
+ for (size_t i = 0; i < children_size; ++i) {
+ size_t index = children_size - 1 - i;
+ FindClosestMatchingLayer(screen_space_point, layer->children()[index], func,
+ data_for_recursion);
}
float distance_to_intersection = 0.f;
@@ -1358,7 +1417,7 @@ static void FindClosestMatchingLayer(
static bool ScrollsAnyDrawnRenderSurfaceLayerListMember(LayerImpl* layer) {
if (!layer->scrollable())
return false;
- if (layer->draw_properties().layer_or_descendant_is_drawn)
+ if (layer->layer_or_descendant_is_drawn())
return true;
if (!layer->scroll_children())
@@ -1367,7 +1426,7 @@ static bool ScrollsAnyDrawnRenderSurfaceLayerListMember(LayerImpl* layer) {
layer->scroll_children()->begin();
it != layer->scroll_children()->end();
++it) {
- if ((*it)->draw_properties().layer_or_descendant_is_drawn)
+ if ((*it)->layer_or_descendant_is_drawn())
return true;
}
return false;
@@ -1418,11 +1477,8 @@ static bool LayerHasTouchEventHandlersAt(const gfx::PointF& screen_space_point,
if (layer_impl->touch_event_handler_region().IsEmpty())
return false;
- if (!PointHitsRegion(screen_space_point,
- layer_impl->screen_space_transform(),
- layer_impl->touch_event_handler_region(),
- layer_impl->contents_scale_x(),
- layer_impl->contents_scale_y()))
+ if (!PointHitsRegion(screen_space_point, layer_impl->screen_space_transform(),
+ layer_impl->touch_event_handler_region()))
return false;
// At this point, we think the point does hit the touch event handler region
@@ -1490,18 +1546,14 @@ static ViewportSelectionBound ComputeViewportSelectionBound(
if (!layer || layer_bound.type == SELECTION_BOUND_EMPTY)
return viewport_bound;
- gfx::PointF layer_scaled_top = gfx::ScalePoint(layer_bound.edge_top,
- layer->contents_scale_x(),
- layer->contents_scale_y());
- gfx::PointF layer_scaled_bottom = gfx::ScalePoint(layer_bound.edge_bottom,
- layer->contents_scale_x(),
- layer->contents_scale_y());
+ gfx::PointF layer_top = layer_bound.edge_top;
+ gfx::PointF layer_bottom = layer_bound.edge_bottom;
bool clipped = false;
- gfx::PointF screen_top = MathUtil::MapPoint(
- layer->screen_space_transform(), layer_scaled_top, &clipped);
+ gfx::PointF screen_top =
+ MathUtil::MapPoint(layer->screen_space_transform(), layer_top, &clipped);
gfx::PointF screen_bottom = MathUtil::MapPoint(
- layer->screen_space_transform(), layer_scaled_bottom, &clipped);
+ layer->screen_space_transform(), layer_bottom, &clipped);
const float inv_scale = 1.f / device_scale_factor;
viewport_bound.edge_top = gfx::ScalePoint(screen_top, inv_scale);
@@ -1512,9 +1564,9 @@ static ViewportSelectionBound ComputeViewportSelectionBound(
// Shifting the visibility point fractionally inward ensures that neighboring
// or logically coincident layers aligned to integral DPI coordinates will not
// spuriously occlude the bound.
- gfx::Vector2dF visibility_offset = layer_scaled_top - layer_scaled_bottom;
+ gfx::Vector2dF visibility_offset = layer_top - layer_bottom;
visibility_offset.Scale(device_scale_factor / visibility_offset.Length());
- gfx::PointF visibility_point = layer_scaled_bottom + visibility_offset;
+ gfx::PointF visibility_point = layer_bottom + visibility_offset;
if (visibility_point.x() <= 0)
visibility_point.set_x(visibility_point.x() + device_scale_factor);
visibility_point = MathUtil::MapPoint(
@@ -1574,4 +1626,131 @@ scoped_ptr<PendingPageScaleAnimation>
return pending_page_scale_animation_.Pass();
}
+bool LayerTreeImpl::IsAnimatingFilterProperty(const LayerImpl* layer) const {
+ return layer_tree_host_impl_->animation_host()
+ ? layer_tree_host_impl_->animation_host()
+ ->IsAnimatingFilterProperty(layer->id())
+ : false;
+}
+
+bool LayerTreeImpl::IsAnimatingOpacityProperty(const LayerImpl* layer) const {
+ return layer_tree_host_impl_->animation_host()
+ ? layer_tree_host_impl_->animation_host()
+ ->IsAnimatingOpacityProperty(layer->id())
+ : false;
+}
+
+bool LayerTreeImpl::IsAnimatingTransformProperty(const LayerImpl* layer) const {
+ return layer_tree_host_impl_->animation_host()
+ ? layer_tree_host_impl_->animation_host()
+ ->IsAnimatingTransformProperty(layer->id())
+ : false;
+}
+
+bool LayerTreeImpl::HasPotentiallyRunningOpacityAnimation(
+ const LayerImpl* layer) const {
+ return layer_tree_host_impl_->animation_host()
+ ? layer_tree_host_impl_->animation_host()
+ ->HasPotentiallyRunningOpacityAnimation(layer->id())
+ : false;
+}
+
+bool LayerTreeImpl::HasPotentiallyRunningTransformAnimation(
+ const LayerImpl* layer) const {
+ return layer_tree_host_impl_->animation_host()
+ ? layer_tree_host_impl_->animation_host()
+ ->HasPotentiallyRunningTransformAnimation(layer->id())
+ : false;
+}
+
+bool LayerTreeImpl::FilterIsAnimatingOnImplOnly(const LayerImpl* layer) const {
+ return layer_tree_host_impl_->animation_host()
+ ? layer_tree_host_impl_->animation_host()
+ ->FilterIsAnimatingOnImplOnly(layer->id())
+ : false;
+}
+
+bool LayerTreeImpl::OpacityIsAnimatingOnImplOnly(const LayerImpl* layer) const {
+ return layer_tree_host_impl_->animation_host()
+ ? layer_tree_host_impl_->animation_host()
+ ->OpacityIsAnimatingOnImplOnly(layer->id())
+ : false;
+}
+
+bool LayerTreeImpl::TransformIsAnimatingOnImplOnly(
+ const LayerImpl* layer) const {
+ return layer_tree_host_impl_->animation_host()
+ ? layer_tree_host_impl_->animation_host()
+ ->TransformIsAnimatingOnImplOnly(layer->id())
+ : false;
+}
+
+bool LayerTreeImpl::HasOnlyTranslationTransforms(const LayerImpl* layer) const {
+ return layer_tree_host_impl_->animation_host()
+ ? layer_tree_host_impl_->animation_host()
+ ->HasOnlyTranslationTransforms(layer->id())
+ : true;
+}
+
+bool LayerTreeImpl::MaximumTargetScale(const LayerImpl* layer,
+ float* max_scale) const {
+ *max_scale = 0.f;
+ return layer_tree_host_impl_->animation_host()
+ ? layer_tree_host_impl_->animation_host()->MaximumTargetScale(
+ layer->id(), max_scale)
+ : true;
+}
+
+bool LayerTreeImpl::AnimationStartScale(const LayerImpl* layer,
+ float* start_scale) const {
+ *start_scale = 0.f;
+ return layer_tree_host_impl_->animation_host()
+ ? layer_tree_host_impl_->animation_host()->AnimationStartScale(
+ layer->id(), start_scale)
+ : true;
+}
+
+bool LayerTreeImpl::HasFilterAnimationThatInflatesBounds(
+ const LayerImpl* layer) const {
+ return layer_tree_host_impl_->animation_host()
+ ? layer_tree_host_impl_->animation_host()
+ ->HasFilterAnimationThatInflatesBounds(layer->id())
+ : false;
+}
+
+bool LayerTreeImpl::HasTransformAnimationThatInflatesBounds(
+ const LayerImpl* layer) const {
+ return layer_tree_host_impl_->animation_host()
+ ? layer_tree_host_impl_->animation_host()
+ ->HasTransformAnimationThatInflatesBounds(layer->id())
+ : false;
+}
+
+bool LayerTreeImpl::HasAnimationThatInflatesBounds(
+ const LayerImpl* layer) const {
+ return layer_tree_host_impl_->animation_host()
+ ? layer_tree_host_impl_->animation_host()
+ ->HasAnimationThatInflatesBounds(layer->id())
+ : false;
+}
+
+bool LayerTreeImpl::FilterAnimationBoundsForBox(const LayerImpl* layer,
+ const gfx::BoxF& box,
+ gfx::BoxF* bounds) const {
+ return layer_tree_host_impl_->animation_host()
+ ? layer_tree_host_impl_->animation_host()
+ ->FilterAnimationBoundsForBox(layer->id(), box, bounds)
+ : false;
+}
+
+bool LayerTreeImpl::TransformAnimationBoundsForBox(const LayerImpl* layer,
+ const gfx::BoxF& box,
+ gfx::BoxF* bounds) const {
+ *bounds = gfx::BoxF();
+ return layer_tree_host_impl_->animation_host()
+ ? layer_tree_host_impl_->animation_host()
+ ->TransformAnimationBoundsForBox(layer->id(), box, bounds)
+ : true;
+}
+
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_impl.h b/chromium/cc/trees/layer_tree_impl.h
index 9c1b5b942db..973df977733 100644
--- a/chromium/cc/trees/layer_tree_impl.h
+++ b/chromium/cc/trees/layer_tree_impl.h
@@ -96,7 +96,7 @@ class CC_EXPORT LayerTreeImpl {
LayerImpl* FindPendingTreeLayerById(int id);
bool PinchGestureActive() const;
BeginFrameArgs CurrentBeginFrameArgs() const;
- base::TimeDelta begin_impl_frame_interval() const;
+ base::TimeDelta CurrentBeginFrameInterval() const;
void SetNeedsCommit();
gfx::Rect DeviceViewport() const;
gfx::Size DrawViewportSize() const;
@@ -131,7 +131,11 @@ class CC_EXPORT LayerTreeImpl {
void SetPropertyTrees(const PropertyTrees& property_trees) {
property_trees_ = property_trees;
+ property_trees_.transform_tree.set_source_to_parent_updates_allowed(false);
}
+ PropertyTrees* property_trees() { return &property_trees_; }
+
+ void UpdatePropertyTreesForBoundsDelta();
void PushPropertiesTo(LayerTreeImpl* tree_impl);
@@ -178,6 +182,7 @@ class CC_EXPORT LayerTreeImpl {
has_transparent_background_ = transparent;
}
+ void UpdatePropertyTreeScrollingAndAnimationFromMainThread();
void SetPageScaleOnActiveTree(float active_page_scale);
void PushPageScaleFromMainThread(float page_scale_factor,
float min_page_scale_factor,
@@ -211,6 +216,7 @@ class CC_EXPORT LayerTreeImpl {
// priorities. Returns false if it was unable to update. Updating lcd
// text may cause invalidations, so should only be done after a commit.
bool UpdateDrawProperties(bool update_lcd_text);
+ void BuildPropertyTreesForTesting();
void set_needs_update_draw_properties() {
needs_update_draw_properties_ = true;
@@ -241,7 +247,7 @@ class CC_EXPORT LayerTreeImpl {
gfx::Rect RootScrollLayerDeviceViewportBounds() const;
- LayerImpl* LayerById(int id);
+ LayerImpl* LayerById(int id) const;
// These should be called by LayerImpl's ctor/dtor.
void RegisterLayer(LayerImpl* layer);
@@ -255,10 +261,6 @@ class CC_EXPORT LayerTreeImpl {
void DidBecomeActive();
- bool ContentsTexturesPurged() const;
- void SetContentsTexturesPurged();
- void ResetContentsTexturesPurged();
-
// Set on the active tree when the viewport size recently changed
// and the active tree's size is now out of date.
bool ViewportSizeInvalid() const;
@@ -286,7 +288,7 @@ class CC_EXPORT LayerTreeImpl {
void DidModifyTilePriorities();
- ResourceProvider::ResourceId ResourceIdForUIResource(UIResourceId uid) const;
+ ResourceId ResourceIdForUIResource(UIResourceId uid) const;
void ProcessUIResourceRequestQueue();
bool IsUIResourceOpaque(UIResourceId uid) const;
@@ -340,9 +342,36 @@ class CC_EXPORT LayerTreeImpl {
void GatherFrameTimingRequestIds(std::vector<int64_t>* request_ids);
- bool IsExternalFlingActive() const;
+ bool IsExternalScrollActive() const;
void DidUpdateScrollOffset(int layer_id);
+ bool IsAnimatingFilterProperty(const LayerImpl* layer) const;
+ bool IsAnimatingOpacityProperty(const LayerImpl* layer) const;
+ bool IsAnimatingTransformProperty(const LayerImpl* layer) const;
+
+ bool HasPotentiallyRunningOpacityAnimation(const LayerImpl* layer) const;
+ bool HasPotentiallyRunningTransformAnimation(const LayerImpl* layer) const;
+
+ bool FilterIsAnimatingOnImplOnly(const LayerImpl* layer) const;
+ bool OpacityIsAnimatingOnImplOnly(const LayerImpl* layer) const;
+ bool TransformIsAnimatingOnImplOnly(const LayerImpl* layer) const;
+
+ bool HasOnlyTranslationTransforms(const LayerImpl* layer) const;
+
+ bool MaximumTargetScale(const LayerImpl* layer, float* max_scale) const;
+ bool AnimationStartScale(const LayerImpl* layer, float* start_scale) const;
+
+ bool HasFilterAnimationThatInflatesBounds(const LayerImpl* layer) const;
+ bool HasTransformAnimationThatInflatesBounds(const LayerImpl* layer) const;
+ bool HasAnimationThatInflatesBounds(const LayerImpl* layer) const;
+
+ bool FilterAnimationBoundsForBox(const LayerImpl* layer,
+ const gfx::BoxF& box,
+ gfx::BoxF* bounds) const;
+ bool TransformAnimationBoundsForBox(const LayerImpl* layer,
+ const gfx::BoxF& box,
+ gfx::BoxF* bounds) const;
+
protected:
explicit LayerTreeImpl(
LayerTreeHostImpl* layer_tree_host_impl,
@@ -396,7 +425,6 @@ class CC_EXPORT LayerTreeImpl {
// would not be fully covered by opaque content.
Region unoccluded_screen_space_region_;
- bool contents_textures_purged_;
bool viewport_size_invalid_;
bool needs_update_draw_properties_;
diff --git a/chromium/cc/trees/layer_tree_impl_unittest.cc b/chromium/cc/trees/layer_tree_impl_unittest.cc
index 04c108f1bdf..81a566fe7f3 100644
--- a/chromium/cc/trees/layer_tree_impl_unittest.cc
+++ b/chromium/cc/trees/layer_tree_impl_unittest.cc
@@ -380,87 +380,6 @@ TEST_F(LayerTreeImplTest, HitTestingForSinglePerspectiveLayer) {
EXPECT_EQ(12345, result_layer->id());
}
-TEST_F(LayerTreeImplTest, HitTestingForSingleLayerWithScaledContents) {
- // A layer's visible content rect is actually in the layer's content space.
- // The screen space transform converts from the layer's origin space to screen
- // space. This test makes sure that hit testing works correctly accounts for
- // the contents scale. A contents scale that is not 1 effectively forces a
- // non-identity transform between layer's content space and layer's origin
- // space. The hit testing code must take this into account.
- //
- // To test this, the layer is positioned at (25, 25), and is size (50, 50). If
- // contents scale is ignored, then hit testing will mis-interpret the visible
- // content rect as being larger than the actual bounds of the layer.
- //
- scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1);
-
- gfx::Transform identity_matrix;
- gfx::Point3F transform_origin;
-
- SetLayerPropertiesForTesting(root.get(), identity_matrix, transform_origin,
- gfx::PointF(), gfx::Size(100, 100), true, false,
- true);
- {
- gfx::PointF position(25.f, 25.f);
- gfx::Size bounds(50, 50);
- scoped_ptr<LayerImpl> test_layer =
- LayerImpl::Create(host_impl().active_tree(), 12345);
- SetLayerPropertiesForTesting(test_layer.get(), identity_matrix,
- transform_origin, position, bounds, true,
- false, false);
-
- // override content bounds and contents scale
- test_layer->SetContentBounds(gfx::Size(100, 100));
- test_layer->SetContentsScale(2, 2);
-
- test_layer->SetDrawsContent(true);
- root->AddChild(test_layer.Pass());
- }
-
- host_impl().SetViewportSize(root->bounds());
- host_impl().active_tree()->SetRootLayer(root.Pass());
- host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
-
- // Sanity check the scenario we just created.
- // The visible content rect for test_layer is actually 100x100, even though
- // its layout size is 50x50, positioned at 25x25.
- LayerImpl* test_layer =
- host_impl().active_tree()->root_layer()->children()[0];
- EXPECT_EQ(gfx::Rect(0, 0, 100, 100), test_layer->visible_content_rect());
- ASSERT_EQ(1u, RenderSurfaceLayerList().size());
- ASSERT_EQ(1u, root_layer()->render_surface()->layer_list().size());
-
- // Hit testing for a point outside the layer should return a null pointer (the
- // root layer does not draw content, so it will not be hit tested either).
- gfx::Point test_point(101, 101);
- LayerImpl* result_layer =
- host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
- EXPECT_FALSE(result_layer);
-
- test_point = gfx::Point(24, 24);
- result_layer =
- host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
- EXPECT_FALSE(result_layer);
-
- test_point = gfx::Point(76, 76);
- result_layer =
- host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
- EXPECT_FALSE(result_layer);
-
- // Hit testing for a point inside should return the test layer.
- test_point = gfx::Point(26, 26);
- result_layer =
- host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
- ASSERT_TRUE(result_layer);
- EXPECT_EQ(12345, result_layer->id());
-
- test_point = gfx::Point(74, 74);
- result_layer =
- host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
- ASSERT_TRUE(result_layer);
- EXPECT_EQ(12345, result_layer->id());
-}
-
TEST_F(LayerTreeImplTest, HitTestingForSimpleClippedLayer) {
// Test that hit-testing will only work for the visible portion of a layer,
// and not the entire layer bounds. Here we just test the simple axis-aligned
@@ -1500,110 +1419,6 @@ TEST_F(LayerTreeImplTest,
}
TEST_F(LayerTreeImplTest,
- HitCheckingTouchHandlerRegionsForSingleLayerWithScaledContents) {
- // A layer's visible content rect is actually in the layer's content space.
- // The screen space transform converts from the layer's origin space to screen
- // space. This test makes sure that hit testing works correctly accounts for
- // the contents scale. A contents scale that is not 1 effectively forces a
- // non-identity transform between layer's content space and layer's origin
- // space. The hit testing code must take this into account.
- //
- // To test this, the layer is positioned at (25, 25), and is size (50, 50). If
- // contents scale is ignored, then hit checking will mis-interpret the visible
- // content rect as being larger than the actual bounds of the layer.
- //
- scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1);
-
- gfx::Transform identity_matrix;
- gfx::Point3F transform_origin;
-
- SetLayerPropertiesForTesting(root.get(), identity_matrix, transform_origin,
- gfx::PointF(), gfx::Size(100, 100), true, false,
- true);
- {
- Region touch_handler_region(gfx::Rect(10, 10, 30, 30));
- gfx::PointF position(25.f, 25.f);
- gfx::Size bounds(50, 50);
- scoped_ptr<LayerImpl> test_layer =
- LayerImpl::Create(host_impl().active_tree(), 12345);
- SetLayerPropertiesForTesting(test_layer.get(), identity_matrix,
- transform_origin, position, bounds, true,
- false, false);
-
- // override content bounds and contents scale
- test_layer->SetContentBounds(gfx::Size(100, 100));
- test_layer->SetContentsScale(2, 2);
-
- test_layer->SetDrawsContent(true);
- test_layer->SetTouchEventHandlerRegion(touch_handler_region);
- root->AddChild(test_layer.Pass());
- }
-
- host_impl().SetViewportSize(root->bounds());
- host_impl().active_tree()->SetRootLayer(root.Pass());
- host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
-
- // Sanity check the scenario we just created.
- // The visible content rect for test_layer is actually 100x100, even though
- // its layout size is 50x50, positioned at 25x25.
- LayerImpl* test_layer =
- host_impl().active_tree()->root_layer()->children()[0];
- EXPECT_EQ(gfx::Rect(0, 0, 100, 100), test_layer->visible_content_rect());
- ASSERT_EQ(1u, RenderSurfaceLayerList().size());
- ASSERT_EQ(1u, root_layer()->render_surface()->layer_list().size());
-
- // Hit checking for a point outside the layer should return a null pointer
- // (the root layer does not draw content, so it will not be tested either).
- gfx::Point test_point(76, 76);
- LayerImpl* result_layer =
- host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
- test_point);
- EXPECT_FALSE(result_layer);
-
- // Hit checking for a point inside the layer, but outside the touch handler
- // region should return a null pointer.
- test_point = gfx::Point(26, 26);
- result_layer =
- host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
- test_point);
- EXPECT_FALSE(result_layer);
-
- test_point = gfx::Point(34, 34);
- result_layer =
- host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
- test_point);
- EXPECT_FALSE(result_layer);
-
- test_point = gfx::Point(65, 65);
- result_layer =
- host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
- test_point);
- EXPECT_FALSE(result_layer);
-
- test_point = gfx::Point(74, 74);
- result_layer =
- host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
- test_point);
- EXPECT_FALSE(result_layer);
-
- // Hit checking for a point inside the touch event handler region should
- // return the root layer.
- test_point = gfx::Point(35, 35);
- result_layer =
- host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
- test_point);
- ASSERT_TRUE(result_layer);
- EXPECT_EQ(12345, result_layer->id());
-
- test_point = gfx::Point(64, 64);
- result_layer =
- host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
- test_point);
- ASSERT_TRUE(result_layer);
- EXPECT_EQ(12345, result_layer->id());
-}
-
-TEST_F(LayerTreeImplTest,
HitCheckingTouchHandlerRegionsForSingleLayerWithDeviceScale) {
// The layer's device_scale_factor and page_scale_factor should scale the
// content rect and we should be able to hit the touch handler region by
@@ -1655,8 +1470,7 @@ TEST_F(LayerTreeImplTest,
ASSERT_EQ(1u, root_layer()->render_surface()->layer_list().size());
// Check whether the child layer fits into the root after scaled.
- EXPECT_EQ(gfx::Rect(test_layer->content_bounds()),
- test_layer->visible_content_rect());
+ EXPECT_EQ(gfx::Rect(test_layer->bounds()), test_layer->visible_layer_rect());
// Hit checking for a point outside the layer should return a null pointer
// (the root layer does not draw content, so it will not be tested either).
@@ -2127,11 +1941,11 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForScaledLayers) {
host_impl().active_tree()->GetViewportSelection(&output);
EXPECT_EQ(input.start.type, output.start.type);
gfx::PointF expected_output_start_top = input.start.edge_top;
- gfx::PointF expected_output_edge_botom = input.start.edge_bottom;
+ gfx::PointF expected_output_edge_bottom = input.start.edge_bottom;
expected_output_start_top.Scale(page_scale_factor);
- expected_output_edge_botom.Scale(page_scale_factor);
- EXPECT_EQ(input.start.edge_top, output.start.edge_top);
- EXPECT_EQ(input.start.edge_bottom, output.start.edge_bottom);
+ expected_output_edge_bottom.Scale(page_scale_factor);
+ EXPECT_EQ(expected_output_start_top, output.start.edge_top);
+ EXPECT_EQ(expected_output_edge_bottom, output.start.edge_bottom);
EXPECT_TRUE(output.start.visible);
EXPECT_EQ(input.end.type, output.end.type);
diff --git a/chromium/cc/trees/layer_tree_settings.cc b/chromium/cc/trees/layer_tree_settings.cc
index f7f6f3047da..92d7dda7040 100644
--- a/chromium/cc/trees/layer_tree_settings.cc
+++ b/chromium/cc/trees/layer_tree_settings.cc
@@ -13,16 +13,18 @@
namespace cc {
+LayerSettings::LayerSettings() : use_compositor_animation_timelines(false) {
+}
+
+LayerSettings::~LayerSettings() {
+}
+
LayerTreeSettings::LayerTreeSettings()
- : impl_side_painting(false),
- raster_enabled(true),
- throttle_frame_production(true),
- single_thread_proxy_scheduler(true),
+ : single_thread_proxy_scheduler(true),
use_external_begin_frame_source(false),
main_frame_before_activation_enabled(false),
using_synchronous_renderer_compositor(false),
report_overscroll_only_for_scrollable_axes(false),
- per_tile_painting_enabled(false),
accelerated_animation_enabled(true),
can_use_lcd_text(true),
use_distance_field_text(false),
@@ -38,7 +40,6 @@ LayerTreeSettings::LayerTreeSettings()
scrollbar_show_scale_threshold(1.0f),
solid_color_scrollbar_color(SK_ColorWHITE),
timeout_and_draw_when_animation_checkerboards(true),
- maximum_number_of_failed_draws_before_draw_is_forced_(3),
layer_transforms_should_scale_layer_contents(false),
layers_always_allowed_lcd_text(false),
minimum_contents_scale(0.0625f),
@@ -51,7 +52,6 @@ LayerTreeSettings::LayerTreeSettings()
max_untiled_layer_size(gfx::Size(512, 512)),
default_tile_grid_size(gfx::Size(256, 256)),
minimum_occlusion_tracking_size(gfx::Size(160, 160)),
- use_pinch_virtual_viewport(false),
// At 256x256 tiles, 128 tiles cover an area of 2048x4096 pixels.
max_tiles_for_interest_area(128),
skewport_target_time_in_seconds(1.0f),
@@ -59,8 +59,9 @@ LayerTreeSettings::LayerTreeSettings()
max_unused_resource_memory_percentage(100),
max_memory_for_prepaint_percentage(100),
strict_layer_property_change_checking(false),
- use_one_copy(false),
+ use_one_copy(true),
use_zero_copy(false),
+ use_persistent_map_for_gpu_memory_buffers(false),
enable_elastic_overscroll(false),
use_image_texture_target(GL_TEXTURE_2D),
ignore_root_layer_flings(false),
@@ -68,10 +69,10 @@ LayerTreeSettings::LayerTreeSettings()
use_occlusion_for_tile_prioritization(false),
record_full_layer(false),
use_display_lists(false),
- use_cached_picture_in_display_list(true),
verify_property_trees(false),
gather_pixel_refs(false),
- use_compositor_animation_timelines(false) {
+ use_compositor_animation_timelines(false),
+ invert_viewport_scroll_order(false) {
}
LayerTreeSettings::~LayerTreeSettings() {}
@@ -82,15 +83,12 @@ SchedulerSettings LayerTreeSettings::ToSchedulerSettings() const {
use_external_begin_frame_source;
scheduler_settings.main_frame_before_activation_enabled =
main_frame_before_activation_enabled;
- scheduler_settings.impl_side_painting = impl_side_painting;
scheduler_settings.timeout_and_draw_when_animation_checkerboards =
timeout_and_draw_when_animation_checkerboards;
- scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ =
- maximum_number_of_failed_draws_before_draw_is_forced_;
scheduler_settings.using_synchronous_renderer_compositor =
using_synchronous_renderer_compositor;
- scheduler_settings.throttle_frame_production = throttle_frame_production;
- scheduler_settings.main_thread_should_always_be_low_latency = false;
+ scheduler_settings.throttle_frame_production =
+ !renderer_settings.disable_gpu_vsync;
scheduler_settings.background_frame_interval =
base::TimeDelta::FromSecondsD(1.0 / background_animation_rate);
return scheduler_settings;
diff --git a/chromium/cc/trees/layer_tree_settings.h b/chromium/cc/trees/layer_tree_settings.h
index 56cfa3a9809..6334f94bb13 100644
--- a/chromium/cc/trees/layer_tree_settings.h
+++ b/chromium/cc/trees/layer_tree_settings.h
@@ -15,21 +15,25 @@
namespace cc {
+class CC_EXPORT LayerSettings {
+ public:
+ LayerSettings();
+ ~LayerSettings();
+
+ bool use_compositor_animation_timelines;
+};
+
class CC_EXPORT LayerTreeSettings {
public:
LayerTreeSettings();
~LayerTreeSettings();
RendererSettings renderer_settings;
- bool impl_side_painting;
- bool raster_enabled;
- bool throttle_frame_production;
bool single_thread_proxy_scheduler;
bool use_external_begin_frame_source;
bool main_frame_before_activation_enabled;
bool using_synchronous_renderer_compositor;
bool report_overscroll_only_for_scrollable_axes;
- bool per_tile_painting_enabled;
bool accelerated_animation_enabled;
bool can_use_lcd_text;
bool use_distance_field_text;
@@ -51,7 +55,6 @@ class CC_EXPORT LayerTreeSettings {
float scrollbar_show_scale_threshold;
SkColor solid_color_scrollbar_color;
bool timeout_and_draw_when_animation_checkerboards;
- int maximum_number_of_failed_draws_before_draw_is_forced_;
bool layer_transforms_should_scale_layer_contents;
bool layers_always_allowed_lcd_text;
float minimum_contents_scale;
@@ -64,7 +67,6 @@ class CC_EXPORT LayerTreeSettings {
gfx::Size max_untiled_layer_size;
gfx::Size default_tile_grid_size;
gfx::Size minimum_occlusion_tracking_size;
- bool use_pinch_virtual_viewport;
size_t max_tiles_for_interest_area;
float skewport_target_time_in_seconds;
int skewport_extrapolation_limit_in_content_pixels;
@@ -73,6 +75,7 @@ class CC_EXPORT LayerTreeSettings {
bool strict_layer_property_change_checking;
bool use_one_copy;
bool use_zero_copy;
+ bool use_persistent_map_for_gpu_memory_buffers;
bool enable_elastic_overscroll;
unsigned use_image_texture_target;
bool ignore_root_layer_flings;
@@ -80,10 +83,10 @@ class CC_EXPORT LayerTreeSettings {
bool use_occlusion_for_tile_prioritization;
bool record_full_layer;
bool use_display_lists;
- bool use_cached_picture_in_display_list;
bool verify_property_trees;
bool gather_pixel_refs;
bool use_compositor_animation_timelines;
+ bool invert_viewport_scroll_order;
LayerTreeDebugState initial_debug_state;
diff --git a/chromium/cc/trees/mutator_host_client.h b/chromium/cc/trees/mutator_host_client.h
new file mode 100644
index 00000000000..56123b4a62a
--- /dev/null
+++ b/chromium/cc/trees/mutator_host_client.h
@@ -0,0 +1,45 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_TREES_MUTATOR_HOST_CLIENT_H_
+#define CC_TREES_MUTATOR_HOST_CLIENT_H_
+
+namespace gfx {
+class Transform;
+class ScrollOffset;
+}
+
+namespace cc {
+
+class FilterOperations;
+class Layer;
+
+enum class LayerTreeType { ACTIVE, PENDING };
+
+class MutatorHostClient {
+ public:
+ virtual bool IsLayerInTree(int layer_id, LayerTreeType tree_type) const = 0;
+ virtual void SetMutatorsNeedCommit() = 0;
+
+ virtual void SetLayerFilterMutated(int layer_id,
+ LayerTreeType tree_type,
+ const FilterOperations& filters) = 0;
+ virtual void SetLayerOpacityMutated(int layer_id,
+ LayerTreeType tree_type,
+ float opacity) = 0;
+ virtual void SetLayerTransformMutated(int layer_id,
+ LayerTreeType tree_type,
+ const gfx::Transform& transform) = 0;
+ virtual void SetLayerScrollOffsetMutated(
+ int layer_id,
+ LayerTreeType tree_type,
+ const gfx::ScrollOffset& scroll_offset) = 0;
+
+ virtual void ScrollOffsetAnimationFinished() = 0;
+ virtual gfx::ScrollOffset GetScrollOffsetForAnimation(int layer_id) const = 0;
+};
+
+} // namespace cc
+
+#endif // CC_TREES_MUTATOR_HOST_CLIENT_H_
diff --git a/chromium/cc/trees/occlusion_tracker.cc b/chromium/cc/trees/occlusion_tracker.cc
index 0f0ce158400..996adc895af 100644
--- a/chromium/cc/trees/occlusion_tracker.cc
+++ b/chromium/cc/trees/occlusion_tracker.cc
@@ -17,18 +17,14 @@
namespace cc {
-template <typename LayerType>
-OcclusionTracker<LayerType>::OcclusionTracker(
- const gfx::Rect& screen_space_clip_rect)
+OcclusionTracker::OcclusionTracker(const gfx::Rect& screen_space_clip_rect)
: screen_space_clip_rect_(screen_space_clip_rect) {
}
-template <typename LayerType>
-OcclusionTracker<LayerType>::~OcclusionTracker() {
+OcclusionTracker::~OcclusionTracker() {
}
-template <typename LayerType>
-Occlusion OcclusionTracker<LayerType>::GetCurrentOcclusionForLayer(
+Occlusion OcclusionTracker::GetCurrentOcclusionForLayer(
const gfx::Transform& draw_transform) const {
DCHECK(!stack_.empty());
const StackObject& back = stack_.back();
@@ -37,9 +33,7 @@ Occlusion OcclusionTracker<LayerType>::GetCurrentOcclusionForLayer(
back.occlusion_from_inside_target);
}
-template <typename LayerType>
-Occlusion
-OcclusionTracker<LayerType>::GetCurrentOcclusionForContributingSurface(
+Occlusion OcclusionTracker::GetCurrentOcclusionForContributingSurface(
const gfx::Transform& draw_transform) const {
DCHECK(!stack_.empty());
if (stack_.size() < 2)
@@ -52,10 +46,8 @@ OcclusionTracker<LayerType>::GetCurrentOcclusionForContributingSurface(
second_last.occlusion_from_inside_target);
}
-template <typename LayerType>
-void OcclusionTracker<LayerType>::EnterLayer(
- const LayerIteratorPosition<LayerType>& layer_iterator) {
- LayerType* render_target = layer_iterator.target_render_surface_layer;
+void OcclusionTracker::EnterLayer(const LayerIteratorPosition& layer_iterator) {
+ LayerImpl* render_target = layer_iterator.target_render_surface_layer;
if (layer_iterator.represents_itself)
EnterRenderTarget(render_target);
@@ -63,10 +55,8 @@ void OcclusionTracker<LayerType>::EnterLayer(
FinishedRenderTarget(render_target);
}
-template <typename LayerType>
-void OcclusionTracker<LayerType>::LeaveLayer(
- const LayerIteratorPosition<LayerType>& layer_iterator) {
- LayerType* render_target = layer_iterator.target_render_surface_layer;
+void OcclusionTracker::LeaveLayer(const LayerIteratorPosition& layer_iterator) {
+ LayerImpl* render_target = layer_iterator.target_render_surface_layer;
if (layer_iterator.represents_itself)
MarkOccludedBehindLayer(layer_iterator.current_layer);
@@ -76,9 +66,8 @@ void OcclusionTracker<LayerType>::LeaveLayer(
LeaveToRenderTarget(render_target);
}
-template <typename RenderSurfaceType>
static gfx::Rect ScreenSpaceClipRectInTargetSurface(
- const RenderSurfaceType* target_surface,
+ const RenderSurfaceImpl* target_surface,
const gfx::Rect& screen_space_clip_rect) {
gfx::Transform inverse_screen_space_transform(
gfx::Transform::kSkipInitialization);
@@ -90,7 +79,6 @@ static gfx::Rect ScreenSpaceClipRectInTargetSurface(
screen_space_clip_rect);
}
-template <typename RenderSurfaceType>
static SimpleEnclosedRegion TransformSurfaceOpaqueRegion(
const SimpleEnclosedRegion& region,
bool have_clip_rect,
@@ -119,73 +107,25 @@ static SimpleEnclosedRegion TransformSurfaceOpaqueRegion(
return transformed_region;
}
-static inline bool LayerOpacityKnown(const Layer* layer) {
- return !layer->draw_opacity_is_animating();
-}
-static inline bool LayerOpacityKnown(const LayerImpl* layer) {
- return true;
-}
-static inline bool LayerTransformsToTargetKnown(const Layer* layer) {
- return !layer->draw_transform_is_animating();
-}
-static inline bool LayerTransformsToTargetKnown(const LayerImpl* layer) {
- return true;
-}
-
-static inline bool SurfaceOpacityKnown(const RenderSurface* rs) {
- return !rs->draw_opacity_is_animating();
-}
-static inline bool SurfaceOpacityKnown(const RenderSurfaceImpl* rs) {
- return true;
-}
-static inline bool SurfaceTransformsToTargetKnown(const RenderSurface* rs) {
- return !rs->target_surface_transforms_are_animating();
-}
-static inline bool SurfaceTransformsToTargetKnown(const RenderSurfaceImpl* rs) {
- return true;
-}
-static inline bool SurfaceTransformsToScreenKnown(const RenderSurface* rs) {
- return !rs->screen_space_transforms_are_animating();
-}
-static inline bool SurfaceTransformsToScreenKnown(const RenderSurfaceImpl* rs) {
- return true;
-}
-
-static inline bool LayerIsInUnsorted3dRenderingContext(const Layer* layer) {
- return layer->Is3dSorted();
-}
-static inline bool LayerIsInUnsorted3dRenderingContext(const LayerImpl* layer) {
- return layer->Is3dSorted();
-}
-
-template <typename LayerType>
-static inline bool LayerIsHidden(const LayerType* layer) {
- return layer->hide_layer_and_subtree() ||
- (layer->parent() && LayerIsHidden(layer->parent()));
-}
-
-template <typename LayerType>
-void OcclusionTracker<LayerType>::EnterRenderTarget(
- const LayerType* new_target) {
+void OcclusionTracker::EnterRenderTarget(const LayerImpl* new_target) {
if (!stack_.empty() && stack_.back().target == new_target)
return;
- const LayerType* old_target = NULL;
- const typename LayerType::RenderSurfaceType* old_occlusion_immune_ancestor =
- NULL;
+ const LayerImpl* old_target = NULL;
+ const RenderSurfaceImpl* old_occlusion_immune_ancestor = NULL;
if (!stack_.empty()) {
old_target = stack_.back().target;
old_occlusion_immune_ancestor =
old_target->render_surface()->nearest_occlusion_immune_ancestor();
}
- const typename LayerType::RenderSurfaceType* new_occlusion_immune_ancestor =
+ const RenderSurfaceImpl* new_occlusion_immune_ancestor =
new_target->render_surface()->nearest_occlusion_immune_ancestor();
stack_.push_back(StackObject(new_target));
- // We copy the screen occlusion into the new RenderSurface subtree, but we
+ // We copy the screen occlusion into the new RenderSurfaceImpl subtree, but we
// never copy in the occlusion from inside the target, since we are looking
- // at a new RenderSurface target.
+ // at a new RenderSurfaceImpl target.
// If entering an unoccluded subtree, do not carry forward the outside
// occlusion calculated so far.
@@ -193,15 +133,12 @@ void OcclusionTracker<LayerType>::EnterRenderTarget(
new_occlusion_immune_ancestor &&
new_occlusion_immune_ancestor != old_occlusion_immune_ancestor;
- bool have_transform_from_screen_to_new_target = false;
gfx::Transform inverse_new_target_screen_space_transform(
// Note carefully, not used if screen space transform is uninvertible.
gfx::Transform::kSkipInitialization);
- if (SurfaceTransformsToScreenKnown(new_target->render_surface())) {
- have_transform_from_screen_to_new_target =
- new_target->render_surface()->screen_space_transform().GetInverse(
- &inverse_new_target_screen_space_transform);
- }
+ bool have_transform_from_screen_to_new_target =
+ new_target->render_surface()->screen_space_transform().GetInverse(
+ &inverse_new_target_screen_space_transform);
bool entering_root_target = new_target->parent() == NULL;
@@ -213,32 +150,30 @@ void OcclusionTracker<LayerType>::EnterRenderTarget(
if (!copy_outside_occlusion_forward)
return;
- int last_index = stack_.size() - 1;
+ size_t last_index = stack_.size() - 1;
gfx::Transform old_target_to_new_target_transform(
inverse_new_target_screen_space_transform,
old_target->render_surface()->screen_space_transform());
stack_[last_index].occlusion_from_outside_target =
- TransformSurfaceOpaqueRegion<typename LayerType::RenderSurfaceType>(
- stack_[last_index - 1].occlusion_from_outside_target,
- false,
- gfx::Rect(),
- old_target_to_new_target_transform);
+ TransformSurfaceOpaqueRegion(
+ stack_[last_index - 1].occlusion_from_outside_target, false,
+ gfx::Rect(), old_target_to_new_target_transform);
stack_[last_index].occlusion_from_outside_target.Union(
- TransformSurfaceOpaqueRegion<typename LayerType::RenderSurfaceType>(
- stack_[last_index - 1].occlusion_from_inside_target,
- false,
- gfx::Rect(),
- old_target_to_new_target_transform));
+ TransformSurfaceOpaqueRegion(
+ stack_[last_index - 1].occlusion_from_inside_target, false,
+ gfx::Rect(), old_target_to_new_target_transform));
}
-template <typename LayerType>
-void OcclusionTracker<LayerType>::FinishedRenderTarget(
- const LayerType* finished_target) {
+static bool LayerIsHidden(const LayerImpl* layer) {
+ return layer->hide_layer_and_subtree() ||
+ (layer->parent() && LayerIsHidden(layer->parent()));
+}
+
+void OcclusionTracker::FinishedRenderTarget(const LayerImpl* finished_target) {
// Make sure we know about the target surface.
EnterRenderTarget(finished_target);
- typename LayerType::RenderSurfaceType* surface =
- finished_target->render_surface();
+ RenderSurfaceImpl* surface = finished_target->render_surface();
// Readbacks always happen on render targets so we only need to check
// for readbacks here.
@@ -247,25 +182,20 @@ void OcclusionTracker<LayerType>::FinishedRenderTarget(
// If the occlusion within the surface can not be applied to things outside of
// the surface's subtree, then clear the occlusion here so it won't be used.
- if (finished_target->mask_layer() || !SurfaceOpacityKnown(surface) ||
- surface->draw_opacity() < 1 ||
+ if (finished_target->mask_layer() || surface->draw_opacity() < 1 ||
!finished_target->uses_default_blend_mode() ||
target_is_only_for_copy_request ||
finished_target->filters().HasFilterThatAffectsOpacity()) {
stack_.back().occlusion_from_outside_target.Clear();
stack_.back().occlusion_from_inside_target.Clear();
- } else if (!SurfaceTransformsToTargetKnown(surface)) {
- stack_.back().occlusion_from_inside_target.Clear();
- stack_.back().occlusion_from_outside_target.Clear();
}
}
-template <typename LayerType>
static void ReduceOcclusionBelowSurface(
- LayerType* contributing_layer,
+ const LayerImpl* contributing_layer,
const gfx::Rect& surface_rect,
const gfx::Transform& surface_transform,
- LayerType* render_target,
+ const LayerImpl* render_target,
SimpleEnclosedRegion* occlusion_from_inside_target) {
if (surface_rect.IsEmpty())
return;
@@ -315,10 +245,9 @@ static void ReduceOcclusionBelowSurface(
}
}
-template <typename LayerType>
-void OcclusionTracker<LayerType>::LeaveToRenderTarget(
- const LayerType* new_target) {
- int last_index = stack_.size() - 1;
+void OcclusionTracker::LeaveToRenderTarget(const LayerImpl* new_target) {
+ DCHECK(!stack_.empty());
+ size_t last_index = stack_.size() - 1;
bool surface_will_be_at_top_after_pop =
stack_.size() > 1 && stack_[last_index - 1].target == new_target;
@@ -326,30 +255,25 @@ void OcclusionTracker<LayerType>::LeaveToRenderTarget(
// out to its parent target RenderSurfaceImpl. The target occlusion can be
// merged out as well but needs to be transformed to the new target.
- const LayerType* old_target = stack_[last_index].target;
- const typename LayerType::RenderSurfaceType* old_surface =
- old_target->render_surface();
+ const LayerImpl* old_target = stack_[last_index].target;
+ const RenderSurfaceImpl* old_surface = old_target->render_surface();
SimpleEnclosedRegion old_occlusion_from_inside_target_in_new_target =
- TransformSurfaceOpaqueRegion<typename LayerType::RenderSurfaceType>(
+ TransformSurfaceOpaqueRegion(
stack_[last_index].occlusion_from_inside_target,
- old_surface->is_clipped(),
- old_surface->clip_rect(),
+ old_surface->is_clipped(), old_surface->clip_rect(),
old_surface->draw_transform());
if (old_target->has_replica() && !old_target->replica_has_mask()) {
old_occlusion_from_inside_target_in_new_target.Union(
- TransformSurfaceOpaqueRegion<typename LayerType::RenderSurfaceType>(
+ TransformSurfaceOpaqueRegion(
stack_[last_index].occlusion_from_inside_target,
- old_surface->is_clipped(),
- old_surface->clip_rect(),
+ old_surface->is_clipped(), old_surface->clip_rect(),
old_surface->replica_draw_transform()));
}
SimpleEnclosedRegion old_occlusion_from_outside_target_in_new_target =
- TransformSurfaceOpaqueRegion<typename LayerType::RenderSurfaceType>(
- stack_[last_index].occlusion_from_outside_target,
- false,
- gfx::Rect(),
+ TransformSurfaceOpaqueRegion(
+ stack_[last_index].occlusion_from_outside_target, false, gfx::Rect(),
old_surface->draw_transform());
gfx::Rect unoccluded_surface_rect;
@@ -419,29 +343,24 @@ void OcclusionTracker<LayerType>::LeaveToRenderTarget(
&stack_.back().occlusion_from_outside_target);
}
-template <typename LayerType>
-void OcclusionTracker<LayerType>::MarkOccludedBehindLayer(
- const LayerType* layer) {
+void OcclusionTracker::MarkOccludedBehindLayer(const LayerImpl* layer) {
DCHECK(!stack_.empty());
DCHECK_EQ(layer->render_target(), stack_.back().target);
- if (!LayerOpacityKnown(layer) || layer->draw_opacity() < 1)
+ if (layer->draw_opacity() < 1)
return;
if (!layer->uses_default_blend_mode())
return;
- if (LayerIsInUnsorted3dRenderingContext(layer))
+ if (layer->Is3dSorted())
return;
- if (!LayerTransformsToTargetKnown(layer))
+ SimpleEnclosedRegion opaque_layer_region = layer->VisibleOpaqueRegion();
+ if (opaque_layer_region.IsEmpty())
return;
- SimpleEnclosedRegion opaque_contents = layer->VisibleContentOpaqueRegion();
- if (opaque_contents.IsEmpty())
- return;
-
- DCHECK(layer->visible_content_rect().Contains(opaque_contents.bounds()));
+ DCHECK(layer->visible_layer_rect().Contains(opaque_layer_region.bounds()));
// TODO(danakj): Find a rect interior to each transformed quad.
if (!layer->draw_transform().Preserves2dAxisAlignment())
@@ -456,10 +375,10 @@ void OcclusionTracker<LayerType>::MarkOccludedBehindLayer(
layer->render_target()->render_surface()->content_rect());
}
- for (size_t i = 0; i < opaque_contents.GetRegionComplexity(); ++i) {
+ for (size_t i = 0; i < opaque_layer_region.GetRegionComplexity(); ++i) {
gfx::Rect transformed_rect =
MathUtil::MapEnclosedRectWith2dAxisAlignedTransform(
- layer->draw_transform(), opaque_contents.GetRect(i));
+ layer->draw_transform(), opaque_layer_region.GetRect(i));
transformed_rect.Intersect(clip_rect_in_target);
if (transformed_rect.width() < minimum_tracking_size_.width() &&
transformed_rect.height() < minimum_tracking_size_.height())
@@ -468,8 +387,7 @@ void OcclusionTracker<LayerType>::MarkOccludedBehindLayer(
}
}
-template <typename LayerType>
-Region OcclusionTracker<LayerType>::ComputeVisibleRegionInScreen() const {
+Region OcclusionTracker::ComputeVisibleRegionInScreen() const {
DCHECK(!stack_.back().target->parent());
const SimpleEnclosedRegion& occluded =
stack_.back().occlusion_from_inside_target;
@@ -479,8 +397,4 @@ Region OcclusionTracker<LayerType>::ComputeVisibleRegionInScreen() const {
return visible_region;
}
-// Instantiate (and export) templates here for the linker.
-template class OcclusionTracker<Layer>;
-template class OcclusionTracker<LayerImpl>;
-
} // namespace cc
diff --git a/chromium/cc/trees/occlusion_tracker.h b/chromium/cc/trees/occlusion_tracker.h
index ff6f18dda9c..9a9294c779d 100644
--- a/chromium/cc/trees/occlusion_tracker.h
+++ b/chromium/cc/trees/occlusion_tracker.h
@@ -18,8 +18,6 @@ namespace cc {
class LayerImpl;
class Region;
class RenderSurfaceImpl;
-class Layer;
-class RenderSurface;
// This class is used to track occlusion of layers while traversing them in a
// front-to-back order. As each layer is visited, one of the methods in this
@@ -30,7 +28,6 @@ class RenderSurface;
// queried via surfaceOccluded() and surfaceUnoccludedContentRect(). Finally,
// once finished with the layer, occlusion behind the layer should be marked by
// calling MarkOccludedBehindLayer().
-template <typename LayerType>
class CC_EXPORT OcclusionTracker {
public:
explicit OcclusionTracker(const gfx::Rect& screen_space_clip_rect);
@@ -45,10 +42,10 @@ class CC_EXPORT OcclusionTracker {
// Called at the beginning of each step in the LayerIterator's front-to-back
// traversal.
- void EnterLayer(const LayerIteratorPosition<LayerType>& layer_iterator);
+ void EnterLayer(const LayerIteratorPosition& layer_iterator);
// Called at the end of each step in the LayerIterator's front-to-back
// traversal.
- void LeaveLayer(const LayerIteratorPosition<LayerType>& layer_iterator);
+ void LeaveLayer(const LayerIteratorPosition& layer_iterator);
// Gives the region of the screen that is not occluded by something opaque.
Region ComputeVisibleRegionInScreen() const;
@@ -60,8 +57,8 @@ class CC_EXPORT OcclusionTracker {
protected:
struct StackObject {
StackObject() : target(0) {}
- explicit StackObject(const LayerType* target) : target(target) {}
- const LayerType* target;
+ explicit StackObject(const LayerImpl* target) : target(target) {}
+ const LayerImpl* target;
SimpleEnclosedRegion occlusion_from_outside_target;
SimpleEnclosedRegion occlusion_from_inside_target;
};
@@ -86,21 +83,21 @@ class CC_EXPORT OcclusionTracker {
private:
// Called when visiting a layer representing itself. If the target was not
// already current, then this indicates we have entered a new surface subtree.
- void EnterRenderTarget(const LayerType* new_target);
+ void EnterRenderTarget(const LayerImpl* new_target);
// Called when visiting a layer representing a target surface. This indicates
// we have visited all the layers within the surface, and we may perform any
// surface-wide operations.
- void FinishedRenderTarget(const LayerType* finished_target);
+ void FinishedRenderTarget(const LayerImpl* finished_target);
// Called when visiting a layer representing a contributing surface. This
// indicates that we are leaving our current surface, and entering the new
// one. We then perform any operations required for merging results from the
// child subtree into its parent.
- void LeaveToRenderTarget(const LayerType* new_target);
+ void LeaveToRenderTarget(const LayerImpl* new_target);
// Add the layer's occlusion to the tracked state.
- void MarkOccludedBehindLayer(const LayerType* layer);
+ void MarkOccludedBehindLayer(const LayerImpl* layer);
gfx::Rect screen_space_clip_rect_;
gfx::Size minimum_tracking_size_;
@@ -108,11 +105,6 @@ class CC_EXPORT OcclusionTracker {
DISALLOW_COPY_AND_ASSIGN(OcclusionTracker);
};
-#if !defined(COMPILER_MSVC)
-extern template class OcclusionTracker<Layer>;
-extern template class OcclusionTracker<LayerImpl>;
-#endif
-
} // namespace cc
#endif // CC_TREES_OCCLUSION_TRACKER_H_
diff --git a/chromium/cc/trees/occlusion_tracker_perftest.cc b/chromium/cc/trees/occlusion_tracker_perftest.cc
index 854dacdb5f0..209399dce11 100644
--- a/chromium/cc/trees/occlusion_tracker_perftest.cc
+++ b/chromium/cc/trees/occlusion_tracker_perftest.cc
@@ -4,6 +4,7 @@
#include "cc/trees/occlusion_tracker.h"
+#include "base/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "cc/debug/lap_timer.h"
#include "cc/layers/layer_iterator.h"
@@ -13,6 +14,7 @@
#include "cc/test/fake_proxy.h"
#include "cc/test/fake_rendering_stats_instrumentation.h"
#include "cc/test/test_shared_bitmap_manager.h"
+#include "cc/test/test_task_graph_runner.h"
#include "cc/trees/layer_tree_host_impl.h"
#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/single_thread_proxy.h"
@@ -32,13 +34,13 @@ class OcclusionTrackerPerfTest : public testing::Test {
: timer_(kWarmupRuns,
base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
kTimeCheckInterval),
+ proxy_(base::ThreadTaskRunnerHandle::Get(), nullptr),
impl_(&proxy_) {}
void CreateHost() {
LayerTreeSettings settings;
- shared_bitmap_manager_.reset(new TestSharedBitmapManager());
- host_impl_ =
- LayerTreeHostImpl::Create(settings, &client_, &proxy_, &stats_,
- shared_bitmap_manager_.get(), NULL, NULL, 1);
+ host_impl_ = LayerTreeHostImpl::Create(settings, &client_, &proxy_, &stats_,
+ &shared_bitmap_manager_, nullptr,
+ &task_graph_runner_, 1);
host_impl_->InitializeRenderer(FakeOutputSurface::Create3d());
scoped_ptr<LayerImpl> root_layer = LayerImpl::Create(active_tree(), 1);
@@ -67,7 +69,8 @@ class OcclusionTrackerPerfTest : public testing::Test {
FakeProxy proxy_;
DebugScopedSetImplThread impl_;
FakeRenderingStatsInstrumentation stats_;
- scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
+ TestSharedBitmapManager shared_bitmap_manager_;
+ TestTaskGraphRunner task_graph_runner_;
scoped_ptr<LayerTreeHostImpl> host_impl_;
};
@@ -75,7 +78,7 @@ TEST_F(OcclusionTrackerPerfTest, UnoccludedContentRect_FullyOccluded) {
SetTestName("unoccluded_content_rect_fully_occluded");
gfx::Rect viewport_rect(768, 1038);
- OcclusionTracker<LayerImpl> tracker(viewport_rect);
+ OcclusionTracker tracker(viewport_rect);
CreateHost();
host_impl_->SetViewportSize(viewport_rect.size());
@@ -86,7 +89,6 @@ TEST_F(OcclusionTrackerPerfTest, UnoccludedContentRect_FullyOccluded) {
opaque_layer->SetContentsOpaque(true);
opaque_layer->SetDrawsContent(true);
opaque_layer->SetBounds(viewport_rect.size());
- opaque_layer->SetContentBounds(viewport_rect.size());
active_tree()->root_layer()->AddChild(opaque_layer.Pass());
bool update_lcd_text = false;
@@ -95,10 +97,10 @@ TEST_F(OcclusionTrackerPerfTest, UnoccludedContentRect_FullyOccluded) {
ASSERT_EQ(1u, rsll.size());
EXPECT_EQ(1u, rsll[0]->render_surface()->layer_list().size());
- LayerIterator<LayerImpl> begin = LayerIterator<LayerImpl>::Begin(&rsll);
- LayerIterator<LayerImpl> end = LayerIterator<LayerImpl>::End(&rsll);
+ LayerIterator begin = LayerIterator::Begin(&rsll);
+ LayerIterator end = LayerIterator::End(&rsll);
- LayerIteratorPosition<LayerImpl> pos = begin;
+ LayerIteratorPosition pos = begin;
// The opaque_layer adds occlusion over the whole viewport.
tracker.EnterLayer(pos);
@@ -128,7 +130,7 @@ TEST_F(OcclusionTrackerPerfTest, UnoccludedContentRect_FullyOccluded) {
} while (!timer_.HasTimeLimitExpired());
++begin;
- LayerIteratorPosition<LayerImpl> next = begin;
+ LayerIteratorPosition next = begin;
EXPECT_EQ(active_tree()->root_layer(), next.current_layer);
++begin;
@@ -142,7 +144,7 @@ TEST_F(OcclusionTrackerPerfTest, UnoccludedContentRect_10OpaqueLayers) {
SetTestName("unoccluded_content_rect_10_opaque_layers");
gfx::Rect viewport_rect(768, 1038);
- OcclusionTracker<LayerImpl> tracker(viewport_rect);
+ OcclusionTracker tracker(viewport_rect);
CreateHost();
host_impl_->SetViewportSize(viewport_rect.size());
@@ -155,8 +157,6 @@ TEST_F(OcclusionTrackerPerfTest, UnoccludedContentRect_10OpaqueLayers) {
opaque_layer->SetDrawsContent(true);
opaque_layer->SetBounds(
gfx::Size(viewport_rect.width() / 2, viewport_rect.height() / 2));
- opaque_layer->SetContentBounds(
- gfx::Size(viewport_rect.width() / 2, viewport_rect.height() / 2));
opaque_layer->SetPosition(gfx::Point(i, i));
active_tree()->root_layer()->AddChild(opaque_layer.Pass());
}
@@ -168,17 +168,17 @@ TEST_F(OcclusionTrackerPerfTest, UnoccludedContentRect_10OpaqueLayers) {
EXPECT_EQ(static_cast<size_t>(kNumOpaqueLayers),
rsll[0]->render_surface()->layer_list().size());
- LayerIterator<LayerImpl> begin = LayerIterator<LayerImpl>::Begin(&rsll);
- LayerIterator<LayerImpl> end = LayerIterator<LayerImpl>::End(&rsll);
+ LayerIterator begin = LayerIterator::Begin(&rsll);
+ LayerIterator end = LayerIterator::End(&rsll);
// The opaque_layers add occlusion.
for (int i = 0; i < kNumOpaqueLayers - 1; ++i) {
- LayerIteratorPosition<LayerImpl> pos = begin;
+ LayerIteratorPosition pos = begin;
tracker.EnterLayer(pos);
tracker.LeaveLayer(pos);
++begin;
}
- LayerIteratorPosition<LayerImpl> pos = begin;
+ LayerIteratorPosition pos = begin;
tracker.EnterLayer(pos);
tracker.LeaveLayer(pos);
@@ -200,7 +200,7 @@ TEST_F(OcclusionTrackerPerfTest, UnoccludedContentRect_10OpaqueLayers) {
} while (!timer_.HasTimeLimitExpired());
++begin;
- LayerIteratorPosition<LayerImpl> next = begin;
+ LayerIteratorPosition next = begin;
EXPECT_EQ(active_tree()->root_layer(), next.current_layer);
++begin;
diff --git a/chromium/cc/trees/occlusion_tracker_unittest.cc b/chromium/cc/trees/occlusion_tracker_unittest.cc
index f3f218570eb..08cfcf7290e 100644
--- a/chromium/cc/trees/occlusion_tracker_unittest.cc
+++ b/chromium/cc/trees/occlusion_tracker_unittest.cc
@@ -18,6 +18,7 @@
#include "cc/test/fake_layer_tree_host_impl.h"
#include "cc/test/geometry_test_utils.h"
#include "cc/test/test_occlusion_tracker.h"
+#include "cc/test/test_task_graph_runner.h"
#include "cc/trees/layer_tree_host_common.h"
#include "cc/trees/single_thread_proxy.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -27,31 +28,6 @@
namespace cc {
namespace {
-class TestContentLayer : public Layer {
- public:
- TestContentLayer() : Layer(), override_opaque_contents_rect_(false) {
- SetIsDrawable(true);
- }
-
- SimpleEnclosedRegion VisibleContentOpaqueRegion() const override {
- if (override_opaque_contents_rect_) {
- return SimpleEnclosedRegion(
- gfx::IntersectRects(opaque_contents_rect_, visible_content_rect()));
- }
- return Layer::VisibleContentOpaqueRegion();
- }
- void SetOpaqueContentsRect(const gfx::Rect& opaque_contents_rect) {
- override_opaque_contents_rect_ = true;
- opaque_contents_rect_ = opaque_contents_rect;
- }
-
- private:
- ~TestContentLayer() override {}
-
- bool override_opaque_contents_rect_;
- gfx::Rect opaque_contents_rect_;
-};
-
class TestContentLayerImpl : public LayerImpl {
public:
TestContentLayerImpl(LayerTreeImpl* tree_impl, int id)
@@ -59,12 +35,12 @@ class TestContentLayerImpl : public LayerImpl {
SetDrawsContent(true);
}
- SimpleEnclosedRegion VisibleContentOpaqueRegion() const override {
+ SimpleEnclosedRegion VisibleOpaqueRegion() const override {
if (override_opaque_contents_rect_) {
return SimpleEnclosedRegion(
- gfx::IntersectRects(opaque_contents_rect_, visible_content_rect()));
+ gfx::IntersectRects(opaque_contents_rect_, visible_layer_rect()));
}
- return LayerImpl::VisibleContentOpaqueRegion();
+ return LayerImpl::VisibleOpaqueRegion();
}
void SetOpaqueContentsRect(const gfx::Rect& opaque_contents_rect) {
override_opaque_contents_rect_ = true;
@@ -76,162 +52,97 @@ class TestContentLayerImpl : public LayerImpl {
gfx::Rect opaque_contents_rect_;
};
-template <typename LayerType>
-class TestOcclusionTrackerWithClip : public TestOcclusionTracker<LayerType> {
+class TestOcclusionTrackerWithClip : public TestOcclusionTracker {
public:
explicit TestOcclusionTrackerWithClip(const gfx::Rect& viewport_rect)
- : TestOcclusionTracker<LayerType>(viewport_rect) {}
+ : TestOcclusionTracker(viewport_rect) {}
- bool OccludedLayer(const LayerType* layer,
+ bool OccludedLayer(const LayerImpl* layer,
const gfx::Rect& content_rect) const {
- DCHECK(layer->visible_content_rect().Contains(content_rect));
+ DCHECK(layer->visible_layer_rect().Contains(content_rect));
return this->GetCurrentOcclusionForLayer(layer->draw_transform())
.IsOccluded(content_rect);
}
// Gives an unoccluded sub-rect of |content_rect| in the content space of the
// layer. Simple wrapper around GetUnoccludedContentRect.
- gfx::Rect UnoccludedLayerContentRect(const LayerType* layer,
+ gfx::Rect UnoccludedLayerContentRect(const LayerImpl* layer,
const gfx::Rect& content_rect) const {
- DCHECK(layer->visible_content_rect().Contains(content_rect));
+ DCHECK(layer->visible_layer_rect().Contains(content_rect));
return this->GetCurrentOcclusionForLayer(layer->draw_transform())
.GetUnoccludedContentRect(content_rect);
}
- gfx::Rect UnoccludedSurfaceContentRect(const LayerType* layer,
+ gfx::Rect UnoccludedSurfaceContentRect(const LayerImpl* layer,
const gfx::Rect& content_rect) const {
- typename LayerType::RenderSurfaceType* surface = layer->render_surface();
+ RenderSurfaceImpl* surface = layer->render_surface();
return this->GetCurrentOcclusionForContributingSurface(
surface->draw_transform())
.GetUnoccludedContentRect(content_rect);
}
};
-struct OcclusionTrackerTestMainThreadTypes {
- typedef Layer LayerType;
- typedef FakeLayerTreeHost HostType;
- typedef RenderSurface RenderSurfaceType;
- typedef TestContentLayer ContentLayerType;
- typedef scoped_refptr<Layer> LayerPtrType;
- typedef scoped_refptr<ContentLayerType> ContentLayerPtrType;
- typedef LayerIterator<Layer> TestLayerIterator;
- typedef OcclusionTracker<Layer> OcclusionTrackerType;
-
- static LayerPtrType CreateLayer(HostType* host) { return Layer::Create(); }
- static ContentLayerPtrType CreateContentLayer(HostType* host) {
- return make_scoped_refptr(new ContentLayerType());
- }
-
- template <typename T>
- static LayerPtrType PassLayerPtr(T* layer) {
- LayerPtrType ref(*layer);
- *layer = NULL;
- return ref;
- }
- static void SetForceRenderSurface(LayerType* layer, bool force) {
- layer->SetForceRenderSurface(force);
- }
-
- static void DestroyLayer(LayerPtrType* layer) { *layer = NULL; }
-
- static void RecursiveUpdateNumChildren(LayerType* layerType) {}
-};
-
-struct OcclusionTrackerTestImplThreadTypes {
- typedef LayerImpl LayerType;
- typedef LayerTreeImpl HostType;
- typedef RenderSurfaceImpl RenderSurfaceType;
- typedef TestContentLayerImpl ContentLayerType;
- typedef scoped_ptr<LayerImpl> LayerPtrType;
- typedef scoped_ptr<ContentLayerType> ContentLayerPtrType;
- typedef LayerIterator<LayerImpl> TestLayerIterator;
- typedef OcclusionTracker<LayerImpl> OcclusionTrackerType;
-
- static LayerPtrType CreateLayer(HostType* host) {
- return LayerImpl::Create(host, next_layer_impl_id++);
- }
- static ContentLayerPtrType CreateContentLayer(HostType* host) {
- return make_scoped_ptr(new ContentLayerType(host, next_layer_impl_id++));
- }
- static int next_layer_impl_id;
-
- template <typename T>
- static LayerPtrType PassLayerPtr(T* layer) {
- return layer->Pass();
- }
-
- static void SetForceRenderSurface(LayerType* layer, bool force) {
- layer->SetHasRenderSurface(force);
- }
- static void DestroyLayer(LayerPtrType* layer) { layer->reset(); }
-
- static void RecursiveUpdateNumChildren(LayerType* layer) {
- FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(layer);
- }
-};
-
-int OcclusionTrackerTestImplThreadTypes::next_layer_impl_id = 1;
-
-template <typename Types> class OcclusionTrackerTest : public testing::Test {
+class OcclusionTrackerTest : public testing::Test {
protected:
explicit OcclusionTrackerTest(bool opaque_layers)
: opaque_layers_(opaque_layers),
client_(FakeLayerTreeHostClient::DIRECT_3D),
- host_(FakeLayerTreeHost::Create(&client_)) {}
+ host_(FakeLayerTreeHost::Create(&client_, &task_graph_runner_)),
+ next_layer_impl_id_(1) {}
virtual void RunMyTest() = 0;
void TearDown() override { DestroyLayers(); }
- typename Types::HostType* GetHost();
-
- typename Types::ContentLayerType* CreateRoot(const gfx::Transform& transform,
- const gfx::PointF& position,
- const gfx::Size& bounds) {
- typename Types::ContentLayerPtrType layer(
- Types::CreateContentLayer(GetHost()));
- typename Types::ContentLayerType* layer_ptr = layer.get();
+ TestContentLayerImpl* CreateRoot(const gfx::Transform& transform,
+ const gfx::PointF& position,
+ const gfx::Size& bounds) {
+ LayerTreeImpl* tree = host_->host_impl()->active_tree();
+ int id = next_layer_impl_id_++;
+ scoped_ptr<TestContentLayerImpl> layer(new TestContentLayerImpl(tree, id));
+ TestContentLayerImpl* layer_ptr = layer.get();
SetProperties(layer_ptr, transform, position, bounds);
DCHECK(!root_.get());
- root_ = Types::PassLayerPtr(&layer);
+ root_ = layer.Pass();
- Types::SetForceRenderSurface(layer_ptr, true);
+ layer_ptr->SetHasRenderSurface(true);
SetRootLayerOnMainThread(layer_ptr);
return layer_ptr;
}
- typename Types::LayerType* CreateLayer(typename Types::LayerType* parent,
- const gfx::Transform& transform,
- const gfx::PointF& position,
- const gfx::Size& bounds) {
- typename Types::LayerPtrType layer(Types::CreateLayer(GetHost()));
- typename Types::LayerType* layer_ptr = layer.get();
+ LayerImpl* CreateLayer(LayerImpl* parent,
+ const gfx::Transform& transform,
+ const gfx::PointF& position,
+ const gfx::Size& bounds) {
+ LayerTreeImpl* tree = host_->host_impl()->active_tree();
+ int id = next_layer_impl_id_++;
+ scoped_ptr<LayerImpl> layer = LayerImpl::Create(tree, id);
+ LayerImpl* layer_ptr = layer.get();
SetProperties(layer_ptr, transform, position, bounds);
- parent->AddChild(Types::PassLayerPtr(&layer));
+ parent->AddChild(layer.Pass());
return layer_ptr;
}
- typename Types::LayerType* CreateSurface(typename Types::LayerType* parent,
- const gfx::Transform& transform,
- const gfx::PointF& position,
- const gfx::Size& bounds) {
- typename Types::LayerType* layer =
- CreateLayer(parent, transform, position, bounds);
- Types::SetForceRenderSurface(layer, true);
+ LayerImpl* CreateSurface(LayerImpl* parent,
+ const gfx::Transform& transform,
+ const gfx::PointF& position,
+ const gfx::Size& bounds) {
+ LayerImpl* layer = CreateLayer(parent, transform, position, bounds);
+ layer->SetHasRenderSurface(true);
return layer;
}
- typename Types::ContentLayerType* CreateDrawingLayer(
- typename Types::LayerType* parent,
- const gfx::Transform& transform,
- const gfx::PointF& position,
- const gfx::Size& bounds,
- bool opaque) {
- typename Types::ContentLayerPtrType layer(
- Types::CreateContentLayer(GetHost()));
- typename Types::ContentLayerType* layer_ptr = layer.get();
+ TestContentLayerImpl* CreateDrawingLayer(LayerImpl* parent,
+ const gfx::Transform& transform,
+ const gfx::PointF& position,
+ const gfx::Size& bounds,
+ bool opaque) {
+ LayerTreeImpl* tree = host_->host_impl()->active_tree();
+ int id = next_layer_impl_id_++;
+ scoped_ptr<TestContentLayerImpl> layer(new TestContentLayerImpl(tree, id));
+ TestContentLayerImpl* layer_ptr = layer.get();
SetProperties(layer_ptr, transform, position, bounds);
if (opaque_layers_) {
@@ -244,48 +155,46 @@ template <typename Types> class OcclusionTrackerTest : public testing::Test {
layer_ptr->SetOpaqueContentsRect(gfx::Rect());
}
- parent->AddChild(Types::PassLayerPtr(&layer));
+ parent->AddChild(layer.Pass());
return layer_ptr;
}
- typename Types::LayerType* CreateReplicaLayer(
- typename Types::LayerType* owning_layer,
- const gfx::Transform& transform,
- const gfx::PointF& position,
- const gfx::Size& bounds) {
- typename Types::ContentLayerPtrType layer(
- Types::CreateContentLayer(GetHost()));
- typename Types::ContentLayerType* layer_ptr = layer.get();
+ LayerImpl* CreateReplicaLayer(LayerImpl* owning_layer,
+ const gfx::Transform& transform,
+ const gfx::PointF& position,
+ const gfx::Size& bounds) {
+ LayerTreeImpl* tree = host_->host_impl()->active_tree();
+ int id = next_layer_impl_id_++;
+ scoped_ptr<TestContentLayerImpl> layer(new TestContentLayerImpl(tree, id));
+ TestContentLayerImpl* layer_ptr = layer.get();
SetProperties(layer_ptr, transform, position, bounds);
- SetReplica(owning_layer, Types::PassLayerPtr(&layer));
+ SetReplica(owning_layer, layer.Pass());
return layer_ptr;
}
- typename Types::LayerType* CreateMaskLayer(
- typename Types::LayerType* owning_layer,
- const gfx::Size& bounds) {
- typename Types::ContentLayerPtrType layer(
- Types::CreateContentLayer(GetHost()));
- typename Types::ContentLayerType* layer_ptr = layer.get();
+ LayerImpl* CreateMaskLayer(LayerImpl* owning_layer, const gfx::Size& bounds) {
+ LayerTreeImpl* tree = host_->host_impl()->active_tree();
+ int id = next_layer_impl_id_++;
+ scoped_ptr<TestContentLayerImpl> layer(new TestContentLayerImpl(tree, id));
+ TestContentLayerImpl* layer_ptr = layer.get();
SetProperties(layer_ptr, identity_matrix, gfx::PointF(), bounds);
- SetMask(owning_layer, Types::PassLayerPtr(&layer));
+ SetMask(owning_layer, layer.Pass());
return layer_ptr;
}
- typename Types::ContentLayerType* CreateDrawingSurface(
- typename Types::LayerType* parent,
- const gfx::Transform& transform,
- const gfx::PointF& position,
- const gfx::Size& bounds,
- bool opaque) {
- typename Types::ContentLayerType* layer =
+ TestContentLayerImpl* CreateDrawingSurface(LayerImpl* parent,
+ const gfx::Transform& transform,
+ const gfx::PointF& position,
+ const gfx::Size& bounds,
+ bool opaque) {
+ TestContentLayerImpl* layer =
CreateDrawingLayer(parent, transform, position, bounds, opaque);
- Types::SetForceRenderSurface(layer, true);
+ layer->SetHasRenderSurface(true);
return layer;
}
void DestroyLayers() {
- Types::DestroyLayer(&root_);
+ root_ = nullptr;
render_surface_layer_list_ = nullptr;
render_surface_layer_list_impl_.clear();
replica_layers_.clear();
@@ -296,18 +205,15 @@ template <typename Types> class OcclusionTrackerTest : public testing::Test {
void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}
void AddCopyRequest(Layer* layer) {
- layer->RequestCopyOfOutput(
- CopyOutputRequest::CreateBitmapRequest(base::Bind(
- &OcclusionTrackerTest<Types>::CopyOutputCallback,
- base::Unretained(this))));
+ layer->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
+ base::Bind(&OcclusionTrackerTest::CopyOutputCallback,
+ base::Unretained(this))));
}
void AddCopyRequest(LayerImpl* layer) {
ScopedPtrVector<CopyOutputRequest> requests;
- requests.push_back(
- CopyOutputRequest::CreateBitmapRequest(base::Bind(
- &OcclusionTrackerTest<Types>::CopyOutputCallback,
- base::Unretained(this))));
+ requests.push_back(CopyOutputRequest::CreateBitmapRequest(base::Bind(
+ &OcclusionTrackerTest::CopyOutputCallback, base::Unretained(this))));
layer->SetHasRenderSurface(true);
layer->PassCopyRequests(&requests);
}
@@ -315,54 +221,40 @@ template <typename Types> class OcclusionTrackerTest : public testing::Test {
void CalcDrawEtc(TestContentLayerImpl* root) {
DCHECK(root == root_.get());
- Types::RecursiveUpdateNumChildren(root);
- LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
- root, root->bounds(), &render_surface_layer_list_impl_);
- inputs.can_adjust_raster_scales = true;
- LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+ // These occlusion tests attach and detach layers in multiple
+ // iterations, so rebuild property trees every time.
+ root->layer_tree_impl()->property_trees()->needs_rebuild = true;
- layer_iterator_ = layer_iterator_begin_ =
- Types::TestLayerIterator::Begin(&render_surface_layer_list_impl_);
- }
+ FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(root);
- void CalcDrawEtc(TestContentLayer* root) {
- DCHECK(root == root_.get());
- DCHECK(!root->render_surface());
-
- render_surface_layer_list_.reset(new RenderSurfaceLayerList);
- LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
- root, root->bounds(), render_surface_layer_list_.get());
+ LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
+ root, root->bounds(), &render_surface_layer_list_impl_);
inputs.can_adjust_raster_scales = true;
LayerTreeHostCommon::CalculateDrawProperties(&inputs);
layer_iterator_ = layer_iterator_begin_ =
- Types::TestLayerIterator::Begin(render_surface_layer_list_.get());
+ LayerIterator::Begin(&render_surface_layer_list_impl_);
}
- void EnterLayer(typename Types::LayerType* layer,
- typename Types::OcclusionTrackerType* occlusion) {
+ void EnterLayer(LayerImpl* layer, OcclusionTracker* occlusion) {
ASSERT_EQ(*layer_iterator_, layer);
ASSERT_TRUE(layer_iterator_.represents_itself());
occlusion->EnterLayer(layer_iterator_);
}
- void LeaveLayer(typename Types::LayerType* layer,
- typename Types::OcclusionTrackerType* occlusion) {
+ void LeaveLayer(LayerImpl* layer, OcclusionTracker* occlusion) {
ASSERT_EQ(*layer_iterator_, layer);
ASSERT_TRUE(layer_iterator_.represents_itself());
occlusion->LeaveLayer(layer_iterator_);
++layer_iterator_;
}
- void VisitLayer(typename Types::LayerType* layer,
- typename Types::OcclusionTrackerType* occlusion) {
+ void VisitLayer(LayerImpl* layer, OcclusionTracker* occlusion) {
EnterLayer(layer, occlusion);
LeaveLayer(layer, occlusion);
}
- void EnterContributingSurface(
- typename Types::LayerType* layer,
- typename Types::OcclusionTrackerType* occlusion) {
+ void EnterContributingSurface(LayerImpl* layer, OcclusionTracker* occlusion) {
ASSERT_EQ(*layer_iterator_, layer);
ASSERT_TRUE(layer_iterator_.represents_target_render_surface());
occlusion->EnterLayer(layer_iterator_);
@@ -372,18 +264,14 @@ template <typename Types> class OcclusionTrackerTest : public testing::Test {
occlusion->EnterLayer(layer_iterator_);
}
- void LeaveContributingSurface(
- typename Types::LayerType* layer,
- typename Types::OcclusionTrackerType* occlusion) {
+ void LeaveContributingSurface(LayerImpl* layer, OcclusionTracker* occlusion) {
ASSERT_EQ(*layer_iterator_, layer);
ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface());
occlusion->LeaveLayer(layer_iterator_);
++layer_iterator_;
}
- void VisitContributingSurface(
- typename Types::LayerType* layer,
- typename Types::OcclusionTrackerType* occlusion) {
+ void VisitContributingSurface(LayerImpl* layer, OcclusionTracker* occlusion) {
EnterContributingSurface(layer, occlusion);
LeaveContributingSurface(layer, occlusion);
}
@@ -399,148 +287,72 @@ template <typename Types> class OcclusionTrackerTest : public testing::Test {
void SetRootLayerOnMainThread(LayerImpl* root) {}
- void SetBaseProperties(typename Types::LayerType* layer,
- const gfx::Transform& transform,
- const gfx::PointF& position,
- const gfx::Size& bounds) {
- layer->SetTransform(transform);
- layer->SetPosition(position);
- layer->SetBounds(bounds);
- }
-
- void SetProperties(Layer* layer,
- const gfx::Transform& transform,
- const gfx::PointF& position,
- const gfx::Size& bounds) {
- SetBaseProperties(layer, transform, position, bounds);
- }
-
void SetProperties(LayerImpl* layer,
const gfx::Transform& transform,
const gfx::PointF& position,
const gfx::Size& bounds) {
- SetBaseProperties(layer, transform, position, bounds);
-
- layer->SetContentBounds(layer->bounds());
- }
-
- void SetReplica(Layer* owning_layer, scoped_refptr<Layer> layer) {
- owning_layer->SetReplicaLayer(layer.get());
- replica_layers_.push_back(layer);
+ layer->SetTransform(transform);
+ layer->SetPosition(position);
+ layer->SetBounds(bounds);
}
void SetReplica(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
owning_layer->SetReplicaLayer(layer.Pass());
}
- void SetMask(Layer* owning_layer, scoped_refptr<Layer> layer) {
- owning_layer->SetMaskLayer(layer.get());
- mask_layers_.push_back(layer);
- }
-
void SetMask(LayerImpl* owning_layer, scoped_ptr<LayerImpl> layer) {
owning_layer->SetMaskLayer(layer.Pass());
}
bool opaque_layers_;
FakeLayerTreeHostClient client_;
+ TestTaskGraphRunner task_graph_runner_;
scoped_ptr<FakeLayerTreeHost> host_;
// These hold ownership of the layers for the duration of the test.
- typename Types::LayerPtrType root_;
+ scoped_ptr<LayerImpl> root_;
scoped_ptr<RenderSurfaceLayerList> render_surface_layer_list_;
LayerImplList render_surface_layer_list_impl_;
- typename Types::TestLayerIterator layer_iterator_begin_;
- typename Types::TestLayerIterator layer_iterator_;
- typename Types::LayerType* last_layer_visited_;
+ LayerIterator layer_iterator_begin_;
+ LayerIterator layer_iterator_;
LayerList replica_layers_;
LayerList mask_layers_;
+ int next_layer_impl_id_;
};
-template <>
-FakeLayerTreeHost*
-OcclusionTrackerTest<OcclusionTrackerTestMainThreadTypes>::GetHost() {
- return host_.get();
-}
-
-template <>
-LayerTreeImpl*
-OcclusionTrackerTest<OcclusionTrackerTestImplThreadTypes>::GetHost() {
- return host_->host_impl()->active_tree();
-}
-
-#define RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
- class ClassName##MainThreadOpaqueLayers \
- : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
- public: /* NOLINT(whitespace/indent) */ \
- ClassName##MainThreadOpaqueLayers() \
- : ClassName<OcclusionTrackerTestMainThreadTypes>(true) {} \
- }; \
- TEST_F(ClassName##MainThreadOpaqueLayers, RunTest) { RunMyTest(); }
-#define RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
- class ClassName##MainThreadOpaquePaints \
- : public ClassName<OcclusionTrackerTestMainThreadTypes> { \
- public: /* NOLINT(whitespace/indent) */ \
- ClassName##MainThreadOpaquePaints() \
- : ClassName<OcclusionTrackerTestMainThreadTypes>(false) {} \
- }; \
- TEST_F(ClassName##MainThreadOpaquePaints, RunTest) { RunMyTest(); }
-
-#define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
- class ClassName##ImplThreadOpaqueLayers \
- : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
- public: /* NOLINT(whitespace/indent) */ \
- ClassName##ImplThreadOpaqueLayers() \
- : ClassName<OcclusionTrackerTestImplThreadTypes>(true) {} \
- }; \
+#define RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
+ class ClassName##ImplThreadOpaqueLayers : public ClassName { \
+ public: /* NOLINT(whitespace/indent) */ \
+ ClassName##ImplThreadOpaqueLayers() : ClassName(true) {} \
+ }; \
TEST_F(ClassName##ImplThreadOpaqueLayers, RunTest) { RunMyTest(); }
-#define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
- class ClassName##ImplThreadOpaquePaints \
- : public ClassName<OcclusionTrackerTestImplThreadTypes> { \
- public: /* NOLINT(whitespace/indent) */ \
- ClassName##ImplThreadOpaquePaints() \
- : ClassName<OcclusionTrackerTestImplThreadTypes>(false) {} \
- }; \
+#define RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName) \
+ class ClassName##ImplThreadOpaquePaints : public ClassName { \
+ public: /* NOLINT(whitespace/indent) */ \
+ ClassName##ImplThreadOpaquePaints() : ClassName(false) {} \
+ }; \
TEST_F(ClassName##ImplThreadOpaquePaints, RunTest) { RunMyTest(); }
#define ALL_OCCLUSIONTRACKER_TEST(ClassName) \
- RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
- RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
-#define MAIN_THREAD_TEST(ClassName) \
- RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
-
-#define IMPL_THREAD_TEST(ClassName) \
- RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
-
-#define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
- RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
- RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
-
-template <class Types>
-class OcclusionTrackerTestIdentityTransforms
- : public OcclusionTrackerTest<Types> {
+class OcclusionTrackerTestIdentityTransforms : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestIdentityTransforms(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
- typename Types::ContentLayerType* root = this->CreateRoot(
+ TestContentLayerImpl* root = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
- typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
+ TestContentLayerImpl* parent = this->CreateDrawingLayer(
root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
- typename Types::ContentLayerType* layer =
- this->CreateDrawingLayer(parent,
- this->identity_matrix,
- gfx::PointF(30.f, 30.f),
- gfx::Size(500, 500),
- true);
+ TestContentLayerImpl* layer = this->CreateDrawingLayer(
+ parent, this->identity_matrix, gfx::PointF(30.f, 30.f),
+ gfx::Size(500, 500), true);
parent->SetMasksToBounds(true);
this->CalcDrawEtc(root);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
this->VisitLayer(layer, &occlusion);
this->EnterLayer(parent, &occlusion);
@@ -554,32 +366,27 @@ class OcclusionTrackerTestIdentityTransforms
ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms);
-template <class Types>
-class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest<Types> {
+class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestRotatedChild(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
gfx::Transform layer_transform;
layer_transform.Translate(250.0, 250.0);
layer_transform.Rotate(90.0);
layer_transform.Translate(-250.0, -250.0);
- typename Types::ContentLayerType* root = this->CreateRoot(
+ TestContentLayerImpl* root = this->CreateRoot(
this->identity_matrix, gfx::Point(0, 0), gfx::Size(200, 200));
- typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
+ TestContentLayerImpl* parent = this->CreateDrawingLayer(
root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
- typename Types::ContentLayerType* layer =
- this->CreateDrawingLayer(parent,
- layer_transform,
- gfx::PointF(30.f, 30.f),
- gfx::Size(500, 500),
- true);
+ TestContentLayerImpl* layer = this->CreateDrawingLayer(
+ parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500),
+ true);
parent->SetMasksToBounds(true);
this->CalcDrawEtc(root);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
this->VisitLayer(layer, &occlusion);
this->EnterLayer(parent, &occlusion);
@@ -593,30 +400,25 @@ class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest<Types> {
ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestRotatedChild);
-template <class Types>
-class OcclusionTrackerTestTranslatedChild : public OcclusionTrackerTest<Types> {
+class OcclusionTrackerTestTranslatedChild : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestTranslatedChild(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
gfx::Transform layer_transform;
layer_transform.Translate(20.0, 20.0);
- typename Types::ContentLayerType* root = this->CreateRoot(
+ TestContentLayerImpl* root = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
- typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
+ TestContentLayerImpl* parent = this->CreateDrawingLayer(
root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
- typename Types::ContentLayerType* layer =
- this->CreateDrawingLayer(parent,
- layer_transform,
- gfx::PointF(30.f, 30.f),
- gfx::Size(500, 500),
- true);
+ TestContentLayerImpl* layer = this->CreateDrawingLayer(
+ parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500),
+ true);
parent->SetMasksToBounds(true);
this->CalcDrawEtc(root);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
this->VisitLayer(layer, &occlusion);
this->EnterLayer(parent, &occlusion);
@@ -630,34 +432,28 @@ class OcclusionTrackerTestTranslatedChild : public OcclusionTrackerTest<Types> {
ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestTranslatedChild);
-template <class Types>
-class OcclusionTrackerTestChildInRotatedChild
- : public OcclusionTrackerTest<Types> {
+class OcclusionTrackerTestChildInRotatedChild : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestChildInRotatedChild(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
gfx::Transform child_transform;
child_transform.Translate(250.0, 250.0);
child_transform.Rotate(90.0);
child_transform.Translate(-250.0, -250.0);
- typename Types::ContentLayerType* parent = this->CreateRoot(
+ TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
parent->SetMasksToBounds(true);
- typename Types::LayerType* child = this->CreateSurface(
+ LayerImpl* child = this->CreateSurface(
parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
child->SetMasksToBounds(true);
- typename Types::ContentLayerType* layer =
- this->CreateDrawingLayer(child,
- this->identity_matrix,
- gfx::PointF(10.f, 10.f),
- gfx::Size(500, 500),
- true);
+ TestContentLayerImpl* layer = this->CreateDrawingLayer(
+ child, this->identity_matrix, gfx::PointF(10.f, 10.f),
+ gfx::Size(500, 500), true);
this->CalcDrawEtc(parent);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
this->VisitLayer(layer, &occlusion);
this->EnterContributingSurface(child, &occlusion);
@@ -727,37 +523,31 @@ class OcclusionTrackerTestChildInRotatedChild
ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestChildInRotatedChild);
-template <class Types>
-class OcclusionTrackerTestScaledRenderSurface
- : public OcclusionTrackerTest<Types> {
+class OcclusionTrackerTestScaledRenderSurface : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestScaledRenderSurface(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
- typename Types::ContentLayerType* parent = this->CreateRoot(
+ TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
gfx::Transform layer1_matrix;
layer1_matrix.Scale(2.0, 2.0);
- typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer(
+ TestContentLayerImpl* layer1 = this->CreateDrawingLayer(
parent, layer1_matrix, gfx::PointF(), gfx::Size(100, 100), true);
- Types::SetForceRenderSurface(layer1, true);
+ layer1->SetHasRenderSurface(true);
gfx::Transform layer2_matrix;
layer2_matrix.Translate(25.0, 25.0);
- typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer(
+ TestContentLayerImpl* layer2 = this->CreateDrawingLayer(
layer1, layer2_matrix, gfx::PointF(), gfx::Size(50, 50), true);
- typename Types::ContentLayerType* occluder =
- this->CreateDrawingLayer(parent,
- this->identity_matrix,
- gfx::PointF(100.f, 100.f),
- gfx::Size(500, 500),
- true);
+ TestContentLayerImpl* occluder = this->CreateDrawingLayer(
+ parent, this->identity_matrix, gfx::PointF(100.f, 100.f),
+ gfx::Size(500, 500), true);
this->CalcDrawEtc(parent);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
this->VisitLayer(occluder, &occlusion);
this->EnterLayer(layer2, &occlusion);
@@ -771,37 +561,28 @@ class OcclusionTrackerTestScaledRenderSurface
ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledRenderSurface);
-template <class Types>
-class OcclusionTrackerTestVisitTargetTwoTimes
- : public OcclusionTrackerTest<Types> {
+class OcclusionTrackerTestVisitTargetTwoTimes : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
- typename Types::ContentLayerType* root = this->CreateRoot(
+ TestContentLayerImpl* root = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
- typename Types::LayerType* surface = this->CreateSurface(
+ LayerImpl* surface = this->CreateSurface(
root, this->identity_matrix, gfx::PointF(30.f, 30.f), gfx::Size());
- typename Types::ContentLayerType* surface_child =
- this->CreateDrawingLayer(surface,
- this->identity_matrix,
- gfx::PointF(10.f, 10.f),
- gfx::Size(50, 50),
- true);
+ TestContentLayerImpl* surface_child = this->CreateDrawingLayer(
+ surface, this->identity_matrix, gfx::PointF(10.f, 10.f),
+ gfx::Size(50, 50), true);
// |top_layer| makes |root|'s surface get considered by OcclusionTracker
// first, instead of |surface|'s. This exercises different code in
// LeaveToRenderTarget, as the target surface has already been seen when
// leaving |surface| later.
- typename Types::ContentLayerType* top_layer =
- this->CreateDrawingLayer(root,
- this->identity_matrix,
- gfx::PointF(40.f, 90.f),
- gfx::Size(50, 20),
- true);
+ TestContentLayerImpl* top_layer = this->CreateDrawingLayer(
+ root, this->identity_matrix, gfx::PointF(40.f, 90.f), gfx::Size(50, 20),
+ true);
this->CalcDrawEtc(root);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
this->VisitLayer(top_layer, &occlusion);
@@ -837,12 +618,10 @@ class OcclusionTrackerTestVisitTargetTwoTimes
ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestVisitTargetTwoTimes);
-template <class Types>
-class OcclusionTrackerTestSurfaceRotatedOffAxis
- : public OcclusionTrackerTest<Types> {
+class OcclusionTrackerTestSurfaceRotatedOffAxis : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestSurfaceRotatedOffAxis(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
gfx::Transform child_transform;
child_transform.Translate(250.0, 250.0);
@@ -852,21 +631,20 @@ class OcclusionTrackerTestSurfaceRotatedOffAxis
gfx::Transform layer_transform;
layer_transform.Translate(10.0, 10.0);
- typename Types::ContentLayerType* root = this->CreateRoot(
+ TestContentLayerImpl* root = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
- typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
+ TestContentLayerImpl* parent = this->CreateDrawingLayer(
root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
- typename Types::LayerType* child = this->CreateSurface(
+ LayerImpl* child = this->CreateSurface(
parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500));
- typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
+ TestContentLayerImpl* layer = this->CreateDrawingLayer(
child, layer_transform, gfx::PointF(), gfx::Size(500, 500), true);
this->CalcDrawEtc(root);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
gfx::Rect clipped_layer_in_child = MathUtil::MapEnclosingClippedRect(
- layer_transform, layer->visible_content_rect());
+ layer_transform, layer->visible_layer_rect());
this->VisitLayer(layer, &occlusion);
this->EnterContributingSurface(child, &occlusion);
@@ -888,46 +666,35 @@ class OcclusionTrackerTestSurfaceRotatedOffAxis
ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceRotatedOffAxis);
-template <class Types>
class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
- : public OcclusionTrackerTest<Types> {
+ : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestSurfaceWithTwoOpaqueChildren(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
gfx::Transform child_transform;
child_transform.Translate(250.0, 250.0);
child_transform.Rotate(90.0);
child_transform.Translate(-250.0, -250.0);
- typename Types::ContentLayerType* root = this->CreateRoot(
+ TestContentLayerImpl* root = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000));
- typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
+ TestContentLayerImpl* parent = this->CreateDrawingLayer(
root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true);
parent->SetMasksToBounds(true);
- typename Types::ContentLayerType* child =
- this->CreateDrawingSurface(parent,
- child_transform,
- gfx::PointF(30.f, 30.f),
- gfx::Size(500, 500),
- false);
+ TestContentLayerImpl* child = this->CreateDrawingSurface(
+ parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500),
+ false);
child->SetMasksToBounds(true);
- typename Types::ContentLayerType* layer1 =
- this->CreateDrawingLayer(child,
- this->identity_matrix,
- gfx::PointF(10.f, 10.f),
- gfx::Size(500, 500),
- true);
- typename Types::ContentLayerType* layer2 =
- this->CreateDrawingLayer(child,
- this->identity_matrix,
- gfx::PointF(10.f, 450.f),
- gfx::Size(500, 60),
- true);
+ TestContentLayerImpl* layer1 = this->CreateDrawingLayer(
+ child, this->identity_matrix, gfx::PointF(10.f, 10.f),
+ gfx::Size(500, 500), true);
+ TestContentLayerImpl* layer2 = this->CreateDrawingLayer(
+ child, this->identity_matrix, gfx::PointF(10.f, 450.f),
+ gfx::Size(500, 60), true);
this->CalcDrawEtc(root);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
this->VisitLayer(layer2, &occlusion);
this->VisitLayer(layer1, &occlusion);
@@ -976,32 +743,27 @@ class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren
ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithTwoOpaqueChildren);
-template <class Types>
class OcclusionTrackerTestOverlappingSurfaceSiblings
- : public OcclusionTrackerTest<Types> {
+ : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
- typename Types::ContentLayerType* parent = this->CreateRoot(
+ TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
parent->SetMasksToBounds(true);
- typename Types::LayerType* child1 = this->CreateSurface(
+ LayerImpl* child1 = this->CreateSurface(
parent, this->identity_matrix, gfx::PointF(10.f, 0.f), gfx::Size());
- typename Types::LayerType* child2 = this->CreateSurface(
+ LayerImpl* child2 = this->CreateSurface(
parent, this->identity_matrix, gfx::PointF(30.f, 0.f), gfx::Size());
- typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer(
+ TestContentLayerImpl* layer1 = this->CreateDrawingLayer(
child1, this->identity_matrix, gfx::PointF(), gfx::Size(40, 50), true);
- typename Types::ContentLayerType* layer2 =
- this->CreateDrawingLayer(child2,
- this->identity_matrix,
- gfx::PointF(10.f, 0.f),
- gfx::Size(40, 50),
- true);
+ TestContentLayerImpl* layer2 = this->CreateDrawingLayer(
+ child2, this->identity_matrix, gfx::PointF(10.f, 0.f),
+ gfx::Size(40, 50), true);
this->CalcDrawEtc(parent);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
this->VisitLayer(layer2, &occlusion);
this->EnterContributingSurface(child2, &occlusion);
@@ -1035,13 +797,12 @@ class OcclusionTrackerTestOverlappingSurfaceSiblings
ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOverlappingSurfaceSiblings);
-template <class Types>
class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
- : public OcclusionTrackerTest<Types> {
+ : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms(
bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
gfx::Transform child1_transform;
child1_transform.Translate(250.0, 250.0);
@@ -1053,33 +814,23 @@ class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
child2_transform.Rotate(90.0);
child2_transform.Translate(-250.0, -250.0);
- typename Types::ContentLayerType* parent = this->CreateRoot(
+ TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
parent->SetMasksToBounds(true);
- typename Types::LayerType* child1 = this->CreateSurface(
+ LayerImpl* child1 = this->CreateSurface(
parent, child1_transform, gfx::PointF(30.f, 20.f), gfx::Size(10, 10));
- typename Types::LayerType* child2 =
- this->CreateDrawingSurface(parent,
- child2_transform,
- gfx::PointF(20.f, 40.f),
- gfx::Size(10, 10),
- false);
- typename Types::ContentLayerType* layer1 =
- this->CreateDrawingLayer(child1,
- this->identity_matrix,
- gfx::PointF(-10.f, -20.f),
- gfx::Size(510, 510),
- true);
- typename Types::ContentLayerType* layer2 =
- this->CreateDrawingLayer(child2,
- this->identity_matrix,
- gfx::PointF(-10.f, -10.f),
- gfx::Size(510, 510),
- true);
+ LayerImpl* child2 = this->CreateDrawingSurface(parent, child2_transform,
+ gfx::PointF(20.f, 40.f),
+ gfx::Size(10, 10), false);
+ TestContentLayerImpl* layer1 = this->CreateDrawingLayer(
+ child1, this->identity_matrix, gfx::PointF(-10.f, -20.f),
+ gfx::Size(510, 510), true);
+ TestContentLayerImpl* layer2 = this->CreateDrawingLayer(
+ child2, this->identity_matrix, gfx::PointF(-10.f, -10.f),
+ gfx::Size(510, 510), true);
this->CalcDrawEtc(parent);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
this->VisitLayer(layer2, &occlusion);
this->EnterLayer(child2, &occlusion);
@@ -1143,58 +894,47 @@ class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms
ALL_OCCLUSIONTRACKER_TEST(
OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms);
-template <class Types>
-class OcclusionTrackerTestFilters : public OcclusionTrackerTest<Types> {
+class OcclusionTrackerTestFilters : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestFilters(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
gfx::Transform layer_transform;
layer_transform.Translate(250.0, 250.0);
layer_transform.Rotate(90.0);
layer_transform.Translate(-250.0, -250.0);
- typename Types::ContentLayerType* parent = this->CreateRoot(
+ TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
parent->SetMasksToBounds(true);
- typename Types::ContentLayerType* blur_layer =
- this->CreateDrawingLayer(parent,
- layer_transform,
- gfx::PointF(30.f, 30.f),
- gfx::Size(500, 500),
- true);
- typename Types::ContentLayerType* opaque_layer =
- this->CreateDrawingLayer(parent,
- layer_transform,
- gfx::PointF(30.f, 30.f),
- gfx::Size(500, 500),
- true);
- typename Types::ContentLayerType* opacity_layer =
- this->CreateDrawingLayer(parent,
- layer_transform,
- gfx::PointF(30.f, 30.f),
- gfx::Size(500, 500),
- true);
-
- Types::SetForceRenderSurface(blur_layer, true);
+ TestContentLayerImpl* blur_layer = this->CreateDrawingLayer(
+ parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500),
+ true);
+ TestContentLayerImpl* opaque_layer = this->CreateDrawingLayer(
+ parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500),
+ true);
+ TestContentLayerImpl* opacity_layer = this->CreateDrawingLayer(
+ parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500),
+ true);
+
+ blur_layer->SetHasRenderSurface(true);
FilterOperations filters;
filters.Append(FilterOperation::CreateBlurFilter(10.f));
blur_layer->SetFilters(filters);
- Types::SetForceRenderSurface(opaque_layer, true);
+ opaque_layer->SetHasRenderSurface(true);
filters.Clear();
filters.Append(FilterOperation::CreateGrayscaleFilter(0.5f));
opaque_layer->SetFilters(filters);
- Types::SetForceRenderSurface(opacity_layer, true);
+ opacity_layer->SetHasRenderSurface(true);
filters.Clear();
filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
opacity_layer->SetFilters(filters);
this->CalcDrawEtc(parent);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
// Opacity layer won't contribute to occlusion.
this->VisitLayer(opacity_layer, &occlusion);
@@ -1245,23 +985,20 @@ class OcclusionTrackerTestFilters : public OcclusionTrackerTest<Types> {
ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestFilters);
-template <class Types>
-class OcclusionTrackerTestReplicaDoesOcclude
- : public OcclusionTrackerTest<Types> {
+class OcclusionTrackerTestReplicaDoesOcclude : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestReplicaDoesOcclude(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
- typename Types::ContentLayerType* parent = this->CreateRoot(
+ TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
- typename Types::LayerType* surface = this->CreateDrawingSurface(
+ LayerImpl* surface = this->CreateDrawingSurface(
parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), true);
this->CreateReplicaLayer(
surface, this->identity_matrix, gfx::PointF(0.f, 50.f), gfx::Size());
this->CalcDrawEtc(parent);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
this->VisitLayer(surface, &occlusion);
@@ -1279,28 +1016,22 @@ class OcclusionTrackerTestReplicaDoesOcclude
ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaDoesOcclude);
-template <class Types>
-class OcclusionTrackerTestReplicaWithClipping
- : public OcclusionTrackerTest<Types> {
+class OcclusionTrackerTestReplicaWithClipping : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestReplicaWithClipping(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
- typename Types::ContentLayerType* parent = this->CreateRoot(
+ TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(100, 170));
parent->SetMasksToBounds(true);
- typename Types::LayerType* surface =
- this->CreateDrawingSurface(parent,
- this->identity_matrix,
- gfx::PointF(0.f, 100.f),
- gfx::Size(50, 50),
- true);
+ LayerImpl* surface = this->CreateDrawingSurface(
+ parent, this->identity_matrix, gfx::PointF(0.f, 100.f),
+ gfx::Size(50, 50), true);
this->CreateReplicaLayer(
surface, this->identity_matrix, gfx::PointF(0.f, 50.f), gfx::Size());
this->CalcDrawEtc(parent);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
this->VisitLayer(surface, &occlusion);
@@ -1322,27 +1053,22 @@ class OcclusionTrackerTestReplicaWithClipping
ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithClipping);
-template <class Types>
-class OcclusionTrackerTestReplicaWithMask : public OcclusionTrackerTest<Types> {
+class OcclusionTrackerTestReplicaWithMask : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestReplicaWithMask(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
- typename Types::ContentLayerType* parent = this->CreateRoot(
+ TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
- typename Types::LayerType* surface =
- this->CreateDrawingSurface(parent,
- this->identity_matrix,
- gfx::PointF(0.f, 100.f),
- gfx::Size(50, 50),
- true);
- typename Types::LayerType* replica = this->CreateReplicaLayer(
+ LayerImpl* surface = this->CreateDrawingSurface(
+ parent, this->identity_matrix, gfx::PointF(0.f, 100.f),
+ gfx::Size(50, 50), true);
+ LayerImpl* replica = this->CreateReplicaLayer(
surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size());
this->CreateMaskLayer(replica, gfx::Size(10, 10));
this->CalcDrawEtc(parent);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
this->VisitLayer(surface, &occlusion);
@@ -1361,25 +1087,20 @@ class OcclusionTrackerTestReplicaWithMask : public OcclusionTrackerTest<Types> {
ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaWithMask);
-template <class Types>
class OcclusionTrackerTestOpaqueContentsRegionEmpty
- : public OcclusionTrackerTest<Types> {
+ : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
- typename Types::ContentLayerType* parent = this->CreateRoot(
+ TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
- typename Types::ContentLayerType* layer =
- this->CreateDrawingSurface(parent,
- this->identity_matrix,
- gfx::PointF(),
- gfx::Size(200, 200),
- false);
+ TestContentLayerImpl* layer =
+ this->CreateDrawingSurface(parent, this->identity_matrix, gfx::PointF(),
+ gfx::Size(200, 200), false);
this->CalcDrawEtc(parent);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
this->EnterLayer(layer, &occlusion);
EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
@@ -1394,27 +1115,22 @@ class OcclusionTrackerTestOpaqueContentsRegionEmpty
}
};
-MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty);
+ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOpaqueContentsRegionEmpty);
-template <class Types>
class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
- : public OcclusionTrackerTest<Types> {
+ : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
- typename Types::ContentLayerType* parent = this->CreateRoot(
+ TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
- typename Types::ContentLayerType* layer =
- this->CreateDrawingLayer(parent,
- this->identity_matrix,
- gfx::PointF(100.f, 100.f),
- gfx::Size(200, 200),
- false);
+ TestContentLayerImpl* layer = this->CreateDrawingLayer(
+ parent, this->identity_matrix, gfx::PointF(100.f, 100.f),
+ gfx::Size(200, 200), false);
this->CalcDrawEtc(parent);
{
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
layer->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100));
this->ResetLayerIterator();
@@ -1425,8 +1141,7 @@ class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
occlusion.occlusion_from_inside_target().ToString());
}
{
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
layer->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180));
this->ResetLayerIterator();
@@ -1437,8 +1152,7 @@ class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
occlusion.occlusion_from_inside_target().ToString());
}
{
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
layer->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100));
this->ResetLayerIterator();
@@ -1451,67 +1165,14 @@ class OcclusionTrackerTestOpaqueContentsRegionNonEmpty
}
};
-MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty);
-
-template <class Types>
-class OcclusionTrackerTestUnsorted3dLayers
- : public OcclusionTrackerTest<Types> {
- protected:
- explicit OcclusionTrackerTestUnsorted3dLayers(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
- void RunMyTest() override {
- // Currently, The main thread layer iterator does not iterate over 3d items
- // in sorted order, because layer sorting is not performed on the main
- // thread. Because of this, the occlusion tracker cannot assume that a 3d
- // layer occludes other layers that have not yet been iterated over. For
- // now, the expected behavior is that a 3d layer simply does not add any
- // occlusion to the occlusion tracker.
-
- gfx::Transform translation_to_front;
- translation_to_front.Translate3d(0.0, 0.0, -10.0);
- gfx::Transform translation_to_back;
- translation_to_front.Translate3d(0.0, 0.0, -100.0);
-
- typename Types::ContentLayerType* parent = this->CreateRoot(
- this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
- typename Types::ContentLayerType* child1 = this->CreateDrawingLayer(
- parent, translation_to_back, gfx::PointF(), gfx::Size(100, 100), true);
- typename Types::ContentLayerType* child2 =
- this->CreateDrawingLayer(parent,
- translation_to_front,
- gfx::PointF(50.f, 50.f),
- gfx::Size(100, 100),
- true);
- parent->SetShouldFlattenTransform(false);
- parent->Set3dSortingContextId(1);
- child1->Set3dSortingContextId(1);
- child2->Set3dSortingContextId(1);
-
- this->CalcDrawEtc(parent);
-
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
- this->VisitLayer(child2, &occlusion);
- EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
- EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
-
- this->VisitLayer(child1, &occlusion);
- EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty());
- EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty());
- }
-};
-
-// This test will have different layer ordering on the impl thread; the test
-// will only work on the main thread.
-MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers);
+ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty);
-template <class Types>
class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
- : public OcclusionTrackerTest<Types> {
+ : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestLayerBehindCameraDoesNotOcclude(
bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
gfx::Transform transform;
transform.Translate(50.0, 50.0);
@@ -1519,9 +1180,9 @@ class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
transform.Translate3d(0.0, 0.0, 110.0);
transform.Translate(-50.0, -50.0);
- typename Types::ContentLayerType* parent = this->CreateRoot(
+ TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
- typename Types::ContentLayerType* layer = this->CreateDrawingLayer(
+ TestContentLayerImpl* layer = this->CreateDrawingLayer(
parent, transform, gfx::PointF(), gfx::Size(100, 100), true);
parent->SetShouldFlattenTransform(false);
parent->Set3dSortingContextId(1);
@@ -1529,8 +1190,7 @@ class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
layer->Set3dSortingContextId(1);
this->CalcDrawEtc(parent);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
// The |layer| is entirely behind the camera and should not occlude.
this->VisitLayer(layer, &occlusion);
@@ -1540,394 +1200,30 @@ class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude
}
};
-template <class Types>
-class OcclusionTrackerTestAnimationOpacity1OnMainThread
- : public OcclusionTrackerTest<Types> {
- protected:
- explicit OcclusionTrackerTestAnimationOpacity1OnMainThread(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
- void RunMyTest() override {
- // parent
- // +--layer
- // +--surface
- // | +--surface_child
- // | +--surface_child2
- // +--parent2
- // +--topmost
-
- typename Types::ContentLayerType* parent = this->CreateRoot(
- this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
- typename Types::ContentLayerType* layer =
- this->CreateDrawingLayer(parent,
- this->identity_matrix,
- gfx::PointF(),
- gfx::Size(300, 300),
- true);
- typename Types::ContentLayerType* surface =
- this->CreateDrawingSurface(parent,
- this->identity_matrix,
- gfx::PointF(),
- gfx::Size(300, 300),
- true);
- typename Types::ContentLayerType* surface_child =
- this->CreateDrawingLayer(surface,
- this->identity_matrix,
- gfx::PointF(),
- gfx::Size(200, 300),
- true);
- typename Types::ContentLayerType* surface_child2 =
- this->CreateDrawingLayer(surface,
- this->identity_matrix,
- gfx::PointF(),
- gfx::Size(100, 300),
- true);
- typename Types::ContentLayerType* parent2 =
- this->CreateDrawingLayer(parent,
- this->identity_matrix,
- gfx::PointF(),
- gfx::Size(300, 300),
- false);
- typename Types::ContentLayerType* topmost =
- this->CreateDrawingLayer(parent,
- this->identity_matrix,
- gfx::PointF(250.f, 0.f),
- gfx::Size(50, 300),
- true);
-
- AddOpacityTransitionToController(
- layer->layer_animation_controller(), 10.0, 0.f, 1.f, false);
- AddOpacityTransitionToController(
- surface->layer_animation_controller(), 10.0, 0.f, 1.f, false);
- this->CalcDrawEtc(parent);
-
- EXPECT_TRUE(layer->draw_opacity_is_animating());
- EXPECT_FALSE(surface->draw_opacity_is_animating());
- EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating());
-
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
-
- this->VisitLayer(topmost, &occlusion);
- this->EnterLayer(parent2, &occlusion);
-
- // This occlusion will affect all surfaces.
- EXPECT_EQ(gfx::Rect().ToString(),
- occlusion.occlusion_from_outside_target().ToString());
- EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
- occlusion.occlusion_from_inside_target().ToString());
-
- this->LeaveLayer(parent2, &occlusion);
- this->VisitLayer(surface_child2, &occlusion);
- this->EnterLayer(surface_child, &occlusion);
- EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
- occlusion.occlusion_from_outside_target().ToString());
- EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
- occlusion.occlusion_from_inside_target().ToString());
-
- this->LeaveLayer(surface_child, &occlusion);
- this->EnterLayer(surface, &occlusion);
- EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
- occlusion.occlusion_from_outside_target().ToString());
- EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
- occlusion.occlusion_from_inside_target().ToString());
-
- this->LeaveLayer(surface, &occlusion);
- this->EnterContributingSurface(surface, &occlusion);
- // Occlusion within the surface is lost when leaving the animating surface.
- EXPECT_EQ(gfx::Rect().ToString(),
- occlusion.occlusion_from_outside_target().ToString());
- EXPECT_EQ(gfx::Rect().ToString(),
- occlusion.occlusion_from_inside_target().ToString());
-
- this->LeaveContributingSurface(surface, &occlusion);
- // Occlusion from outside the animating surface still exists.
- EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
- occlusion.occlusion_from_inside_target().ToString());
- EXPECT_EQ(gfx::Rect().ToString(),
- occlusion.occlusion_from_outside_target().ToString());
-
- this->VisitLayer(layer, &occlusion);
- this->EnterLayer(parent, &occlusion);
-
- // Occlusion is not added for the animating |layer|.
- EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
- occlusion.occlusion_from_inside_target().ToString());
- EXPECT_EQ(gfx::Rect().ToString(),
- occlusion.occlusion_from_outside_target().ToString());
- }
-};
-
-MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity1OnMainThread);
-
-template <class Types>
-class OcclusionTrackerTestAnimationOpacity0OnMainThread
- : public OcclusionTrackerTest<Types> {
- protected:
- explicit OcclusionTrackerTestAnimationOpacity0OnMainThread(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
- void RunMyTest() override {
- typename Types::ContentLayerType* parent = this->CreateRoot(
- this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
- typename Types::ContentLayerType* layer =
- this->CreateDrawingLayer(parent,
- this->identity_matrix,
- gfx::PointF(),
- gfx::Size(300, 300),
- true);
- typename Types::ContentLayerType* surface =
- this->CreateDrawingSurface(parent,
- this->identity_matrix,
- gfx::PointF(),
- gfx::Size(300, 300),
- true);
- typename Types::ContentLayerType* surface_child =
- this->CreateDrawingLayer(surface,
- this->identity_matrix,
- gfx::PointF(),
- gfx::Size(200, 300),
- true);
- typename Types::ContentLayerType* surface_child2 =
- this->CreateDrawingLayer(surface,
- this->identity_matrix,
- gfx::PointF(),
- gfx::Size(100, 300),
- true);
- typename Types::ContentLayerType* parent2 =
- this->CreateDrawingLayer(parent,
- this->identity_matrix,
- gfx::PointF(),
- gfx::Size(300, 300),
- false);
- typename Types::ContentLayerType* topmost =
- this->CreateDrawingLayer(parent,
- this->identity_matrix,
- gfx::PointF(250.f, 0.f),
- gfx::Size(50, 300),
- true);
-
- AddOpacityTransitionToController(
- layer->layer_animation_controller(), 10.0, 1.f, 0.f, false);
- AddOpacityTransitionToController(
- surface->layer_animation_controller(), 10.0, 1.f, 0.f, false);
- this->CalcDrawEtc(parent);
-
- EXPECT_TRUE(layer->draw_opacity_is_animating());
- EXPECT_FALSE(surface->draw_opacity_is_animating());
- EXPECT_TRUE(surface->render_surface()->draw_opacity_is_animating());
-
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
-
- this->VisitLayer(topmost, &occlusion);
- this->EnterLayer(parent2, &occlusion);
- // This occlusion will affect all surfaces.
- EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
- occlusion.occlusion_from_inside_target().ToString());
- EXPECT_EQ(gfx::Rect().ToString(),
- occlusion.occlusion_from_outside_target().ToString());
-
- this->LeaveLayer(parent2, &occlusion);
- this->VisitLayer(surface_child2, &occlusion);
- this->EnterLayer(surface_child, &occlusion);
- EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
- occlusion.occlusion_from_inside_target().ToString());
- EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
- occlusion.occlusion_from_outside_target().ToString());
-
- this->LeaveLayer(surface_child, &occlusion);
- this->EnterLayer(surface, &occlusion);
- EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(),
- occlusion.occlusion_from_inside_target().ToString());
- EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
- occlusion.occlusion_from_outside_target().ToString());
-
- this->LeaveLayer(surface, &occlusion);
- this->EnterContributingSurface(surface, &occlusion);
- // Occlusion within the surface is lost when leaving the animating surface.
- EXPECT_EQ(gfx::Rect().ToString(),
- occlusion.occlusion_from_inside_target().ToString());
- EXPECT_EQ(gfx::Rect().ToString(),
- occlusion.occlusion_from_outside_target().ToString());
-
- this->LeaveContributingSurface(surface, &occlusion);
- // Occlusion from outside the animating surface still exists.
- EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
- occlusion.occlusion_from_inside_target().ToString());
- EXPECT_EQ(gfx::Rect().ToString(),
- occlusion.occlusion_from_outside_target().ToString());
-
- this->VisitLayer(layer, &occlusion);
- this->EnterLayer(parent, &occlusion);
-
- // Occlusion is not added for the animating |layer|.
- EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(),
- occlusion.occlusion_from_inside_target().ToString());
- EXPECT_EQ(gfx::Rect().ToString(),
- occlusion.occlusion_from_outside_target().ToString());
- }
-};
-
-MAIN_THREAD_TEST(OcclusionTrackerTestAnimationOpacity0OnMainThread);
-
-template <class Types>
-class OcclusionTrackerTestAnimationTranslateOnMainThread
- : public OcclusionTrackerTest<Types> {
- protected:
- explicit OcclusionTrackerTestAnimationTranslateOnMainThread(
- bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
- void RunMyTest() override {
- typename Types::ContentLayerType* parent = this->CreateRoot(
- this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
- typename Types::ContentLayerType* layer =
- this->CreateDrawingLayer(parent,
- this->identity_matrix,
- gfx::PointF(),
- gfx::Size(300, 300),
- true);
- typename Types::ContentLayerType* surface =
- this->CreateDrawingSurface(parent,
- this->identity_matrix,
- gfx::PointF(),
- gfx::Size(300, 300),
- true);
- typename Types::ContentLayerType* surface_child =
- this->CreateDrawingLayer(surface,
- this->identity_matrix,
- gfx::PointF(),
- gfx::Size(200, 300),
- true);
- typename Types::ContentLayerType* surface_child2 =
- this->CreateDrawingLayer(surface,
- this->identity_matrix,
- gfx::PointF(),
- gfx::Size(100, 300),
- true);
- typename Types::ContentLayerType* surface2 = this->CreateDrawingSurface(
- parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 300), true);
-
- AddAnimatedTransformToController(
- layer->layer_animation_controller(), 10.0, 30, 0);
- AddAnimatedTransformToController(
- surface->layer_animation_controller(), 10.0, 30, 0);
- AddAnimatedTransformToController(
- surface_child->layer_animation_controller(), 10.0, 30, 0);
- this->CalcDrawEtc(parent);
-
- EXPECT_TRUE(layer->draw_transform_is_animating());
- EXPECT_TRUE(layer->screen_space_transform_is_animating());
- EXPECT_TRUE(
- surface->render_surface()->target_surface_transforms_are_animating());
- EXPECT_TRUE(
- surface->render_surface()->screen_space_transforms_are_animating());
- // The surface owning layer doesn't animate against its own surface.
- EXPECT_FALSE(surface->draw_transform_is_animating());
- EXPECT_TRUE(surface->screen_space_transform_is_animating());
- EXPECT_TRUE(surface_child->draw_transform_is_animating());
- EXPECT_TRUE(surface_child->screen_space_transform_is_animating());
-
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
-
- this->VisitLayer(surface2, &occlusion);
- this->EnterContributingSurface(surface2, &occlusion);
-
- EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
- occlusion.occlusion_from_inside_target().ToString());
-
- this->LeaveContributingSurface(surface2, &occlusion);
- this->EnterLayer(surface_child2, &occlusion);
- // surface_child2 is moving in screen space but not relative to its target,
- // so occlusion should happen in its target space only. It also means that
- // things occluding from outside the target (e.g. surface2) cannot occlude
- // this layer.
- EXPECT_EQ(gfx::Rect().ToString(),
- occlusion.occlusion_from_outside_target().ToString());
- EXPECT_EQ(gfx::Rect().ToString(),
- occlusion.occlusion_from_inside_target().ToString());
-
- this->LeaveLayer(surface_child2, &occlusion);
- this->EnterLayer(surface_child, &occlusion);
- // surface_child2 added to the occlusion since it is not moving relative
- // to its target.
- EXPECT_EQ(gfx::Rect().ToString(),
- occlusion.occlusion_from_outside_target().ToString());
- EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
- occlusion.occlusion_from_inside_target().ToString());
-
- this->LeaveLayer(surface_child, &occlusion);
- // surface_child is moving relative to its target, so it does not add
- // occlusion.
- EXPECT_EQ(gfx::Rect().ToString(),
- occlusion.occlusion_from_outside_target().ToString());
- EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
- occlusion.occlusion_from_inside_target().ToString());
-
- this->EnterLayer(surface, &occlusion);
- EXPECT_EQ(gfx::Rect().ToString(),
- occlusion.occlusion_from_outside_target().ToString());
- EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(),
- occlusion.occlusion_from_inside_target().ToString());
-
- this->LeaveLayer(surface, &occlusion);
- // The surface's owning layer is moving in screen space but not relative to
- // its target, so it adds to the occlusion.
- EXPECT_EQ(gfx::Rect().ToString(),
- occlusion.occlusion_from_outside_target().ToString());
- EXPECT_EQ(gfx::Rect(0, 0, 300, 300).ToString(),
- occlusion.occlusion_from_inside_target().ToString());
-
- this->EnterContributingSurface(surface, &occlusion);
- this->LeaveContributingSurface(surface, &occlusion);
- // The |surface| is moving in the screen and in its target, so all occlusion
- // within the surface is lost when leaving it. Only the |surface2| occlusion
- // is left.
- EXPECT_EQ(gfx::Rect().ToString(),
- occlusion.occlusion_from_outside_target().ToString());
- EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
- occlusion.occlusion_from_inside_target().ToString());
-
- this->VisitLayer(layer, &occlusion);
- // The |layer| is animating in the screen and in its target, so no occlusion
- // is added.
- EXPECT_EQ(gfx::Rect().ToString(),
- occlusion.occlusion_from_outside_target().ToString());
- EXPECT_EQ(gfx::Rect(0, 0, 50, 300).ToString(),
- occlusion.occlusion_from_inside_target().ToString());
- }
-};
-
-MAIN_THREAD_TEST(OcclusionTrackerTestAnimationTranslateOnMainThread);
-
-template <class Types>
class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
- : public OcclusionTrackerTest<Types> {
+ : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestSurfaceOcclusionTranslatesToParent(
bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
gfx::Transform surface_transform;
surface_transform.Translate(300.0, 300.0);
surface_transform.Scale(2.0, 2.0);
surface_transform.Translate(-150.0, -150.0);
- typename Types::ContentLayerType* parent = this->CreateRoot(
+ TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(500, 500));
- typename Types::ContentLayerType* surface = this->CreateDrawingSurface(
+ TestContentLayerImpl* surface = this->CreateDrawingSurface(
parent, surface_transform, gfx::PointF(), gfx::Size(300, 300), false);
- typename Types::ContentLayerType* surface2 =
- this->CreateDrawingSurface(parent,
- this->identity_matrix,
- gfx::PointF(50.f, 50.f),
- gfx::Size(300, 300),
- false);
+ TestContentLayerImpl* surface2 = this->CreateDrawingSurface(
+ parent, this->identity_matrix, gfx::PointF(50.f, 50.f),
+ gfx::Size(300, 300), false);
surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
surface2->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200));
this->CalcDrawEtc(parent);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
this->VisitLayer(surface2, &occlusion);
this->VisitContributingSurface(surface2, &occlusion);
@@ -1951,31 +1247,26 @@ class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent
}
};
-MAIN_AND_IMPL_THREAD_TEST(
+ALL_OCCLUSIONTRACKER_TEST(
OcclusionTrackerTestSurfaceOcclusionTranslatesToParent);
-template <class Types>
class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
- : public OcclusionTrackerTest<Types> {
+ : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping(
bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
- typename Types::ContentLayerType* parent = this->CreateRoot(
+ TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(300, 300));
parent->SetMasksToBounds(true);
- typename Types::ContentLayerType* surface =
- this->CreateDrawingSurface(parent,
- this->identity_matrix,
- gfx::PointF(),
- gfx::Size(500, 300),
- false);
+ TestContentLayerImpl* surface =
+ this->CreateDrawingSurface(parent, this->identity_matrix, gfx::PointF(),
+ gfx::Size(500, 300), false);
surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200));
this->CalcDrawEtc(parent);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
this->VisitLayer(surface, &occlusion);
this->VisitContributingSurface(surface, &occlusion);
@@ -1987,38 +1278,30 @@ class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping
}
};
-MAIN_AND_IMPL_THREAD_TEST(
+ALL_OCCLUSIONTRACKER_TEST(
OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping);
-template <class Types>
class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
- : public OcclusionTrackerTest<Types> {
+ : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestSurfaceWithReplicaUnoccluded(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
- typename Types::ContentLayerType* parent = this->CreateRoot(
+ TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
- typename Types::LayerType* surface =
- this->CreateDrawingSurface(parent,
- this->identity_matrix,
- gfx::PointF(),
- gfx::Size(100, 100),
- true);
+ LayerImpl* surface =
+ this->CreateDrawingSurface(parent, this->identity_matrix, gfx::PointF(),
+ gfx::Size(100, 100), true);
this->CreateReplicaLayer(surface,
this->identity_matrix,
gfx::PointF(0.f, 100.f),
gfx::Size(100, 100));
- typename Types::LayerType* topmost =
- this->CreateDrawingLayer(parent,
- this->identity_matrix,
- gfx::PointF(),
- gfx::Size(100, 110),
- true);
+ LayerImpl* topmost =
+ this->CreateDrawingLayer(parent, this->identity_matrix, gfx::PointF(),
+ gfx::Size(100, 110), true);
this->CalcDrawEtc(parent);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
// |topmost| occludes the surface, but not the entire surface's replica.
this->VisitLayer(topmost, &occlusion);
@@ -2050,36 +1333,27 @@ class OcclusionTrackerTestSurfaceWithReplicaUnoccluded
ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded);
-template <class Types>
-class OcclusionTrackerTestSurfaceChildOfSurface
- : public OcclusionTrackerTest<Types> {
+class OcclusionTrackerTestSurfaceChildOfSurface : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestSurfaceChildOfSurface(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
// This test verifies that the surface cliprect does not end up empty and
// clip away the entire unoccluded rect.
- typename Types::ContentLayerType* parent = this->CreateRoot(
+ TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(100, 200));
- typename Types::LayerType* surface =
- this->CreateDrawingSurface(parent,
- this->identity_matrix,
- gfx::PointF(),
- gfx::Size(100, 100),
- false);
- typename Types::LayerType* surface_child =
- this->CreateDrawingSurface(surface,
- this->identity_matrix,
- gfx::PointF(0.f, 10.f),
- gfx::Size(100, 50),
- true);
- typename Types::LayerType* topmost = this->CreateDrawingLayer(
+ LayerImpl* surface =
+ this->CreateDrawingSurface(parent, this->identity_matrix, gfx::PointF(),
+ gfx::Size(100, 100), false);
+ LayerImpl* surface_child = this->CreateDrawingSurface(
+ surface, this->identity_matrix, gfx::PointF(0.f, 10.f),
+ gfx::Size(100, 50), true);
+ LayerImpl* topmost = this->CreateDrawingLayer(
parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true);
this->CalcDrawEtc(parent);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(-100, -100, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(-100, -100, 1000, 1000));
// |topmost| occludes everything partially so we know occlusion is happening
// at all.
@@ -2147,13 +1421,12 @@ class OcclusionTrackerTestSurfaceChildOfSurface
ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceChildOfSurface);
-template <class Types>
class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
- : public OcclusionTrackerTest<Types> {
+ : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter(
bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
gfx::Transform scale_by_half;
scale_by_half.Scale(0.5, 0.5);
@@ -2181,15 +1454,12 @@ class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
// which are above it in the z-order in various configurations. The
// surface is scaled to test that the pixel moving is done in the target
// space, where the background filter is applied.
- typename Types::ContentLayerType* parent = this->CreateRoot(
+ TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(200, 200));
- typename Types::LayerType* filtered_surface =
- this->CreateDrawingLayer(parent,
- scale_by_half,
- gfx::PointF(50.f, 50.f),
- gfx::Size(100, 100),
- false);
- Types::SetForceRenderSurface(filtered_surface, true);
+ LayerImpl* filtered_surface = this->CreateDrawingLayer(
+ parent, scale_by_half, gfx::PointF(50.f, 50.f), gfx::Size(100, 100),
+ false);
+ filtered_surface->SetHasRenderSurface(true);
filtered_surface->SetBackgroundFilters(filters);
gfx::Rect occlusion_rect;
switch (i) {
@@ -2207,16 +1477,12 @@ class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
break;
}
- typename Types::LayerType* occluding_layer =
- this->CreateDrawingLayer(parent,
- this->identity_matrix,
- occlusion_rect.origin(),
- occlusion_rect.size(),
- true);
+ LayerImpl* occluding_layer = this->CreateDrawingLayer(
+ parent, this->identity_matrix, occlusion_rect.origin(),
+ occlusion_rect.size(), true);
this->CalcDrawEtc(parent);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 200, 200));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 200, 200));
// This layer occludes pixels directly beside the filtered_surface.
// Because filtered surface blends pixels in a radius, it will need to see
@@ -2271,38 +1537,34 @@ class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter
ALL_OCCLUSIONTRACKER_TEST(
OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter);
-template <class Types>
class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
- : public OcclusionTrackerTest<Types> {
+ : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice(
bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
gfx::Transform scale_by_half;
scale_by_half.Scale(0.5, 0.5);
// Makes two surfaces that completely cover |parent|. The occlusion both
// above and below the filters will be reduced by each of them.
- typename Types::ContentLayerType* root = this->CreateRoot(
+ TestContentLayerImpl* root = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(75, 75));
- typename Types::LayerType* parent = this->CreateSurface(
- root, scale_by_half, gfx::PointF(), gfx::Size(150, 150));
+ LayerImpl* parent = this->CreateSurface(root, scale_by_half, gfx::PointF(),
+ gfx::Size(150, 150));
parent->SetMasksToBounds(true);
- typename Types::LayerType* filtered_surface1 = this->CreateDrawingLayer(
+ LayerImpl* filtered_surface1 = this->CreateDrawingLayer(
parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
- typename Types::LayerType* filtered_surface2 = this->CreateDrawingLayer(
+ LayerImpl* filtered_surface2 = this->CreateDrawingLayer(
parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false);
- typename Types::LayerType* occluding_layer_above =
- this->CreateDrawingLayer(parent,
- this->identity_matrix,
- gfx::PointF(100.f, 100.f),
- gfx::Size(50, 50),
- true);
+ LayerImpl* occluding_layer_above = this->CreateDrawingLayer(
+ parent, this->identity_matrix, gfx::PointF(100.f, 100.f),
+ gfx::Size(50, 50), true);
// Filters make the layers own surfaces.
- Types::SetForceRenderSurface(filtered_surface1, true);
- Types::SetForceRenderSurface(filtered_surface2, true);
+ filtered_surface1->SetHasRenderSurface(true);
+ filtered_surface2->SetHasRenderSurface(true);
FilterOperations filters;
filters.Append(FilterOperation::CreateBlurFilter(1.f));
filtered_surface1->SetBackgroundFilters(filters);
@@ -2315,8 +1577,7 @@ class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
this->CalcDrawEtc(root);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
this->VisitLayer(occluding_layer_above, &occlusion);
EXPECT_EQ(gfx::Rect().ToString(),
@@ -2348,13 +1609,12 @@ class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice
ALL_OCCLUSIONTRACKER_TEST(
OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice);
-template <class Types>
class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
- : public OcclusionTrackerTest<Types> {
+ : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter(
bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
gfx::Transform scale_by_half;
scale_by_half.Scale(0.5, 0.5);
@@ -2363,41 +1623,31 @@ class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
// centered below each. The surface is scaled to test that the pixel moving
// is done in the target space, where the background filter is applied, but
// the surface appears at 50, 50 and the replica at 200, 50.
- typename Types::ContentLayerType* parent = this->CreateRoot(
+ TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
- typename Types::LayerType* behind_surface_layer =
- this->CreateDrawingLayer(parent,
- this->identity_matrix,
- gfx::PointF(60.f, 60.f),
- gfx::Size(30, 30),
- true);
- typename Types::LayerType* behind_replica_layer =
- this->CreateDrawingLayer(parent,
- this->identity_matrix,
- gfx::PointF(210.f, 60.f),
- gfx::Size(30, 30),
- true);
- typename Types::LayerType* filtered_surface =
- this->CreateDrawingLayer(parent,
- scale_by_half,
- gfx::PointF(50.f, 50.f),
- gfx::Size(100, 100),
- false);
+ LayerImpl* behind_surface_layer = this->CreateDrawingLayer(
+ parent, this->identity_matrix, gfx::PointF(60.f, 60.f),
+ gfx::Size(30, 30), true);
+ LayerImpl* behind_replica_layer = this->CreateDrawingLayer(
+ parent, this->identity_matrix, gfx::PointF(210.f, 60.f),
+ gfx::Size(30, 30), true);
+ LayerImpl* filtered_surface =
+ this->CreateDrawingLayer(parent, scale_by_half, gfx::PointF(50.f, 50.f),
+ gfx::Size(100, 100), false);
this->CreateReplicaLayer(filtered_surface,
this->identity_matrix,
gfx::PointF(300.f, 0.f),
gfx::Size());
// Filters make the layer own a surface.
- Types::SetForceRenderSurface(filtered_surface, true);
+ filtered_surface->SetHasRenderSurface(true);
FilterOperations filters;
filters.Append(FilterOperation::CreateBlurFilter(3.f));
filtered_surface->SetBackgroundFilters(filters);
this->CalcDrawEtc(parent);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
// The surface has a background blur, so it blurs non-opaque pixels below
// it.
@@ -2433,13 +1683,12 @@ class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter
ALL_OCCLUSIONTRACKER_TEST(
OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter);
-template <class Types>
class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
- : public OcclusionTrackerTest<Types> {
+ : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded(
bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
gfx::Transform scale_by_half;
scale_by_half.Scale(0.5, 0.5);
@@ -2448,31 +1697,24 @@ class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
// layer which is above it in the z-order. The surface is
// scaled to test that the pixel moving is done in the target space, where
// the background filter is applied, but the surface appears at 50, 50.
- typename Types::ContentLayerType* parent = this->CreateRoot(
+ TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(200, 150));
- typename Types::LayerType* filtered_surface =
- this->CreateDrawingLayer(parent,
- scale_by_half,
- gfx::PointF(50.f, 50.f),
- gfx::Size(100, 100),
- false);
- typename Types::LayerType* occluding_layer =
- this->CreateDrawingLayer(parent,
- this->identity_matrix,
- gfx::PointF(50.f, 50.f),
- gfx::Size(50, 50),
- true);
+ LayerImpl* filtered_surface =
+ this->CreateDrawingLayer(parent, scale_by_half, gfx::PointF(50.f, 50.f),
+ gfx::Size(100, 100), false);
+ LayerImpl* occluding_layer = this->CreateDrawingLayer(
+ parent, this->identity_matrix, gfx::PointF(50.f, 50.f),
+ gfx::Size(50, 50), true);
// Filters make the layer own a surface.
- Types::SetForceRenderSurface(filtered_surface, true);
+ filtered_surface->SetHasRenderSurface(true);
FilterOperations filters;
filters.Append(FilterOperation::CreateBlurFilter(3.f));
filtered_surface->SetBackgroundFilters(filters);
this->CalcDrawEtc(parent);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
this->VisitLayer(occluding_layer, &occlusion);
@@ -2506,14 +1748,12 @@ class OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded
ALL_OCCLUSIONTRACKER_TEST(
OcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded);
-template <class Types>
-class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
- : public OcclusionTrackerTest<Types> {
+class OcclusionTrackerTestReduceOcclusionWhenBkgdFilterIsPartiallyOccluded
+ : public OcclusionTrackerTest {
protected:
- explicit
- OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded(
+ explicit OcclusionTrackerTestReduceOcclusionWhenBkgdFilterIsPartiallyOccluded(
bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
gfx::Transform scale_by_half;
scale_by_half.Scale(0.5, 0.5);
@@ -2523,45 +1763,30 @@ class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
// scaled to test that the pixel moving is done in the target space, where
// the background filter is applied, but the surface appears at 50, 50 and
// the replica at 200, 50.
- typename Types::ContentLayerType* parent = this->CreateRoot(
+ TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(300, 150));
- typename Types::LayerType* filtered_surface =
- this->CreateDrawingLayer(parent,
- scale_by_half,
- gfx::PointF(50.f, 50.f),
- gfx::Size(100, 100),
- false);
+ LayerImpl* filtered_surface =
+ this->CreateDrawingLayer(parent, scale_by_half, gfx::PointF(50.f, 50.f),
+ gfx::Size(100, 100), false);
this->CreateReplicaLayer(filtered_surface,
this->identity_matrix,
gfx::PointF(300.f, 0.f),
gfx::Size());
- typename Types::LayerType* above_surface_layer =
- this->CreateDrawingLayer(parent,
- this->identity_matrix,
- gfx::PointF(70.f, 50.f),
- gfx::Size(30, 50),
- true);
- typename Types::LayerType* above_replica_layer =
- this->CreateDrawingLayer(parent,
- this->identity_matrix,
- gfx::PointF(200.f, 50.f),
- gfx::Size(30, 50),
- true);
- typename Types::LayerType* beside_surface_layer =
- this->CreateDrawingLayer(parent,
- this->identity_matrix,
- gfx::PointF(90.f, 40.f),
- gfx::Size(10, 10),
- true);
- typename Types::LayerType* beside_replica_layer =
- this->CreateDrawingLayer(parent,
- this->identity_matrix,
- gfx::PointF(200.f, 40.f),
- gfx::Size(10, 10),
- true);
+ LayerImpl* above_surface_layer = this->CreateDrawingLayer(
+ parent, this->identity_matrix, gfx::PointF(70.f, 50.f),
+ gfx::Size(30, 50), true);
+ LayerImpl* above_replica_layer = this->CreateDrawingLayer(
+ parent, this->identity_matrix, gfx::PointF(200.f, 50.f),
+ gfx::Size(30, 50), true);
+ LayerImpl* beside_surface_layer = this->CreateDrawingLayer(
+ parent, this->identity_matrix, gfx::PointF(90.f, 40.f),
+ gfx::Size(10, 10), true);
+ LayerImpl* beside_replica_layer = this->CreateDrawingLayer(
+ parent, this->identity_matrix, gfx::PointF(200.f, 40.f),
+ gfx::Size(10, 10), true);
// Filters make the layer own a surface.
- Types::SetForceRenderSurface(filtered_surface, true);
+ filtered_surface->SetHasRenderSurface(true);
FilterOperations filters;
filters.Append(FilterOperation::CreateBlurFilter(3.f));
filtered_surface->SetBackgroundFilters(filters);
@@ -2573,8 +1798,7 @@ class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
this->CalcDrawEtc(parent);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
this->VisitLayer(beside_replica_layer, &occlusion);
this->VisitLayer(beside_surface_layer, &occlusion);
@@ -2619,32 +1843,30 @@ class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded
};
ALL_OCCLUSIONTRACKER_TEST(
- OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded);
+ OcclusionTrackerTestReduceOcclusionWhenBkgdFilterIsPartiallyOccluded);
-template <class Types>
class OcclusionTrackerTestBlendModeDoesNotOcclude
- : public OcclusionTrackerTest<Types> {
+ : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestBlendModeDoesNotOcclude(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
- typename Types::ContentLayerType* parent = this->CreateRoot(
+ TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(100, 100));
- typename Types::LayerType* blend_mode_layer = this->CreateDrawingLayer(
+ LayerImpl* blend_mode_layer = this->CreateDrawingLayer(
parent, this->identity_matrix, gfx::PointF(0.f, 0.f),
gfx::Size(100, 100), true);
- typename Types::LayerType* top_layer = this->CreateDrawingLayer(
+ LayerImpl* top_layer = this->CreateDrawingLayer(
parent, this->identity_matrix, gfx::PointF(10.f, 12.f),
gfx::Size(20, 22), true);
// Blend mode makes the layer own a surface.
- Types::SetForceRenderSurface(blend_mode_layer, true);
+ blend_mode_layer->SetHasRenderSurface(true);
blend_mode_layer->SetBlendMode(SkXfermode::kMultiply_Mode);
this->CalcDrawEtc(parent);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
this->VisitLayer(top_layer, &occlusion);
// |top_layer| occludes.
@@ -2668,30 +1890,24 @@ class OcclusionTrackerTestBlendModeDoesNotOcclude
ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestBlendModeDoesNotOcclude);
-template <class Types>
-class OcclusionTrackerTestMinimumTrackingSize
- : public OcclusionTrackerTest<Types> {
+class OcclusionTrackerTestMinimumTrackingSize : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestMinimumTrackingSize(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
gfx::Size tracking_size(100, 100);
gfx::Size below_tracking_size(99, 99);
- typename Types::ContentLayerType* parent = this->CreateRoot(
+ TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
- typename Types::LayerType* large = this->CreateDrawingLayer(
+ LayerImpl* large = this->CreateDrawingLayer(
parent, this->identity_matrix, gfx::PointF(), tracking_size, true);
- typename Types::LayerType* small =
- this->CreateDrawingLayer(parent,
- this->identity_matrix,
- gfx::PointF(),
- below_tracking_size,
- true);
+ LayerImpl* small =
+ this->CreateDrawingLayer(parent, this->identity_matrix, gfx::PointF(),
+ below_tracking_size, true);
this->CalcDrawEtc(parent);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
occlusion.set_minimum_tracking_size(tracking_size);
// The small layer is not tracked because it is too small.
@@ -2714,31 +1930,27 @@ class OcclusionTrackerTestMinimumTrackingSize
ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize);
-template <class Types>
-class OcclusionTrackerTestScaledLayerIsClipped
- : public OcclusionTrackerTest<Types> {
+class OcclusionTrackerTestScaledLayerIsClipped : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestScaledLayerIsClipped(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
gfx::Transform scale_transform;
scale_transform.Scale(512.0, 512.0);
- typename Types::ContentLayerType* parent = this->CreateRoot(
+ TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
- typename Types::LayerType* clip = this->CreateLayer(parent,
- this->identity_matrix,
- gfx::PointF(10.f, 10.f),
- gfx::Size(50, 50));
+ LayerImpl* clip =
+ this->CreateLayer(parent, this->identity_matrix,
+ gfx::PointF(10.f, 10.f), gfx::Size(50, 50));
clip->SetMasksToBounds(true);
- typename Types::LayerType* scale = this->CreateLayer(
- clip, scale_transform, gfx::PointF(), gfx::Size(1, 1));
- typename Types::LayerType* scaled = this->CreateDrawingLayer(
+ LayerImpl* scale = this->CreateLayer(clip, scale_transform, gfx::PointF(),
+ gfx::Size(1, 1));
+ LayerImpl* scaled = this->CreateDrawingLayer(
scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
this->CalcDrawEtc(parent);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
this->VisitLayer(scaled, &occlusion);
@@ -2751,33 +1963,30 @@ class OcclusionTrackerTestScaledLayerIsClipped
ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerIsClipped)
-template <class Types>
class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
- : public OcclusionTrackerTest<Types> {
+ : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestScaledLayerInSurfaceIsClipped(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
gfx::Transform scale_transform;
scale_transform.Scale(512.0, 512.0);
- typename Types::ContentLayerType* parent = this->CreateRoot(
+ TestContentLayerImpl* parent = this->CreateRoot(
this->identity_matrix, gfx::PointF(), gfx::Size(400, 400));
- typename Types::LayerType* clip = this->CreateLayer(parent,
- this->identity_matrix,
- gfx::PointF(10.f, 10.f),
- gfx::Size(50, 50));
+ LayerImpl* clip =
+ this->CreateLayer(parent, this->identity_matrix,
+ gfx::PointF(10.f, 10.f), gfx::Size(50, 50));
clip->SetMasksToBounds(true);
- typename Types::LayerType* surface = this->CreateDrawingSurface(
+ LayerImpl* surface = this->CreateDrawingSurface(
clip, this->identity_matrix, gfx::PointF(), gfx::Size(400, 30), false);
- typename Types::LayerType* scale = this->CreateLayer(
- surface, scale_transform, gfx::PointF(), gfx::Size(1, 1));
- typename Types::LayerType* scaled = this->CreateDrawingLayer(
+ LayerImpl* scale = this->CreateLayer(surface, scale_transform,
+ gfx::PointF(), gfx::Size(1, 1));
+ LayerImpl* scaled = this->CreateDrawingLayer(
scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true);
this->CalcDrawEtc(parent);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
this->VisitLayer(scaled, &occlusion);
this->VisitLayer(surface, &occlusion);
@@ -2792,35 +2001,26 @@ class OcclusionTrackerTestScaledLayerInSurfaceIsClipped
ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestScaledLayerInSurfaceIsClipped)
-template <class Types>
-class OcclusionTrackerTestCopyRequestDoesOcclude
- : public OcclusionTrackerTest<Types> {
+class OcclusionTrackerTestCopyRequestDoesOcclude : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
- typename Types::ContentLayerType* root = this->CreateRoot(
+ TestContentLayerImpl* root = this->CreateRoot(
this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
- typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
+ TestContentLayerImpl* parent = this->CreateDrawingLayer(
root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true);
- typename Types::LayerType* copy = this->CreateLayer(parent,
- this->identity_matrix,
- gfx::Point(100, 0),
- gfx::Size(200, 400));
+ LayerImpl* copy = this->CreateLayer(
+ parent, this->identity_matrix, gfx::Point(100, 0), gfx::Size(200, 400));
this->AddCopyRequest(copy);
- typename Types::LayerType* copy_child = this->CreateDrawingLayer(
- copy,
- this->identity_matrix,
- gfx::PointF(),
- gfx::Size(200, 400),
- true);
- typename Types::LayerType* top_layer =
+ LayerImpl* copy_child = this->CreateDrawingLayer(
+ copy, this->identity_matrix, gfx::PointF(), gfx::Size(200, 400), true);
+ LayerImpl* top_layer =
this->CreateDrawingLayer(root, this->identity_matrix,
gfx::PointF(50, 0), gfx::Size(50, 400), true);
this->CalcDrawEtc(root);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
this->VisitLayer(top_layer, &occlusion);
EXPECT_EQ(gfx::Rect().ToString(),
@@ -2848,24 +2048,23 @@ class OcclusionTrackerTestCopyRequestDoesOcclude
ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestCopyRequestDoesOcclude)
-template <class Types>
class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
- : public OcclusionTrackerTest<Types> {
+ : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude(
bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
- typename Types::ContentLayerType* root = this->CreateRoot(
+ TestContentLayerImpl* root = this->CreateRoot(
this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
- typename Types::ContentLayerType* parent = this->CreateDrawingLayer(
+ TestContentLayerImpl* parent = this->CreateDrawingLayer(
root, this->identity_matrix, gfx::Point(), gfx::Size(400, 400), true);
- typename Types::LayerType* hide = this->CreateLayer(
- parent, this->identity_matrix, gfx::Point(), gfx::Size());
- typename Types::LayerType* copy = this->CreateLayer(
+ LayerImpl* hide = this->CreateLayer(parent, this->identity_matrix,
+ gfx::Point(), gfx::Size());
+ LayerImpl* copy = this->CreateLayer(
hide, this->identity_matrix, gfx::Point(100, 0), gfx::Size(200, 400));
this->AddCopyRequest(copy);
- typename Types::LayerType* copy_child = this->CreateDrawingLayer(
+ LayerImpl* copy_child = this->CreateDrawingLayer(
copy, this->identity_matrix, gfx::PointF(), gfx::Size(200, 400), true);
// The |copy| layer is hidden but since it is being copied, it will be
@@ -2874,8 +2073,7 @@ class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
this->CalcDrawEtc(root);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 1000, 1000));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000));
this->VisitLayer(copy_child, &occlusion);
EXPECT_EQ(gfx::Rect().ToString(),
@@ -2896,26 +2094,24 @@ class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude)
-template <class Types>
-class OcclusionTrackerTestOccludedLayer : public OcclusionTrackerTest<Types> {
+class OcclusionTrackerTestOccludedLayer : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestOccludedLayer(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
gfx::Transform translate;
translate.Translate(10.0, 20.0);
- typename Types::ContentLayerType* root = this->CreateRoot(
+ TestContentLayerImpl* root = this->CreateRoot(
this->identity_matrix, gfx::Point(), gfx::Size(200, 200));
- typename Types::LayerType* surface = this->CreateSurface(
- root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200));
- typename Types::LayerType* layer = this->CreateDrawingLayer(
+ LayerImpl* surface = this->CreateSurface(root, this->identity_matrix,
+ gfx::Point(), gfx::Size(200, 200));
+ LayerImpl* layer = this->CreateDrawingLayer(
surface, translate, gfx::Point(), gfx::Size(200, 200), false);
- typename Types::ContentLayerType* outside_layer = this->CreateDrawingLayer(
+ TestContentLayerImpl* outside_layer = this->CreateDrawingLayer(
root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), false);
this->CalcDrawEtc(root);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 200, 200));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 200, 200));
this->VisitLayer(outside_layer, &occlusion);
this->EnterLayer(layer, &occlusion);
@@ -2986,27 +2182,24 @@ class OcclusionTrackerTestOccludedLayer : public OcclusionTrackerTest<Types> {
ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOccludedLayer)
-template <class Types>
-class OcclusionTrackerTestUnoccludedLayerQuery
- : public OcclusionTrackerTest<Types> {
+class OcclusionTrackerTestUnoccludedLayerQuery : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestUnoccludedLayerQuery(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
gfx::Transform translate;
translate.Translate(10.0, 20.0);
- typename Types::ContentLayerType* root = this->CreateRoot(
+ TestContentLayerImpl* root = this->CreateRoot(
this->identity_matrix, gfx::Point(), gfx::Size(200, 200));
- typename Types::LayerType* surface = this->CreateSurface(
- root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200));
- typename Types::LayerType* layer = this->CreateDrawingLayer(
+ LayerImpl* surface = this->CreateSurface(root, this->identity_matrix,
+ gfx::Point(), gfx::Size(200, 200));
+ LayerImpl* layer = this->CreateDrawingLayer(
surface, translate, gfx::Point(), gfx::Size(200, 200), false);
- typename Types::ContentLayerType* outside_layer = this->CreateDrawingLayer(
+ TestContentLayerImpl* outside_layer = this->CreateDrawingLayer(
root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), false);
this->CalcDrawEtc(root);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 200, 200));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 200, 200));
this->VisitLayer(outside_layer, &occlusion);
this->EnterLayer(layer, &occlusion);
@@ -3152,31 +2345,25 @@ class OcclusionTrackerTestUnoccludedLayerQuery
ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedLayerQuery)
-template <class Types>
-class OcclusionTrackerTestUnoccludedSurfaceQuery
- : public OcclusionTrackerTest<Types> {
+class OcclusionTrackerTestUnoccludedSurfaceQuery : public OcclusionTrackerTest {
protected:
explicit OcclusionTrackerTestUnoccludedSurfaceQuery(bool opaque_layers)
- : OcclusionTrackerTest<Types>(opaque_layers) {}
+ : OcclusionTrackerTest(opaque_layers) {}
void RunMyTest() override {
gfx::Transform translate;
translate.Translate(10.0, 20.0);
- typename Types::ContentLayerType* root = this->CreateRoot(
+ TestContentLayerImpl* root = this->CreateRoot(
this->identity_matrix, gfx::Point(), gfx::Size(200, 200));
- typename Types::LayerType* surface =
+ LayerImpl* surface =
this->CreateSurface(root, translate, gfx::Point(), gfx::Size(200, 200));
- typename Types::LayerType* layer =
- this->CreateDrawingLayer(surface,
- this->identity_matrix,
- gfx::Point(),
- gfx::Size(200, 200),
- false);
- typename Types::ContentLayerType* outside_layer = this->CreateDrawingLayer(
+ LayerImpl* layer =
+ this->CreateDrawingLayer(surface, this->identity_matrix, gfx::Point(),
+ gfx::Size(200, 200), false);
+ TestContentLayerImpl* outside_layer = this->CreateDrawingLayer(
root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), false);
this->CalcDrawEtc(root);
- TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion(
- gfx::Rect(0, 0, 200, 200));
+ TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 200, 200));
this->VisitLayer(outside_layer, &occlusion);
this->VisitLayer(layer, &occlusion);
this->EnterContributingSurface(surface, &occlusion);
diff --git a/chromium/cc/trees/property_tree.cc b/chromium/cc/trees/property_tree.cc
index d369ad91060..05fa3947f0c 100644
--- a/chromium/cc/trees/property_tree.cc
+++ b/chromium/cc/trees/property_tree.cc
@@ -23,6 +23,12 @@ template <typename T>
PropertyTree<T>::~PropertyTree() {
}
+TransformTree::TransformTree() : source_to_parent_updates_allowed_(true) {
+}
+
+TransformTree::~TransformTree() {
+}
+
template <typename T>
int PropertyTree<T>::Insert(const T& tree_node, int parent_id) {
DCHECK_GT(nodes_.size(), 0u);
@@ -56,9 +62,15 @@ TransformNodeData::TransformNodeData()
to_screen_is_animated(false),
flattens_inherited_transform(false),
node_and_ancestors_are_flat(true),
+ node_and_ancestors_have_only_integer_translation(true),
scrolls(false),
needs_sublayer_scale(false),
- layer_scale_factor(1.0f) {
+ affected_by_inner_viewport_bounds_delta_x(false),
+ affected_by_inner_viewport_bounds_delta_y(false),
+ affected_by_outer_viewport_bounds_delta_x(false),
+ affected_by_outer_viewport_bounds_delta_y(false),
+ layer_scale_factor(1.0f),
+ post_local_scale_factor(1.0f) {
}
TransformNodeData::~TransformNodeData() {
@@ -85,6 +97,16 @@ void TransformNodeData::update_post_local_transform(
ClipNodeData::ClipNodeData() : transform_id(-1), target_id(-1) {
}
+OpacityNodeData::OpacityNodeData() : opacity(1.f), screen_space_opacity(1.f) {
+}
+
+void TransformTree::clear() {
+ PropertyTree<TransformNode>::clear();
+
+ nodes_affected_by_inner_viewport_bounds_delta_.clear();
+ nodes_affected_by_outer_viewport_bounds_delta_.clear();
+}
+
bool TransformTree::ComputeTransform(int source_id,
int dest_id,
gfx::Transform* transform) const {
@@ -136,18 +158,24 @@ bool TransformTree::Are2DAxisAligned(int source_id, int dest_id) const {
transform.Preserves2dAxisAlignment();
}
+bool TransformTree::NeedsSourceToParentUpdate(TransformNode* node) {
+ return (source_to_parent_updates_allowed() &&
+ node->parent_id != node->data.source_node_id);
+}
+
void TransformTree::UpdateTransforms(int id) {
TransformNode* node = Node(id);
TransformNode* parent_node = parent(node);
TransformNode* target_node = Node(node->data.target_id);
if (node->data.needs_local_transform_update ||
- node->parent_id != node->data.source_node_id)
+ NeedsSourceToParentUpdate(node))
UpdateLocalTransform(node);
UpdateScreenSpaceTransform(node, parent_node, target_node);
UpdateSublayerScale(node);
UpdateTargetSpaceTransform(node, target_node);
UpdateIsAnimated(node, parent_node);
UpdateSnapping(node);
+ UpdateNodeAndAncestorsHaveIntegerTranslations(node, parent_node);
}
bool TransformTree::IsDescendant(int desc_id, int source_id) const {
@@ -188,12 +216,21 @@ bool TransformTree::CombineTransformsBetween(int source_id,
// path from the source to the destination (this is traversing upward), and
// then we visit these nodes in reverse order, flattening as needed. We
// early-out if we get to a node whose target node is the destination, since
- // we can then re-use the target space transform stored at that node.
+ // we can then re-use the target space transform stored at that node. However,
+ // we cannot re-use a stored target space transform if the destination has a
+ // zero sublayer scale, since stored target space transforms have sublayer
+ // scale baked in, but we need to compute an unscaled transform.
std::vector<int> source_to_destination;
source_to_destination.push_back(current->id);
current = parent(current);
+ bool destination_has_non_zero_sublayer_scale =
+ dest->data.sublayer_scale.x() != 0.f &&
+ dest->data.sublayer_scale.y() != 0.f;
+ DCHECK(destination_has_non_zero_sublayer_scale ||
+ !dest->data.ancestors_are_invertible);
for (; current && current->id > dest_id; current = parent(current)) {
- if (current->data.target_id == dest_id &&
+ if (destination_has_non_zero_sublayer_scale &&
+ current->data.target_id == dest_id &&
current->data.content_target_id == dest_id)
break;
source_to_destination.push_back(current->id);
@@ -230,8 +267,10 @@ bool TransformTree::CombineTransformsBetween(int source_id,
SkDoubleToMScalar(1e-4)));
}
- for (int i = source_to_destination.size() - 1; i >= 0; i--) {
- const TransformNode* node = Node(source_to_destination[i]);
+ size_t source_to_destination_size = source_to_destination.size();
+ for (size_t i = 0; i < source_to_destination_size; ++i) {
+ size_t index = source_to_destination_size - 1 - i;
+ const TransformNode* node = Node(source_to_destination[index]);
if (node->data.flattens_inherited_transform)
combined_transform.FlattenTo2d();
combined_transform.PreconcatTransform(node->data.to_parent);
@@ -273,14 +312,28 @@ bool TransformTree::CombineInversesBetween(int source_id,
void TransformTree::UpdateLocalTransform(TransformNode* node) {
gfx::Transform transform = node->data.post_local;
- gfx::Vector2dF source_to_parent;
- if (node->parent_id != node->data.source_node_id) {
+ if (NeedsSourceToParentUpdate(node)) {
gfx::Transform to_parent;
ComputeTransform(node->data.source_node_id, node->parent_id, &to_parent);
- source_to_parent = to_parent.To2dTranslation();
+ node->data.source_to_parent = to_parent.To2dTranslation();
}
- transform.Translate(source_to_parent.x() - node->data.scroll_offset.x(),
- source_to_parent.y() - node->data.scroll_offset.y());
+
+ gfx::Vector2dF fixed_position_adjustment;
+ if (node->data.affected_by_inner_viewport_bounds_delta_x)
+ fixed_position_adjustment.set_x(inner_viewport_bounds_delta_.x());
+ else if (node->data.affected_by_outer_viewport_bounds_delta_x)
+ fixed_position_adjustment.set_x(outer_viewport_bounds_delta_.x());
+
+ if (node->data.affected_by_inner_viewport_bounds_delta_y)
+ fixed_position_adjustment.set_y(inner_viewport_bounds_delta_.y());
+ else if (node->data.affected_by_outer_viewport_bounds_delta_y)
+ fixed_position_adjustment.set_y(outer_viewport_bounds_delta_.y());
+
+ transform.Translate(
+ node->data.source_to_parent.x() - node->data.scroll_offset.x() +
+ fixed_position_adjustment.x(),
+ node->data.source_to_parent.y() - node->data.scroll_offset.y() +
+ fixed_position_adjustment.y());
transform.PreconcatTransform(node->data.local);
transform.PreconcatTransform(node->data.pre_local);
node->data.set_to_parent(transform);
@@ -382,6 +435,70 @@ void TransformTree::UpdateSnapping(TransformNode* node) {
node->data.scroll_snap = translation;
}
+void TransformTree::SetInnerViewportBoundsDelta(gfx::Vector2dF bounds_delta) {
+ if (inner_viewport_bounds_delta_ == bounds_delta)
+ return;
+
+ inner_viewport_bounds_delta_ = bounds_delta;
+
+ if (nodes_affected_by_inner_viewport_bounds_delta_.empty())
+ return;
+
+ set_needs_update(true);
+ for (int i : nodes_affected_by_inner_viewport_bounds_delta_)
+ Node(i)->data.needs_local_transform_update = true;
+}
+
+void TransformTree::SetOuterViewportBoundsDelta(gfx::Vector2dF bounds_delta) {
+ if (outer_viewport_bounds_delta_ == bounds_delta)
+ return;
+
+ outer_viewport_bounds_delta_ = bounds_delta;
+
+ if (nodes_affected_by_outer_viewport_bounds_delta_.empty())
+ return;
+
+ set_needs_update(true);
+ for (int i : nodes_affected_by_outer_viewport_bounds_delta_)
+ Node(i)->data.needs_local_transform_update = true;
+}
+
+void TransformTree::AddNodeAffectedByInnerViewportBoundsDelta(int node_id) {
+ nodes_affected_by_inner_viewport_bounds_delta_.push_back(node_id);
+}
+
+void TransformTree::AddNodeAffectedByOuterViewportBoundsDelta(int node_id) {
+ nodes_affected_by_outer_viewport_bounds_delta_.push_back(node_id);
+}
+
+bool TransformTree::HasNodesAffectedByInnerViewportBoundsDelta() const {
+ return !nodes_affected_by_inner_viewport_bounds_delta_.empty();
+}
+
+bool TransformTree::HasNodesAffectedByOuterViewportBoundsDelta() const {
+ return !nodes_affected_by_outer_viewport_bounds_delta_.empty();
+}
+
+void OpacityTree::UpdateOpacities(int id) {
+ OpacityNode* node = Node(id);
+ node->data.screen_space_opacity = node->data.opacity;
+
+ OpacityNode* parent_node = parent(node);
+ if (parent_node)
+ node->data.screen_space_opacity *= parent_node->data.screen_space_opacity;
+}
+
+void TransformTree::UpdateNodeAndAncestorsHaveIntegerTranslations(
+ TransformNode* node,
+ TransformNode* parent_node) {
+ node->data.node_and_ancestors_have_only_integer_translation =
+ node->data.to_parent.IsIdentityOrIntegerTranslation();
+ if (parent_node)
+ node->data.node_and_ancestors_have_only_integer_translation =
+ node->data.node_and_ancestors_have_only_integer_translation &&
+ parent_node->data.node_and_ancestors_have_only_integer_translation;
+}
+
PropertyTrees::PropertyTrees() : needs_rebuild(true), sequence_number(0) {
}
diff --git a/chromium/cc/trees/property_tree.h b/chromium/cc/trees/property_tree.h
index caa819c6c6d..0ec77bc5bbe 100644
--- a/chromium/cc/trees/property_tree.h
+++ b/chromium/cc/trees/property_tree.h
@@ -10,6 +10,7 @@
#include "base/basictypes.h"
#include "cc/base/cc_export.h"
#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/scroll_offset.h"
#include "ui/gfx/transform.h"
namespace cc {
@@ -67,25 +68,36 @@ struct CC_EXPORT TransformNodeData {
int source_node_id;
// TODO(vollick): will be moved when accelerated effects are implemented.
- bool needs_local_transform_update;
+ bool needs_local_transform_update : 1;
- bool is_invertible;
- bool ancestors_are_invertible;
+ bool is_invertible : 1;
+ bool ancestors_are_invertible : 1;
- bool is_animated;
- bool to_screen_is_animated;
+ bool is_animated : 1;
+ bool to_screen_is_animated : 1;
// Flattening, when needed, is only applied to a node's inherited transform,
// never to its local transform.
- bool flattens_inherited_transform;
+ bool flattens_inherited_transform : 1;
// This is true if the to_parent transform at every node on the path to the
// root is flat.
- bool node_and_ancestors_are_flat;
+ bool node_and_ancestors_are_flat : 1;
- bool scrolls;
+ // This is needed to know if a layer can use lcd text.
+ bool node_and_ancestors_have_only_integer_translation : 1;
+
+ bool scrolls : 1;
+
+ bool needs_sublayer_scale : 1;
+
+ // These are used to position nodes wrt the right or bottom of the inner or
+ // outer viewport.
+ bool affected_by_inner_viewport_bounds_delta_x : 1;
+ bool affected_by_inner_viewport_bounds_delta_y : 1;
+ bool affected_by_outer_viewport_bounds_delta_x : 1;
+ bool affected_by_outer_viewport_bounds_delta_y : 1;
- bool needs_sublayer_scale;
// This is used as a fallback when we either cannot adjust raster scale or if
// the raster scale cannot be extracted from the screen space transform.
float layer_scale_factor;
@@ -96,7 +108,7 @@ struct CC_EXPORT TransformNodeData {
gfx::Vector2dF sublayer_scale;
// TODO(vollick): will be moved when accelerated effects are implemented.
- gfx::Vector2dF scroll_offset;
+ gfx::ScrollOffset scroll_offset;
// We scroll snap where possible, but this has an effect on scroll
// compensation: the snap is yet more scrolling that must be compensated for.
@@ -105,6 +117,7 @@ struct CC_EXPORT TransformNodeData {
// TODO(vollick): will be moved when accelerated effects are implemented.
gfx::Vector2dF source_offset;
+ gfx::Vector2dF source_to_parent;
void set_to_parent(const gfx::Transform& transform) {
to_parent = transform;
@@ -130,7 +143,14 @@ struct CC_EXPORT ClipNodeData {
typedef TreeNode<ClipNodeData> ClipNode;
-typedef TreeNode<float> OpacityNode;
+struct CC_EXPORT OpacityNodeData {
+ OpacityNodeData();
+
+ float opacity;
+ float screen_space_opacity;
+};
+
+typedef TreeNode<OpacityNodeData> OpacityNode;
template <typename T>
class CC_EXPORT PropertyTree {
@@ -159,7 +179,7 @@ class CC_EXPORT PropertyTree {
return size() ? &nodes_[nodes_.size() - 1] : nullptr;
}
- void clear();
+ virtual void clear();
size_t size() const { return nodes_.size(); }
void set_needs_update(bool needs_update) { needs_update_ = needs_update; }
@@ -174,6 +194,11 @@ class CC_EXPORT PropertyTree {
class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> {
public:
+ TransformTree();
+ ~TransformTree() override;
+
+ void clear() override;
+
// Computes the change of basis transform from node |source_id| to |dest_id|.
// The function returns false iff the inverse of a singular transform was
// used (and the result should, therefore, not be trusted). Transforms may
@@ -211,6 +236,37 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> {
// Updates the parent, target, and screen space transforms and snapping.
void UpdateTransforms(int id);
+ // A TransformNode's source_to_parent value is used to account for the fact
+ // that fixed-position layers are positioned by Blink wrt to their layer tree
+ // parent (their "source"), but are parented in the transform tree by their
+ // fixed-position container. This value needs to be updated on main-thread
+ // property trees (for position changes initiated by Blink), but not on the
+ // compositor thread (since the offset from a node corresponding to a
+ // fixed-position layer to its fixed-position container is unaffected by
+ // compositor-driven effects).
+ void set_source_to_parent_updates_allowed(bool allowed) {
+ source_to_parent_updates_allowed_ = allowed;
+ }
+ bool source_to_parent_updates_allowed() const {
+ return source_to_parent_updates_allowed_;
+ }
+
+ void SetInnerViewportBoundsDelta(gfx::Vector2dF bounds_delta);
+ gfx::Vector2dF inner_viewport_bounds_delta() const {
+ return inner_viewport_bounds_delta_;
+ }
+
+ void SetOuterViewportBoundsDelta(gfx::Vector2dF bounds_delta);
+ gfx::Vector2dF outer_viewport_bounds_delta() const {
+ return outer_viewport_bounds_delta_;
+ }
+
+ void AddNodeAffectedByInnerViewportBoundsDelta(int node_id);
+ void AddNodeAffectedByOuterViewportBoundsDelta(int node_id);
+
+ bool HasNodesAffectedByInnerViewportBoundsDelta() const;
+ bool HasNodesAffectedByOuterViewportBoundsDelta() const;
+
private:
// Returns true iff the node at |desc_id| is a descendant of the node at
// |anc_id|.
@@ -239,11 +295,24 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> {
TransformNode* target_node);
void UpdateIsAnimated(TransformNode* node, TransformNode* parent_node);
void UpdateSnapping(TransformNode* node);
+ void UpdateNodeAndAncestorsHaveIntegerTranslations(
+ TransformNode* node,
+ TransformNode* parent_node);
+ bool NeedsSourceToParentUpdate(TransformNode* node);
+
+ bool source_to_parent_updates_allowed_;
+ gfx::Vector2dF inner_viewport_bounds_delta_;
+ gfx::Vector2dF outer_viewport_bounds_delta_;
+ std::vector<int> nodes_affected_by_inner_viewport_bounds_delta_;
+ std::vector<int> nodes_affected_by_outer_viewport_bounds_delta_;
};
class CC_EXPORT ClipTree final : public PropertyTree<ClipNode> {};
-class CC_EXPORT OpacityTree final : public PropertyTree<OpacityNode> {};
+class CC_EXPORT OpacityTree final : public PropertyTree<OpacityNode> {
+ public:
+ void UpdateOpacities(int id);
+};
class CC_EXPORT PropertyTrees final {
public:
diff --git a/chromium/cc/trees/property_tree_builder.cc b/chromium/cc/trees/property_tree_builder.cc
index 815692db211..28ad43f3091 100644
--- a/chromium/cc/trees/property_tree_builder.cc
+++ b/chromium/cc/trees/property_tree_builder.cc
@@ -31,9 +31,13 @@ struct DataForRecursion {
int clip_tree_parent;
int opacity_tree_parent;
const LayerType* page_scale_layer;
+ const LayerType* inner_viewport_scroll_layer;
+ const LayerType* outer_viewport_scroll_layer;
float page_scale_factor;
float device_scale_factor;
- bool in_subtree_of_page_scale_application_layer;
+ bool in_subtree_of_page_scale_layer;
+ bool affected_by_inner_viewport_bounds_delta;
+ bool affected_by_outer_viewport_bounds_delta;
bool should_flatten;
bool ancestor_clips_subtree;
const gfx::Transform* device_transform;
@@ -59,16 +63,6 @@ static ClipNode* GetClipParent(const DataForRecursion<LayerType>& data,
}
template <typename LayerType>
-static bool HasPotentiallyRunningAnimation(LayerType* layer,
- Animation::TargetProperty property) {
- if (Animation* animation =
- layer->layer_animation_controller()->GetAnimation(property)) {
- return !animation->is_finished();
- }
- return false;
-}
-
-template <typename LayerType>
static bool RequiresClipNode(LayerType* layer,
const DataForRecursion<LayerType>& data,
int parent_transform_id,
@@ -78,7 +72,7 @@ static bool RequiresClipNode(LayerType* layer,
const bool render_surface_may_grow_due_to_clip_children =
layer->render_surface() && layer->num_unclipped_descendants() > 0;
- if (!layer->parent() || layer->masks_to_bounds() || layer->mask_layer() ||
+ if (layer->masks_to_bounds() || layer->mask_layer() ||
render_surface_may_grow_due_to_clip_children)
return true;
@@ -130,8 +124,7 @@ void AddClipNodeIfNeeded(const DataForRecursion<LayerType>& data_from_ancestor,
data_for_children->ancestor_clips_subtree)) {
// Unclipped surfaces reset the clip rect.
data_for_children->clip_tree_parent = parent_id;
- } else if (layer->parent()) {
- // Note the root clip gets handled elsewhere.
+ } else {
LayerType* transform_parent = data_for_children->transform_tree_parent;
if (layer->position_constraint().is_fixed_position() &&
!created_transform_node) {
@@ -163,8 +156,7 @@ bool AddTransformNodeIfNeeded(
LayerType* layer,
DataForRecursion<LayerType>* data_for_children) {
const bool is_root = !layer->parent();
- const bool is_page_scale_application_layer =
- layer->parent() && layer->parent() == data_from_ancestor.page_scale_layer;
+ const bool is_page_scale_layer = layer == data_from_ancestor.page_scale_layer;
const bool is_scrollable = layer->scrollable();
const bool is_fixed = layer->position_constraint().is_fixed_position();
@@ -172,19 +164,17 @@ bool AddTransformNodeIfNeeded(
!layer->transform().IsIdentityOr2DTranslation();
const bool has_potentially_animated_transform =
- HasPotentiallyRunningAnimation(layer, Animation::TRANSFORM);
-
- const bool has_animated_transform =
- layer->layer_animation_controller()->IsAnimatingProperty(
- Animation::TRANSFORM);
+ layer->HasPotentiallyRunningTransformAnimation();
+ const bool has_animated_transform = layer->TransformIsAnimating();
const bool has_surface = !!layer->render_surface();
bool requires_node = is_root || is_scrollable || has_significant_transform ||
has_potentially_animated_transform || has_surface ||
- is_fixed || is_page_scale_application_layer;
+ is_fixed || is_page_scale_layer;
LayerType* transform_parent = GetTransformParent(data_from_ancestor, layer);
+ DCHECK_IMPLIES(!is_root, transform_parent);
int parent_index = 0;
if (transform_parent)
@@ -201,19 +191,27 @@ bool AddTransformNodeIfNeeded(
} else if (!is_fixed) {
source_offset = transform_parent->offset_to_transform_parent();
} else {
- if (data_from_ancestor.transform_tree_parent !=
- data_from_ancestor.transform_fixed_parent) {
- source_offset = data_from_ancestor.transform_tree_parent
- ->offset_to_transform_parent();
- source_index =
- data_from_ancestor.transform_tree_parent->transform_tree_index();
- }
+ source_offset = data_from_ancestor.transform_tree_parent
+ ->offset_to_transform_parent();
+ source_index =
+ data_from_ancestor.transform_tree_parent->transform_tree_index();
source_offset += data_from_ancestor.scroll_compensation_adjustment;
}
}
- if (layer->IsContainerForFixedPositionLayers() || is_root)
- data_for_children->transform_fixed_parent = layer;
+ if (layer->IsContainerForFixedPositionLayers() || is_root) {
+ data_for_children->affected_by_inner_viewport_bounds_delta =
+ layer == data_from_ancestor.inner_viewport_scroll_layer;
+ data_for_children->affected_by_outer_viewport_bounds_delta =
+ layer == data_from_ancestor.outer_viewport_scroll_layer;
+ if (is_scrollable) {
+ DCHECK(!is_root);
+ DCHECK(layer->transform().IsIdentity());
+ data_for_children->transform_fixed_parent = layer->parent();
+ } else {
+ data_for_children->transform_fixed_parent = layer;
+ }
+ }
data_for_children->transform_tree_parent = layer;
if (layer->IsContainerForFixedPositionLayers() || is_fixed)
@@ -262,30 +260,54 @@ bool AddTransformNodeIfNeeded(
post_local_scale_factor = data_from_ancestor.device_scale_factor;
}
- if (is_page_scale_application_layer)
+ if (is_page_scale_layer)
post_local_scale_factor *= data_from_ancestor.page_scale_factor;
if (has_surface && !is_root) {
node->data.needs_sublayer_scale = true;
node->data.layer_scale_factor = data_from_ancestor.device_scale_factor;
- if (data_from_ancestor.in_subtree_of_page_scale_application_layer)
+ if (data_from_ancestor.in_subtree_of_page_scale_layer)
node->data.layer_scale_factor *= data_from_ancestor.page_scale_factor;
}
+ node->data.source_node_id = source_index;
if (is_root) {
node->data.post_local.Scale(post_local_scale_factor,
post_local_scale_factor);
+ node->data.post_local.Translate(layer->position().x(),
+ layer->position().y());
} else {
node->data.post_local_scale_factor = post_local_scale_factor;
node->data.source_offset = source_offset;
- node->data.source_node_id = source_index;
node->data.update_post_local_transform(layer->position(),
layer->transform_origin());
}
- if (!layer->scroll_parent()) {
- node->data.scroll_offset =
- gfx::ScrollOffsetToVector2dF(layer->CurrentScrollOffset());
+ if (!layer->scroll_parent())
+ node->data.scroll_offset = layer->CurrentScrollOffset();
+
+ if (is_fixed) {
+ if (data_from_ancestor.affected_by_inner_viewport_bounds_delta) {
+ node->data.affected_by_inner_viewport_bounds_delta_x =
+ layer->position_constraint().is_fixed_to_right_edge();
+ node->data.affected_by_inner_viewport_bounds_delta_y =
+ layer->position_constraint().is_fixed_to_bottom_edge();
+ if (node->data.affected_by_inner_viewport_bounds_delta_x ||
+ node->data.affected_by_inner_viewport_bounds_delta_y) {
+ data_for_children->transform_tree
+ ->AddNodeAffectedByInnerViewportBoundsDelta(node->id);
+ }
+ } else if (data_from_ancestor.affected_by_outer_viewport_bounds_delta) {
+ node->data.affected_by_outer_viewport_bounds_delta_x =
+ layer->position_constraint().is_fixed_to_right_edge();
+ node->data.affected_by_outer_viewport_bounds_delta_y =
+ layer->position_constraint().is_fixed_to_bottom_edge();
+ if (node->data.affected_by_outer_viewport_bounds_delta_x ||
+ node->data.affected_by_outer_viewport_bounds_delta_y) {
+ data_for_children->transform_tree
+ ->AddNodeAffectedByOuterViewportBoundsDelta(node->id);
+ }
+ }
}
node->data.local = layer->transform();
@@ -308,12 +330,12 @@ bool AddTransformNodeIfNeeded(
}
bool IsAnimatingOpacity(Layer* layer) {
- return HasPotentiallyRunningAnimation(layer, Animation::OPACITY) ||
+ return layer->HasPotentiallyRunningOpacityAnimation() ||
layer->OpacityCanAnimateOnImplThread();
}
bool IsAnimatingOpacity(LayerImpl* layer) {
- return HasPotentiallyRunningAnimation(layer, Animation::OPACITY);
+ return layer->HasPotentiallyRunningOpacityAnimation();
}
template <typename LayerType>
@@ -336,7 +358,12 @@ void AddOpacityNodeIfNeeded(
OpacityNode node;
node.owner_id = layer->id();
- node.data = layer->opacity();
+ node.data.opacity = layer->opacity();
+ node.data.screen_space_opacity = layer->opacity();
+ if (!is_root)
+ node.data.screen_space_opacity *=
+ data_from_ancestor.opacity_tree->Node(parent_id)
+ ->data.screen_space_opacity;
data_for_children->opacity_tree_parent =
data_for_children->opacity_tree->Insert(node, parent_id);
layer->SetOpacityTreeIndex(data_for_children->opacity_tree_parent);
@@ -360,15 +387,22 @@ void BuildPropertyTreesInternal(
AddOpacityNodeIfNeeded(data_from_parent, layer, &data_for_children);
if (layer == data_from_parent.page_scale_layer)
- data_for_children.in_subtree_of_page_scale_application_layer = true;
+ data_for_children.in_subtree_of_page_scale_layer = true;
for (size_t i = 0; i < layer->children().size(); ++i) {
- if (!layer->child_at(i)->scroll_parent())
+ if (!layer->child_at(i)->scroll_parent()) {
BuildPropertyTreesInternal(layer->child_at(i), data_for_children);
+ } else {
+ // The child should be included in its scroll parent's list of scroll
+ // children.
+ DCHECK(layer->child_at(i)->scroll_parent()->scroll_children()->count(
+ layer->child_at(i)));
+ }
}
if (layer->scroll_children()) {
for (LayerType* scroll_child : *layer->scroll_children()) {
+ DCHECK_EQ(scroll_child->scroll_parent(), layer);
BuildPropertyTreesInternal(scroll_child, data_for_children);
}
}
@@ -380,13 +414,19 @@ void BuildPropertyTreesInternal(
} // namespace
template <typename LayerType>
-void BuildPropertyTreesTopLevelInternal(LayerType* root_layer,
- const LayerType* page_scale_layer,
- float page_scale_factor,
- float device_scale_factor,
- const gfx::Rect& viewport,
- const gfx::Transform& device_transform,
- PropertyTrees* property_trees) {
+void BuildPropertyTreesTopLevelInternal(
+ LayerType* root_layer,
+ const LayerType* page_scale_layer,
+ const LayerType* inner_viewport_scroll_layer,
+ const LayerType* outer_viewport_scroll_layer,
+ float page_scale_factor,
+ float device_scale_factor,
+ const gfx::Rect& viewport,
+ const gfx::Transform& device_transform,
+ PropertyTrees* property_trees) {
+ if (!property_trees->needs_rebuild)
+ return;
+
property_trees->sequence_number++;
DataForRecursion<LayerType> data_for_recursion;
@@ -399,9 +439,13 @@ void BuildPropertyTreesTopLevelInternal(LayerType* root_layer,
data_for_recursion.clip_tree_parent = 0;
data_for_recursion.opacity_tree_parent = -1;
data_for_recursion.page_scale_layer = page_scale_layer;
+ data_for_recursion.inner_viewport_scroll_layer = inner_viewport_scroll_layer;
+ data_for_recursion.outer_viewport_scroll_layer = outer_viewport_scroll_layer;
data_for_recursion.page_scale_factor = page_scale_factor;
data_for_recursion.device_scale_factor = device_scale_factor;
- data_for_recursion.in_subtree_of_page_scale_application_layer = false;
+ data_for_recursion.in_subtree_of_page_scale_layer = false;
+ data_for_recursion.affected_by_inner_viewport_bounds_delta = false;
+ data_for_recursion.affected_by_outer_viewport_bounds_delta = false;
data_for_recursion.should_flatten = false;
data_for_recursion.ancestor_clips_subtree = true;
data_for_recursion.device_transform = &device_transform;
@@ -424,35 +468,38 @@ void BuildPropertyTreesTopLevelInternal(LayerType* root_layer,
// building.
property_trees->transform_tree.set_needs_update(false);
property_trees->clip_tree.set_needs_update(true);
+ property_trees->opacity_tree.set_needs_update(false);
}
void PropertyTreeBuilder::BuildPropertyTrees(
Layer* root_layer,
const Layer* page_scale_layer,
+ const Layer* inner_viewport_scroll_layer,
+ const Layer* outer_viewport_scroll_layer,
float page_scale_factor,
float device_scale_factor,
const gfx::Rect& viewport,
const gfx::Transform& device_transform,
PropertyTrees* property_trees) {
- // TODO(enne): hoist this out of here
- if (!property_trees->needs_rebuild)
- return;
-
BuildPropertyTreesTopLevelInternal(
- root_layer, page_scale_layer, page_scale_factor, device_scale_factor,
+ root_layer, page_scale_layer, inner_viewport_scroll_layer,
+ outer_viewport_scroll_layer, page_scale_factor, device_scale_factor,
viewport, device_transform, property_trees);
}
void PropertyTreeBuilder::BuildPropertyTrees(
LayerImpl* root_layer,
const LayerImpl* page_scale_layer,
+ const LayerImpl* inner_viewport_scroll_layer,
+ const LayerImpl* outer_viewport_scroll_layer,
float page_scale_factor,
float device_scale_factor,
const gfx::Rect& viewport,
const gfx::Transform& device_transform,
PropertyTrees* property_trees) {
BuildPropertyTreesTopLevelInternal(
- root_layer, page_scale_layer, page_scale_factor, device_scale_factor,
+ root_layer, page_scale_layer, inner_viewport_scroll_layer,
+ outer_viewport_scroll_layer, page_scale_factor, device_scale_factor,
viewport, device_transform, property_trees);
}
diff --git a/chromium/cc/trees/property_tree_builder.h b/chromium/cc/trees/property_tree_builder.h
index 15f326ef15c..f877aebe3dd 100644
--- a/chromium/cc/trees/property_tree_builder.h
+++ b/chromium/cc/trees/property_tree_builder.h
@@ -20,6 +20,8 @@ class PropertyTreeBuilder {
// in a null |opacity_tree|.
static void BuildPropertyTrees(Layer* root_layer,
const Layer* page_scale_layer,
+ const Layer* inner_viewport_scroll_layer,
+ const Layer* outer_viewport_scroll_layer,
float page_scale_factor,
float device_scale_factor,
const gfx::Rect& viewport,
@@ -27,6 +29,8 @@ class PropertyTreeBuilder {
PropertyTrees* property_trees);
static void BuildPropertyTrees(LayerImpl* root_layer,
const LayerImpl* page_scale_layer,
+ const LayerImpl* inner_viewport_scroll_layer,
+ const LayerImpl* outer_viewport_scroll_layer,
float page_scale_factor,
float device_scale_factor,
const gfx::Rect& viewport,
diff --git a/chromium/cc/trees/property_tree_unittest.cc b/chromium/cc/trees/property_tree_unittest.cc
index 7e179388b5f..8497dca6af1 100644
--- a/chromium/cc/trees/property_tree_unittest.cc
+++ b/chromium/cc/trees/property_tree_unittest.cc
@@ -422,6 +422,68 @@ TEST(PropertyTreeTest, ComputeTransformWithSublayerScale) {
transform);
}
+TEST(PropertyTreeTest, ComputeTransformToTargetWithZeroSublayerScale) {
+ TransformTree tree;
+ TransformNode& root = *tree.Node(0);
+ root.data.target_id = 0;
+ tree.UpdateTransforms(0);
+
+ TransformNode grand_parent;
+ grand_parent.data.local.Scale(2.f, 0.f);
+ grand_parent.data.target_id = 0;
+ grand_parent.data.source_node_id = 0;
+ grand_parent.data.needs_sublayer_scale = true;
+ int grand_parent_id = tree.Insert(grand_parent, 0);
+ tree.Node(grand_parent_id)->data.content_target_id = grand_parent_id;
+ tree.UpdateTransforms(grand_parent_id);
+
+ TransformNode parent;
+ parent.data.local.Translate(1.f, 1.f);
+ parent.data.target_id = grand_parent_id;
+ parent.data.content_target_id = grand_parent_id;
+ parent.data.source_node_id = grand_parent_id;
+ int parent_id = tree.Insert(parent, grand_parent_id);
+ tree.UpdateTransforms(parent_id);
+
+ TransformNode child;
+ child.data.local.Translate(3.f, 4.f);
+ child.data.target_id = grand_parent_id;
+ child.data.content_target_id = grand_parent_id;
+ child.data.source_node_id = parent_id;
+ int child_id = tree.Insert(child, parent_id);
+ tree.UpdateTransforms(child_id);
+
+ gfx::Transform expected_transform;
+ expected_transform.Translate(4.f, 5.f);
+
+ gfx::Transform transform;
+ bool success = tree.ComputeTransform(child_id, grand_parent_id, &transform);
+ EXPECT_TRUE(success);
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform, transform);
+
+ tree.Node(grand_parent_id)->data.local.MakeIdentity();
+ tree.Node(grand_parent_id)->data.local.Scale(0.f, 2.f);
+ tree.Node(grand_parent_id)->data.needs_local_transform_update = true;
+ tree.set_needs_update(true);
+
+ ComputeTransforms(&tree);
+
+ success = tree.ComputeTransform(child_id, grand_parent_id, &transform);
+ EXPECT_TRUE(success);
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform, transform);
+
+ tree.Node(grand_parent_id)->data.local.MakeIdentity();
+ tree.Node(grand_parent_id)->data.local.Scale(0.f, 0.f);
+ tree.Node(grand_parent_id)->data.needs_local_transform_update = true;
+ tree.set_needs_update(true);
+
+ ComputeTransforms(&tree);
+
+ success = tree.ComputeTransform(child_id, grand_parent_id, &transform);
+ EXPECT_TRUE(success);
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform, transform);
+}
+
TEST(PropertyTreeTest, FlatteningWhenDestinationHasOnlyFlatAncestors) {
// This tests that flattening is performed correctly when
// destination and its ancestors are flat, but there are 3d transforms
@@ -464,4 +526,62 @@ TEST(PropertyTreeTest, FlatteningWhenDestinationHasOnlyFlatAncestors) {
grand_child_to_parent);
}
+TEST(PropertyTreeTest, ScreenSpaceOpacityUpdateTest) {
+ // This tests that screen space opacity is updated for the subtree when
+ // opacity of a node changes.
+ OpacityTree tree;
+
+ int parent = tree.Insert(OpacityNode(), 0);
+ int child = tree.Insert(OpacityNode(), parent);
+
+ EXPECT_EQ(tree.Node(child)->data.screen_space_opacity, 1.f);
+ tree.Node(parent)->data.opacity = 0.5f;
+ tree.set_needs_update(true);
+ ComputeOpacities(&tree);
+ EXPECT_EQ(tree.Node(child)->data.screen_space_opacity, 0.5f);
+
+ tree.Node(child)->data.opacity = 0.5f;
+ tree.set_needs_update(true);
+ ComputeOpacities(&tree);
+ EXPECT_EQ(tree.Node(child)->data.screen_space_opacity, 0.25f);
+}
+
+TEST(PropertyTreeTest, NonIntegerTranslationTest) {
+ // This tests that when a node has non-integer translation, the information
+ // is propagated to the subtree.
+ TransformTree tree;
+
+ int parent = tree.Insert(TransformNode(), 0);
+ tree.Node(parent)->data.target_id = parent;
+ tree.Node(parent)->data.local.Translate(1.5f, 1.5f);
+
+ int child = tree.Insert(TransformNode(), parent);
+ tree.Node(child)->data.target_id = parent;
+ tree.Node(child)->data.local.Translate(1, 1);
+ tree.set_needs_update(true);
+ ComputeTransforms(&tree);
+ EXPECT_FALSE(
+ tree.Node(parent)->data.node_and_ancestors_have_only_integer_translation);
+ EXPECT_FALSE(
+ tree.Node(child)->data.node_and_ancestors_have_only_integer_translation);
+
+ tree.Node(parent)->data.local.Translate(0.5f, 0.5f);
+ tree.Node(child)->data.local.Translate(0.5f, 0.5f);
+ tree.set_needs_update(true);
+ ComputeTransforms(&tree);
+ EXPECT_TRUE(
+ tree.Node(parent)->data.node_and_ancestors_have_only_integer_translation);
+ EXPECT_FALSE(
+ tree.Node(child)->data.node_and_ancestors_have_only_integer_translation);
+
+ tree.Node(child)->data.local.Translate(0.5f, 0.5f);
+ tree.Node(child)->data.target_id = child;
+ tree.set_needs_update(true);
+ ComputeTransforms(&tree);
+ EXPECT_TRUE(
+ tree.Node(parent)->data.node_and_ancestors_have_only_integer_translation);
+ EXPECT_TRUE(
+ tree.Node(child)->data.node_and_ancestors_have_only_integer_translation);
+}
+
} // namespace cc
diff --git a/chromium/cc/trees/proxy.cc b/chromium/cc/trees/proxy.cc
index eb81e2e6735..58d10b910cb 100644
--- a/chromium/cc/trees/proxy.cc
+++ b/chromium/cc/trees/proxy.cc
@@ -4,7 +4,6 @@
#include "cc/trees/proxy.h"
-#include "base/message_loop/message_loop_proxy.h"
#include "base/single_thread_task_runner.h"
#include "cc/trees/blocking_task_runner.h"
diff --git a/chromium/cc/trees/proxy.h b/chromium/cc/trees/proxy.h
index 55e54beb6ae..d403ae0eb6d 100644
--- a/chromium/cc/trees/proxy.h
+++ b/chromium/cc/trees/proxy.h
@@ -97,9 +97,6 @@ class CC_EXPORT Proxy {
// to finish before executing in the GPU process.
virtual void ForceSerializeOnSwapBuffers() = 0;
- // Maximum number of sub-region texture updates supported for each commit.
- virtual size_t MaxPartialTextureUpdates() const = 0;
-
virtual bool SupportsImplScrolling() const = 0;
virtual void SetDebugState(const LayerTreeDebugState& debug_state) = 0;
diff --git a/chromium/cc/trees/proxy_timing_history.cc b/chromium/cc/trees/proxy_timing_history.cc
deleted file mode 100644
index 90abad1632f..00000000000
--- a/chromium/cc/trees/proxy_timing_history.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/trees/proxy_timing_history.h"
-
-#include "base/metrics/histogram.h"
-
-const size_t kDurationHistorySize = 60;
-const double kCommitAndActivationDurationEstimationPercentile = 50.0;
-const double kDrawDurationEstimationPercentile = 100.0;
-const int kDrawDurationEstimatePaddingInMicroseconds = 0;
-
-namespace cc {
-
-ProxyTimingHistory::ProxyTimingHistory(
- RenderingStatsInstrumentation* rendering_stats_instrumentation)
- : draw_duration_history_(kDurationHistorySize),
- begin_main_frame_to_commit_duration_history_(kDurationHistorySize),
- commit_to_activate_duration_history_(kDurationHistorySize),
- rendering_stats_instrumentation_(rendering_stats_instrumentation) {
-}
-
-ProxyTimingHistory::~ProxyTimingHistory() {}
-
-base::TimeDelta ProxyTimingHistory::DrawDurationEstimate() const {
- base::TimeDelta historical_estimate =
- draw_duration_history_.Percentile(kDrawDurationEstimationPercentile);
- base::TimeDelta padding = base::TimeDelta::FromMicroseconds(
- kDrawDurationEstimatePaddingInMicroseconds);
- return historical_estimate + padding;
-}
-
-base::TimeDelta ProxyTimingHistory::BeginMainFrameToCommitDurationEstimate()
- const {
- return begin_main_frame_to_commit_duration_history_.Percentile(
- kCommitAndActivationDurationEstimationPercentile);
-}
-
-base::TimeDelta ProxyTimingHistory::CommitToActivateDurationEstimate() const {
- return commit_to_activate_duration_history_.Percentile(
- kCommitAndActivationDurationEstimationPercentile);
-}
-
-void ProxyTimingHistory::DidBeginMainFrame() {
- begin_main_frame_sent_time_ = base::TimeTicks::Now();
-}
-
-void ProxyTimingHistory::DidCommit() {
- commit_complete_time_ = base::TimeTicks::Now();
- base::TimeDelta begin_main_frame_to_commit_duration =
- commit_complete_time_ - begin_main_frame_sent_time_;
-
- // Before adding the new data point to the timing history, see what we would
- // have predicted for this frame. This allows us to keep track of the accuracy
- // of our predictions.
- rendering_stats_instrumentation_->AddBeginMainFrameToCommitDuration(
- begin_main_frame_to_commit_duration,
- BeginMainFrameToCommitDurationEstimate());
-
- begin_main_frame_to_commit_duration_history_.InsertSample(
- begin_main_frame_to_commit_duration);
-}
-
-void ProxyTimingHistory::DidActivateSyncTree() {
- base::TimeDelta commit_to_activate_duration =
- base::TimeTicks::Now() - commit_complete_time_;
-
- // Before adding the new data point to the timing history, see what we would
- // have predicted for this frame. This allows us to keep track of the accuracy
- // of our predictions.
- rendering_stats_instrumentation_->AddCommitToActivateDuration(
- commit_to_activate_duration, CommitToActivateDurationEstimate());
-
- commit_to_activate_duration_history_.InsertSample(
- commit_to_activate_duration);
-}
-
-void ProxyTimingHistory::DidStartDrawing() {
- start_draw_time_ = base::TimeTicks::Now();
-}
-
-void ProxyTimingHistory::DidFinishDrawing() {
- base::TimeDelta draw_duration = base::TimeTicks::Now() - start_draw_time_;
-
- // Before adding the new data point to the timing history, see what we would
- // have predicted for this frame. This allows us to keep track of the accuracy
- // of our predictions.
- base::TimeDelta draw_duration_estimate = DrawDurationEstimate();
- rendering_stats_instrumentation_->AddDrawDuration(draw_duration,
- draw_duration_estimate);
-
- AddDrawDurationUMA(draw_duration, draw_duration_estimate);
-
- draw_duration_history_.InsertSample(draw_duration);
-}
-
-void ProxyTimingHistory::AddDrawDurationUMA(
- base::TimeDelta draw_duration,
- base::TimeDelta draw_duration_estimate) {
- base::TimeDelta draw_duration_overestimate;
- base::TimeDelta draw_duration_underestimate;
- if (draw_duration > draw_duration_estimate)
- draw_duration_underestimate = draw_duration - draw_duration_estimate;
- else
- draw_duration_overestimate = draw_duration_estimate - draw_duration;
- UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDuration",
- draw_duration,
- base::TimeDelta::FromMilliseconds(1),
- base::TimeDelta::FromMilliseconds(100),
- 50);
- UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDurationUnderestimate",
- draw_duration_underestimate,
- base::TimeDelta::FromMilliseconds(1),
- base::TimeDelta::FromMilliseconds(100),
- 50);
- UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDurationOverestimate",
- draw_duration_overestimate,
- base::TimeDelta::FromMilliseconds(1),
- base::TimeDelta::FromMilliseconds(100),
- 50);
-}
-
-} // namespace cc
diff --git a/chromium/cc/trees/proxy_timing_history.h b/chromium/cc/trees/proxy_timing_history.h
deleted file mode 100644
index aa213b6bdb7..00000000000
--- a/chromium/cc/trees/proxy_timing_history.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_TREES_PROXY_TIMING_HISTORY_H_
-#define CC_TREES_PROXY_TIMING_HISTORY_H_
-
-#include "cc/base/rolling_time_delta_history.h"
-#include "cc/debug/rendering_stats_instrumentation.h"
-
-namespace cc {
-
-class ProxyTimingHistory {
- public:
- explicit ProxyTimingHistory(
- RenderingStatsInstrumentation* rendering_stats_instrumentation);
- ~ProxyTimingHistory();
-
- base::TimeDelta DrawDurationEstimate() const;
- base::TimeDelta BeginMainFrameToCommitDurationEstimate() const;
- base::TimeDelta CommitToActivateDurationEstimate() const;
-
- void DidBeginMainFrame();
- void DidCommit();
- void DidActivateSyncTree();
- void DidStartDrawing();
- void DidFinishDrawing();
-
- protected:
- void AddDrawDurationUMA(base::TimeDelta draw_duration,
- base::TimeDelta draw_duration_estimate);
-
- RollingTimeDeltaHistory draw_duration_history_;
- RollingTimeDeltaHistory begin_main_frame_to_commit_duration_history_;
- RollingTimeDeltaHistory commit_to_activate_duration_history_;
-
- base::TimeTicks begin_main_frame_sent_time_;
- base::TimeTicks commit_complete_time_;
- base::TimeTicks start_draw_time_;
-
- RenderingStatsInstrumentation* rendering_stats_instrumentation_;
-};
-
-} // namespace cc
-
-#endif // CC_TREES_PROXY_TIMING_HISTORY_H_
diff --git a/chromium/cc/trees/single_thread_proxy.cc b/chromium/cc/trees/single_thread_proxy.cc
index f05a9a6a529..b6d120b4805 100644
--- a/chromium/cc/trees/single_thread_proxy.cc
+++ b/chromium/cc/trees/single_thread_proxy.cc
@@ -12,14 +12,13 @@
#include "cc/output/context_provider.h"
#include "cc/output/output_surface.h"
#include "cc/quads/draw_quad.h"
-#include "cc/resources/prioritized_resource_manager.h"
-#include "cc/resources/resource_update_controller.h"
#include "cc/scheduler/commit_earlyout_reason.h"
+#include "cc/scheduler/compositor_timing_history.h"
+#include "cc/scheduler/scheduler.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/layer_tree_host_single_thread_client.h"
#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/scoped_abort_remaining_swap_promises.h"
-#include "ui/gfx/frame_time.h"
namespace cc {
@@ -43,7 +42,7 @@ SingleThreadProxy::SingleThreadProxy(
: Proxy(main_task_runner, NULL),
layer_tree_host_(layer_tree_host),
client_(client),
- timing_history_(layer_tree_host->rendering_stats_instrumentation()),
+ external_begin_frame_source_(external_begin_frame_source.Pass()),
next_frame_is_newly_committed_frame_(false),
#if DCHECK_IS_ON()
inside_impl_frame_(false),
@@ -63,11 +62,16 @@ SingleThreadProxy::SingleThreadProxy(
!scheduler_on_impl_thread_) {
SchedulerSettings scheduler_settings(
layer_tree_host->settings().ToSchedulerSettings());
- // SingleThreadProxy should run in main thread low latency mode.
- scheduler_settings.main_thread_should_always_be_low_latency = true;
+ scheduler_settings.commit_to_active_tree = CommitToActiveTree();
+
+ scoped_ptr<CompositorTimingHistory> compositor_timing_history(
+ new CompositorTimingHistory(
+ layer_tree_host->rendering_stats_instrumentation()));
+
scheduler_on_impl_thread_ = Scheduler::Create(
this, scheduler_settings, layer_tree_host_->id(),
- MainThreadTaskRunner(), external_begin_frame_source.Pass());
+ MainThreadTaskRunner(), external_begin_frame_source_.get(),
+ compositor_timing_history.Pass());
}
}
@@ -153,8 +157,6 @@ void SingleThreadProxy::SetOutputSurface(
{
DebugScopedSetMainThreadBlocked main_thread_blocked(this);
DebugScopedSetImplThread impl(this);
- layer_tree_host_->DeleteContentsTexturesOnImplThread(
- layer_tree_host_impl_->resource_provider());
success = layer_tree_host_impl_->InitializeRenderer(output_surface.Pass());
}
@@ -243,39 +245,10 @@ void SingleThreadProxy::DoCommit() {
blocking_main_thread_task_runner()));
layer_tree_host_impl_->BeginCommit();
-
- if (PrioritizedResourceManager* contents_texture_manager =
- layer_tree_host_->contents_texture_manager()) {
- // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
- // is fixed.
- tracked_objects::ScopedTracker tracking_profile3(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "461509 SingleThreadProxy::DoCommit3"));
- contents_texture_manager->PushTexturePrioritiesToBackings();
- }
layer_tree_host_->BeginCommitOnImplThread(layer_tree_host_impl_.get());
// TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
// is fixed.
- tracked_objects::ScopedTracker tracking_profile4(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "461509 SingleThreadProxy::DoCommit4"));
- scoped_ptr<ResourceUpdateController> update_controller =
- ResourceUpdateController::Create(
- NULL,
- MainThreadTaskRunner(),
- queue_for_commit_.Pass(),
- layer_tree_host_impl_->resource_provider());
-
- // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
- // is fixed.
- tracked_objects::ScopedTracker tracking_profile5(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "461509 SingleThreadProxy::DoCommit5"));
- update_controller->Finalize();
-
- // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
- // is fixed.
tracked_objects::ScopedTracker tracking_profile6(
FROM_HERE_WITH_EXPLICIT_FUNCTION(
"461509 SingleThreadProxy::DoCommit6"));
@@ -298,26 +271,17 @@ void SingleThreadProxy::DoCommit() {
DCHECK_EQ(1.f, scroll_info->page_scale_delta);
#endif
- if (layer_tree_host_->settings().impl_side_painting) {
- // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
- // is fixed.
- tracked_objects::ScopedTracker tracking_profile8(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "461509 SingleThreadProxy::DoCommit8"));
- // Commit goes directly to the active tree, but we need to synchronously
- // "activate" the tree still during commit to satisfy any potential
- // SetNextCommitWaitsForActivation calls. Unfortunately, the tree
- // might not be ready to draw, so DidActivateSyncTree must set
- // the flag to force the tree to not draw until textures are ready.
- NotifyReadyToActivate();
- } else {
- // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
- // is fixed.
- tracked_objects::ScopedTracker tracking_profile9(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "461509 SingleThreadProxy::DoCommit9"));
- CommitComplete();
- }
+ // TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
+ // is fixed.
+ tracked_objects::ScopedTracker tracking_profile8(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "461509 SingleThreadProxy::DoCommit8"));
+ // Commit goes directly to the active tree, but we need to synchronously
+ // "activate" the tree still during commit to satisfy any potential
+ // SetNextCommitWaitsForActivation calls. Unfortunately, the tree
+ // might not be ready to draw, so DidActivateSyncTree must set
+ // the flag to force the tree to not draw until textures are ready.
+ NotifyReadyToActivate();
}
}
@@ -326,6 +290,9 @@ void SingleThreadProxy::CommitComplete() {
<< "Activation is expected to have synchronously occurred by now.";
DCHECK(commit_blocking_task_runner_);
+ if (scheduler_on_impl_thread_)
+ scheduler_on_impl_thread_->DidCommit();
+
// Notify commit complete on the impl side after activate to satisfy any
// SetNextCommitWaitsForActivation calls.
layer_tree_host_impl_->CommitComplete();
@@ -334,7 +301,6 @@ void SingleThreadProxy::CommitComplete() {
commit_blocking_task_runner_.reset();
layer_tree_host_->CommitComplete();
layer_tree_host_->DidBeginMainFrame();
- timing_history_.DidCommit();
next_frame_is_newly_committed_frame_ = true;
}
@@ -394,10 +360,6 @@ bool SingleThreadProxy::BeginMainFrameRequested() const {
return commit_requested_;
}
-size_t SingleThreadProxy::MaxPartialTextureUpdates() const {
- return std::numeric_limits<size_t>::max();
-}
-
void SingleThreadProxy::Stop() {
TRACE_EVENT0("cc", "SingleThreadProxy::stop");
DCHECK(Proxy::IsMainThread());
@@ -407,8 +369,6 @@ void SingleThreadProxy::Stop() {
BlockingTaskRunner::CapturePostTasks blocked(
blocking_main_thread_task_runner());
- layer_tree_host_->DeleteContentsTexturesOnImplThread(
- layer_tree_host_impl_->resource_provider());
scheduler_on_impl_thread_ = nullptr;
layer_tree_host_impl_ = nullptr;
}
@@ -484,45 +444,27 @@ void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
layer_tree_host_->SetAnimationEvents(events.Pass());
}
-bool SingleThreadProxy::ReduceContentsTextureMemoryOnImplThread(
- size_t limit_bytes,
- int priority_cutoff) {
- DCHECK(IsImplThread());
- PrioritizedResourceManager* contents_texture_manager =
- layer_tree_host_->contents_texture_manager();
-
- ResourceProvider* resource_provider =
- layer_tree_host_impl_->resource_provider();
-
- if (!contents_texture_manager || !resource_provider)
- return false;
-
- return contents_texture_manager->ReduceMemoryOnImplThread(
- limit_bytes, priority_cutoff, resource_provider);
-}
-
bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; }
void SingleThreadProxy::DidActivateSyncTree() {
- // Non-impl-side painting finishes commit in DoCommit. Impl-side painting
- // defers until here to simulate SetNextCommitWaitsForActivation.
- if (layer_tree_host_impl_->settings().impl_side_painting) {
- // This is required because NotifyReadyToActivate gets called immediately
- // after commit since single thread commits directly to the active tree.
- if (scheduler_on_impl_thread_)
- scheduler_on_impl_thread_->SetWaitForReadyToDraw();
+ // This is required because NotifyReadyToActivate gets called immediately
+ // after commit since single thread commits directly to the active tree.
+ if (scheduler_on_impl_thread_)
+ scheduler_on_impl_thread_->SetWaitForReadyToDraw();
- // Synchronously call to CommitComplete. Resetting
- // |commit_blocking_task_runner| would make sure all tasks posted during
- // commit/activation before CommitComplete.
- CommitComplete();
- }
+ // Synchronously call to CommitComplete. Resetting
+ // |commit_blocking_task_runner| would make sure all tasks posted during
+ // commit/activation before CommitComplete.
+ CommitComplete();
+}
- timing_history_.DidActivateSyncTree();
+void SingleThreadProxy::WillPrepareTiles() {
+ DCHECK(Proxy::IsImplThread());
+ if (scheduler_on_impl_thread_)
+ scheduler_on_impl_thread_->WillPrepareTiles();
}
void SingleThreadProxy::DidPrepareTiles() {
- DCHECK(layer_tree_host_impl_->settings().impl_side_painting);
DCHECK(Proxy::IsImplThread());
if (scheduler_on_impl_thread_)
scheduler_on_impl_thread_->DidPrepareTiles();
@@ -586,6 +528,26 @@ void SingleThreadProxy::OnDrawForOutputSurface() {
NOTREACHED() << "Implemented by ThreadProxy for synchronous compositor.";
}
+void SingleThreadProxy::PostFrameTimingEventsOnImplThread(
+ scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events,
+ scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) {
+ layer_tree_host_->RecordFrameTimingEvents(composite_events.Pass(),
+ main_frame_events.Pass());
+}
+
+void SingleThreadProxy::LayoutAndUpdateLayers() {
+ if (layer_tree_host_->output_surface_lost()) {
+ RequestNewOutputSurface();
+ // RequestNewOutputSurface could have synchronously created an output
+ // surface, so check again before returning.
+ if (layer_tree_host_->output_surface_lost())
+ return;
+ }
+
+ layer_tree_host_->Layout();
+ layer_tree_host_->UpdateLayers();
+}
+
void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) {
TRACE_EVENT0("cc,benchmark", "SingleThreadProxy::CompositeImmediately");
DCHECK(Proxy::IsMainThread());
@@ -627,13 +589,11 @@ void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) {
// Finish the impl frame.
{
DebugScopedSetImplThread impl(this);
- if (layer_tree_host_impl_->settings().impl_side_painting) {
- layer_tree_host_impl_->ActivateSyncTree();
- DCHECK(!layer_tree_host_impl_->active_tree()
- ->needs_update_draw_properties());
- layer_tree_host_impl_->PrepareTiles();
- layer_tree_host_impl_->SynchronouslyInitializeAllTiles();
- }
+ layer_tree_host_impl_->ActivateSyncTree();
+ DCHECK(
+ !layer_tree_host_impl_->active_tree()->needs_update_draw_properties());
+ layer_tree_host_impl_->PrepareTiles();
+ layer_tree_host_impl_->SynchronouslyInitializeAllTiles();
DoAnimate();
@@ -704,8 +664,6 @@ DrawResult SingleThreadProxy::DoComposite(LayerTreeHostImpl::FrameData* frame) {
return DRAW_ABORTED_CANT_DRAW;
}
- timing_history_.DidStartDrawing();
-
// TODO(robliao): Remove ScopedTracker below once https://crbug.com/461509
// is fixed.
tracked_objects::ScopedTracker tracking_profile2(
@@ -741,7 +699,6 @@ DrawResult SingleThreadProxy::DoComposite(LayerTreeHostImpl::FrameData* frame) {
tracked_objects::ScopedTracker tracking_profile7(
FROM_HERE_WITH_EXPLICIT_FUNCTION(
"461509 SingleThreadProxy::DoComposite7"));
- timing_history_.DidFinishDrawing();
}
if (draw_frame) {
@@ -883,24 +840,10 @@ void SingleThreadProxy::DoBeginMainFrame(
layer_tree_host_->AnimateLayers(begin_frame_args.frame_time);
layer_tree_host_->Layout();
- if (PrioritizedResourceManager* contents_texture_manager =
- layer_tree_host_->contents_texture_manager()) {
- contents_texture_manager->UnlinkAndClearEvictedBackings();
- contents_texture_manager->SetMaxMemoryLimitBytes(
- layer_tree_host_impl_->memory_allocation_limit_bytes());
- contents_texture_manager->SetExternalPriorityCutoff(
- layer_tree_host_impl_->memory_allocation_priority_cutoff());
- }
-
- DCHECK(!queue_for_commit_);
- queue_for_commit_ = make_scoped_ptr(new ResourceUpdateQueue);
-
// New commits requested inside UpdateLayers should be respected.
commit_requested_ = false;
- layer_tree_host_->UpdateLayers(queue_for_commit_.get());
-
- timing_history_.DidBeginMainFrame();
+ layer_tree_host_->UpdateLayers();
// TODO(enne): SingleThreadProxy does not support cancelling commits yet,
// search for CommitEarlyOutReason::FINISHED_NO_UPDATES inside
@@ -964,7 +907,6 @@ void SingleThreadProxy::ScheduledActionBeginOutputSurfaceCreation() {
void SingleThreadProxy::ScheduledActionPrepareTiles() {
TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionPrepareTiles");
- DCHECK(layer_tree_host_impl_->settings().impl_side_painting);
DebugScopedSetImplThread impl(this);
layer_tree_host_impl_->PrepareTiles();
}
@@ -973,21 +915,6 @@ void SingleThreadProxy::ScheduledActionInvalidateOutputSurface() {
NOTREACHED();
}
-void SingleThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) {
-}
-
-base::TimeDelta SingleThreadProxy::DrawDurationEstimate() {
- return timing_history_.DrawDurationEstimate();
-}
-
-base::TimeDelta SingleThreadProxy::BeginMainFrameToCommitDurationEstimate() {
- return timing_history_.BeginMainFrameToCommitDurationEstimate();
-}
-
-base::TimeDelta SingleThreadProxy::CommitToActivateDurationEstimate() {
- return timing_history_.CommitToActivateDurationEstimate();
-}
-
void SingleThreadProxy::DidFinishImplFrame() {
layer_tree_host_impl_->DidFinishImplFrame();
#if DCHECK_IS_ON()
diff --git a/chromium/cc/trees/single_thread_proxy.h b/chromium/cc/trees/single_thread_proxy.h
index 98ac5e5c7d4..8bec2b133f9 100644
--- a/chromium/cc/trees/single_thread_proxy.h
+++ b/chromium/cc/trees/single_thread_proxy.h
@@ -15,7 +15,6 @@
#include "cc/trees/blocking_task_runner.h"
#include "cc/trees/layer_tree_host_impl.h"
#include "cc/trees/proxy.h"
-#include "cc/trees/proxy_timing_history.h"
namespace cc {
@@ -23,7 +22,6 @@ class BeginFrameSource;
class ContextProvider;
class LayerTreeHost;
class LayerTreeHostSingleThreadClient;
-class ResourceUpdateQueue;
class CC_EXPORT SingleThreadProxy : public Proxy,
NON_EXPORTED_BASE(LayerTreeHostImplClient),
@@ -57,7 +55,6 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
void MainThreadHasStoppedFlinging() override {}
void Start() override;
void Stop() override;
- size_t MaxPartialTextureUpdates() const override;
void ForceSerializeOnSwapBuffers() override;
bool SupportsImplScrolling() const override;
bool MainFrameWillHappenForTesting() override;
@@ -76,10 +73,6 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
void ScheduledActionBeginOutputSurfaceCreation() override;
void ScheduledActionPrepareTiles() override;
void ScheduledActionInvalidateOutputSurface() override;
- void DidAnticipatedDrawTimeChange(base::TimeTicks time) override;
- base::TimeDelta DrawDurationEstimate() override;
- base::TimeDelta BeginMainFrameToCommitDurationEstimate() override;
- base::TimeDelta CommitToActivateDurationEstimate() override;
void SendBeginFramesToChildren(const BeginFrameArgs& args) override;
void SendBeginMainFrameNotExpectedSoon() override;
@@ -103,22 +96,26 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
void SetVideoNeedsBeginFrames(bool needs_begin_frames) override;
void PostAnimationEventsToMainThreadOnImplThread(
scoped_ptr<AnimationEventsVector> events) override;
- bool ReduceContentsTextureMemoryOnImplThread(size_t limit_bytes,
- int priority_cutoff) override;
bool IsInsideDraw() override;
void RenewTreePriority() override {}
void PostDelayedAnimationTaskOnImplThread(const base::Closure& task,
base::TimeDelta delay) override {}
void DidActivateSyncTree() override;
+ void WillPrepareTiles() override;
void DidPrepareTiles() override;
void DidCompletePageScaleAnimationOnImplThread() override;
void OnDrawForOutputSurface() override;
+ void PostFrameTimingEventsOnImplThread(
+ scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events,
+ scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events)
+ override;
void SetDebugState(const LayerTreeDebugState& debug_state) override {}
void RequestNewOutputSurface();
// Called by the legacy path where RenderWidget does the scheduling.
+ void LayoutAndUpdateLayers();
void CompositeImmediately(base::TimeTicks frame_begin_time);
protected:
@@ -152,11 +149,10 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
RendererCapabilities renderer_capabilities_for_main_thread_;
// Accessed from both threads.
+ scoped_ptr<BeginFrameSource> external_begin_frame_source_;
scoped_ptr<Scheduler> scheduler_on_impl_thread_;
- ProxyTimingHistory timing_history_;
scoped_ptr<BlockingTaskRunner::CapturePostTasks> commit_blocking_task_runner_;
- scoped_ptr<ResourceUpdateQueue> queue_for_commit_;
bool next_frame_is_newly_committed_frame_;
#if DCHECK_IS_ON()
diff --git a/chromium/cc/trees/thread_proxy.cc b/chromium/cc/trees/thread_proxy.cc
index 3010fba95c3..533c4906a01 100644
--- a/chromium/cc/trees/thread_proxy.cc
+++ b/chromium/cc/trees/thread_proxy.cc
@@ -19,16 +19,14 @@
#include "cc/output/output_surface.h"
#include "cc/output/swap_promise.h"
#include "cc/quads/draw_quad.h"
-#include "cc/resources/prioritized_resource_manager.h"
#include "cc/scheduler/commit_earlyout_reason.h"
-#include "cc/scheduler/delay_based_time_source.h"
+#include "cc/scheduler/compositor_timing_history.h"
#include "cc/scheduler/scheduler.h"
#include "cc/trees/blocking_task_runner.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/scoped_abort_remaining_swap_promises.h"
#include "gpu/command_buffer/client/gles2_interface.h"
-#include "ui/gfx/frame_time.h"
namespace cc {
@@ -98,18 +96,12 @@ ThreadProxy::MainThreadOrBlockedMainThread::MainThreadOrBlockedMainThread(
ThreadProxy::MainThreadOrBlockedMainThread::~MainThreadOrBlockedMainThread() {}
-PrioritizedResourceManager*
-ThreadProxy::MainThreadOrBlockedMainThread::contents_texture_manager() {
- return layer_tree_host->contents_texture_manager();
-}
-
ThreadProxy::CompositorThreadOnly::CompositorThreadOnly(
ThreadProxy* proxy,
int layer_tree_host_id,
RenderingStatsInstrumentation* rendering_stats_instrumentation,
scoped_ptr<BeginFrameSource> external_begin_frame_source)
: layer_tree_host_id(layer_tree_host_id),
- contents_texture_manager(NULL),
commit_completion_event(NULL),
completion_event_for_commit_held_on_tree_activation(NULL),
next_frame_is_newly_committed_frame(false),
@@ -120,8 +112,8 @@ ThreadProxy::CompositorThreadOnly::CompositorThreadOnly(
base::Bind(&ThreadProxy::RenewTreePriority, base::Unretained(proxy)),
base::TimeDelta::FromMilliseconds(
kSmoothnessTakesPriorityExpirationDelay * 1000)),
- timing_history(rendering_stats_instrumentation),
external_begin_frame_source(external_begin_frame_source.Pass()),
+ rendering_stats_instrumentation(rendering_stats_instrumentation),
weak_factory(proxy) {
}
@@ -154,9 +146,9 @@ bool ThreadProxy::IsStarted() const {
}
bool ThreadProxy::CommitToActiveTree() const {
- // With ThreadProxy and impl-side painting, we use a pending tree and activate
- // it once it's ready to draw.
- return !impl().layer_tree_host_impl->settings().impl_side_painting;
+ // With ThreadProxy, we use a pending tree and activate it once it's ready to
+ // draw to allow input to modify the active tree and draw during raster.
+ return false;
}
void ThreadProxy::SetLayerTreeHostClientReady() {
@@ -213,22 +205,6 @@ void ThreadProxy::DidLoseOutputSurface() {
TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurface");
DCHECK(IsMainThread());
layer_tree_host()->DidLoseOutputSurface();
-
- {
- DebugScopedSetMainThreadBlocked main_thread_blocked(this);
-
- // Return lost resources to their owners immediately.
- BlockingTaskRunner::CapturePostTasks blocked(
- blocking_main_thread_task_runner());
-
- CompletionEvent completion;
- Proxy::ImplThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::Bind(&ThreadProxy::DeleteContentsTexturesOnImplThread,
- impl_thread_weak_ptr_,
- &completion));
- completion.Wait();
- }
}
void ThreadProxy::RequestNewOutputSurface() {
@@ -422,32 +398,6 @@ void ThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
base::Passed(&events)));
}
-bool ThreadProxy::ReduceContentsTextureMemoryOnImplThread(size_t limit_bytes,
- int priority_cutoff) {
- DCHECK(IsImplThread());
-
- if (!impl().contents_texture_manager)
- return false;
- if (!impl().layer_tree_host_impl->resource_provider())
- return false;
-
- bool reduce_result =
- impl().contents_texture_manager->ReduceMemoryOnImplThread(
- limit_bytes,
- priority_cutoff,
- impl().layer_tree_host_impl->resource_provider());
- if (!reduce_result)
- return false;
-
- // The texture upload queue may reference textures that were just purged,
- // clear them from the queue.
- if (impl().current_resource_update_controller) {
- impl()
- .current_resource_update_controller->DiscardUploadsToEvictedResources();
- }
- return true;
-}
-
bool ThreadProxy::IsInsideDraw() { return impl().inside_draw; }
void ThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) {
@@ -700,14 +650,8 @@ void ThreadProxy::ScheduledActionSendBeginMainFrame() {
impl().layer_tree_host_impl->CurrentBeginFrameArgs();
begin_main_frame_state->scroll_info =
impl().layer_tree_host_impl->ProcessScrollDeltas();
-
- if (!impl().layer_tree_host_impl->settings().impl_side_painting) {
- DCHECK_GT(impl().layer_tree_host_impl->memory_allocation_limit_bytes(), 0u);
- }
begin_main_frame_state->memory_allocation_limit_bytes =
impl().layer_tree_host_impl->memory_allocation_limit_bytes();
- begin_main_frame_state->memory_allocation_priority_cutoff =
- impl().layer_tree_host_impl->memory_allocation_priority_cutoff();
begin_main_frame_state->evicted_ui_resources =
impl().layer_tree_host_impl->EvictedUIResourcesExist();
// TODO(vmpstr): This needs to be fixed if
@@ -721,7 +665,6 @@ void ThreadProxy::ScheduledActionSendBeginMainFrame() {
base::Passed(&begin_main_frame_state)));
devtools_instrumentation::DidRequestMainThreadFrame(
impl().layer_tree_host_id);
- impl().timing_history.DidBeginMainFrame();
}
void ThreadProxy::SendBeginMainFrameNotExpectedSoon() {
@@ -797,17 +740,6 @@ void ThreadProxy::BeginMainFrame(
layer_tree_host()->AnimateLayers(
begin_main_frame_state->begin_frame_args.frame_time);
- // Unlink any backings that the impl thread has evicted, so that we know to
- // re-paint them in UpdateLayers.
- if (blocked_main().contents_texture_manager()) {
- blocked_main().contents_texture_manager()->UnlinkAndClearEvictedBackings();
-
- blocked_main().contents_texture_manager()->SetMaxMemoryLimitBytes(
- begin_main_frame_state->memory_allocation_limit_bytes);
- blocked_main().contents_texture_manager()->SetExternalPriorityCutoff(
- begin_main_frame_state->memory_allocation_priority_cutoff);
- }
-
// Recreate all UI resources if there were evicted UI resources when the impl
// thread initiated the commit.
if (begin_main_frame_state->evicted_ui_resources)
@@ -825,10 +757,7 @@ void ThreadProxy::BeginMainFrame(
main().can_cancel_commit && !begin_main_frame_state->evicted_ui_resources;
main().can_cancel_commit = true;
- scoped_ptr<ResourceUpdateQueue> queue =
- make_scoped_ptr(new ResourceUpdateQueue);
-
- bool updated = layer_tree_host()->UpdateLayers(queue.get());
+ bool updated = layer_tree_host()->UpdateLayers();
layer_tree_host()->WillCommit();
devtools_instrumentation::ScopedCommitTrace commit_task(
@@ -878,11 +807,8 @@ void ThreadProxy::BeginMainFrame(
CompletionEvent completion;
Proxy::ImplThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::Bind(&ThreadProxy::StartCommitOnImplThread,
- impl_thread_weak_ptr_,
- &completion,
- queue.release()));
+ FROM_HERE, base::Bind(&ThreadProxy::StartCommitOnImplThread,
+ impl_thread_weak_ptr_, &completion));
completion.Wait();
}
@@ -896,8 +822,7 @@ void ThreadProxy::BeginMainFrameNotExpectedSoon() {
layer_tree_host()->BeginMainFrameNotExpectedSoon();
}
-void ThreadProxy::StartCommitOnImplThread(CompletionEvent* completion,
- ResourceUpdateQueue* raw_queue) {
+void ThreadProxy::StartCommitOnImplThread(CompletionEvent* completion) {
TRACE_EVENT0("cc", "ThreadProxy::StartCommitOnImplThread");
DCHECK(!impl().commit_completion_event);
DCHECK(IsImplThread() && IsMainThreadBlocked());
@@ -914,39 +839,8 @@ void ThreadProxy::StartCommitOnImplThread(CompletionEvent* completion,
// Ideally, we should inform to impl thread when BeginMainFrame is started.
// But, we can avoid a PostTask in here.
impl().scheduler->NotifyBeginMainFrameStarted();
-
- scoped_ptr<ResourceUpdateQueue> queue(raw_queue);
-
- if (impl().contents_texture_manager) {
- DCHECK_EQ(impl().contents_texture_manager,
- blocked_main().contents_texture_manager());
- } else {
- // Cache this pointer that was created on the main thread side to avoid a
- // data race between creating it and using it on the compositor thread.
- impl().contents_texture_manager = blocked_main().contents_texture_manager();
- }
-
- if (impl().contents_texture_manager) {
- if (impl().contents_texture_manager->LinkedEvictedBackingsExist()) {
- // Clear any uploads we were making to textures linked to evicted
- // resources
- queue->ClearUploadsToEvictedResources();
- // Some textures in the layer tree are invalid. Kick off another commit
- // to fill them again.
- SetNeedsCommitOnImplThread();
- }
-
- impl().contents_texture_manager->PushTexturePrioritiesToBackings();
- }
-
impl().commit_completion_event = completion;
- impl().current_resource_update_controller = ResourceUpdateController::Create(
- this,
- Proxy::ImplThreadTaskRunner(),
- queue.Pass(),
- impl().layer_tree_host_impl->resource_provider());
- impl().current_resource_update_controller->PerformMoreUpdates(
- impl().scheduler->AnticipatedDrawTime());
+ impl().scheduler->NotifyReadyToCommit();
}
void ThreadProxy::BeginMainFrameAbortedOnImplThread(
@@ -994,11 +888,6 @@ void ThreadProxy::ScheduledActionCommit() {
DCHECK(IsImplThread());
DCHECK(IsMainThreadBlocked());
DCHECK(impl().commit_completion_event);
- DCHECK(impl().current_resource_update_controller);
-
- // Complete all remaining texture updates.
- impl().current_resource_update_controller->Finalize();
- impl().current_resource_update_controller = nullptr;
blocked_main().main_thread_inside_commit = true;
impl().layer_tree_host_impl->BeginCommit();
@@ -1007,8 +896,7 @@ void ThreadProxy::ScheduledActionCommit() {
impl().layer_tree_host_impl.get());
blocked_main().main_thread_inside_commit = false;
- bool hold_commit = layer_tree_host()->settings().impl_side_painting &&
- blocked_main().commit_waits_for_activation;
+ bool hold_commit = blocked_main().commit_waits_for_activation;
blocked_main().commit_waits_for_activation = false;
if (hold_commit) {
@@ -1024,6 +912,8 @@ void ThreadProxy::ScheduledActionCommit() {
impl().commit_completion_event = NULL;
}
+ impl().scheduler->DidCommit();
+
// Delay this step until afer the main thread has been released as it's
// often a good bit of work to update the tree and prepare the new frame.
impl().layer_tree_host_impl->CommitComplete();
@@ -1031,8 +921,6 @@ void ThreadProxy::ScheduledActionCommit() {
SetInputThrottledUntilCommitOnImplThread(false);
impl().next_frame_is_newly_committed_frame = true;
-
- impl().timing_history.DidCommit();
}
void ThreadProxy::ScheduledActionActivateSyncTree() {
@@ -1056,7 +944,6 @@ DrawResult ThreadProxy::DrawSwapInternal(bool forced_draw) {
DCHECK(IsImplThread());
DCHECK(impl().layer_tree_host_impl.get());
- impl().timing_history.DidStartDrawing();
base::AutoReset<bool> mark_inside(&impl().inside_draw, true);
if (impl().layer_tree_host_impl->pending_tree()) {
@@ -1108,16 +995,12 @@ DrawResult ThreadProxy::DrawSwapInternal(bool forced_draw) {
base::Bind(&ThreadProxy::DidCommitAndDrawFrame, main_thread_weak_ptr_));
}
- if (result == DRAW_SUCCESS)
- impl().timing_history.DidFinishDrawing();
-
DCHECK_NE(INVALID_RESULT, result);
return result;
}
void ThreadProxy::ScheduledActionPrepareTiles() {
TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionPrepareTiles");
- DCHECK(impl().layer_tree_host_impl->settings().impl_side_painting);
impl().layer_tree_host_impl->PrepareTiles();
}
@@ -1145,23 +1028,6 @@ void ThreadProxy::ScheduledActionInvalidateOutputSurface() {
impl().layer_tree_host_impl->output_surface()->Invalidate();
}
-void ThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) {
- if (impl().current_resource_update_controller)
- impl().current_resource_update_controller->PerformMoreUpdates(time);
-}
-
-base::TimeDelta ThreadProxy::DrawDurationEstimate() {
- return impl().timing_history.DrawDurationEstimate();
-}
-
-base::TimeDelta ThreadProxy::BeginMainFrameToCommitDurationEstimate() {
- return impl().timing_history.BeginMainFrameToCommitDurationEstimate();
-}
-
-base::TimeDelta ThreadProxy::CommitToActivateDurationEstimate() {
- return impl().timing_history.CommitToActivateDurationEstimate();
-}
-
void ThreadProxy::DidFinishImplFrame() {
impl().layer_tree_host_impl->DidFinishImplFrame();
}
@@ -1175,11 +1041,6 @@ void ThreadProxy::SetAuthoritativeVSyncInterval(
NOTREACHED() << "Only used by SingleThreadProxy";
}
-void ThreadProxy::ReadyToFinalizeTextureUpdates() {
- DCHECK(IsImplThread());
- impl().scheduler->NotifyReadyToCommit();
-}
-
void ThreadProxy::DidCommitAndDrawFrame() {
DCHECK(IsMainThread());
layer_tree_host()->DidCommitAndDrawFrame();
@@ -1201,29 +1062,23 @@ void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) {
DCHECK(IsImplThread());
impl().layer_tree_host_impl =
layer_tree_host()->CreateLayerTreeHostImpl(this);
+
SchedulerSettings scheduler_settings(
layer_tree_host()->settings().ToSchedulerSettings());
+
+ scoped_ptr<CompositorTimingHistory> compositor_timing_history(
+ new CompositorTimingHistory(impl().rendering_stats_instrumentation));
+
impl().scheduler = Scheduler::Create(
- this,
- scheduler_settings,
- impl().layer_tree_host_id,
- ImplThreadTaskRunner(),
- impl().external_begin_frame_source.Pass());
+ this, scheduler_settings, impl().layer_tree_host_id,
+ ImplThreadTaskRunner(), impl().external_begin_frame_source.get(),
+ compositor_timing_history.Pass());
+
impl().scheduler->SetVisible(impl().layer_tree_host_impl->visible());
impl_thread_weak_ptr_ = impl().weak_factory.GetWeakPtr();
completion->Signal();
}
-void ThreadProxy::DeleteContentsTexturesOnImplThread(
- CompletionEvent* completion) {
- TRACE_EVENT0("cc", "ThreadProxy::DeleteContentsTexturesOnImplThread");
- DCHECK(IsImplThread());
- DCHECK(IsMainThreadBlocked());
- layer_tree_host()->DeleteContentsTexturesOnImplThread(
- impl().layer_tree_host_impl->resource_provider());
- completion->Signal();
-}
-
void ThreadProxy::InitializeOutputSurfaceOnImplThread(
scoped_ptr<OutputSurface> output_surface) {
TRACE_EVENT0("cc", "ThreadProxy::InitializeOutputSurfaceOnImplThread");
@@ -1264,27 +1119,19 @@ void ThreadProxy::LayerTreeHostClosedOnImplThread(CompletionEvent* completion) {
TRACE_EVENT0("cc", "ThreadProxy::LayerTreeHostClosedOnImplThread");
DCHECK(IsImplThread());
DCHECK(IsMainThreadBlocked());
- layer_tree_host()->DeleteContentsTexturesOnImplThread(
- impl().layer_tree_host_impl->resource_provider());
- impl().current_resource_update_controller = nullptr;
impl().scheduler = nullptr;
+ impl().external_begin_frame_source = nullptr;
impl().layer_tree_host_impl = nullptr;
impl().weak_factory.InvalidateWeakPtrs();
// We need to explicitly shutdown the notifier to destroy any weakptrs it is
// holding while still on the compositor thread. This also ensures any
// callbacks holding a ThreadProxy pointer are cancelled.
impl().smoothness_priority_expiration_notifier.Shutdown();
- impl().contents_texture_manager = NULL;
completion->Signal();
}
-size_t ThreadProxy::MaxPartialTextureUpdates() const {
- return ResourceUpdateController::MaxPartialTextureUpdates();
-}
-
ThreadProxy::BeginMainFrameAndCommitState::BeginMainFrameAndCommitState()
: memory_allocation_limit_bytes(0),
- memory_allocation_priority_cutoff(0),
evicted_ui_resources(false) {}
ThreadProxy::BeginMainFrameAndCommitState::~BeginMainFrameAndCommitState() {}
@@ -1340,10 +1187,9 @@ void ThreadProxy::RenewTreePriority() {
if (impl().smoothness_priority_expiration_notifier.HasPendingNotification())
priority = SMOOTHNESS_TAKES_PRIORITY;
- // New content always takes priority when the active tree has
- // evicted resources or there is an invalid viewport size.
- if (impl().layer_tree_host_impl->active_tree()->ContentsTexturesPurged() ||
- impl().layer_tree_host_impl->active_tree()->ViewportSizeInvalid() ||
+ // New content always takes priority when there is an invalid viewport size or
+ // ui resources have been evicted.
+ if (impl().layer_tree_host_impl->active_tree()->ViewportSizeInvalid() ||
impl().layer_tree_host_impl->EvictedUIResourcesExist() ||
impl().input_throttled_until_commit) {
// Once we enter NEW_CONTENTS_TAKES_PRIORITY mode, visible tiles on active
@@ -1386,16 +1232,19 @@ void ThreadProxy::DidActivateSyncTree() {
if (impl().completion_event_for_commit_held_on_tree_activation) {
TRACE_EVENT_INSTANT0(
"cc", "ReleaseCommitbyActivation", TRACE_EVENT_SCOPE_THREAD);
- DCHECK(impl().layer_tree_host_impl->settings().impl_side_painting);
impl().completion_event_for_commit_held_on_tree_activation->Signal();
impl().completion_event_for_commit_held_on_tree_activation = NULL;
}
- impl().timing_history.DidActivateSyncTree();
impl().last_processed_begin_main_frame_args =
impl().last_begin_main_frame_args;
}
+void ThreadProxy::WillPrepareTiles() {
+ DCHECK(IsImplThread());
+ impl().scheduler->WillPrepareTiles();
+}
+
void ThreadProxy::DidPrepareTiles() {
DCHECK(IsImplThread());
impl().scheduler->DidPrepareTiles();
@@ -1413,4 +1262,23 @@ void ThreadProxy::OnDrawForOutputSurface() {
impl().scheduler->OnDrawForOutputSurface();
}
+void ThreadProxy::PostFrameTimingEventsOnImplThread(
+ scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events,
+ scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) {
+ DCHECK(IsImplThread());
+ Proxy::MainThreadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::Bind(&ThreadProxy::PostFrameTimingEvents, main_thread_weak_ptr_,
+ base::Passed(composite_events.Pass()),
+ base::Passed(main_frame_events.Pass())));
+}
+
+void ThreadProxy::PostFrameTimingEvents(
+ scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events,
+ scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) {
+ DCHECK(IsMainThread());
+ layer_tree_host()->RecordFrameTimingEvents(composite_events.Pass(),
+ main_frame_events.Pass());
+}
+
} // namespace cc
diff --git a/chromium/cc/trees/thread_proxy.h b/chromium/cc/trees/thread_proxy.h
index f4f1f283c77..ca76e42669b 100644
--- a/chromium/cc/trees/thread_proxy.h
+++ b/chromium/cc/trees/thread_proxy.h
@@ -13,12 +13,10 @@
#include "cc/animation/animation_events.h"
#include "cc/base/completion_event.h"
#include "cc/base/delayed_unique_notifier.h"
-#include "cc/resources/resource_update_controller.h"
#include "cc/scheduler/commit_earlyout_reason.h"
#include "cc/scheduler/scheduler.h"
#include "cc/trees/layer_tree_host_impl.h"
#include "cc/trees/proxy.h"
-#include "cc/trees/proxy_timing_history.h"
namespace base {
class SingleThreadTaskRunner;
@@ -30,15 +28,12 @@ class BeginFrameSource;
class ContextProvider;
class InputHandlerClient;
class LayerTreeHost;
-class PrioritizedResourceManager;
-class ResourceUpdateQueue;
class Scheduler;
class ScopedThreadProxy;
class CC_EXPORT ThreadProxy : public Proxy,
- NON_EXPORTED_BASE(LayerTreeHostImplClient),
- NON_EXPORTED_BASE(SchedulerClient),
- NON_EXPORTED_BASE(ResourceUpdateControllerClient) {
+ NON_EXPORTED_BASE(LayerTreeHostImplClient),
+ NON_EXPORTED_BASE(SchedulerClient) {
public:
static scoped_ptr<Proxy> Create(
LayerTreeHost* layer_tree_host,
@@ -56,7 +51,6 @@ class CC_EXPORT ThreadProxy : public Proxy,
BeginFrameArgs begin_frame_args;
scoped_ptr<ScrollAndScaleSet> scroll_info;
size_t memory_allocation_limit_bytes;
- int memory_allocation_priority_cutoff;
bool evicted_ui_resources;
};
@@ -88,8 +82,6 @@ class CC_EXPORT ThreadProxy : public Proxy,
explicit MainThreadOrBlockedMainThread(LayerTreeHost* host);
~MainThreadOrBlockedMainThread();
- PrioritizedResourceManager* contents_texture_manager();
-
LayerTreeHost* layer_tree_host;
bool commit_waits_for_activation;
bool main_thread_inside_commit;
@@ -105,10 +97,6 @@ class CC_EXPORT ThreadProxy : public Proxy,
const int layer_tree_host_id;
- // Copy of the main thread side contents texture manager for work
- // that needs to be done on the compositor thread.
- PrioritizedResourceManager* contents_texture_manager;
-
scoped_ptr<Scheduler> scheduler;
// Set when the main thread is waiting on a
@@ -121,8 +109,6 @@ class CC_EXPORT ThreadProxy : public Proxy,
// Set when the main thread is waiting on a pending tree activation.
CompletionEvent* completion_event_for_commit_held_on_tree_activation;
- scoped_ptr<ResourceUpdateController> current_resource_update_controller;
-
// Set when the next draw should post DidCommitAndDrawFrame to the main
// thread.
bool next_frame_is_newly_committed_frame;
@@ -139,10 +125,10 @@ class CC_EXPORT ThreadProxy : public Proxy,
DelayedUniqueNotifier smoothness_priority_expiration_notifier;
- ProxyTimingHistory timing_history;
-
scoped_ptr<BeginFrameSource> external_begin_frame_source;
+ RenderingStatsInstrumentation* rendering_stats_instrumentation;
+
// Values used to keep track of frame durations. Used only in frame timing.
BeginFrameArgs last_begin_main_frame_args;
BeginFrameArgs last_processed_begin_main_frame_args;
@@ -176,7 +162,6 @@ class CC_EXPORT ThreadProxy : public Proxy,
void MainThreadHasStoppedFlinging() override;
void Start() override;
void Stop() override;
- size_t MaxPartialTextureUpdates() const override;
void ForceSerializeOnSwapBuffers() override;
bool SupportsImplScrolling() const override;
void SetDebugState(const LayerTreeDebugState& debug_state) override;
@@ -207,16 +192,20 @@ class CC_EXPORT ThreadProxy : public Proxy,
void SetVideoNeedsBeginFrames(bool needs_begin_frames) override;
void PostAnimationEventsToMainThreadOnImplThread(
scoped_ptr<AnimationEventsVector> queue) override;
- bool ReduceContentsTextureMemoryOnImplThread(size_t limit_bytes,
- int priority_cutoff) override;
bool IsInsideDraw() override;
void RenewTreePriority() override;
void PostDelayedAnimationTaskOnImplThread(const base::Closure& task,
base::TimeDelta delay) override;
void DidActivateSyncTree() override;
+ void WillPrepareTiles() override;
void DidPrepareTiles() override;
void DidCompletePageScaleAnimationOnImplThread() override;
void OnDrawForOutputSurface() override;
+ // This should only be called by LayerTreeHostImpl::PostFrameTimingEvents.
+ void PostFrameTimingEventsOnImplThread(
+ scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events,
+ scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events)
+ override;
// SchedulerClient implementation
void WillBeginImplFrame(const BeginFrameArgs& args) override;
@@ -230,16 +219,9 @@ class CC_EXPORT ThreadProxy : public Proxy,
void ScheduledActionBeginOutputSurfaceCreation() override;
void ScheduledActionPrepareTiles() override;
void ScheduledActionInvalidateOutputSurface() override;
- void DidAnticipatedDrawTimeChange(base::TimeTicks time) override;
- base::TimeDelta DrawDurationEstimate() override;
- base::TimeDelta BeginMainFrameToCommitDurationEstimate() override;
- base::TimeDelta CommitToActivateDurationEstimate() override;
void SendBeginFramesToChildren(const BeginFrameArgs& args) override;
void SendBeginMainFrameNotExpectedSoon() override;
- // ResourceUpdateControllerClient implementation
- void ReadyToFinalizeTextureUpdates() override;
-
protected:
ThreadProxy(
LayerTreeHost* layer_tree_host,
@@ -267,8 +249,7 @@ class CC_EXPORT ThreadProxy : public Proxy,
// Called on impl thread.
struct SchedulerStateRequest;
- void StartCommitOnImplThread(CompletionEvent* completion,
- ResourceUpdateQueue* queue);
+ void StartCommitOnImplThread(CompletionEvent* completion);
void BeginMainFrameAbortedOnImplThread(CommitEarlyOutReason reason);
void FinishAllRenderingOnImplThread(CompletionEvent* completion);
void InitializeImplOnImplThread(CompletionEvent* completion);
@@ -292,6 +273,9 @@ class CC_EXPORT ThreadProxy : public Proxy,
void SetInputThrottledUntilCommitOnImplThread(bool is_throttled);
void SetDebugStateOnImplThread(const LayerTreeDebugState& debug_state);
void SetDeferCommitsOnImplThread(bool defer_commits) const;
+ void PostFrameTimingEvents(
+ scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events,
+ scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events);
LayerTreeHost* layer_tree_host();
const LayerTreeHost* layer_tree_host() const;
diff --git a/chromium/cc/trees/tree_synchronizer.cc b/chromium/cc/trees/tree_synchronizer.cc
index 8fe23077a41..3646dcaa4f7 100644
--- a/chromium/cc/trees/tree_synchronizer.cc
+++ b/chromium/cc/trees/tree_synchronizer.cc
@@ -188,7 +188,7 @@ template <typename LayerType>
void TreeSynchronizer::PushPropertiesInternal(
LayerType* layer,
LayerImpl* layer_impl,
- size_t* num_dependents_need_push_properties_for_parent) {
+ int* num_dependents_need_push_properties_for_parent) {
if (!layer) {
DCHECK(!layer_impl);
return;
@@ -205,7 +205,7 @@ void TreeSynchronizer::PushPropertiesInternal(
else if (layer->ToScrollbarLayer())
layer->ToScrollbarLayer()->PushScrollClipPropertiesTo(layer_impl);
- size_t num_dependents_need_push_properties = 0;
+ int num_dependents_need_push_properties = 0;
if (recurse_on_children_and_dependents) {
PushPropertiesInternal(layer->mask_layer(),
layer_impl->mask_layer(),
@@ -295,7 +295,7 @@ static void CheckScrollAndClipPointersRecursive(Layer* layer,
void TreeSynchronizer::PushProperties(Layer* layer,
LayerImpl* layer_impl) {
- size_t num_dependents_need_push_properties = 0;
+ int num_dependents_need_push_properties = 0;
PushPropertiesInternal(
layer, layer_impl, &num_dependents_need_push_properties);
#if DCHECK_IS_ON()
@@ -304,7 +304,7 @@ void TreeSynchronizer::PushProperties(Layer* layer,
}
void TreeSynchronizer::PushProperties(LayerImpl* layer, LayerImpl* layer_impl) {
- size_t num_dependents_need_push_properties = 0;
+ int num_dependents_need_push_properties = 0;
PushPropertiesInternal(
layer, layer_impl, &num_dependents_need_push_properties);
}
diff --git a/chromium/cc/trees/tree_synchronizer.h b/chromium/cc/trees/tree_synchronizer.h
index e7b2e2bdeda..ef13b1dba81 100644
--- a/chromium/cc/trees/tree_synchronizer.h
+++ b/chromium/cc/trees/tree_synchronizer.h
@@ -42,7 +42,7 @@ class CC_EXPORT TreeSynchronizer {
static void PushPropertiesInternal(
LayerType* layer,
LayerImpl* layer_impl,
- size_t* num_dependents_need_push_properties_for_parent);
+ int* num_dependents_need_push_properties_for_parent);
DISALLOW_COPY_AND_ASSIGN(TreeSynchronizer);
};
diff --git a/chromium/cc/trees/tree_synchronizer_unittest.cc b/chromium/cc/trees/tree_synchronizer_unittest.cc
index a17bec8e53b..466a7017a72 100644
--- a/chromium/cc/trees/tree_synchronizer_unittest.cc
+++ b/chromium/cc/trees/tree_synchronizer_unittest.cc
@@ -18,6 +18,7 @@
#include "cc/test/fake_layer_tree_host.h"
#include "cc/test/fake_rendering_stats_instrumentation.h"
#include "cc/test/test_shared_bitmap_manager.h"
+#include "cc/test/test_task_graph_runner.h"
#include "cc/trees/proxy.h"
#include "cc/trees/single_thread_proxy.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -51,8 +52,10 @@ class MockLayerImpl : public LayerImpl {
class MockLayer : public Layer {
public:
static scoped_refptr<MockLayer> Create(
+ const LayerSettings& settings,
std::vector<int>* layer_impl_destruction_list) {
- return make_scoped_refptr(new MockLayer(layer_impl_destruction_list));
+ return make_scoped_refptr(
+ new MockLayer(settings, layer_impl_destruction_list));
}
scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override {
@@ -67,8 +70,10 @@ class MockLayer : public Layer {
}
private:
- explicit MockLayer(std::vector<int>* layer_impl_destruction_list)
- : Layer(), layer_impl_destruction_list_(layer_impl_destruction_list) {}
+ explicit MockLayer(const LayerSettings& settings,
+ std::vector<int>* layer_impl_destruction_list)
+ : Layer(settings),
+ layer_impl_destruction_list_(layer_impl_destruction_list) {}
~MockLayer() override {}
std::vector<int>* layer_impl_destruction_list_;
@@ -191,11 +196,13 @@ class TreeSynchronizerTest : public testing::Test {
public:
TreeSynchronizerTest()
: client_(FakeLayerTreeHostClient::DIRECT_3D),
- host_(FakeLayerTreeHost::Create(&client_)) {}
+ host_(FakeLayerTreeHost::Create(&client_, &task_graph_runner_)) {}
protected:
FakeLayerTreeHostClient client_;
+ TestTaskGraphRunner task_graph_runner_;
scoped_ptr<FakeLayerTreeHost> host_;
+ LayerSettings layer_settings_;
};
// Attempts to synchronizes a null tree. This should not crash, and should
@@ -211,9 +218,9 @@ TEST_F(TreeSynchronizerTest, SyncNullTree) {
// Constructs a very simple tree and synchronizes it without trying to reuse any
// preexisting layers.
TEST_F(TreeSynchronizerTest, SyncSimpleTreeFromEmpty) {
- scoped_refptr<Layer> layer_tree_root = Layer::Create();
- layer_tree_root->AddChild(Layer::Create());
- layer_tree_root->AddChild(Layer::Create());
+ scoped_refptr<Layer> layer_tree_root = Layer::Create(layer_settings_);
+ layer_tree_root->AddChild(Layer::Create(layer_settings_));
+ layer_tree_root->AddChild(Layer::Create(layer_settings_));
host_->SetRootLayer(layer_tree_root);
@@ -232,9 +239,11 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeReusingLayers) {
std::vector<int> layer_impl_destruction_list;
scoped_refptr<Layer> layer_tree_root =
- MockLayer::Create(&layer_impl_destruction_list);
- layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));
- layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));
+ MockLayer::Create(layer_settings_, &layer_impl_destruction_list);
+ layer_tree_root->AddChild(
+ MockLayer::Create(layer_settings_, &layer_impl_destruction_list));
+ layer_tree_root->AddChild(
+ MockLayer::Create(layer_settings_, &layer_impl_destruction_list));
host_->SetRootLayer(layer_tree_root);
@@ -250,8 +259,8 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeReusingLayers) {
layer_impl_tree_root.get());
// Add a new layer to the Layer side
- layer_tree_root->children()[0]->
- AddChild(MockLayer::Create(&layer_impl_destruction_list));
+ layer_tree_root->children()[0]->AddChild(
+ MockLayer::Create(layer_settings_, &layer_impl_destruction_list));
// Remove one.
layer_tree_root->children()[1]->RemoveFromParent();
int second_layer_impl_id = layer_impl_tree_root->children()[1]->id();
@@ -278,9 +287,11 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndTrackStackingOrderChange) {
// Set up the tree and sync once. child2 needs to be synced here, too, even
// though we remove it to set up the intended scenario.
scoped_refptr<Layer> layer_tree_root =
- MockLayer::Create(&layer_impl_destruction_list);
- scoped_refptr<Layer> child2 = MockLayer::Create(&layer_impl_destruction_list);
- layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));
+ MockLayer::Create(layer_settings_, &layer_impl_destruction_list);
+ scoped_refptr<Layer> child2 =
+ MockLayer::Create(layer_settings_, &layer_impl_destruction_list);
+ layer_tree_root->AddChild(
+ MockLayer::Create(layer_settings_, &layer_impl_destruction_list));
layer_tree_root->AddChild(child2);
host_->SetRootLayer(layer_tree_root);
@@ -319,9 +330,9 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndTrackStackingOrderChange) {
}
TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndProperties) {
- scoped_refptr<Layer> layer_tree_root = Layer::Create();
- layer_tree_root->AddChild(Layer::Create());
- layer_tree_root->AddChild(Layer::Create());
+ scoped_refptr<Layer> layer_tree_root = Layer::Create(layer_settings_);
+ layer_tree_root->AddChild(Layer::Create(layer_settings_));
+ layer_tree_root->AddChild(Layer::Create(layer_settings_));
host_->SetRootLayer(layer_tree_root);
@@ -372,17 +383,21 @@ TEST_F(TreeSynchronizerTest, ReuseLayerImplsAfterStructuralChange) {
// |
// +--- D
scoped_refptr<Layer> layer_tree_root =
- MockLayer::Create(&layer_impl_destruction_list);
- layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));
+ MockLayer::Create(layer_settings_, &layer_impl_destruction_list);
+ layer_tree_root->AddChild(
+ MockLayer::Create(layer_settings_, &layer_impl_destruction_list));
scoped_refptr<Layer> layer_a = layer_tree_root->children()[0].get();
- layer_a->AddChild(MockLayer::Create(&layer_impl_destruction_list));
+ layer_a->AddChild(
+ MockLayer::Create(layer_settings_, &layer_impl_destruction_list));
scoped_refptr<Layer> layer_b = layer_a->children()[0].get();
- layer_b->AddChild(MockLayer::Create(&layer_impl_destruction_list));
+ layer_b->AddChild(
+ MockLayer::Create(layer_settings_, &layer_impl_destruction_list));
scoped_refptr<Layer> layer_c = layer_b->children()[0].get();
- layer_b->AddChild(MockLayer::Create(&layer_impl_destruction_list));
+ layer_b->AddChild(
+ MockLayer::Create(layer_settings_, &layer_impl_destruction_list));
scoped_refptr<Layer> layer_d = layer_b->children()[1].get();
host_->SetRootLayer(layer_tree_root);
@@ -431,11 +446,11 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeThenDestroy) {
std::vector<int> layer_impl_destruction_list;
scoped_refptr<Layer> old_layer_tree_root =
- MockLayer::Create(&layer_impl_destruction_list);
+ MockLayer::Create(layer_settings_, &layer_impl_destruction_list);
old_layer_tree_root->AddChild(
- MockLayer::Create(&layer_impl_destruction_list));
+ MockLayer::Create(layer_settings_, &layer_impl_destruction_list));
old_layer_tree_root->AddChild(
- MockLayer::Create(&layer_impl_destruction_list));
+ MockLayer::Create(layer_settings_, &layer_impl_destruction_list));
host_->SetRootLayer(old_layer_tree_root);
@@ -459,7 +474,7 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeThenDestroy) {
// Synchronize again. After the sync all LayerImpls from the old tree should
// be deleted.
- scoped_refptr<Layer> new_layer_tree_root = Layer::Create();
+ scoped_refptr<Layer> new_layer_tree_root = Layer::Create(layer_settings_);
host_->SetRootLayer(new_layer_tree_root);
layer_impl_tree_root =
TreeSynchronizer::SynchronizeTrees(new_layer_tree_root.get(),
@@ -487,22 +502,22 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeThenDestroy) {
// Constructs+syncs a tree with mask, replica, and replica mask layers.
TEST_F(TreeSynchronizerTest, SyncMaskReplicaAndReplicaMaskLayers) {
- scoped_refptr<Layer> layer_tree_root = Layer::Create();
- layer_tree_root->AddChild(Layer::Create());
- layer_tree_root->AddChild(Layer::Create());
- layer_tree_root->AddChild(Layer::Create());
+ scoped_refptr<Layer> layer_tree_root = Layer::Create(layer_settings_);
+ layer_tree_root->AddChild(Layer::Create(layer_settings_));
+ layer_tree_root->AddChild(Layer::Create(layer_settings_));
+ layer_tree_root->AddChild(Layer::Create(layer_settings_));
// First child gets a mask layer.
- scoped_refptr<Layer> mask_layer = Layer::Create();
+ scoped_refptr<Layer> mask_layer = Layer::Create(layer_settings_);
layer_tree_root->children()[0]->SetMaskLayer(mask_layer.get());
// Second child gets a replica layer.
- scoped_refptr<Layer> replica_layer = Layer::Create();
+ scoped_refptr<Layer> replica_layer = Layer::Create(layer_settings_);
layer_tree_root->children()[1]->SetReplicaLayer(replica_layer.get());
// Third child gets a replica layer with a mask layer.
- scoped_refptr<Layer> replica_layer_with_mask = Layer::Create();
- scoped_refptr<Layer> replica_mask_layer = Layer::Create();
+ scoped_refptr<Layer> replica_layer_with_mask = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> replica_mask_layer = Layer::Create(layer_settings_);
replica_layer_with_mask->SetMaskLayer(replica_mask_layer.get());
layer_tree_root->children()[2]->
SetReplicaLayer(replica_layer_with_mask.get());
@@ -553,13 +568,13 @@ TEST_F(TreeSynchronizerTest, SynchronizeAnimations) {
FakeProxy proxy;
DebugScopedSetImplThread impl(&proxy);
FakeRenderingStatsInstrumentation stats_instrumentation;
- scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
- new TestSharedBitmapManager());
- scoped_ptr<LayerTreeHostImpl> host_impl =
- LayerTreeHostImpl::Create(settings, NULL, &proxy, &stats_instrumentation,
- shared_bitmap_manager.get(), NULL, NULL, 0);
+ TestSharedBitmapManager shared_bitmap_manager;
+ TestTaskGraphRunner task_graph_runner;
+ scoped_ptr<LayerTreeHostImpl> host_impl = LayerTreeHostImpl::Create(
+ settings, nullptr, &proxy, &stats_instrumentation, &shared_bitmap_manager,
+ nullptr, &task_graph_runner, 0);
- scoped_refptr<Layer> layer_tree_root = Layer::Create();
+ scoped_refptr<Layer> layer_tree_root = Layer::Create(layer_settings_);
host_->SetRootLayer(layer_tree_root);
layer_tree_root->SetLayerAnimationControllerForTest(
@@ -587,17 +602,17 @@ TEST_F(TreeSynchronizerTest, SynchronizeScrollParent) {
FakeProxy proxy;
DebugScopedSetImplThread impl(&proxy);
FakeRenderingStatsInstrumentation stats_instrumentation;
- scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
- new TestSharedBitmapManager());
- scoped_ptr<LayerTreeHostImpl> host_impl =
- LayerTreeHostImpl::Create(settings, NULL, &proxy, &stats_instrumentation,
- shared_bitmap_manager.get(), NULL, NULL, 0);
-
- scoped_refptr<Layer> layer_tree_root = Layer::Create();
- scoped_refptr<Layer> scroll_parent = Layer::Create();
+ TestSharedBitmapManager shared_bitmap_manager;
+ TestTaskGraphRunner task_graph_runner;
+ scoped_ptr<LayerTreeHostImpl> host_impl = LayerTreeHostImpl::Create(
+ settings, nullptr, &proxy, &stats_instrumentation, &shared_bitmap_manager,
+ nullptr, &task_graph_runner, 0);
+
+ scoped_refptr<Layer> layer_tree_root = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> scroll_parent = Layer::Create(layer_settings_);
layer_tree_root->AddChild(scroll_parent);
- layer_tree_root->AddChild(Layer::Create());
- layer_tree_root->AddChild(Layer::Create());
+ layer_tree_root->AddChild(Layer::Create(layer_settings_));
+ layer_tree_root->AddChild(Layer::Create(layer_settings_));
host_->SetRootLayer(layer_tree_root);
@@ -633,7 +648,7 @@ TEST_F(TreeSynchronizerTest, SynchronizeScrollParent) {
}
// Add an additional scroll layer.
- scoped_refptr<Layer> additional_scroll_child = Layer::Create();
+ scoped_refptr<Layer> additional_scroll_child = Layer::Create(layer_settings_);
layer_tree_root->AddChild(additional_scroll_child);
additional_scroll_child->SetScrollParent(scroll_parent.get());
layer_impl_tree_root =
@@ -655,17 +670,17 @@ TEST_F(TreeSynchronizerTest, SynchronizeClipParent) {
FakeProxy proxy;
DebugScopedSetImplThread impl(&proxy);
FakeRenderingStatsInstrumentation stats_instrumentation;
- scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
- new TestSharedBitmapManager());
- scoped_ptr<LayerTreeHostImpl> host_impl =
- LayerTreeHostImpl::Create(settings, NULL, &proxy, &stats_instrumentation,
- shared_bitmap_manager.get(), NULL, NULL, 0);
-
- scoped_refptr<Layer> layer_tree_root = Layer::Create();
- scoped_refptr<Layer> clip_parent = Layer::Create();
- scoped_refptr<Layer> intervening = Layer::Create();
- scoped_refptr<Layer> clip_child1 = Layer::Create();
- scoped_refptr<Layer> clip_child2 = Layer::Create();
+ TestSharedBitmapManager shared_bitmap_manager;
+ TestTaskGraphRunner task_graph_runner;
+ scoped_ptr<LayerTreeHostImpl> host_impl = LayerTreeHostImpl::Create(
+ settings, nullptr, &proxy, &stats_instrumentation, &shared_bitmap_manager,
+ nullptr, &task_graph_runner, 0);
+
+ scoped_refptr<Layer> layer_tree_root = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> clip_parent = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> intervening = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> clip_child1 = Layer::Create(layer_settings_);
+ scoped_refptr<Layer> clip_child2 = Layer::Create(layer_settings_);
layer_tree_root->AddChild(clip_parent);
clip_parent->AddChild(intervening);
intervening->AddChild(clip_child1);
@@ -701,7 +716,7 @@ TEST_F(TreeSynchronizerTest, SynchronizeClipParent) {
host_impl->active_tree());
// Add an additional clip child.
- scoped_refptr<Layer> additional_clip_child = Layer::Create();
+ scoped_refptr<Layer> additional_clip_child = Layer::Create(layer_settings_);
intervening->AddChild(additional_clip_child);
additional_clip_child->SetClipParent(clip_parent.get());
layer_impl_tree_root =